can: sja1000: Validate initialization state in start method
When sja1000 is not compiled as module the SJA1000 chip is only initialized during device registration on kernel boot. Should the chip get a hardware reset there is no way to reinitialize it without re- booting the Linux kernel. This patch adds a check in sja1000_start if the chip is initialized, if not we initialize it. Signed-off-by: Mirza Krak <mirza.krak@hostmobility.com> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
parent
02784f1b05
commit
9e37bc6c63
@ -172,6 +172,35 @@ static void set_normal_mode(struct net_device *dev)
|
||||
netdev_err(dev, "setting SJA1000 into normal mode failed!\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize SJA1000 chip:
|
||||
* - reset chip
|
||||
* - set output mode
|
||||
* - set baudrate
|
||||
* - enable interrupts
|
||||
* - start operating mode
|
||||
*/
|
||||
static void chipset_init(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
|
||||
/* set clock divider and output control register */
|
||||
priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN);
|
||||
|
||||
/* set acceptance filter (accept all) */
|
||||
priv->write_reg(priv, SJA1000_ACCC0, 0x00);
|
||||
priv->write_reg(priv, SJA1000_ACCC1, 0x00);
|
||||
priv->write_reg(priv, SJA1000_ACCC2, 0x00);
|
||||
priv->write_reg(priv, SJA1000_ACCC3, 0x00);
|
||||
|
||||
priv->write_reg(priv, SJA1000_ACCM0, 0xFF);
|
||||
priv->write_reg(priv, SJA1000_ACCM1, 0xFF);
|
||||
priv->write_reg(priv, SJA1000_ACCM2, 0xFF);
|
||||
priv->write_reg(priv, SJA1000_ACCM3, 0xFF);
|
||||
|
||||
priv->write_reg(priv, SJA1000_OCR, priv->ocr | OCR_MODE_NORMAL);
|
||||
}
|
||||
|
||||
static void sja1000_start(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
@ -180,6 +209,10 @@ static void sja1000_start(struct net_device *dev)
|
||||
if (priv->can.state != CAN_STATE_STOPPED)
|
||||
set_reset_mode(dev);
|
||||
|
||||
/* Initialize chip if uninitialized at this stage */
|
||||
if (!(priv->read_reg(priv, SJA1000_CDR) & CDR_PELICAN))
|
||||
chipset_init(dev);
|
||||
|
||||
/* Clear error counters and error code capture */
|
||||
priv->write_reg(priv, SJA1000_TXERR, 0x0);
|
||||
priv->write_reg(priv, SJA1000_RXERR, 0x0);
|
||||
@ -236,35 +269,6 @@ static int sja1000_get_berr_counter(const struct net_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize SJA1000 chip:
|
||||
* - reset chip
|
||||
* - set output mode
|
||||
* - set baudrate
|
||||
* - enable interrupts
|
||||
* - start operating mode
|
||||
*/
|
||||
static void chipset_init(struct net_device *dev)
|
||||
{
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
|
||||
/* set clock divider and output control register */
|
||||
priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN);
|
||||
|
||||
/* set acceptance filter (accept all) */
|
||||
priv->write_reg(priv, SJA1000_ACCC0, 0x00);
|
||||
priv->write_reg(priv, SJA1000_ACCC1, 0x00);
|
||||
priv->write_reg(priv, SJA1000_ACCC2, 0x00);
|
||||
priv->write_reg(priv, SJA1000_ACCC3, 0x00);
|
||||
|
||||
priv->write_reg(priv, SJA1000_ACCM0, 0xFF);
|
||||
priv->write_reg(priv, SJA1000_ACCM1, 0xFF);
|
||||
priv->write_reg(priv, SJA1000_ACCM2, 0xFF);
|
||||
priv->write_reg(priv, SJA1000_ACCM3, 0xFF);
|
||||
|
||||
priv->write_reg(priv, SJA1000_OCR, priv->ocr | OCR_MODE_NORMAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* transmit a CAN message
|
||||
* message layout in the sk_buff should be like this:
|
||||
|
Loading…
Reference in New Issue
Block a user