diff options
author | Johan Hovold <jhovold@gmail.com> | 2013-03-21 07:37:15 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-03-25 16:52:24 -0400 |
commit | c9fac85345ca8fd7f6519232a4c0024f648647b5 (patch) | |
tree | 3415517cb5833e8f377c544f94e0e107bdd73d5e /drivers/usb/serial/mos7840.c | |
parent | 35711578044076d00d396cb6787d3cc593a4c35a (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.c | 48 |
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); |
1512 | exit: | 1494 | exit: |
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)) || |