diff options
Diffstat (limited to 'drivers/net/can/sja1000/sja1000.c')
-rw-r--r-- | drivers/net/can/sja1000/sja1000.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 145b1a731a53..85f7cbfe8e5f 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c | |||
@@ -60,7 +60,6 @@ | |||
60 | #include <linux/skbuff.h> | 60 | #include <linux/skbuff.h> |
61 | #include <linux/delay.h> | 61 | #include <linux/delay.h> |
62 | 62 | ||
63 | #include <linux/can.h> | ||
64 | #include <linux/can/dev.h> | 63 | #include <linux/can/dev.h> |
65 | #include <linux/can/error.h> | 64 | #include <linux/can/error.h> |
66 | 65 | ||
@@ -84,6 +83,20 @@ static struct can_bittiming_const sja1000_bittiming_const = { | |||
84 | .brp_inc = 1, | 83 | .brp_inc = 1, |
85 | }; | 84 | }; |
86 | 85 | ||
86 | static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val) | ||
87 | { | ||
88 | unsigned long flags; | ||
89 | |||
90 | /* | ||
91 | * The command register needs some locking and time to settle | ||
92 | * the write_reg() operation - especially on SMP systems. | ||
93 | */ | ||
94 | spin_lock_irqsave(&priv->cmdreg_lock, flags); | ||
95 | priv->write_reg(priv, REG_CMR, val); | ||
96 | priv->read_reg(priv, REG_SR); | ||
97 | spin_unlock_irqrestore(&priv->cmdreg_lock, flags); | ||
98 | } | ||
99 | |||
87 | static int sja1000_probe_chip(struct net_device *dev) | 100 | static int sja1000_probe_chip(struct net_device *dev) |
88 | { | 101 | { |
89 | struct sja1000_priv *priv = netdev_priv(dev); | 102 | struct sja1000_priv *priv = netdev_priv(dev); |
@@ -293,11 +306,9 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb, | |||
293 | for (i = 0; i < dlc; i++) | 306 | for (i = 0; i < dlc; i++) |
294 | priv->write_reg(priv, dreg++, cf->data[i]); | 307 | priv->write_reg(priv, dreg++, cf->data[i]); |
295 | 308 | ||
296 | dev->trans_start = jiffies; | ||
297 | |||
298 | can_put_echo_skb(skb, dev, 0); | 309 | can_put_echo_skb(skb, dev, 0); |
299 | 310 | ||
300 | priv->write_reg(priv, REG_CMR, CMD_TR); | 311 | sja1000_write_cmdreg(priv, CMD_TR); |
301 | 312 | ||
302 | return NETDEV_TX_OK; | 313 | return NETDEV_TX_OK; |
303 | } | 314 | } |
@@ -346,7 +357,7 @@ static void sja1000_rx(struct net_device *dev) | |||
346 | cf->can_id = id; | 357 | cf->can_id = id; |
347 | 358 | ||
348 | /* release receive buffer */ | 359 | /* release receive buffer */ |
349 | priv->write_reg(priv, REG_CMR, CMD_RRB); | 360 | sja1000_write_cmdreg(priv, CMD_RRB); |
350 | 361 | ||
351 | netif_rx(skb); | 362 | netif_rx(skb); |
352 | 363 | ||
@@ -374,7 +385,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) | |||
374 | cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; | 385 | cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; |
375 | stats->rx_over_errors++; | 386 | stats->rx_over_errors++; |
376 | stats->rx_errors++; | 387 | stats->rx_errors++; |
377 | priv->write_reg(priv, REG_CMR, CMD_CDO); /* clear bit */ | 388 | sja1000_write_cmdreg(priv, CMD_CDO); /* clear bit */ |
378 | } | 389 | } |
379 | 390 | ||
380 | if (isrc & IRQ_EI) { | 391 | if (isrc & IRQ_EI) { |