aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/moxa.c
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2009-11-30 08:17:57 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 18:18:07 -0500
commitf5c5a36d27ae6d9e03c2f1b7890942bf84e92c5b (patch)
tree169cdf790a4938c504b0968e83d5d09ad402e554 /drivers/char/moxa.c
parentf176178ba09d27cc33988435e2c9fe078b44998c (diff)
tty: moxa: rework the locking a bit
Introduce a lock for moxafunc() to protect the cases where were get collisions between two function requests at the same time. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/char/moxa.c')
-rw-r--r--drivers/char/moxa.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index d8bcbed6d28d..474d936d3b31 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -248,9 +248,25 @@ static void moxa_wait_finish(void __iomem *ofsAddr)
248 248
249static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg) 249static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg)
250{ 250{
251 unsigned long flags;
252 spin_lock_irqsave(&moxafunc_lock, flags);
251 writew(arg, ofsAddr + FuncArg); 253 writew(arg, ofsAddr + FuncArg);
252 writew(cmd, ofsAddr + FuncCode); 254 writew(cmd, ofsAddr + FuncCode);
253 moxa_wait_finish(ofsAddr); 255 moxa_wait_finish(ofsAddr);
256 spin_unlock_irqrestore(&moxafunc_lock, flags);
257}
258
259static int moxafuncret(void __iomem *ofsAddr, u16 cmd, u16 arg)
260{
261 unsigned long flags;
262 u16 ret;
263 spin_lock_irqsave(&moxafunc_lock, flags);
264 writew(arg, ofsAddr + FuncArg);
265 writew(cmd, ofsAddr + FuncCode);
266 moxa_wait_finish(ofsAddr);
267 ret = readw(ofsAddr + FuncArg);
268 spin_unlock_irqrestore(&moxafunc_lock, flags);
269 return ret;
254} 270}
255 271
256static void moxa_low_water_check(void __iomem *ofsAddr) 272static void moxa_low_water_check(void __iomem *ofsAddr)
@@ -417,6 +433,7 @@ static const struct tty_port_operations moxa_port_ops = {
417static struct tty_driver *moxaDriver; 433static struct tty_driver *moxaDriver;
418static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0); 434static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);
419static DEFINE_SPINLOCK(moxa_lock); 435static DEFINE_SPINLOCK(moxa_lock);
436static DEFINE_SPINLOCK(moxafunc_lock);
420 437
421/* 438/*
422 * HW init 439 * HW init
@@ -1823,10 +1840,12 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
1823 baud = MoxaPortSetBaud(port, baud); 1840 baud = MoxaPortSetBaud(port, baud);
1824 1841
1825 if (termio->c_iflag & (IXON | IXOFF | IXANY)) { 1842 if (termio->c_iflag & (IXON | IXOFF | IXANY)) {
1843 spin_lock_irq(&moxafunc_lock);
1826 writeb(termio->c_cc[VSTART], ofsAddr + FuncArg); 1844 writeb(termio->c_cc[VSTART], ofsAddr + FuncArg);
1827 writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1); 1845 writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1);
1828 writeb(FC_SetXonXoff, ofsAddr + FuncCode); 1846 writeb(FC_SetXonXoff, ofsAddr + FuncCode);
1829 moxa_wait_finish(ofsAddr); 1847 moxa_wait_finish(ofsAddr);
1848 spin_unlock_irqrestore(&moxafunc_lock);
1830 1849
1831 } 1850 }
1832 return baud; 1851 return baud;
@@ -1879,12 +1898,10 @@ static int MoxaPortLineStatus(struct moxa_port *port)
1879 int val; 1898 int val;
1880 1899
1881 ofsAddr = port->tableAddr; 1900 ofsAddr = port->tableAddr;
1882 if (MOXA_IS_320(port->board)) { 1901 if (MOXA_IS_320(port->board))
1883 moxafunc(ofsAddr, FC_LineStatus, 0); 1902 val = moxafuncret(ofsAddr, FC_LineStatus, 0);
1884 val = readw(ofsAddr + FuncArg); 1903 else
1885 } else {
1886 val = readw(ofsAddr + FlagStat) >> 4; 1904 val = readw(ofsAddr + FlagStat) >> 4;
1887 }
1888 val &= 0x0B; 1905 val &= 0x0B;
1889 if (val & 8) 1906 if (val & 8)
1890 val |= 4; 1907 val |= 4;