|
@@ -83,6 +83,20 @@ static struct can_bittiming_const sja1000_bittiming_const = {
|
|
.brp_inc = 1,
|
|
.brp_inc = 1,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val)
|
|
|
|
+{
|
|
|
|
+ unsigned long flags;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * The command register needs some locking and time to settle
|
|
|
|
+ * the write_reg() operation - especially on SMP systems.
|
|
|
|
+ */
|
|
|
|
+ spin_lock_irqsave(&priv->cmdreg_lock, flags);
|
|
|
|
+ priv->write_reg(priv, REG_CMR, val);
|
|
|
|
+ priv->read_reg(priv, REG_SR);
|
|
|
|
+ spin_unlock_irqrestore(&priv->cmdreg_lock, flags);
|
|
|
|
+}
|
|
|
|
+
|
|
static int sja1000_probe_chip(struct net_device *dev)
|
|
static int sja1000_probe_chip(struct net_device *dev)
|
|
{
|
|
{
|
|
struct sja1000_priv *priv = netdev_priv(dev);
|
|
struct sja1000_priv *priv = netdev_priv(dev);
|
|
@@ -294,7 +308,7 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
|
|
|
|
|
|
can_put_echo_skb(skb, dev, 0);
|
|
can_put_echo_skb(skb, dev, 0);
|
|
|
|
|
|
- priv->write_reg(priv, REG_CMR, CMD_TR);
|
|
|
|
|
|
+ sja1000_write_cmdreg(priv, CMD_TR);
|
|
|
|
|
|
return NETDEV_TX_OK;
|
|
return NETDEV_TX_OK;
|
|
}
|
|
}
|
|
@@ -343,7 +357,7 @@ static void sja1000_rx(struct net_device *dev)
|
|
cf->can_id = id;
|
|
cf->can_id = id;
|
|
|
|
|
|
/* release receive buffer */
|
|
/* release receive buffer */
|
|
- priv->write_reg(priv, REG_CMR, CMD_RRB);
|
|
|
|
|
|
+ sja1000_write_cmdreg(priv, CMD_RRB);
|
|
|
|
|
|
netif_rx(skb);
|
|
netif_rx(skb);
|
|
|
|
|
|
@@ -371,7 +385,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
|
|
cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
|
|
cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
|
|
stats->rx_over_errors++;
|
|
stats->rx_over_errors++;
|
|
stats->rx_errors++;
|
|
stats->rx_errors++;
|
|
- priv->write_reg(priv, REG_CMR, CMD_CDO); /* clear bit */
|
|
|
|
|
|
+ sja1000_write_cmdreg(priv, CMD_CDO); /* clear bit */
|
|
}
|
|
}
|
|
|
|
|
|
if (isrc & IRQ_EI) {
|
|
if (isrc & IRQ_EI) {
|