diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-22 16:12:24 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-22 16:12:24 -0700 |
commit | 94b5aff4c6f72fee6b0f49d49e4fa8b204e8ded9 (patch) | |
tree | 39197121b6ef8cddaa0f4057fe24b4ced58e8982 /drivers/usb | |
parent | 5d4e2d08e7fdf7339f84a1c670d296a77e02f881 (diff) | |
parent | 59bd234b72fc29887839d792b7d6c7e8d2a577a6 (diff) | |
download | blackbird-op-linux-94b5aff4c6f72fee6b0f49d49e4fa8b204e8ded9.tar.gz blackbird-op-linux-94b5aff4c6f72fee6b0f49d49e4fa8b204e8ded9.zip |
Merge tag 'tty-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull TTY updates from Greg Kroah-Hartman:
"Here's the big TTY/serial driver pull request for the 3.5-rc1 merge
window.
Nothing major in here, just lots of incremental changes from Alan and
Jiri reworking some tty core things to behave better and to get a more
solid grasp on some of the nasty tty locking issues.
There are a few tty and serial driver updates in here as well.
All of this has been in the linux-next releases for a while with no
problems.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
* tag 'tty-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (115 commits)
serial: bfin_uart: Make MMR access compatible with 32 bits bf609 style controller.
serial: bfin_uart: RTS and CTS MMRs can be either 16-bit width or 32-bit width.
serial: bfin_uart: narrow the reboot condition in DMA tx interrupt
serial: bfin_uart: Adapt bf5xx serial driver to bf60x serial4 controller.
Revert "serial_core: Update buffer overrun statistics."
tty: hvc_xen: NULL dereference on allocation failure
tty: Fix LED error return
tty: Allow uart_register/unregister/register
tty: move global ldisc idle waitqueue to the individual ldisc
serial8250-em: Add DT support
serial8250-em: clk_get() IS_ERR() error handling fix
serial_core: Update buffer overrun statistics.
tty: drop the pty lock during hangup
cris: fix missing tty arg in wait_event_interruptible_tty call
tty/amiserial: Add missing argument for tty_unlock()
tty_lock: Localise the lock
pty: Lock the devpts bits privately
tty_lock: undo the old tty_lock use on the ctty
serial8250-em: Emma Mobile UART driver V2
Add missing call to uart_update_timeout()
...
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/u_serial.c | 51 |
1 files changed, 24 insertions, 27 deletions
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 380a87f6e56c..15a42c8c1943 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -94,17 +94,14 @@ struct gs_buf { * (and thus for each /dev/ node). */ struct gs_port { + struct tty_port port; spinlock_t port_lock; /* guard port_* access */ struct gserial *port_usb; - struct tty_struct *port_tty; - unsigned open_count; bool openclose; /* open/close in progress */ u8 port_num; - wait_queue_head_t close_wait; /* wait for last close */ - struct list_head read_pool; int read_started; int read_allocated; @@ -412,8 +409,8 @@ __acquires(&port->port_lock) break; } - if (do_tty_wake && port->port_tty) - tty_wakeup(port->port_tty); + if (do_tty_wake && port->port.tty) + tty_wakeup(port->port.tty); return status; } @@ -435,7 +432,7 @@ __acquires(&port->port_lock) struct tty_struct *tty; /* no more rx if closed */ - tty = port->port_tty; + tty = port->port.tty; if (!tty) break; @@ -488,7 +485,7 @@ static void gs_rx_push(unsigned long _port) /* hand any queued data to the tty */ spin_lock_irq(&port->port_lock); - tty = port->port_tty; + tty = port->port.tty; while (!list_empty(queue)) { struct usb_request *req; @@ -699,7 +696,7 @@ static int gs_start_io(struct gs_port *port) /* unblock any pending writes into our circular buffer */ if (started) { - tty_wakeup(port->port_tty); + tty_wakeup(port->port.tty); } else { gs_free_requests(ep, head, &port->read_allocated); gs_free_requests(port->port_usb->in, &port->write_pool, @@ -734,9 +731,9 @@ static int gs_open(struct tty_struct *tty, struct file *file) spin_lock_irq(&port->port_lock); /* already open? Great. */ - if (port->open_count) { + if (port->port.count) { status = 0; - port->open_count++; + port->port.count++; /* currently opening/closing? wait ... */ } else if (port->openclose) { @@ -793,9 +790,9 @@ static int gs_open(struct tty_struct *tty, struct file *file) /* REVISIT maybe wait for "carrier detect" */ tty->driver_data = port; - port->port_tty = tty; + port->port.tty = tty; - port->open_count = 1; + port->port.count = 1; port->openclose = false; /* if connected, start the I/O stream */ @@ -837,11 +834,11 @@ static void gs_close(struct tty_struct *tty, struct file *file) spin_lock_irq(&port->port_lock); - if (port->open_count != 1) { - if (port->open_count == 0) + if (port->port.count != 1) { + if (port->port.count == 0) WARN_ON(1); else - --port->open_count; + --port->port.count; goto exit; } @@ -851,7 +848,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) * and sleep if necessary */ port->openclose = true; - port->open_count = 0; + port->port.count = 0; gser = port->port_usb; if (gser && gser->disconnect) @@ -879,14 +876,14 @@ static void gs_close(struct tty_struct *tty, struct file *file) gs_buf_clear(&port->port_write_buf); tty->driver_data = NULL; - port->port_tty = NULL; + port->port.tty = NULL; port->openclose = false; pr_debug("gs_close: ttyGS%d (%p,%p) done!\n", port->port_num, tty, file); - wake_up_interruptible(&port->close_wait); + wake_up_interruptible(&port->port.close_wait); exit: spin_unlock_irq(&port->port_lock); } @@ -1034,8 +1031,8 @@ gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding) if (port == NULL) return -ENOMEM; + tty_port_init(&port->port); spin_lock_init(&port->port_lock); - init_waitqueue_head(&port->close_wait); init_waitqueue_head(&port->drain_wait); tasklet_init(&port->push, gs_rx_push, (unsigned long) port); @@ -1155,7 +1152,7 @@ static int gs_closed(struct gs_port *port) int cond; spin_lock_irq(&port->port_lock); - cond = (port->open_count == 0) && !port->openclose; + cond = (port->port.count == 0) && !port->openclose; spin_unlock_irq(&port->port_lock); return cond; } @@ -1194,7 +1191,7 @@ void gserial_cleanup(void) tasklet_kill(&port->push); /* wait for old opens to finish */ - wait_event(port->close_wait, gs_closed(port)); + wait_event(port->port.close_wait, gs_closed(port)); WARN_ON(port->port_usb != NULL); @@ -1268,7 +1265,7 @@ int gserial_connect(struct gserial *gser, u8 port_num) /* if it's already open, start I/O ... and notify the serial * protocol about open/close status (connect/disconnect). */ - if (port->open_count) { + if (port->port.count) { pr_debug("gserial_connect: start ttyGS%d\n", port->port_num); gs_start_io(port); if (gser->connect) @@ -1315,10 +1312,10 @@ void gserial_disconnect(struct gserial *gser) port->port_usb = NULL; gser->ioport = NULL; - if (port->open_count > 0 || port->openclose) { + if (port->port.count > 0 || port->openclose) { wake_up_interruptible(&port->drain_wait); - if (port->port_tty) - tty_hangup(port->port_tty); + if (port->port.tty) + tty_hangup(port->port.tty); } spin_unlock_irqrestore(&port->port_lock, flags); @@ -1331,7 +1328,7 @@ void gserial_disconnect(struct gserial *gser) /* finally, free any unused/unusable I/O buffers */ spin_lock_irqsave(&port->port_lock, flags); - if (port->open_count == 0 && !port->openclose) + if (port->port.count == 0 && !port->openclose) gs_buf_free(&port->port_write_buf); gs_free_requests(gser->out, &port->read_pool, NULL); gs_free_requests(gser->out, &port->read_queue, NULL); |