Skip to content

Commit 9e37bc6

Browse files
mirzakmarckleinebudde
authored andcommitted
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 <[email protected]> Signed-off-by: Marc Kleine-Budde <[email protected]>
1 parent 02784f1 commit 9e37bc6

File tree

1 file changed

+33
-29
lines changed

1 file changed

+33
-29
lines changed

drivers/net/can/sja1000/sja1000.c

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,35 @@ static void set_normal_mode(struct net_device *dev)
172172
netdev_err(dev, "setting SJA1000 into normal mode failed!\n");
173173
}
174174

175+
/*
176+
* initialize SJA1000 chip:
177+
* - reset chip
178+
* - set output mode
179+
* - set baudrate
180+
* - enable interrupts
181+
* - start operating mode
182+
*/
183+
static void chipset_init(struct net_device *dev)
184+
{
185+
struct sja1000_priv *priv = netdev_priv(dev);
186+
187+
/* set clock divider and output control register */
188+
priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN);
189+
190+
/* set acceptance filter (accept all) */
191+
priv->write_reg(priv, SJA1000_ACCC0, 0x00);
192+
priv->write_reg(priv, SJA1000_ACCC1, 0x00);
193+
priv->write_reg(priv, SJA1000_ACCC2, 0x00);
194+
priv->write_reg(priv, SJA1000_ACCC3, 0x00);
195+
196+
priv->write_reg(priv, SJA1000_ACCM0, 0xFF);
197+
priv->write_reg(priv, SJA1000_ACCM1, 0xFF);
198+
priv->write_reg(priv, SJA1000_ACCM2, 0xFF);
199+
priv->write_reg(priv, SJA1000_ACCM3, 0xFF);
200+
201+
priv->write_reg(priv, SJA1000_OCR, priv->ocr | OCR_MODE_NORMAL);
202+
}
203+
175204
static void sja1000_start(struct net_device *dev)
176205
{
177206
struct sja1000_priv *priv = netdev_priv(dev);
@@ -180,6 +209,10 @@ static void sja1000_start(struct net_device *dev)
180209
if (priv->can.state != CAN_STATE_STOPPED)
181210
set_reset_mode(dev);
182211

212+
/* Initialize chip if uninitialized at this stage */
213+
if (!(priv->read_reg(priv, SJA1000_CDR) & CDR_PELICAN))
214+
chipset_init(dev);
215+
183216
/* Clear error counters and error code capture */
184217
priv->write_reg(priv, SJA1000_TXERR, 0x0);
185218
priv->write_reg(priv, SJA1000_RXERR, 0x0);
@@ -236,35 +269,6 @@ static int sja1000_get_berr_counter(const struct net_device *dev,
236269
return 0;
237270
}
238271

239-
/*
240-
* initialize SJA1000 chip:
241-
* - reset chip
242-
* - set output mode
243-
* - set baudrate
244-
* - enable interrupts
245-
* - start operating mode
246-
*/
247-
static void chipset_init(struct net_device *dev)
248-
{
249-
struct sja1000_priv *priv = netdev_priv(dev);
250-
251-
/* set clock divider and output control register */
252-
priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN);
253-
254-
/* set acceptance filter (accept all) */
255-
priv->write_reg(priv, SJA1000_ACCC0, 0x00);
256-
priv->write_reg(priv, SJA1000_ACCC1, 0x00);
257-
priv->write_reg(priv, SJA1000_ACCC2, 0x00);
258-
priv->write_reg(priv, SJA1000_ACCC3, 0x00);
259-
260-
priv->write_reg(priv, SJA1000_ACCM0, 0xFF);
261-
priv->write_reg(priv, SJA1000_ACCM1, 0xFF);
262-
priv->write_reg(priv, SJA1000_ACCM2, 0xFF);
263-
priv->write_reg(priv, SJA1000_ACCM3, 0xFF);
264-
265-
priv->write_reg(priv, SJA1000_OCR, priv->ocr | OCR_MODE_NORMAL);
266-
}
267-
268272
/*
269273
* transmit a CAN message
270274
* message layout in the sk_buff should be like this:

0 commit comments

Comments
 (0)