diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2010-05-22 00:36:56 -0600 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-05-22 00:36:56 -0600 |
commit | cf9b59e9d3e008591d1f54830f570982bb307a0d (patch) | |
tree | 113478ce8fd8c832ba726ffdf59b82cb46356476 /drivers/net/can/sja1000/sja1000.c | |
parent | 44504b2bebf8b5823c59484e73096a7d6574471d (diff) | |
parent | f4b87dee923342505e1ddba8d34ce9de33e75050 (diff) |
Merge remote branch 'origin' into secretlab/next-devicetree
Merging in current state of Linus' tree to deal with merge conflicts and
build failures in vio.c after merge.
Conflicts:
drivers/i2c/busses/i2c-cpm.c
drivers/i2c/busses/i2c-mpc.c
drivers/net/gianfar.c
Also fixed up one line in arch/powerpc/kernel/vio.c to use the
correct node pointer.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
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 145b1a731a5..85f7cbfe8e5 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c @@ -60,7 +60,6 @@ #include <linux/skbuff.h> #include <linux/delay.h> -#include <linux/can.h> #include <linux/can/dev.h> #include <linux/can/error.h> @@ -84,6 +83,20 @@ static struct can_bittiming_const sja1000_bittiming_const = { .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) { struct sja1000_priv *priv = netdev_priv(dev); @@ -293,11 +306,9 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb, for (i = 0; i < dlc; i++) priv->write_reg(priv, dreg++, cf->data[i]); - dev->trans_start = jiffies; - 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; } @@ -346,7 +357,7 @@ static void sja1000_rx(struct net_device *dev) cf->can_id = id; /* release receive buffer */ - priv->write_reg(priv, REG_CMR, CMD_RRB); + sja1000_write_cmdreg(priv, CMD_RRB); netif_rx(skb); @@ -374,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; stats->rx_over_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) { |