aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/mos7840.c
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2013-03-21 07:37:15 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-25 16:52:24 -0400
commitc9fac85345ca8fd7f6519232a4c0024f648647b5 (patch)
tree3415517cb5833e8f377c544f94e0e107bdd73d5e /drivers/usb/serial/mos7840.c
parent35711578044076d00d396cb6787d3cc593a4c35a (diff)
USB: mos7840: remove smp barriers from icount handling
Remove SMP memory barriers from icount handling and rely on the barriers implied by wait_event, sleep and locks, while using the port lock to guarantee atomicity. This is a step in moving over to the generic icount implementations. Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/serial/mos7840.c')
-rw-r--r--drivers/usb/serial/mos7840.c48
1 files changed, 19 insertions, 29 deletions
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 979ef1999581..7af3d4206523 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -406,22 +406,14 @@ static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr)
406 icount = &mos7840_port->icount; 406 icount = &mos7840_port->icount;
407 407
408 /* update input line counters */ 408 /* update input line counters */
409 if (new_msr & MOS_MSR_DELTA_CTS) { 409 if (new_msr & MOS_MSR_DELTA_CTS)
410 icount->cts++; 410 icount->cts++;
411 smp_wmb(); 411 if (new_msr & MOS_MSR_DELTA_DSR)
412 }
413 if (new_msr & MOS_MSR_DELTA_DSR) {
414 icount->dsr++; 412 icount->dsr++;
415 smp_wmb(); 413 if (new_msr & MOS_MSR_DELTA_CD)
416 }
417 if (new_msr & MOS_MSR_DELTA_CD) {
418 icount->dcd++; 414 icount->dcd++;
419 smp_wmb(); 415 if (new_msr & MOS_MSR_DELTA_RI)
420 }
421 if (new_msr & MOS_MSR_DELTA_RI) {
422 icount->rng++; 416 icount->rng++;
423 smp_wmb();
424 }
425 417
426 mos7840_port->delta_msr_cond = 1; 418 mos7840_port->delta_msr_cond = 1;
427 wake_up_interruptible(&port->port->delta_msr_wait); 419 wake_up_interruptible(&port->port->delta_msr_wait);
@@ -443,22 +435,14 @@ static void mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr)
443 435
444 /* update input line counters */ 436 /* update input line counters */
445 icount = &port->icount; 437 icount = &port->icount;
446 if (new_lsr & SERIAL_LSR_BI) { 438 if (new_lsr & SERIAL_LSR_BI)
447 icount->brk++; 439 icount->brk++;
448 smp_wmb(); 440 if (new_lsr & SERIAL_LSR_OE)
449 }
450 if (new_lsr & SERIAL_LSR_OE) {
451 icount->overrun++; 441 icount->overrun++;
452 smp_wmb(); 442 if (new_lsr & SERIAL_LSR_PE)
453 }
454 if (new_lsr & SERIAL_LSR_PE) {
455 icount->parity++; 443 icount->parity++;
456 smp_wmb(); 444 if (new_lsr & SERIAL_LSR_FE)
457 }
458 if (new_lsr & SERIAL_LSR_FE) {
459 icount->frame++; 445 icount->frame++;
460 smp_wmb();
461 }
462} 446}
463 447
464/************************************************************************/ 448/************************************************************************/
@@ -778,7 +762,6 @@ static void mos7840_bulk_in_callback(struct urb *urb)
778 tty_insert_flip_string(tport, data, urb->actual_length); 762 tty_insert_flip_string(tport, data, urb->actual_length);
779 tty_flip_buffer_push(tport); 763 tty_flip_buffer_push(tport);
780 mos7840_port->icount.rx += urb->actual_length; 764 mos7840_port->icount.rx += urb->actual_length;
781 smp_wmb();
782 dev_dbg(&port->dev, "mos7840_port->icount.rx is %d:\n", mos7840_port->icount.rx); 765 dev_dbg(&port->dev, "mos7840_port->icount.rx is %d:\n", mos7840_port->icount.rx);
783 } 766 }
784 767
@@ -1507,7 +1490,6 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
1507 } 1490 }
1508 bytes_sent = transfer_size; 1491 bytes_sent = transfer_size;
1509 mos7840_port->icount.tx += transfer_size; 1492 mos7840_port->icount.tx += transfer_size;
1510 smp_wmb();
1511 dev_dbg(&port->dev, "mos7840_port->icount.tx is %d:\n", mos7840_port->icount.tx); 1493 dev_dbg(&port->dev, "mos7840_port->icount.tx is %d:\n", mos7840_port->icount.tx);
1512exit: 1494exit:
1513 return bytes_sent; 1495 return bytes_sent;
@@ -2133,11 +2115,14 @@ static int mos7840_get_icount(struct tty_struct *tty,
2133 struct usb_serial_port *port = tty->driver_data; 2115 struct usb_serial_port *port = tty->driver_data;
2134 struct moschip_port *mos7840_port; 2116 struct moschip_port *mos7840_port;
2135 struct async_icount cnow; 2117 struct async_icount cnow;
2118 unsigned long flags;
2136 2119
2137 mos7840_port = mos7840_get_port_private(port); 2120 mos7840_port = mos7840_get_port_private(port);
2121
2122 spin_lock_irqsave(&port->lock, flags);
2138 cnow = mos7840_port->icount; 2123 cnow = mos7840_port->icount;
2124 spin_unlock_irqrestore(&port->lock, flags);
2139 2125
2140 smp_rmb();
2141 icount->cts = cnow.cts; 2126 icount->cts = cnow.cts;
2142 icount->dsr = cnow.dsr; 2127 icount->dsr = cnow.dsr;
2143 icount->rng = cnow.rng; 2128 icount->rng = cnow.rng;
@@ -2166,7 +2151,7 @@ static int mos7840_ioctl(struct tty_struct *tty,
2166 struct usb_serial_port *port = tty->driver_data; 2151 struct usb_serial_port *port = tty->driver_data;
2167 void __user *argp = (void __user *)arg; 2152 void __user *argp = (void __user *)arg;
2168 struct moschip_port *mos7840_port; 2153 struct moschip_port *mos7840_port;
2169 2154 unsigned long flags;
2170 struct async_icount cnow; 2155 struct async_icount cnow;
2171 struct async_icount cprev; 2156 struct async_icount cprev;
2172 2157
@@ -2197,7 +2182,9 @@ static int mos7840_ioctl(struct tty_struct *tty,
2197 2182
2198 case TIOCMIWAIT: 2183 case TIOCMIWAIT:
2199 dev_dbg(&port->dev, "%s TIOCMIWAIT\n", __func__); 2184 dev_dbg(&port->dev, "%s TIOCMIWAIT\n", __func__);
2185 spin_lock_irqsave(&port->lock, flags);
2200 cprev = mos7840_port->icount; 2186 cprev = mos7840_port->icount;
2187 spin_unlock_irqrestore(&port->lock, flags);
2201 while (1) { 2188 while (1) {
2202 /* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */ 2189 /* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */
2203 mos7840_port->delta_msr_cond = 0; 2190 mos7840_port->delta_msr_cond = 0;
@@ -2213,11 +2200,14 @@ static int mos7840_ioctl(struct tty_struct *tty,
2213 if (port->serial->disconnected) 2200 if (port->serial->disconnected)
2214 return -EIO; 2201 return -EIO;
2215 2202
2203 spin_lock_irqsave(&port->lock, flags);
2216 cnow = mos7840_port->icount; 2204 cnow = mos7840_port->icount;
2217 smp_rmb(); 2205 spin_unlock_irqrestore(&port->lock, flags);
2206
2218 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 2207 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
2219 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) 2208 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
2220 return -EIO; /* no change => error */ 2209 return -EIO; /* no change => error */
2210
2221 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || 2211 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
2222 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || 2212 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
2223 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || 2213 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||