aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/speakup/selection.c5
-rw-r--r--drivers/tty/n_tty.c7
-rw-r--r--drivers/tty/serial/8250/8250_pci.c29
-rw-r--r--drivers/tty/tty_io.c44
-rw-r--r--drivers/tty/tty_mutex.c8
-rw-r--r--include/linux/tty.h1
6 files changed, 82 insertions, 12 deletions
diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c
index aa5ab6c80ed4..41ef099b7aa6 100644
--- a/drivers/staging/speakup/selection.c
+++ b/drivers/staging/speakup/selection.c
@@ -142,7 +142,9 @@ static void __speakup_paste_selection(struct work_struct *work)
142 struct tty_ldisc *ld; 142 struct tty_ldisc *ld;
143 DECLARE_WAITQUEUE(wait, current); 143 DECLARE_WAITQUEUE(wait, current);
144 144
145 ld = tty_ldisc_ref_wait(tty); 145 ld = tty_ldisc_ref(tty);
146 if (!ld)
147 goto tty_unref;
146 tty_buffer_lock_exclusive(&vc->port); 148 tty_buffer_lock_exclusive(&vc->port);
147 149
148 add_wait_queue(&vc->paste_wait, &wait); 150 add_wait_queue(&vc->paste_wait, &wait);
@@ -162,6 +164,7 @@ static void __speakup_paste_selection(struct work_struct *work)
162 164
163 tty_buffer_unlock_exclusive(&vc->port); 165 tty_buffer_unlock_exclusive(&vc->port);
164 tty_ldisc_deref(ld); 166 tty_ldisc_deref(ld);
167tty_unref:
165 tty_kref_put(tty); 168 tty_kref_put(tty);
166} 169}
167 170
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index d9a5fc28fef4..b280abaad91b 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -269,16 +269,13 @@ static void n_tty_check_throttle(struct tty_struct *tty)
269 269
270static void n_tty_check_unthrottle(struct tty_struct *tty) 270static void n_tty_check_unthrottle(struct tty_struct *tty)
271{ 271{
272 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 272 if (tty->driver->type == TTY_DRIVER_TYPE_PTY) {
273 tty->link->ldisc->ops->write_wakeup == n_tty_write_wakeup) {
274 if (chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE) 273 if (chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE)
275 return; 274 return;
276 if (!tty->count) 275 if (!tty->count)
277 return; 276 return;
278 n_tty_kick_worker(tty); 277 n_tty_kick_worker(tty);
279 n_tty_write_wakeup(tty->link); 278 tty_wakeup(tty->link);
280 if (waitqueue_active(&tty->link->write_wait))
281 wake_up_interruptible_poll(&tty->link->write_wait, POLLOUT);
282 return; 279 return;
283 } 280 }
284 281
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index 4097f3f65b3b..e71ec78fc11e 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -1379,6 +1379,9 @@ ce4100_serial_setup(struct serial_private *priv,
1379#define PCI_DEVICE_ID_INTEL_BSW_UART1 0x228a 1379#define PCI_DEVICE_ID_INTEL_BSW_UART1 0x228a
1380#define PCI_DEVICE_ID_INTEL_BSW_UART2 0x228c 1380#define PCI_DEVICE_ID_INTEL_BSW_UART2 0x228c
1381 1381
1382#define PCI_DEVICE_ID_INTEL_BDW_UART1 0x9ce3
1383#define PCI_DEVICE_ID_INTEL_BDW_UART2 0x9ce4
1384
1382#define BYT_PRV_CLK 0x800 1385#define BYT_PRV_CLK 0x800
1383#define BYT_PRV_CLK_EN (1 << 0) 1386#define BYT_PRV_CLK_EN (1 << 0)
1384#define BYT_PRV_CLK_M_VAL_SHIFT 1 1387#define BYT_PRV_CLK_M_VAL_SHIFT 1
@@ -1461,11 +1464,13 @@ byt_serial_setup(struct serial_private *priv,
1461 switch (pdev->device) { 1464 switch (pdev->device) {
1462 case PCI_DEVICE_ID_INTEL_BYT_UART1: 1465 case PCI_DEVICE_ID_INTEL_BYT_UART1:
1463 case PCI_DEVICE_ID_INTEL_BSW_UART1: 1466 case PCI_DEVICE_ID_INTEL_BSW_UART1:
1467 case PCI_DEVICE_ID_INTEL_BDW_UART1:
1464 rx_param->src_id = 3; 1468 rx_param->src_id = 3;
1465 tx_param->dst_id = 2; 1469 tx_param->dst_id = 2;
1466 break; 1470 break;
1467 case PCI_DEVICE_ID_INTEL_BYT_UART2: 1471 case PCI_DEVICE_ID_INTEL_BYT_UART2:
1468 case PCI_DEVICE_ID_INTEL_BSW_UART2: 1472 case PCI_DEVICE_ID_INTEL_BSW_UART2:
1473 case PCI_DEVICE_ID_INTEL_BDW_UART2:
1469 rx_param->src_id = 5; 1474 rx_param->src_id = 5;
1470 tx_param->dst_id = 4; 1475 tx_param->dst_id = 4;
1471 break; 1476 break;
@@ -2062,6 +2067,20 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
2062 .subdevice = PCI_ANY_ID, 2067 .subdevice = PCI_ANY_ID,
2063 .setup = byt_serial_setup, 2068 .setup = byt_serial_setup,
2064 }, 2069 },
2070 {
2071 .vendor = PCI_VENDOR_ID_INTEL,
2072 .device = PCI_DEVICE_ID_INTEL_BDW_UART1,
2073 .subvendor = PCI_ANY_ID,
2074 .subdevice = PCI_ANY_ID,
2075 .setup = byt_serial_setup,
2076 },
2077 {
2078 .vendor = PCI_VENDOR_ID_INTEL,
2079 .device = PCI_DEVICE_ID_INTEL_BDW_UART2,
2080 .subvendor = PCI_ANY_ID,
2081 .subdevice = PCI_ANY_ID,
2082 .setup = byt_serial_setup,
2083 },
2065 /* 2084 /*
2066 * ITE 2085 * ITE
2067 */ 2086 */
@@ -5506,6 +5525,16 @@ static struct pci_device_id serial_pci_tbl[] = {
5506 PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, 5525 PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
5507 pbn_byt }, 5526 pbn_byt },
5508 5527
5528 /* Intel Broadwell */
5529 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BDW_UART1,
5530 PCI_ANY_ID, PCI_ANY_ID,
5531 PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
5532 pbn_byt },
5533 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BDW_UART2,
5534 PCI_ANY_ID, PCI_ANY_ID,
5535 PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
5536 pbn_byt },
5537
5509 /* 5538 /*
5510 * Intel Quark x1000 5539 * Intel Quark x1000
5511 */ 5540 */
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 892c92354745..5cec01c75691 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -1463,13 +1463,13 @@ static int tty_reopen(struct tty_struct *tty)
1463{ 1463{
1464 struct tty_driver *driver = tty->driver; 1464 struct tty_driver *driver = tty->driver;
1465 1465
1466 if (!tty->count)
1467 return -EIO;
1468
1469 if (driver->type == TTY_DRIVER_TYPE_PTY && 1466 if (driver->type == TTY_DRIVER_TYPE_PTY &&
1470 driver->subtype == PTY_TYPE_MASTER) 1467 driver->subtype == PTY_TYPE_MASTER)
1471 return -EIO; 1468 return -EIO;
1472 1469
1470 if (!tty->count)
1471 return -EAGAIN;
1472
1473 if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN)) 1473 if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN))
1474 return -EBUSY; 1474 return -EBUSY;
1475 1475
@@ -2065,7 +2065,12 @@ retry_open:
2065 2065
2066 if (tty) { 2066 if (tty) {
2067 mutex_unlock(&tty_mutex); 2067 mutex_unlock(&tty_mutex);
2068 tty_lock(tty); 2068 retval = tty_lock_interruptible(tty);
2069 if (retval) {
2070 if (retval == -EINTR)
2071 retval = -ERESTARTSYS;
2072 goto err_unref;
2073 }
2069 /* safe to drop the kref from tty_driver_lookup_tty() */ 2074 /* safe to drop the kref from tty_driver_lookup_tty() */
2070 tty_kref_put(tty); 2075 tty_kref_put(tty);
2071 retval = tty_reopen(tty); 2076 retval = tty_reopen(tty);
@@ -2083,7 +2088,11 @@ retry_open:
2083 2088
2084 if (IS_ERR(tty)) { 2089 if (IS_ERR(tty)) {
2085 retval = PTR_ERR(tty); 2090 retval = PTR_ERR(tty);
2086 goto err_file; 2091 if (retval != -EAGAIN || signal_pending(current))
2092 goto err_file;
2093 tty_free_file(filp);
2094 schedule();
2095 goto retry_open;
2087 } 2096 }
2088 2097
2089 tty_add_file(tty, filp); 2098 tty_add_file(tty, filp);
@@ -2152,6 +2161,7 @@ retry_open:
2152 return 0; 2161 return 0;
2153err_unlock: 2162err_unlock:
2154 mutex_unlock(&tty_mutex); 2163 mutex_unlock(&tty_mutex);
2164err_unref:
2155 /* after locks to avoid deadlock */ 2165 /* after locks to avoid deadlock */
2156 if (!IS_ERR_OR_NULL(driver)) 2166 if (!IS_ERR_OR_NULL(driver))
2157 tty_driver_kref_put(driver); 2167 tty_driver_kref_put(driver);
@@ -2649,6 +2659,28 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
2649} 2659}
2650 2660
2651/** 2661/**
2662 * tiocgetd - get line discipline
2663 * @tty: tty device
2664 * @p: pointer to user data
2665 *
2666 * Retrieves the line discipline id directly from the ldisc.
2667 *
2668 * Locking: waits for ldisc reference (in case the line discipline
2669 * is changing or the tty is being hungup)
2670 */
2671
2672static int tiocgetd(struct tty_struct *tty, int __user *p)
2673{
2674 struct tty_ldisc *ld;
2675 int ret;
2676
2677 ld = tty_ldisc_ref_wait(tty);
2678 ret = put_user(ld->ops->num, p);
2679 tty_ldisc_deref(ld);
2680 return ret;
2681}
2682
2683/**
2652 * send_break - performed time break 2684 * send_break - performed time break
2653 * @tty: device to break on 2685 * @tty: device to break on
2654 * @duration: timeout in mS 2686 * @duration: timeout in mS
@@ -2874,7 +2906,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2874 case TIOCGSID: 2906 case TIOCGSID:
2875 return tiocgsid(tty, real_tty, p); 2907 return tiocgsid(tty, real_tty, p);
2876 case TIOCGETD: 2908 case TIOCGETD:
2877 return put_user(tty->ldisc->ops->num, (int __user *)p); 2909 return tiocgetd(tty, p);
2878 case TIOCSETD: 2910 case TIOCSETD:
2879 return tiocsetd(tty, p); 2911 return tiocsetd(tty, p);
2880 case TIOCVHANGUP: 2912 case TIOCVHANGUP:
diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c
index 77703a391207..d2f3c4cd697f 100644
--- a/drivers/tty/tty_mutex.c
+++ b/drivers/tty/tty_mutex.c
@@ -19,6 +19,14 @@ void __lockfunc tty_lock(struct tty_struct *tty)
19} 19}
20EXPORT_SYMBOL(tty_lock); 20EXPORT_SYMBOL(tty_lock);
21 21
22int tty_lock_interruptible(struct tty_struct *tty)
23{
24 if (WARN(tty->magic != TTY_MAGIC, "L Bad %p\n", tty))
25 return -EIO;
26 tty_kref_get(tty);
27 return mutex_lock_interruptible(&tty->legacy_mutex);
28}
29
22void __lockfunc tty_unlock(struct tty_struct *tty) 30void __lockfunc tty_unlock(struct tty_struct *tty)
23{ 31{
24 if (WARN(tty->magic != TTY_MAGIC, "U Bad %p\n", tty)) 32 if (WARN(tty->magic != TTY_MAGIC, "U Bad %p\n", tty))
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 2fd8708ea888..d9fb4b043f56 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -649,6 +649,7 @@ extern long vt_compat_ioctl(struct tty_struct *tty,
649/* tty_mutex.c */ 649/* tty_mutex.c */
650/* functions for preparation of BKL removal */ 650/* functions for preparation of BKL removal */
651extern void __lockfunc tty_lock(struct tty_struct *tty); 651extern void __lockfunc tty_lock(struct tty_struct *tty);
652extern int tty_lock_interruptible(struct tty_struct *tty);
652extern void __lockfunc tty_unlock(struct tty_struct *tty); 653extern void __lockfunc tty_unlock(struct tty_struct *tty);
653extern void __lockfunc tty_lock_slave(struct tty_struct *tty); 654extern void __lockfunc tty_lock_slave(struct tty_struct *tty);
654extern void __lockfunc tty_unlock_slave(struct tty_struct *tty); 655extern void __lockfunc tty_unlock_slave(struct tty_struct *tty);