diff options
author | Mark Salter <msalter@redhat.com> | 2012-12-12 19:36:38 +0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2012-12-12 19:46:14 +0400 |
commit | 8f0bcbcab016324c2a3ba4cc715e8e523c29a578 (patch) | |
tree | 8833a5b7f169942e41ba907c54ba817b64be4ba2 /arch/mn10300/kernel/mn10300-serial-low.S | |
parent | 8d160027ff234bddea627ba54c2b85efa1884867 (diff) | |
download | linux-8f0bcbcab016324c2a3ba4cc715e8e523c29a578.tar.xz |
MN10300: fix SMP synchronization between txdma and serial driver
The SoC serial port driver uses a high priority interrupt to handle tx of
characters in the tx ring buffer. The driver needs to disable/enable this IRQ
from outside of irq context. The original code to do this is not foolproof on
SMP machines because the IRQ running on one core could still access the serial
port for a short time after the driver running on another core disables the
interrupt. This patch adds a flag to tell the IRQ handler that the driver
wants to disable the interrupt. After seeing the flag, the IRQ handler will
immediately disable the interrupt and exit. After setting the flag, the driver
will wait for interrupt to be disabled by the IRQ handler.
Signed-off-by: Mark Salter <msalter@redhat.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'arch/mn10300/kernel/mn10300-serial-low.S')
-rw-r--r-- | arch/mn10300/kernel/mn10300-serial-low.S | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/arch/mn10300/kernel/mn10300-serial-low.S b/arch/mn10300/kernel/mn10300-serial-low.S index dfc1b6f2fa9a..b95e76caf4fa 100644 --- a/arch/mn10300/kernel/mn10300-serial-low.S +++ b/arch/mn10300/kernel/mn10300-serial-low.S @@ -118,8 +118,8 @@ ENTRY(mn10300_serial_vdma_tx_handler) movbu d2,(e3) # ACK the interrupt movhu (e3),d2 # flush - btst 0x01,(__tx_break,a3) # handle transmit break request - bne mnsc_vdma_tx_break + btst 0xFF,(__tx_flags,a3) # handle transmit flags + bne mnsc_vdma_tx_flags movbu (SCxSTR,e2),d2 # don't try and transmit a char if the # buffer is not empty @@ -171,10 +171,13 @@ mnsc_vdma_tx_empty: bset MNSCx_TX_EMPTY,(__intr_flags,a3) bra mnsc_vdma_tx_done -mnsc_vdma_tx_break: +mnsc_vdma_tx_flags: + btst MNSCx_TX_STOP,(__tx_flags,a3) + bne mnsc_vdma_tx_stop movhu (SCxCTR,e2),d2 # turn on break mode or SC01CTR_BKE,d2 movhu d2,(SCxCTR,e2) +mnsc_vdma_tx_stop: mov +(NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)|GxICR_DETECT),d2 movhu d2,(e3) # disable transmit interrupts on this # channel |