diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 15:19:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 15:19:23 -0400 |
commit | ec25e246b94a3233ab064994ef05a170bdba0e7c (patch) | |
tree | 49b7d7e4c46e13bb465c7b832961596e41e8526a /drivers/usb/serial/mos7840.c | |
parent | 507ffe4f3840ac24890a8123c702cf1b7fe4d33c (diff) | |
parent | 4626b8daf9bb00ce6b4d533c1a155211ad880f32 (diff) |
Merge tag 'usb-3.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB patches from Greg Kroah-Hartman:
"Here's the big USB pull request for 3.10-rc1.
Lots of USB patches here, the majority being USB gadget changes and
USB-serial driver cleanups, the rest being ARM build fixes / cleanups,
and individual driver updates. We also finally got some chipidea
fixes, which have been delayed for a number of kernel releases, as the
maintainer has now reappeared.
All of these have been in linux-next for a while"
* tag 'usb-3.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (568 commits)
USB: ehci-msm: USB_MSM_OTG needs USB_PHY
USB: OHCI: avoid conflicting platform drivers
USB: OMAP: ISP1301 needs USB_PHY
USB: lpc32xx: ISP1301 needs USB_PHY
USB: ftdi_sio: enable two UART ports on ST Microconnect Lite
usb: phy: tegra: don't call into tegra-ehci directly
usb: phy: phy core cannot yet be a module
USB: Fix initconst in ehci driver
usb-storage: CY7C68300A chips do not support Cypress ATACB
USB: serial: option: Added support Olivetti Olicard 145
USB: ftdi_sio: correct ST Micro Connect Lite PIDs
ARM: mxs_defconfig: add CONFIG_USB_PHY
ARM: imx_v6_v7_defconfig: add CONFIG_USB_PHY
usb: phy: remove exported function from __init section
usb: gadget: zero: put function instances on unbind
usb: gadget: f_sourcesink.c: correct a copy-paste misnomer
usb: gadget: cdc2: fix error return code in cdc_do_config()
usb: gadget: multi: fix error return code in rndis_do_config()
usb: gadget: f_obex: fix error return code in obex_bind()
USB: storage: convert to use module_usb_driver()
...
Diffstat (limited to 'drivers/usb/serial/mos7840.c')
-rw-r--r-- | drivers/usb/serial/mos7840.c | 157 |
1 files changed, 24 insertions, 133 deletions
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 2be376a2e0e3..a0d5ea545982 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -219,8 +219,6 @@ struct moschip_port { | |||
219 | char open; | 219 | char open; |
220 | char open_ports; | 220 | char open_ports; |
221 | wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ | 221 | wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ |
222 | int delta_msr_cond; | ||
223 | struct async_icount icount; | ||
224 | struct usb_serial_port *port; /* loop back to the owner of this object */ | 222 | struct usb_serial_port *port; /* loop back to the owner of this object */ |
225 | 223 | ||
226 | /* Offsets */ | 224 | /* Offsets */ |
@@ -399,32 +397,22 @@ static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr) | |||
399 | struct moschip_port *mos7840_port; | 397 | struct moschip_port *mos7840_port; |
400 | struct async_icount *icount; | 398 | struct async_icount *icount; |
401 | mos7840_port = port; | 399 | mos7840_port = port; |
402 | icount = &mos7840_port->icount; | ||
403 | if (new_msr & | 400 | if (new_msr & |
404 | (MOS_MSR_DELTA_CTS | MOS_MSR_DELTA_DSR | MOS_MSR_DELTA_RI | | 401 | (MOS_MSR_DELTA_CTS | MOS_MSR_DELTA_DSR | MOS_MSR_DELTA_RI | |
405 | MOS_MSR_DELTA_CD)) { | 402 | MOS_MSR_DELTA_CD)) { |
406 | icount = &mos7840_port->icount; | 403 | icount = &mos7840_port->port->icount; |
407 | 404 | ||
408 | /* update input line counters */ | 405 | /* update input line counters */ |
409 | if (new_msr & MOS_MSR_DELTA_CTS) { | 406 | if (new_msr & MOS_MSR_DELTA_CTS) |
410 | icount->cts++; | 407 | icount->cts++; |
411 | smp_wmb(); | 408 | if (new_msr & MOS_MSR_DELTA_DSR) |
412 | } | ||
413 | if (new_msr & MOS_MSR_DELTA_DSR) { | ||
414 | icount->dsr++; | 409 | icount->dsr++; |
415 | smp_wmb(); | 410 | if (new_msr & MOS_MSR_DELTA_CD) |
416 | } | ||
417 | if (new_msr & MOS_MSR_DELTA_CD) { | ||
418 | icount->dcd++; | 411 | icount->dcd++; |
419 | smp_wmb(); | 412 | if (new_msr & MOS_MSR_DELTA_RI) |
420 | } | ||
421 | if (new_msr & MOS_MSR_DELTA_RI) { | ||
422 | icount->rng++; | 413 | icount->rng++; |
423 | smp_wmb(); | ||
424 | } | ||
425 | 414 | ||
426 | mos7840_port->delta_msr_cond = 1; | 415 | wake_up_interruptible(&port->port->port.delta_msr_wait); |
427 | wake_up_interruptible(&port->port->delta_msr_wait); | ||
428 | } | 416 | } |
429 | } | 417 | } |
430 | 418 | ||
@@ -442,23 +430,15 @@ static void mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr) | |||
442 | } | 430 | } |
443 | 431 | ||
444 | /* update input line counters */ | 432 | /* update input line counters */ |
445 | icount = &port->icount; | 433 | icount = &port->port->icount; |
446 | if (new_lsr & SERIAL_LSR_BI) { | 434 | if (new_lsr & SERIAL_LSR_BI) |
447 | icount->brk++; | 435 | icount->brk++; |
448 | smp_wmb(); | 436 | if (new_lsr & SERIAL_LSR_OE) |
449 | } | ||
450 | if (new_lsr & SERIAL_LSR_OE) { | ||
451 | icount->overrun++; | 437 | icount->overrun++; |
452 | smp_wmb(); | 438 | if (new_lsr & SERIAL_LSR_PE) |
453 | } | ||
454 | if (new_lsr & SERIAL_LSR_PE) { | ||
455 | icount->parity++; | 439 | icount->parity++; |
456 | smp_wmb(); | 440 | if (new_lsr & SERIAL_LSR_FE) |
457 | } | ||
458 | if (new_lsr & SERIAL_LSR_FE) { | ||
459 | icount->frame++; | 441 | icount->frame++; |
460 | smp_wmb(); | ||
461 | } | ||
462 | } | 442 | } |
463 | 443 | ||
464 | /************************************************************************/ | 444 | /************************************************************************/ |
@@ -777,9 +757,8 @@ static void mos7840_bulk_in_callback(struct urb *urb) | |||
777 | struct tty_port *tport = &mos7840_port->port->port; | 757 | struct tty_port *tport = &mos7840_port->port->port; |
778 | tty_insert_flip_string(tport, data, urb->actual_length); | 758 | tty_insert_flip_string(tport, data, urb->actual_length); |
779 | tty_flip_buffer_push(tport); | 759 | tty_flip_buffer_push(tport); |
780 | mos7840_port->icount.rx += urb->actual_length; | 760 | port->icount.rx += urb->actual_length; |
781 | smp_wmb(); | 761 | dev_dbg(&port->dev, "icount.rx is %d:\n", port->icount.rx); |
782 | dev_dbg(&port->dev, "mos7840_port->icount.rx is %d:\n", mos7840_port->icount.rx); | ||
783 | } | 762 | } |
784 | 763 | ||
785 | if (!mos7840_port->read_urb) { | 764 | if (!mos7840_port->read_urb) { |
@@ -1127,17 +1106,12 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1127 | /* initialize our wait queues */ | 1106 | /* initialize our wait queues */ |
1128 | init_waitqueue_head(&mos7840_port->wait_chase); | 1107 | init_waitqueue_head(&mos7840_port->wait_chase); |
1129 | 1108 | ||
1130 | /* initialize our icount structure */ | ||
1131 | memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount)); | ||
1132 | |||
1133 | /* initialize our port settings */ | 1109 | /* initialize our port settings */ |
1134 | /* Must set to enable ints! */ | 1110 | /* Must set to enable ints! */ |
1135 | mos7840_port->shadowMCR = MCR_MASTER_IE; | 1111 | mos7840_port->shadowMCR = MCR_MASTER_IE; |
1136 | /* send a open port command */ | 1112 | /* send a open port command */ |
1137 | mos7840_port->open = 1; | 1113 | mos7840_port->open = 1; |
1138 | /* mos7840_change_port_settings(mos7840_port,old_termios); */ | 1114 | /* mos7840_change_port_settings(mos7840_port,old_termios); */ |
1139 | mos7840_port->icount.tx = 0; | ||
1140 | mos7840_port->icount.rx = 0; | ||
1141 | 1115 | ||
1142 | return 0; | 1116 | return 0; |
1143 | } | 1117 | } |
@@ -1220,25 +1194,10 @@ static void mos7840_close(struct usb_serial_port *port) | |||
1220 | } | 1194 | } |
1221 | } | 1195 | } |
1222 | 1196 | ||
1223 | /* While closing port, shutdown all bulk read, write * | 1197 | usb_kill_urb(mos7840_port->write_urb); |
1224 | * and interrupt read if they exists */ | 1198 | usb_kill_urb(mos7840_port->read_urb); |
1225 | if (serial->dev) { | 1199 | mos7840_port->read_urb_busy = false; |
1226 | if (mos7840_port->write_urb) { | 1200 | |
1227 | dev_dbg(&port->dev, "%s", "Shutdown bulk write\n"); | ||
1228 | usb_kill_urb(mos7840_port->write_urb); | ||
1229 | } | ||
1230 | if (mos7840_port->read_urb) { | ||
1231 | dev_dbg(&port->dev, "%s", "Shutdown bulk read\n"); | ||
1232 | usb_kill_urb(mos7840_port->read_urb); | ||
1233 | mos7840_port->read_urb_busy = false; | ||
1234 | } | ||
1235 | if ((&mos7840_port->control_urb)) { | ||
1236 | dev_dbg(&port->dev, "%s", "Shutdown control read\n"); | ||
1237 | /*/ usb_kill_urb (mos7840_port->control_urb); */ | ||
1238 | } | ||
1239 | } | ||
1240 | /* if(mos7840_port->ctrl_buf != NULL) */ | ||
1241 | /* kfree(mos7840_port->ctrl_buf); */ | ||
1242 | port0->open_ports--; | 1201 | port0->open_ports--; |
1243 | dev_dbg(&port->dev, "%s in close%d:in port%d\n", __func__, port0->open_ports, port->number); | 1202 | dev_dbg(&port->dev, "%s in close%d:in port%d\n", __func__, port0->open_ports, port->number); |
1244 | if (port0->open_ports == 0) { | 1203 | if (port0->open_ports == 0) { |
@@ -1250,8 +1209,7 @@ static void mos7840_close(struct usb_serial_port *port) | |||
1250 | 1209 | ||
1251 | if (mos7840_port->write_urb) { | 1210 | if (mos7840_port->write_urb) { |
1252 | /* if this urb had a transfer buffer already (old tx) free it */ | 1211 | /* if this urb had a transfer buffer already (old tx) free it */ |
1253 | if (mos7840_port->write_urb->transfer_buffer != NULL) | 1212 | kfree(mos7840_port->write_urb->transfer_buffer); |
1254 | kfree(mos7840_port->write_urb->transfer_buffer); | ||
1255 | usb_free_urb(mos7840_port->write_urb); | 1213 | usb_free_urb(mos7840_port->write_urb); |
1256 | } | 1214 | } |
1257 | 1215 | ||
@@ -1328,9 +1286,8 @@ static void mos7840_break(struct tty_struct *tty, int break_state) | |||
1328 | if (mos7840_port == NULL) | 1286 | if (mos7840_port == NULL) |
1329 | return; | 1287 | return; |
1330 | 1288 | ||
1331 | if (serial->dev) | 1289 | /* flush and block until tx is empty */ |
1332 | /* flush and block until tx is empty */ | 1290 | mos7840_block_until_chase_response(tty, mos7840_port); |
1333 | mos7840_block_until_chase_response(tty, mos7840_port); | ||
1334 | 1291 | ||
1335 | if (break_state == -1) | 1292 | if (break_state == -1) |
1336 | data = mos7840_port->shadowLCR | LCR_SET_BREAK; | 1293 | data = mos7840_port->shadowLCR | LCR_SET_BREAK; |
@@ -1520,9 +1477,8 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1520 | goto exit; | 1477 | goto exit; |
1521 | } | 1478 | } |
1522 | bytes_sent = transfer_size; | 1479 | bytes_sent = transfer_size; |
1523 | mos7840_port->icount.tx += transfer_size; | 1480 | port->icount.tx += transfer_size; |
1524 | smp_wmb(); | 1481 | dev_dbg(&port->dev, "icount.tx is %d:\n", port->icount.tx); |
1525 | dev_dbg(&port->dev, "mos7840_port->icount.tx is %d:\n", mos7840_port->icount.tx); | ||
1526 | exit: | 1482 | exit: |
1527 | return bytes_sent; | 1483 | return bytes_sent; |
1528 | 1484 | ||
@@ -2141,34 +2097,6 @@ static int mos7840_get_serial_info(struct moschip_port *mos7840_port, | |||
2141 | return 0; | 2097 | return 0; |
2142 | } | 2098 | } |
2143 | 2099 | ||
2144 | static int mos7840_get_icount(struct tty_struct *tty, | ||
2145 | struct serial_icounter_struct *icount) | ||
2146 | { | ||
2147 | struct usb_serial_port *port = tty->driver_data; | ||
2148 | struct moschip_port *mos7840_port; | ||
2149 | struct async_icount cnow; | ||
2150 | |||
2151 | mos7840_port = mos7840_get_port_private(port); | ||
2152 | cnow = mos7840_port->icount; | ||
2153 | |||
2154 | smp_rmb(); | ||
2155 | icount->cts = cnow.cts; | ||
2156 | icount->dsr = cnow.dsr; | ||
2157 | icount->rng = cnow.rng; | ||
2158 | icount->dcd = cnow.dcd; | ||
2159 | icount->rx = cnow.rx; | ||
2160 | icount->tx = cnow.tx; | ||
2161 | icount->frame = cnow.frame; | ||
2162 | icount->overrun = cnow.overrun; | ||
2163 | icount->parity = cnow.parity; | ||
2164 | icount->brk = cnow.brk; | ||
2165 | icount->buf_overrun = cnow.buf_overrun; | ||
2166 | |||
2167 | dev_dbg(&port->dev, "%s TIOCGICOUNT RX=%d, TX=%d\n", __func__, | ||
2168 | icount->rx, icount->tx); | ||
2169 | return 0; | ||
2170 | } | ||
2171 | |||
2172 | /***************************************************************************** | 2100 | /***************************************************************************** |
2173 | * SerialIoctl | 2101 | * SerialIoctl |
2174 | * this function handles any ioctl calls to the driver | 2102 | * this function handles any ioctl calls to the driver |
@@ -2181,9 +2109,6 @@ static int mos7840_ioctl(struct tty_struct *tty, | |||
2181 | void __user *argp = (void __user *)arg; | 2109 | void __user *argp = (void __user *)arg; |
2182 | struct moschip_port *mos7840_port; | 2110 | struct moschip_port *mos7840_port; |
2183 | 2111 | ||
2184 | struct async_icount cnow; | ||
2185 | struct async_icount cprev; | ||
2186 | |||
2187 | if (mos7840_port_paranoia_check(port, __func__)) | 2112 | if (mos7840_port_paranoia_check(port, __func__)) |
2188 | return -1; | 2113 | return -1; |
2189 | 2114 | ||
@@ -2208,41 +2133,6 @@ static int mos7840_ioctl(struct tty_struct *tty, | |||
2208 | case TIOCSSERIAL: | 2133 | case TIOCSSERIAL: |
2209 | dev_dbg(&port->dev, "%s TIOCSSERIAL\n", __func__); | 2134 | dev_dbg(&port->dev, "%s TIOCSSERIAL\n", __func__); |
2210 | break; | 2135 | break; |
2211 | |||
2212 | case TIOCMIWAIT: | ||
2213 | dev_dbg(&port->dev, "%s TIOCMIWAIT\n", __func__); | ||
2214 | cprev = mos7840_port->icount; | ||
2215 | while (1) { | ||
2216 | /* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */ | ||
2217 | mos7840_port->delta_msr_cond = 0; | ||
2218 | wait_event_interruptible(port->delta_msr_wait, | ||
2219 | (port->serial->disconnected || | ||
2220 | mos7840_port-> | ||
2221 | delta_msr_cond == 1)); | ||
2222 | |||
2223 | /* see if a signal did it */ | ||
2224 | if (signal_pending(current)) | ||
2225 | return -ERESTARTSYS; | ||
2226 | |||
2227 | if (port->serial->disconnected) | ||
2228 | return -EIO; | ||
2229 | |||
2230 | cnow = mos7840_port->icount; | ||
2231 | smp_rmb(); | ||
2232 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && | ||
2233 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) | ||
2234 | return -EIO; /* no change => error */ | ||
2235 | if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || | ||
2236 | ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || | ||
2237 | ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || | ||
2238 | ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { | ||
2239 | return 0; | ||
2240 | } | ||
2241 | cprev = cnow; | ||
2242 | } | ||
2243 | /* NOTREACHED */ | ||
2244 | break; | ||
2245 | |||
2246 | default: | 2136 | default: |
2247 | break; | 2137 | break; |
2248 | } | 2138 | } |
@@ -2589,7 +2479,8 @@ static struct usb_serial_driver moschip7840_4port_device = { | |||
2589 | .break_ctl = mos7840_break, | 2479 | .break_ctl = mos7840_break, |
2590 | .tiocmget = mos7840_tiocmget, | 2480 | .tiocmget = mos7840_tiocmget, |
2591 | .tiocmset = mos7840_tiocmset, | 2481 | .tiocmset = mos7840_tiocmset, |
2592 | .get_icount = mos7840_get_icount, | 2482 | .tiocmiwait = usb_serial_generic_tiocmiwait, |
2483 | .get_icount = usb_serial_generic_get_icount, | ||
2593 | .port_probe = mos7840_port_probe, | 2484 | .port_probe = mos7840_port_probe, |
2594 | .port_remove = mos7840_port_remove, | 2485 | .port_remove = mos7840_port_remove, |
2595 | .read_bulk_callback = mos7840_bulk_in_callback, | 2486 | .read_bulk_callback = mos7840_bulk_in_callback, |