aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/mos7840.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-04-29 15:19:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-29 15:19:23 -0400
commitec25e246b94a3233ab064994ef05a170bdba0e7c (patch)
tree49b7d7e4c46e13bb465c7b832961596e41e8526a /drivers/usb/serial/mos7840.c
parent507ffe4f3840ac24890a8123c702cf1b7fe4d33c (diff)
parent4626b8daf9bb00ce6b4d533c1a155211ad880f32 (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.c157
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);
1526exit: 1482exit:
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
2144static 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,