From 9af92fbff3b06d75470717361076aa7bd097ff8b Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 10 Sep 2015 11:29:03 +0200 Subject: tty/serial: at91: move ATMEL_MAX_UART Move ATMEL_MAX_UART from platform_data/atmel.h to atmel_serial.c as this is the only file using it and it is common practise from tty/serial drivers to define it directly in the driver file. Signed-off-by: Alexandre Belloni Acked-by: Nicolas Ferre Signed-off-by: Greg Kroah-Hartman --- include/linux/platform_data/atmel.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'include') diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h index 527a85c61924..c4bc90bfebe0 100644 --- a/include/linux/platform_data/atmel.h +++ b/include/linux/platform_data/atmel.h @@ -19,12 +19,6 @@ #include #include -/* - * at91: 6 USARTs and one DBGU port (SAM9260) - * avr32: 4 - */ -#define ATMEL_MAX_UART 7 - /* USB Device */ struct at91_udc_data { int vbus_pin; /* high == host powering us */ -- cgit v1.2.3 From 79c1faa4511e78380cd643dac88a775062a08bc0 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sat, 10 Oct 2015 16:00:51 -0400 Subject: tty: Remove tty_wait_until_sent_from_close() tty_wait_until_sent_from_close() drops the tty lock while waiting for the tty driver to finish sending previously accepted data (ie., data remaining in its write buffer and transmit fifo). tty_wait_until_sent_from_close() was added by commit a57a7bf3fc7e ("TTY: define tty_wait_until_sent_from_close") to prevent the entire tty subsystem from being unable to open new ttys while waiting for one tty to close while output drained. However, since commit 0911261d4cb6 ("tty: Don't take tty_mutex for tty count changes"), holding a tty lock while closing does not prevent other ttys from being opened/closed/hung up, but only prevents lifetime event changes for the tty under lock. Holding the tty lock while waiting for output to drain does prevent parallel non-blocking opens (O_NONBLOCK) from advancing or returning while the tty lock is held. However, all parallel opens _already_ block even if the tty lock is dropped while closing and the parallel open advances. Blocking in open has been in mainline since at least 2.6.29 (see tty_port_block_til_ready(); note the test for O_NONBLOCK is _after_ the wait while ASYNC_CLOSING). IOW, before this patch a non-blocking open will sleep anyway for the _entire_ duration of a parallel hardware shutdown, and when it wakes, the error return will cause a release of its tty, and it will restart with a fresh attempt to open. Similarly with a blocking open that is already waiting; when it's woken, the hardware shutdown has already completed to ASYNC_INITIALIZED is not set, which forces a release and restart as well. So, holding the tty lock across the _entire_ close (which is what this patch does), even while waiting for output to drain, is equivalent to the current outcome wrt parallel opens. Cc: Alan Cox Cc: David Laight CC: Arnd Bergmann CC: Karsten Keil CC: linuxppc-dev@lists.ozlabs.org Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/isdn/i4l/isdn_tty.c | 2 +- drivers/tty/hvc/hvc_console.c | 2 +- drivers/tty/hvc/hvcs.c | 2 +- drivers/tty/tty_port.c | 11 ++--------- include/linux/tty.h | 18 ------------------ 5 files changed, 5 insertions(+), 30 deletions(-) (limited to 'include') diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index bc912611fe09..2175225af742 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -1582,7 +1582,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) * line status register. */ if (port->flags & ASYNC_INITIALIZED) { - tty_wait_until_sent_from_close(tty, 3000); /* 30 seconds timeout */ + tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ /* * Before we drop DTR, make sure the UART transmitter * has completely drained; this is especially diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 9c30f67c802a..e46d628998f5 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -418,7 +418,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) * there is no buffered data otherwise sleeps on a wait queue * waking periodically to check chars_in_buffer(). */ - tty_wait_until_sent_from_close(tty, HVC_CLOSE_WAIT); + tty_wait_until_sent(tty, HVC_CLOSE_WAIT); } else { if (hp->port.count < 0) printk(KERN_ERR "hvc_close %X: oops, count is %d\n", diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index f7ff97c0ad34..5997b1731111 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -1230,7 +1230,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) irq = hvcsd->vdev->irq; spin_unlock_irqrestore(&hvcsd->lock, flags); - tty_wait_until_sent_from_close(tty, HVCS_CLOSE_WAIT); + tty_wait_until_sent(tty, HVCS_CLOSE_WAIT); /* * This line is important because it tells hvcs_open that this diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 40b31835f80b..d7d9f9cde964 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -463,10 +463,7 @@ static void tty_port_drain_delay(struct tty_port *port, struct tty_struct *tty) schedule_timeout_interruptible(timeout); } -/* Caller holds tty lock. - * NB: may drop and reacquire tty lock (in tty_wait_until_sent_from_close()) - * so tty and tty port may have changed state (but not hung up or reopened). - */ +/* Caller holds tty lock. */ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp) { @@ -502,7 +499,7 @@ int tty_port_close_start(struct tty_port *port, if (tty->flow_stopped) tty_driver_flush_buffer(tty); if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent_from_close(tty, port->closing_wait); + tty_wait_until_sent(tty, port->closing_wait); if (port->drain_delay) tty_port_drain_delay(port, tty); } @@ -543,10 +540,6 @@ EXPORT_SYMBOL(tty_port_close_end); * tty_port_close * * Caller holds tty lock - * - * NB: may drop and reacquire tty lock (in tty_port_close_start()-> - * tty_wait_until_sent_from_close()) so tty and tty_port may have changed - * state (but not hung up or reopened). */ void tty_port_close(struct tty_port *port, struct tty_struct *tty, struct file *filp) diff --git a/include/linux/tty.h b/include/linux/tty.h index d072ded41678..614c8224c32f 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -656,24 +656,6 @@ extern void __lockfunc tty_unlock(struct tty_struct *tty); extern void __lockfunc tty_lock_slave(struct tty_struct *tty); extern void __lockfunc tty_unlock_slave(struct tty_struct *tty); extern void tty_set_lock_subclass(struct tty_struct *tty); -/* - * this shall be called only from where BTM is held (like close) - * - * We need this to ensure nobody waits for us to finish while we are waiting. - * Without this we were encountering system stalls. - * - * This should be indeed removed with BTM removal later. - * - * Locking: BTM required. Nobody is allowed to hold port->mutex. - */ -static inline void tty_wait_until_sent_from_close(struct tty_struct *tty, - long timeout) -{ - tty_unlock(tty); /* tty->ops->close holds the BTM, drop it while waiting */ - tty_wait_until_sent(tty, timeout); - tty_lock(tty); -} - /* * wait_event_interruptible_tty -- wait for a condition with the tty lock held * -- cgit v1.2.3 From cc2aaabfd6d6335e2156781ca67715b4de17f993 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sat, 10 Oct 2015 16:00:54 -0400 Subject: tty: Remove tty_port::close_wait With the removal of tty_wait_until_sent_from_close(), tty drivers no longer wait during open for parallel closes to complete (instead, the tty core waits before calling the driver open() method). Thus, the close_wait waitqueue is no longer used for waiting. Remove struct tty_port::close_wait. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/rocket.c | 1 - drivers/tty/serial/68328serial.c | 1 - drivers/tty/serial/crisv10.c | 1 - drivers/tty/serial/serial_core.c | 1 - drivers/tty/tty_port.c | 2 -- include/linux/tty.h | 1 - 6 files changed, 7 deletions(-) (limited to 'include') diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index 69c72d1aa627..802eac7e561b 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c @@ -1049,7 +1049,6 @@ static void rp_close(struct tty_struct *tty, struct file *filp) mutex_unlock(&port->mutex); tty_port_tty_set(port, NULL); - wake_up_interruptible(&port->close_wait); complete_all(&info->close_wait); atomic_dec(&rp_num_ports_open); diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index 9ba0c9333078..0140ba4aacde 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c @@ -1071,7 +1071,6 @@ static void rs_close(struct tty_struct *tty, struct file * filp) wake_up_interruptible(&port->open_wait); } port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - wake_up_interruptible(&port->close_wait); local_irq_restore(flags); } diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 06f4fe928dcd..f13f2ebd215b 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c @@ -3655,7 +3655,6 @@ rs_close(struct tty_struct *tty, struct file * filp) wake_up_interruptible(&info->port.open_wait); } info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - wake_up_interruptible(&info->port.close_wait); local_irq_restore(flags); /* port closed */ diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index df4271ae7414..def5199ca004 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1437,7 +1437,6 @@ static void uart_close(struct tty_struct *tty, struct file *filp) clear_bit(ASYNCB_CLOSING, &port->flags); spin_unlock_irq(&port->lock); wake_up_interruptible(&port->open_wait); - wake_up_interruptible(&port->close_wait); mutex_unlock(&port->mutex); diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 0e1cf0495fb9..e04a8cfb16f7 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -22,7 +22,6 @@ void tty_port_init(struct tty_port *port) memset(port, 0, sizeof(*port)); tty_buffer_init(port); init_waitqueue_head(&port->open_wait); - init_waitqueue_head(&port->close_wait); init_waitqueue_head(&port->delta_msr_wait); mutex_init(&port->mutex); mutex_init(&port->buf_mutex); @@ -520,7 +519,6 @@ void tty_port_close_end(struct tty_port *port, struct tty_struct *tty) wake_up_interruptible(&port->open_wait); } port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); - wake_up_interruptible(&port->close_wait); spin_unlock_irqrestore(&port->lock, flags); } EXPORT_SYMBOL(tty_port_close_end); diff --git a/include/linux/tty.h b/include/linux/tty.h index 614c8224c32f..090ce2a52262 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -227,7 +227,6 @@ struct tty_port { int blocked_open; /* Waiting to open */ int count; /* Usage count */ wait_queue_head_t open_wait; /* Open waiters */ - wait_queue_head_t close_wait; /* Close waiters */ wait_queue_head_t delta_msr_wait; /* Modem status change */ unsigned long flags; /* TTY flags ASY_*/ unsigned char console:1, /* port is a console */ -- cgit v1.2.3 From 9b9ab1b3f0860138681862cf6e4c48be59377ef1 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sat, 10 Oct 2015 16:00:55 -0400 Subject: tty: r3964: Use tty->read_wait waitqueue The tty core provides read_wait waitqueue specifically for line disciplines to wait readers; otherwise, the line discipline may miss wakeups generated by the tty core. NB: The tty core already provides serialization for the line discipline's close() method, and guarantees no readers or writers will be using the closing instance of the line discipline. Completely remove that wakeup. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_r3964.c | 10 ++++------ include/linux/n_r3964.h | 3 --- 2 files changed, 4 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c index 8b157d68a03e..6fdef921cdb7 100644 --- a/drivers/tty/n_r3964.c +++ b/drivers/tty/n_r3964.c @@ -276,7 +276,7 @@ static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code) add_msg(pHeader->owner, R3964_MSG_ACK, pHeader->length, error_code, NULL); } - wake_up_interruptible(&pInfo->read_wait); + wake_up_interruptible(&pInfo->tty->read_wait); } spin_lock_irqsave(&pInfo->lock, flags); @@ -542,7 +542,7 @@ static void on_receive_block(struct r3964_info *pInfo) pBlock); } } - wake_up_interruptible(&pInfo->read_wait); + wake_up_interruptible(&pInfo->tty->read_wait); pInfo->state = R3964_IDLE; @@ -979,7 +979,6 @@ static int r3964_open(struct tty_struct *tty) spin_lock_init(&pInfo->lock); pInfo->tty = tty; - init_waitqueue_head(&pInfo->read_wait); pInfo->priority = R3964_MASTER; pInfo->rx_first = pInfo->rx_last = NULL; pInfo->tx_first = pInfo->tx_last = NULL; @@ -1045,7 +1044,6 @@ static void r3964_close(struct tty_struct *tty) } /* Free buffers: */ - wake_up_interruptible(&pInfo->read_wait); kfree(pInfo->rx_buf); TRACE_M("r3964_close - rx_buf kfree %p", pInfo->rx_buf); kfree(pInfo->tx_buf); @@ -1077,7 +1075,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, goto unlock; } /* block until there is a message: */ - wait_event_interruptible_tty(tty, pInfo->read_wait, + wait_event_interruptible_tty(tty, tty->read_wait, (pMsg = remove_msg(pInfo, pClient))); } @@ -1227,7 +1225,7 @@ static unsigned int r3964_poll(struct tty_struct *tty, struct file *file, pClient = findClient(pInfo, task_pid(current)); if (pClient) { - poll_wait(file, &pInfo->read_wait, wait); + poll_wait(file, &tty->read_wait, wait); spin_lock_irqsave(&pInfo->lock, flags); pMsg = pClient->first_msg; spin_unlock_irqrestore(&pInfo->lock, flags); diff --git a/include/linux/n_r3964.h b/include/linux/n_r3964.h index 5d0b2a1dee69..e9adb4226224 100644 --- a/include/linux/n_r3964.h +++ b/include/linux/n_r3964.h @@ -152,9 +152,6 @@ struct r3964_info { unsigned char *rx_buf; /* ring buffer */ unsigned char *tx_buf; - wait_queue_head_t read_wait; - //struct wait_queue *read_wait; - struct r3964_block_header *rx_first; struct r3964_block_header *rx_last; struct r3964_block_header *tx_first; -- cgit v1.2.3 From aba24888d9af19e0bd1c7e7344fd27841611d7a8 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sat, 10 Oct 2015 16:00:56 -0400 Subject: tty: r3964: Replace/remove bogus tty lock use The tty lock is strictly for serializing tty lifetime events (open/close/hangup), and not for line discipline serialization. The tty core already provides serialization of concurrent writes to the same tty, and line discipline lifetime management (by ldisc references), so pinning the tty via tty_lock() is unnecessary and counter-productive; remove tty lock use. However, the line discipline is responsible for serializing reads (if required by the line discipline); add read_lock mutex to serialize calls of r3964_read(). Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_r3964.c | 20 +++++++++++++------- include/linux/n_r3964.h | 5 +++-- 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c index 6fdef921cdb7..345111467b85 100644 --- a/drivers/tty/n_r3964.c +++ b/drivers/tty/n_r3964.c @@ -978,6 +978,7 @@ static int r3964_open(struct tty_struct *tty) } spin_lock_init(&pInfo->lock); + mutex_init(&pInfo->read_lock); pInfo->tty = tty; pInfo->priority = R3964_MASTER; pInfo->rx_first = pInfo->rx_last = NULL; @@ -1063,7 +1064,16 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, TRACE_L("read()"); - tty_lock(tty); + /* + * Internal serialization of reads. + */ + if (file->f_flags & O_NONBLOCK) { + if (!mutex_trylock(&pInfo->read_lock)) + return -EAGAIN; + } else { + if (mutex_lock_interruptible(&pInfo->read_lock)) + return -ERESTARTSYS; + } pClient = findClient(pInfo, task_pid(current)); if (pClient) { @@ -1075,7 +1085,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, goto unlock; } /* block until there is a message: */ - wait_event_interruptible_tty(tty, tty->read_wait, + wait_event_interruptible(tty->read_wait, (pMsg = remove_msg(pInfo, pClient))); } @@ -1105,7 +1115,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, } ret = -EPERM; unlock: - tty_unlock(tty); + mutex_unlock(&pInfo->read_lock); return ret; } @@ -1154,8 +1164,6 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, pHeader->locks = 0; pHeader->owner = NULL; - tty_lock(tty); - pClient = findClient(pInfo, task_pid(current)); if (pClient) { pHeader->owner = pClient; @@ -1173,8 +1181,6 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, add_tx_queue(pInfo, pHeader); trigger_transmit(pInfo); - tty_unlock(tty); - return 0; } diff --git a/include/linux/n_r3964.h b/include/linux/n_r3964.h index e9adb4226224..90a803aa42e8 100644 --- a/include/linux/n_r3964.h +++ b/include/linux/n_r3964.h @@ -161,8 +161,9 @@ struct r3964_info { unsigned char last_rx; unsigned char bcc; unsigned int blocks_in_rx_queue; - - + + struct mutex read_lock; /* serialize r3964_read */ + struct r3964_client_info *firstClient; unsigned int state; unsigned int flags; -- cgit v1.2.3 From f148d6d7b79adb42a8e7fa95bf6be5b607015f26 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sat, 10 Oct 2015 16:00:57 -0400 Subject: tty: Remove wait_event_interruptible_tty() In-tree users of wait_event_interruptible_tty() have been removed; remove. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- include/linux/tty.h | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'include') diff --git a/include/linux/tty.h b/include/linux/tty.h index 090ce2a52262..c2889f4331e1 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -655,32 +655,6 @@ extern void __lockfunc tty_unlock(struct tty_struct *tty); extern void __lockfunc tty_lock_slave(struct tty_struct *tty); extern void __lockfunc tty_unlock_slave(struct tty_struct *tty); extern void tty_set_lock_subclass(struct tty_struct *tty); -/* - * wait_event_interruptible_tty -- wait for a condition with the tty lock held - * - * The condition we are waiting for might take a long time to - * become true, or might depend on another thread taking the - * BTM. In either case, we need to drop the BTM to guarantee - * forward progress. This is a leftover from the conversion - * from the BKL and should eventually get removed as the BTM - * falls out of use. - * - * Do not use in new code. - */ -#define wait_event_interruptible_tty(tty, wq, condition) \ -({ \ - int __ret = 0; \ - if (!(condition)) \ - __ret = __wait_event_interruptible_tty(tty, wq, \ - condition); \ - __ret; \ -}) - -#define __wait_event_interruptible_tty(tty, wq, condition) \ - ___wait_event(wq, condition, TASK_INTERRUPTIBLE, 0, 0, \ - tty_unlock(tty); \ - schedule(); \ - tty_lock(tty)) #ifdef CONFIG_PROC_FS extern void proc_tty_register_driver(struct tty_driver *); -- cgit v1.2.3 From 47f82f1adf701b31d1816bf45118f8e83c02588e Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Tue, 13 Oct 2015 13:29:04 +0300 Subject: dmaengine: hsu: introduce stubs for the exported functions This allows UART drivers to register HSU DMA Engine without being forced to use ifdefs. Signed-off-by: Heikki Krogerus Acked-by: Vinod Koul Acked-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- include/linux/dma/hsu.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/linux/dma/hsu.h b/include/linux/dma/hsu.h index 234393a6997b..765b414eef98 100644 --- a/include/linux/dma/hsu.h +++ b/include/linux/dma/hsu.h @@ -38,11 +38,21 @@ struct hsu_dma_chip { struct hsu_dma_platform_data *pdata; }; +#if IS_ENABLED(CONFIG_HSU_DMA) /* Export to the internal users */ irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr); /* Export to the platform drivers */ int hsu_dma_probe(struct hsu_dma_chip *chip); int hsu_dma_remove(struct hsu_dma_chip *chip); +#else +static inline irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, + unsigned short nr) +{ + return IRQ_NONE; +} +static inline int hsu_dma_probe(struct hsu_dma_chip *chip) { return -ENODEV; } +static inline int hsu_dma_remove(struct hsu_dma_chip *chip) { return 0; } +#endif /* CONFIG_HSU_DMA */ #endif /* _DMA_HSU_H */ -- cgit v1.2.3 From 4c97ad993d763904fc1c9e0bdc3a6dba062802a2 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Tue, 13 Oct 2015 13:29:05 +0300 Subject: dmaengine: hsu: remove platform data There are no platforms where it's not possible to calculate the number of channels based on IO space length, and since that is the only purpose for struct hsu_dma_platform_data, removing it. Suggested-by: Andy Shevchenko Signed-off-by: Heikki Krogerus Acked-by: Vinod Koul Acked-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/dma/hsu/hsu.c | 24 +++++++----------------- drivers/dma/hsu/hsu.h | 1 + drivers/dma/hsu/pci.c | 2 +- include/linux/dma/hsu.h | 1 - include/linux/platform_data/dma-hsu.h | 4 ---- 5 files changed, 9 insertions(+), 23 deletions(-) (limited to 'include') diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c index 7669c7dd1e34..823ad728aecf 100644 --- a/drivers/dma/hsu/hsu.c +++ b/drivers/dma/hsu/hsu.c @@ -146,7 +146,7 @@ irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr) u32 sr; /* Sanity check */ - if (nr >= chip->pdata->nr_channels) + if (nr >= chip->hsu->nr_channels) return IRQ_NONE; hsuc = &chip->hsu->chan[nr]; @@ -375,7 +375,6 @@ static void hsu_dma_free_chan_resources(struct dma_chan *chan) int hsu_dma_probe(struct hsu_dma_chip *chip) { struct hsu_dma *hsu; - struct hsu_dma_platform_data *pdata = chip->pdata; void __iomem *addr = chip->regs + chip->offset; unsigned short i; int ret; @@ -386,25 +385,16 @@ int hsu_dma_probe(struct hsu_dma_chip *chip) chip->hsu = hsu; - if (!pdata) { - pdata = devm_kzalloc(chip->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return -ENOMEM; + /* Calculate nr_channels from the IO space length */ + hsu->nr_channels = (chip->length - chip->offset) / HSU_DMA_CHAN_LENGTH; - chip->pdata = pdata; - - /* Guess nr_channels from the IO space length */ - pdata->nr_channels = (chip->length - chip->offset) / - HSU_DMA_CHAN_LENGTH; - } - - hsu->chan = devm_kcalloc(chip->dev, pdata->nr_channels, + hsu->chan = devm_kcalloc(chip->dev, hsu->nr_channels, sizeof(*hsu->chan), GFP_KERNEL); if (!hsu->chan) return -ENOMEM; INIT_LIST_HEAD(&hsu->dma.channels); - for (i = 0; i < pdata->nr_channels; i++) { + for (i = 0; i < hsu->nr_channels; i++) { struct hsu_dma_chan *hsuc = &hsu->chan[i]; hsuc->vchan.desc_free = hsu_dma_desc_free; @@ -440,7 +430,7 @@ int hsu_dma_probe(struct hsu_dma_chip *chip) if (ret) return ret; - dev_info(chip->dev, "Found HSU DMA, %d channels\n", pdata->nr_channels); + dev_info(chip->dev, "Found HSU DMA, %d channels\n", hsu->nr_channels); return 0; } EXPORT_SYMBOL_GPL(hsu_dma_probe); @@ -452,7 +442,7 @@ int hsu_dma_remove(struct hsu_dma_chip *chip) dma_async_device_unregister(&hsu->dma); - for (i = 0; i < chip->pdata->nr_channels; i++) { + for (i = 0; i < hsu->nr_channels; i++) { struct hsu_dma_chan *hsuc = &hsu->chan[i]; tasklet_kill(&hsuc->vchan.task); diff --git a/drivers/dma/hsu/hsu.h b/drivers/dma/hsu/hsu.h index eeb9fff66967..f06579c6d548 100644 --- a/drivers/dma/hsu/hsu.h +++ b/drivers/dma/hsu/hsu.h @@ -107,6 +107,7 @@ struct hsu_dma { /* channels */ struct hsu_dma_chan *chan; + unsigned short nr_channels; }; static inline struct hsu_dma *to_hsu_dma(struct dma_device *ddev) diff --git a/drivers/dma/hsu/pci.c b/drivers/dma/hsu/pci.c index 77879e6ddc4c..e2db76bd56d8 100644 --- a/drivers/dma/hsu/pci.c +++ b/drivers/dma/hsu/pci.c @@ -31,7 +31,7 @@ static irqreturn_t hsu_pci_irq(int irq, void *dev) irqreturn_t ret = IRQ_NONE; dmaisr = readl(chip->regs + HSU_PCI_DMAISR); - for (i = 0; i < chip->pdata->nr_channels; i++) { + for (i = 0; i < chip->hsu->nr_channels; i++) { if (dmaisr & 0x1) ret |= hsu_dma_irq(chip, i); dmaisr >>= 1; diff --git a/include/linux/dma/hsu.h b/include/linux/dma/hsu.h index 765b414eef98..79df69dc629c 100644 --- a/include/linux/dma/hsu.h +++ b/include/linux/dma/hsu.h @@ -35,7 +35,6 @@ struct hsu_dma_chip { unsigned int length; unsigned int offset; struct hsu_dma *hsu; - struct hsu_dma_platform_data *pdata; }; #if IS_ENABLED(CONFIG_HSU_DMA) diff --git a/include/linux/platform_data/dma-hsu.h b/include/linux/platform_data/dma-hsu.h index 8a1f6a4920b2..3453fa655502 100644 --- a/include/linux/platform_data/dma-hsu.h +++ b/include/linux/platform_data/dma-hsu.h @@ -18,8 +18,4 @@ struct hsu_dma_slave { int chan_id; }; -struct hsu_dma_platform_data { - unsigned short nr_channels; -}; - #endif /* _PLATFORM_DATA_DMA_HSU_H */ -- cgit v1.2.3 From 2812d9e9fd94c54b0482215f579e6aa04452a322 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sat, 10 Oct 2015 20:28:42 -0400 Subject: tty: Combine SIGTTOU/SIGTTIN handling The job_control() check in n_tty_read() has nearly identical purpose and results as tty_check_change(). Both functions' purpose is to determine if the current task's pgrp is the foreground pgrp for the tty, and if not, to signal the current pgrp. Introduce __tty_check_change() which takes the signal to send and performs the shared operations for job control() and tty_check_change(). Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 26 ++------------------------ drivers/tty/tty_io.c | 46 ++++++++++++++++++++++++---------------------- include/linux/tty.h | 1 + 3 files changed, 27 insertions(+), 46 deletions(-) (limited to 'include') diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index ff728d32cb53..fb8ccbfdbb30 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2138,37 +2138,15 @@ extern ssize_t redirected_tty_write(struct file *, const char __user *, static int job_control(struct tty_struct *tty, struct file *file) { - struct pid *pgrp; - /* Job control check -- must be done at start and after every sleep (POSIX.1 7.1.1.4). */ /* NOTE: not yet done after every sleep pending a thorough check of the logic of this change. -- jlc */ /* don't stop on /dev/console */ - if (file->f_op->write == redirected_tty_write || - current->signal->tty != tty) + if (file->f_op->write == redirected_tty_write) return 0; - rcu_read_lock(); - pgrp = task_pgrp(current); - - spin_lock_irq(&tty->ctrl_lock); - if (!tty->pgrp) - printk(KERN_ERR "n_tty_read: no tty->pgrp!\n"); - else if (pgrp != tty->pgrp) { - spin_unlock_irq(&tty->ctrl_lock); - if (is_ignored(SIGTTIN) || is_current_pgrp_orphaned()) { - rcu_read_unlock(); - return -EIO; - } - kill_pgrp(pgrp, SIGTTIN, 1); - rcu_read_unlock(); - set_thread_flag(TIF_SIGPENDING); - return -ERESTARTSYS; - } - spin_unlock_irq(&tty->ctrl_lock); - rcu_read_unlock(); - return 0; + return __tty_check_change(tty, SIGTTIN); } diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 2eefaa6e3e3a..aa48367a0c79 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -390,10 +390,10 @@ EXPORT_SYMBOL_GPL(tty_find_polling_driver); * Locking: ctrl_lock */ -int tty_check_change(struct tty_struct *tty) +int __tty_check_change(struct tty_struct *tty, int sig) { unsigned long flags; - struct pid *pgrp; + struct pid *pgrp, *tty_pgrp; int ret = 0; if (current->signal->tty != tty) @@ -403,33 +403,35 @@ int tty_check_change(struct tty_struct *tty) pgrp = task_pgrp(current); spin_lock_irqsave(&tty->ctrl_lock, flags); - - if (!tty->pgrp) { - printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n"); - goto out_unlock; - } - if (pgrp == tty->pgrp) - goto out_unlock; + tty_pgrp = tty->pgrp; spin_unlock_irqrestore(&tty->ctrl_lock, flags); - if (is_ignored(SIGTTOU)) - goto out_rcuunlock; - if (is_current_pgrp_orphaned()) { - ret = -EIO; - goto out_rcuunlock; + if (tty_pgrp && pgrp != tty->pgrp) { + if (is_ignored(sig)) { + if (sig == SIGTTIN) + ret = -EIO; + } else if (is_current_pgrp_orphaned()) + ret = -EIO; + else { + kill_pgrp(pgrp, sig, 1); + set_thread_flag(TIF_SIGPENDING); + ret = -ERESTARTSYS; + } } - kill_pgrp(pgrp, SIGTTOU, 1); - rcu_read_unlock(); - set_thread_flag(TIF_SIGPENDING); - ret = -ERESTARTSYS; - return ret; -out_unlock: - spin_unlock_irqrestore(&tty->ctrl_lock, flags); -out_rcuunlock: rcu_read_unlock(); + + if (!tty_pgrp) { + pr_warn("%s: tty_check_change: sig=%d, tty->pgrp == NULL!\n", + tty_name(tty), sig); + } + return ret; } +int tty_check_change(struct tty_struct *tty) +{ + return __tty_check_change(tty, SIGTTOU); +} EXPORT_SYMBOL(tty_check_change); static ssize_t hung_up_tty_read(struct file *file, char __user *buf, diff --git a/include/linux/tty.h b/include/linux/tty.h index c2889f4331e1..533d7f6e2481 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -423,6 +423,7 @@ extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, const char *routine); extern const char *tty_name(const struct tty_struct *tty); extern void tty_wait_until_sent(struct tty_struct *tty, long timeout); +extern int __tty_check_change(struct tty_struct *tty, int sig); extern int tty_check_change(struct tty_struct *tty); extern void __stop_tty(struct tty_struct *tty); extern void stop_tty(struct tty_struct *tty); -- cgit v1.2.3 From e176058f0de53c2346734e5254835e0045364001 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sat, 17 Oct 2015 16:36:23 -0400 Subject: tty: Abstract tty buffer work Introduce API functions to restart and cancel tty buffer work, rather than manipulate buffer work directly. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 2 +- drivers/tty/tty_buffer.c | 10 ++++++++++ drivers/tty/tty_io.c | 2 +- drivers/tty/tty_port.c | 2 +- include/linux/tty.h | 2 ++ 5 files changed, 15 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index fb8ccbfdbb30..13844261cd5f 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -201,7 +201,7 @@ static void n_tty_kick_worker(struct tty_struct *tty) */ WARN_RATELIMIT(test_bit(TTY_LDISC_HALTED, &tty->flags), "scheduling buffer work for halted ldisc\n"); - queue_work(system_unbound_wq, &tty->port->buf.work); + tty_buffer_restart_work(tty->port); } } diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index a660ab181cca..7cc16db37e0e 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -587,3 +587,13 @@ void tty_buffer_set_lock_subclass(struct tty_port *port) { lockdep_set_subclass(&port->buf.lock, TTY_LOCK_SLAVE); } + +bool tty_buffer_restart_work(struct tty_port *port) +{ + return queue_work(system_unbound_wq, &port->buf.work); +} + +bool tty_buffer_cancel_work(struct tty_port *port) +{ + return cancel_work_sync(&port->buf.work); +} diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 173fdeba0987..0c41dbcb90b8 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1689,7 +1689,7 @@ static void release_tty(struct tty_struct *tty, int idx) tty->port->itty = NULL; if (tty->link) tty->link->port->itty = NULL; - cancel_work_sync(&tty->port->buf.work); + tty_buffer_cancel_work(tty->port); tty_kref_put(tty->link); tty_kref_put(tty); diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index e04a8cfb16f7..482f33f20043 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -130,7 +130,7 @@ EXPORT_SYMBOL(tty_port_free_xmit_buf); */ void tty_port_destroy(struct tty_port *port) { - cancel_work_sync(&port->buf.work); + tty_buffer_cancel_work(port); tty_buffer_free_all(port); } EXPORT_SYMBOL(tty_port_destroy); diff --git a/include/linux/tty.h b/include/linux/tty.h index 533d7f6e2481..5b04b0a5375b 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -467,6 +467,8 @@ extern void tty_buffer_free_all(struct tty_port *port); extern void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld); extern void tty_buffer_init(struct tty_port *port); extern void tty_buffer_set_lock_subclass(struct tty_port *port); +extern bool tty_buffer_restart_work(struct tty_port *port); +extern bool tty_buffer_cancel_work(struct tty_port *port); extern speed_t tty_termios_baud_rate(struct ktermios *termios); extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); extern void tty_termios_encode_baud_rate(struct ktermios *termios, -- cgit v1.2.3