aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can/sja1000/sja1000.h
diff options
context:
space:
mode:
authorOliver Hartkopp <socketcan@hartkopp.net>2010-05-18 14:03:10 -0700
committerDavid S. Miller <davem@davemloft.net>2010-05-18 14:03:10 -0700
commit57c8a456640fa3ca777652f11f2db4179a3e66b6 (patch)
treea290a904176384e1a9c80edc291f08286e23f3f3 /drivers/net/can/sja1000/sja1000.h
parentb3bcb72edb29c52fb0a065d5b1c7cf40ed9287f4 (diff)
downloadmrst-s0i3-test-57c8a456640fa3ca777652f11f2db4179a3e66b6.tar.gz
mrst-s0i3-test-57c8a456640fa3ca777652f11f2db4179a3e66b6.tar.xz
mrst-s0i3-test-57c8a456640fa3ca777652f11f2db4179a3e66b6.zip
can: Fix SJA1000 command register writes on SMP systems
The SJA1000 command register is concurrently written in the rx-path to free the receive buffer _and_ in the tx-path to start the transmission. The SJA1000 data sheet, 6.4.4 COMMAND REGISTER (CMR) states: "Between two commands at least one internal clock cycle is needed in order to proceed. The internal clock is half of the external oscillator frequency." On SMP systems the current implementation leads to a write stall in the tx-path, which can be solved by adding some general locking and some time to settle the write_reg() operation for the command register. Thanks to Klaus Hitschler for the original fix and detailed problem description. This patch applies on net-2.6 and (with some offsets) on net-next-2.6 . Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net> Acked-by: Wolfgang Grandegger <wg@grandegger.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/can/sja1000/sja1000.h')
-rw-r--r--drivers/net/can/sja1000/sja1000.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/net/can/sja1000/sja1000.h b/drivers/net/can/sja1000/sja1000.h
index 97a622b9302..de8e778f683 100644
--- a/drivers/net/can/sja1000/sja1000.h
+++ b/drivers/net/can/sja1000/sja1000.h
@@ -167,6 +167,7 @@ struct sja1000_priv {
void __iomem *reg_base; /* ioremap'ed address to registers */
unsigned long irq_flags; /* for request_irq() */
+ spinlock_t cmdreg_lock; /* lock for concurrent cmd register writes */
u16 flags; /* custom mode flags */
u8 ocr; /* output control register */