aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/dz.c
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2008-02-07 03:15:11 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 11:42:24 -0500
commit43d46ab1cdeb12b8d072cfdf84956073a1fa8866 (patch)
tree00e55a9babe058feef7065621f12c63dd493ff07 /drivers/serial/dz.c
parent6d83c067ebd11d375b34c53192c10826947e8568 (diff)
dz: fix locking issues
The ->start_tx(), ->stop_tx() and ->stop_rx() backends are called with the port's lock already taken. Remove locking from within them and wrap around calls as necessary. Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Cc: Jiri Slaby <jirislaby@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/serial/dz.c')
-rw-r--r--drivers/serial/dz.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c
index c2f867777145..656c342a80f8 100644
--- a/drivers/serial/dz.c
+++ b/drivers/serial/dz.c
@@ -108,37 +108,28 @@ static void dz_stop_tx(struct uart_port *uport)
108{ 108{
109 struct dz_port *dport = (struct dz_port *)uport; 109 struct dz_port *dport = (struct dz_port *)uport;
110 unsigned short tmp, mask = 1 << dport->port.line; 110 unsigned short tmp, mask = 1 << dport->port.line;
111 unsigned long flags;
112 111
113 spin_lock_irqsave(&dport->port.lock, flags);
114 tmp = dz_in(dport, DZ_TCR); /* read the TX flag */ 112 tmp = dz_in(dport, DZ_TCR); /* read the TX flag */
115 tmp &= ~mask; /* clear the TX flag */ 113 tmp &= ~mask; /* clear the TX flag */
116 dz_out(dport, DZ_TCR, tmp); 114 dz_out(dport, DZ_TCR, tmp);
117 spin_unlock_irqrestore(&dport->port.lock, flags);
118} 115}
119 116
120static void dz_start_tx(struct uart_port *uport) 117static void dz_start_tx(struct uart_port *uport)
121{ 118{
122 struct dz_port *dport = (struct dz_port *)uport; 119 struct dz_port *dport = (struct dz_port *)uport;
123 unsigned short tmp, mask = 1 << dport->port.line; 120 unsigned short tmp, mask = 1 << dport->port.line;
124 unsigned long flags;
125 121
126 spin_lock_irqsave(&dport->port.lock, flags);
127 tmp = dz_in(dport, DZ_TCR); /* read the TX flag */ 122 tmp = dz_in(dport, DZ_TCR); /* read the TX flag */
128 tmp |= mask; /* set the TX flag */ 123 tmp |= mask; /* set the TX flag */
129 dz_out(dport, DZ_TCR, tmp); 124 dz_out(dport, DZ_TCR, tmp);
130 spin_unlock_irqrestore(&dport->port.lock, flags);
131} 125}
132 126
133static void dz_stop_rx(struct uart_port *uport) 127static void dz_stop_rx(struct uart_port *uport)
134{ 128{
135 struct dz_port *dport = (struct dz_port *)uport; 129 struct dz_port *dport = (struct dz_port *)uport;
136 unsigned long flags;
137 130
138 spin_lock_irqsave(&dport->port.lock, flags);
139 dport->cflag &= ~DZ_CREAD; 131 dport->cflag &= ~DZ_CREAD;
140 dz_out(dport, DZ_LPR, dport->cflag | dport->port.line); 132 dz_out(dport, DZ_LPR, dport->cflag | dport->port.line);
141 spin_unlock_irqrestore(&dport->port.lock, flags);
142} 133}
143 134
144static void dz_enable_ms(struct uart_port *port) 135static void dz_enable_ms(struct uart_port *port)
@@ -268,7 +259,9 @@ static inline void dz_transmit_chars(struct dz_port *dport_in)
268 } 259 }
269 /* If nothing to do or stopped or hardware stopped. */ 260 /* If nothing to do or stopped or hardware stopped. */
270 if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) { 261 if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) {
262 spin_lock(&dport->port.lock);
271 dz_stop_tx(&dport->port); 263 dz_stop_tx(&dport->port);
264 spin_unlock(&dport->port.lock);
272 return; 265 return;
273 } 266 }
274 267
@@ -285,8 +278,11 @@ static inline void dz_transmit_chars(struct dz_port *dport_in)
285 uart_write_wakeup(&dport->port); 278 uart_write_wakeup(&dport->port);
286 279
287 /* Are we are done. */ 280 /* Are we are done. */
288 if (uart_circ_empty(xmit)) 281 if (uart_circ_empty(xmit)) {
282 spin_lock(&dport->port.lock);
289 dz_stop_tx(&dport->port); 283 dz_stop_tx(&dport->port);
284 spin_unlock(&dport->port.lock);
285 }
290} 286}
291 287
292/* 288/*
@@ -417,7 +413,12 @@ static int dz_startup(struct uart_port *uport)
417 */ 413 */
418static void dz_shutdown(struct uart_port *uport) 414static void dz_shutdown(struct uart_port *uport)
419{ 415{
420 dz_stop_tx(uport); 416 struct dz_port *dport = (struct dz_port *)uport;
417 unsigned long flags;
418
419 spin_lock_irqsave(&dport->port.lock, flags);
420 dz_stop_tx(&dport->port);
421 spin_unlock_irqrestore(&dport->port.lock, flags);
421} 422}
422 423
423/* 424/*