Commit 23c5a948 authored by Jeroen Hofstee's avatar Jeroen Hofstee Committed by Marc Kleine-Budde
Browse files

can: c_can: D_CAN: c_can_chip_config(): perform a sofware reset on open

When the CAN interface is closed it the hardwre is put in power down
mode, but does not reset the error counters / state. Reset the D_CAN on
open, so the reported state and the actual state match.

According to [1], the C_CAN module doesn't have the software reset.

[1] http://www.bosch-semiconductors.com/media/ip_modules/pdf_2/c_can_fd8/users_manual_c_can_fd8_r210_1.pdf



Signed-off-by: default avatarJeroen Hofstee <jhofstee@victronenergy.com>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 3cb3eaac
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@
#define CONTROL_EX_PDR		BIT(8)

/* control register */
#define CONTROL_SWR		BIT(15)
#define CONTROL_TEST		BIT(7)
#define CONTROL_CCE		BIT(6)
#define CONTROL_DISABLE_AR	BIT(5)
@@ -572,6 +573,26 @@ static void c_can_configure_msg_objects(struct net_device *dev)
				   IF_MCONT_RCV_EOB);
}

static int c_can_software_reset(struct net_device *dev)
{
	struct c_can_priv *priv = netdev_priv(dev);
	int retry = 0;

	if (priv->type != BOSCH_D_CAN)
		return 0;

	priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_SWR | CONTROL_INIT);
	while (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_SWR) {
		msleep(20);
		if (retry++ > 100) {
			netdev_err(dev, "CCTRL: software reset failed\n");
			return -EIO;
		}
	}

	return 0;
}

/*
 * Configure C_CAN chip:
 * - enable/disable auto-retransmission
@@ -581,6 +602,11 @@ static void c_can_configure_msg_objects(struct net_device *dev)
static int c_can_chip_config(struct net_device *dev)
{
	struct c_can_priv *priv = netdev_priv(dev);
	int err;

	err = c_can_software_reset(dev);
	if (err)
		return err;

	/* enable automatic retransmission */
	priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_ENABLE_AR);