Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec56acfe authored by Stefan Agner's avatar Stefan Agner Committed by Marc Kleine-Budde
Browse files

can: flexcan: flexcan_get_berr_counter(): switch on clocks before accessing ecr register



The funcion flexcan_get_berr_counter() may be called from userspace even if the
interface is down, this the clocks are disabled. This patch switches on the
clocks before accessing the ecr register.

Reported-by: default avatarAshutosh Singh <ashuleapyear@gmail.com>
Signed-off-by: default avatarStefan Agner <stefan@agner.ch>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 4ade6feb
Loading
Loading
Loading
Loading
+27 −3
Original line number Diff line number Diff line
@@ -378,7 +378,8 @@ static int flexcan_chip_softreset(struct flexcan_priv *priv)
	return 0;
}

static int flexcan_get_berr_counter(const struct net_device *dev,

static int __flexcan_get_berr_counter(const struct net_device *dev,
				      struct can_berr_counter *bec)
{
	const struct flexcan_priv *priv = netdev_priv(dev);
@@ -391,6 +392,29 @@ static int flexcan_get_berr_counter(const struct net_device *dev,
	return 0;
}

static int flexcan_get_berr_counter(const struct net_device *dev,
				    struct can_berr_counter *bec)
{
	const struct flexcan_priv *priv = netdev_priv(dev);
	int err;

	err = clk_prepare_enable(priv->clk_ipg);
	if (err)
		return err;

	err = clk_prepare_enable(priv->clk_per);
	if (err)
		goto out_disable_ipg;

	err = __flexcan_get_berr_counter(dev, bec);

	clk_disable_unprepare(priv->clk_per);
 out_disable_ipg:
	clk_disable_unprepare(priv->clk_ipg);

	return err;
}

static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	const struct flexcan_priv *priv = netdev_priv(dev);
@@ -503,7 +527,7 @@ static void do_state(struct net_device *dev,
	struct flexcan_priv *priv = netdev_priv(dev);
	struct can_berr_counter bec;

	flexcan_get_berr_counter(dev, &bec);
	__flexcan_get_berr_counter(dev, &bec);

	switch (priv->can.state) {
	case CAN_STATE_ERROR_ACTIVE: