Lines Matching +full:port +full:-
1 // SPDX-License-Identifier: GPL-2.0
3 * Tty port functions
23 static size_t tty_port_default_receive_buf(struct tty_port *port, const u8 *p, in tty_port_default_receive_buf() argument
29 tty = READ_ONCE(port->itty); in tty_port_default_receive_buf()
44 static void tty_port_default_lookahead_buf(struct tty_port *port, const u8 *p, in tty_port_default_lookahead_buf() argument
50 tty = READ_ONCE(port->itty); in tty_port_default_lookahead_buf()
58 if (ld->ops->lookahead_buf) in tty_port_default_lookahead_buf()
59 ld->ops->lookahead_buf(ld->tty, p, f, count); in tty_port_default_lookahead_buf()
64 static void tty_port_default_wakeup(struct tty_port *port) in tty_port_default_wakeup() argument
66 struct tty_struct *tty = tty_port_tty_get(port); in tty_port_default_wakeup()
82 * tty_port_init -- initialize tty_port
83 * @port: tty_port to initialize
85 * Initializes the state of struct tty_port. When a port was initialized using
86 * this function, one has to destroy the port by tty_port_destroy(). Either
90 void tty_port_init(struct tty_port *port) in tty_port_init() argument
92 memset(port, 0, sizeof(*port)); in tty_port_init()
93 tty_buffer_init(port); in tty_port_init()
94 init_waitqueue_head(&port->open_wait); in tty_port_init()
95 init_waitqueue_head(&port->delta_msr_wait); in tty_port_init()
96 mutex_init(&port->mutex); in tty_port_init()
97 mutex_init(&port->buf_mutex); in tty_port_init()
98 spin_lock_init(&port->lock); in tty_port_init()
99 port->close_delay = (50 * HZ) / 100; in tty_port_init()
100 port->closing_wait = (3000 * HZ) / 100; in tty_port_init()
101 port->client_ops = &tty_port_default_client_ops; in tty_port_init()
102 kref_init(&port->kref); in tty_port_init()
107 * tty_port_link_device - link tty and tty_port
108 * @port: tty_port of the device
113 * tty_port (@port). Use this only if neither tty_port_register_device() nor
117 void tty_port_link_device(struct tty_port *port, in tty_port_link_device() argument
120 if (WARN_ON(index >= driver->num)) in tty_port_link_device()
122 driver->ports[index] = port; in tty_port_link_device()
127 * tty_port_register_device - register tty device
128 * @port: tty_port of the device
133 * It is the same as tty_register_device() except the provided @port is linked
137 struct device *tty_port_register_device(struct tty_port *port, in tty_port_register_device() argument
141 return tty_port_register_device_attr(port, driver, index, device, NULL, NULL); in tty_port_register_device()
146 * tty_port_register_device_attr - register tty device
147 * @port: tty_port of the device
154 * It is the same as tty_register_device_attr() except the provided @port is
158 struct device *tty_port_register_device_attr(struct tty_port *port, in tty_port_register_device_attr() argument
163 tty_port_link_device(port, driver, index); in tty_port_register_device_attr()
170 * tty_port_register_device_attr_serdev - register tty or serdev device
171 * @port: tty_port of the device
181 struct device *tty_port_register_device_attr_serdev(struct tty_port *port, in tty_port_register_device_attr_serdev() argument
188 tty_port_link_device(port, driver, index); in tty_port_register_device_attr_serdev()
190 dev = serdev_tty_port_register(port, device, driver, index); in tty_port_register_device_attr_serdev()
191 if (PTR_ERR(dev) != -ENODEV) { in tty_port_register_device_attr_serdev()
202 * tty_port_register_device_serdev - register tty or serdev device
203 * @port: tty_port of the device
211 struct device *tty_port_register_device_serdev(struct tty_port *port, in tty_port_register_device_serdev() argument
215 return tty_port_register_device_attr_serdev(port, driver, index, in tty_port_register_device_serdev()
221 * tty_port_unregister_device - deregister a tty or serdev device
222 * @port: tty_port of the device
230 void tty_port_unregister_device(struct tty_port *port, in tty_port_unregister_device() argument
235 ret = serdev_tty_port_unregister(port); in tty_port_unregister_device()
243 int tty_port_alloc_xmit_buf(struct tty_port *port) in tty_port_alloc_xmit_buf() argument
246 mutex_lock(&port->buf_mutex); in tty_port_alloc_xmit_buf()
247 if (port->xmit_buf == NULL) { in tty_port_alloc_xmit_buf()
248 port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); in tty_port_alloc_xmit_buf()
249 if (port->xmit_buf) in tty_port_alloc_xmit_buf()
250 kfifo_init(&port->xmit_fifo, port->xmit_buf, PAGE_SIZE); in tty_port_alloc_xmit_buf()
252 mutex_unlock(&port->buf_mutex); in tty_port_alloc_xmit_buf()
253 if (port->xmit_buf == NULL) in tty_port_alloc_xmit_buf()
254 return -ENOMEM; in tty_port_alloc_xmit_buf()
259 void tty_port_free_xmit_buf(struct tty_port *port) in tty_port_free_xmit_buf() argument
261 mutex_lock(&port->buf_mutex); in tty_port_free_xmit_buf()
262 free_page((unsigned long)port->xmit_buf); in tty_port_free_xmit_buf()
263 port->xmit_buf = NULL; in tty_port_free_xmit_buf()
264 INIT_KFIFO(port->xmit_fifo); in tty_port_free_xmit_buf()
265 mutex_unlock(&port->buf_mutex); in tty_port_free_xmit_buf()
270 * tty_port_destroy -- destroy inited port
271 * @port: tty port to be destroyed
273 * When a port was initialized using tty_port_init(), one has to destroy the
274 * port by this function. Either indirectly by using &tty_port refcounting
277 void tty_port_destroy(struct tty_port *port) in tty_port_destroy() argument
279 tty_buffer_cancel_work(port); in tty_port_destroy()
280 tty_buffer_free_all(port); in tty_port_destroy()
286 struct tty_port *port = container_of(kref, struct tty_port, kref); in tty_port_destructor() local
288 /* check if last port ref was dropped before tty release */ in tty_port_destructor()
289 if (WARN_ON(port->itty)) in tty_port_destructor()
291 free_page((unsigned long)port->xmit_buf); in tty_port_destructor()
292 tty_port_destroy(port); in tty_port_destructor()
293 if (port->ops && port->ops->destruct) in tty_port_destructor()
294 port->ops->destruct(port); in tty_port_destructor()
296 kfree(port); in tty_port_destructor()
300 * tty_port_put -- drop a reference to tty_port
301 * @port: port to drop a reference of (can be NULL)
303 * The final put will destroy and free up the @port using
304 * @port->ops->destruct() hook, or using kfree() if not provided.
306 void tty_port_put(struct tty_port *port) in tty_port_put() argument
308 if (port) in tty_port_put()
309 kref_put(&port->kref, tty_port_destructor); in tty_port_put()
314 * tty_port_tty_get - get a tty reference
315 * @port: tty port
317 * Return a refcount protected tty instance or %NULL if the port is not
320 struct tty_struct *tty_port_tty_get(struct tty_port *port) in tty_port_tty_get() argument
325 spin_lock_irqsave(&port->lock, flags); in tty_port_tty_get()
326 tty = tty_kref_get(port->tty); in tty_port_tty_get()
327 spin_unlock_irqrestore(&port->lock, flags); in tty_port_tty_get()
333 * tty_port_tty_set - set the tty of a port
334 * @port: tty port
337 * Associate the port and tty pair. Manages any internal refcounts. Pass %NULL
338 * to deassociate a port.
340 void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty) in tty_port_tty_set() argument
344 spin_lock_irqsave(&port->lock, flags); in tty_port_tty_set()
345 tty_kref_put(port->tty); in tty_port_tty_set()
346 port->tty = tty_kref_get(tty); in tty_port_tty_set()
347 spin_unlock_irqrestore(&port->lock, flags); in tty_port_tty_set()
352 * tty_port_shutdown - internal helper to shutdown the device
353 * @port: tty port to be shut down
359 * @port->ops->shutdown().
361 static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty) in tty_port_shutdown() argument
363 mutex_lock(&port->mutex); in tty_port_shutdown()
364 if (port->console) in tty_port_shutdown()
367 if (tty_port_initialized(port)) { in tty_port_shutdown()
368 tty_port_set_initialized(port, false); in tty_port_shutdown()
374 tty_port_lower_dtr_rts(port); in tty_port_shutdown()
376 if (port->ops->shutdown) in tty_port_shutdown()
377 port->ops->shutdown(port); in tty_port_shutdown()
380 mutex_unlock(&port->mutex); in tty_port_shutdown()
384 * tty_port_hangup - hangup helper
385 * @port: tty port
387 * Perform port level tty hangup flag and count changes. Drop the tty
392 void tty_port_hangup(struct tty_port *port) in tty_port_hangup() argument
397 spin_lock_irqsave(&port->lock, flags); in tty_port_hangup()
398 port->count = 0; in tty_port_hangup()
399 tty = port->tty; in tty_port_hangup()
401 set_bit(TTY_IO_ERROR, &tty->flags); in tty_port_hangup()
402 port->tty = NULL; in tty_port_hangup()
403 spin_unlock_irqrestore(&port->lock, flags); in tty_port_hangup()
404 tty_port_set_active(port, false); in tty_port_hangup()
405 tty_port_shutdown(port, tty); in tty_port_hangup()
407 wake_up_interruptible(&port->open_wait); in tty_port_hangup()
408 wake_up_interruptible(&port->delta_msr_wait); in tty_port_hangup()
413 * tty_port_tty_hangup - helper to hang up a tty
414 * @port: tty port
417 void tty_port_tty_hangup(struct tty_port *port, bool check_clocal) in tty_port_tty_hangup() argument
419 struct tty_struct *tty = tty_port_tty_get(port); in tty_port_tty_hangup()
428 * tty_port_tty_wakeup - helper to wake up a tty
429 * @port: tty port
431 void tty_port_tty_wakeup(struct tty_port *port) in tty_port_tty_wakeup() argument
433 port->client_ops->write_wakeup(port); in tty_port_tty_wakeup()
438 * tty_port_carrier_raised - carrier raised check
439 * @port: tty port
443 * internal to the tty port.
445 bool tty_port_carrier_raised(struct tty_port *port) in tty_port_carrier_raised() argument
447 if (port->ops->carrier_raised == NULL) in tty_port_carrier_raised()
449 return port->ops->carrier_raised(port); in tty_port_carrier_raised()
454 * tty_port_raise_dtr_rts - Raise DTR/RTS
455 * @port: tty port
459 * tty port.
461 void tty_port_raise_dtr_rts(struct tty_port *port) in tty_port_raise_dtr_rts() argument
463 if (port->ops->dtr_rts) in tty_port_raise_dtr_rts()
464 port->ops->dtr_rts(port, true); in tty_port_raise_dtr_rts()
469 * tty_port_lower_dtr_rts - Lower DTR/RTS
470 * @port: tty port
474 * tty port.
476 void tty_port_lower_dtr_rts(struct tty_port *port) in tty_port_lower_dtr_rts() argument
478 if (port->ops->dtr_rts) in tty_port_lower_dtr_rts()
479 port->ops->dtr_rts(port, false); in tty_port_lower_dtr_rts()
484 * tty_port_block_til_ready - Waiting logic for tty open
485 * @port: the tty port being opened
492 * - hangup (both before and during)
493 * - non blocking open
494 * - rts/dtr/dcd
495 * - signals
496 * - port flags and counts
498 * The passed @port must implement the @port->ops->carrier_raised method if it
499 * can do carrier detect and the @port->ops->dtr_rts method if it supports
505 * Note: May drop and reacquire tty lock when blocking, so @tty and @port may
508 int tty_port_block_til_ready(struct tty_port *port, in tty_port_block_til_ready() argument
515 /* if non-blocking mode is set we can pass directly to open unless in tty_port_block_til_ready()
516 * the port has just hung up or is in another error state. in tty_port_block_til_ready()
519 tty_port_set_active(port, true); in tty_port_block_til_ready()
522 if (filp == NULL || (filp->f_flags & O_NONBLOCK)) { in tty_port_block_til_ready()
525 tty_port_raise_dtr_rts(port); in tty_port_block_til_ready()
526 tty_port_set_active(port, true); in tty_port_block_til_ready()
540 /* The port lock protects the port counts */ in tty_port_block_til_ready()
541 spin_lock_irqsave(&port->lock, flags); in tty_port_block_til_ready()
542 port->count--; in tty_port_block_til_ready()
543 port->blocked_open++; in tty_port_block_til_ready()
544 spin_unlock_irqrestore(&port->lock, flags); in tty_port_block_til_ready()
548 if (C_BAUD(tty) && tty_port_initialized(port)) in tty_port_block_til_ready()
549 tty_port_raise_dtr_rts(port); in tty_port_block_til_ready()
551 prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); in tty_port_block_til_ready()
552 /* Check for a hangup or uninitialised port. in tty_port_block_til_ready()
555 if (tty_hung_up_p(filp) || !tty_port_initialized(port)) { in tty_port_block_til_ready()
556 if (port->flags & ASYNC_HUP_NOTIFY) in tty_port_block_til_ready()
557 retval = -EAGAIN; in tty_port_block_til_ready()
559 retval = -ERESTARTSYS; in tty_port_block_til_ready()
568 if (do_clocal || tty_port_carrier_raised(port)) in tty_port_block_til_ready()
571 retval = -ERESTARTSYS; in tty_port_block_til_ready()
578 finish_wait(&port->open_wait, &wait); in tty_port_block_til_ready()
583 spin_lock_irqsave(&port->lock, flags); in tty_port_block_til_ready()
585 port->count++; in tty_port_block_til_ready()
586 port->blocked_open--; in tty_port_block_til_ready()
587 spin_unlock_irqrestore(&port->lock, flags); in tty_port_block_til_ready()
589 tty_port_set_active(port, true); in tty_port_block_til_ready()
594 static void tty_port_drain_delay(struct tty_port *port, struct tty_struct *tty) in tty_port_drain_delay() argument
600 timeout = (HZ * 10 * port->drain_delay) / bps; in tty_port_drain_delay()
609 * tty_port_close_start - helper for tty->ops->close, part 1/2
610 * @port: tty_port of the device
614 * Decrements and checks open count. Flushes the port if this is the last
623 int tty_port_close_start(struct tty_port *port, in tty_port_close_start() argument
631 spin_lock_irqsave(&port->lock, flags); in tty_port_close_start()
632 if (tty->count == 1 && port->count != 1) { in tty_port_close_start()
633 tty_warn(tty, "%s: tty->count = 1 port count = %d\n", __func__, in tty_port_close_start()
634 port->count); in tty_port_close_start()
635 port->count = 1; in tty_port_close_start()
637 if (--port->count < 0) { in tty_port_close_start()
638 tty_warn(tty, "%s: bad port count (%d)\n", __func__, in tty_port_close_start()
639 port->count); in tty_port_close_start()
640 port->count = 0; in tty_port_close_start()
643 if (port->count) { in tty_port_close_start()
644 spin_unlock_irqrestore(&port->lock, flags); in tty_port_close_start()
647 spin_unlock_irqrestore(&port->lock, flags); in tty_port_close_start()
649 tty->closing = 1; in tty_port_close_start()
651 if (tty_port_initialized(port)) { in tty_port_close_start()
652 /* Don't block on a stalled port, just pull the chain */ in tty_port_close_start()
653 if (tty->flow.tco_stopped) in tty_port_close_start()
655 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) in tty_port_close_start()
656 tty_wait_until_sent(tty, port->closing_wait); in tty_port_close_start()
657 if (port->drain_delay) in tty_port_close_start()
658 tty_port_drain_delay(port, tty); in tty_port_close_start()
663 /* Report to caller this is the last port reference */ in tty_port_close_start()
669 * tty_port_close_end - helper for tty->ops->close, part 2/2
670 * @port: tty_port of the device
675 * line discipline and delays the close by @port->close_delay.
679 void tty_port_close_end(struct tty_port *port, struct tty_struct *tty) in tty_port_close_end() argument
684 tty->closing = 0; in tty_port_close_end()
686 spin_lock_irqsave(&port->lock, flags); in tty_port_close_end()
688 if (port->blocked_open) { in tty_port_close_end()
689 spin_unlock_irqrestore(&port->lock, flags); in tty_port_close_end()
690 if (port->close_delay) in tty_port_close_end()
691 msleep_interruptible(jiffies_to_msecs(port->close_delay)); in tty_port_close_end()
692 spin_lock_irqsave(&port->lock, flags); in tty_port_close_end()
693 wake_up_interruptible(&port->open_wait); in tty_port_close_end()
695 spin_unlock_irqrestore(&port->lock, flags); in tty_port_close_end()
696 tty_port_set_active(port, false); in tty_port_close_end()
701 * tty_port_close - generic tty->ops->close handler
702 * @port: tty_port of the device
706 * It is a generic helper to be used in driver's @tty->ops->close. It wraps a
713 void tty_port_close(struct tty_port *port, struct tty_struct *tty, in tty_port_close() argument
716 if (tty_port_close_start(port, tty, filp) == 0) in tty_port_close()
718 tty_port_shutdown(port, tty); in tty_port_close()
719 if (!port->console) in tty_port_close()
720 set_bit(TTY_IO_ERROR, &tty->flags); in tty_port_close()
721 tty_port_close_end(port, tty); in tty_port_close()
722 tty_port_tty_set(port, NULL); in tty_port_close()
727 * tty_port_install - generic tty->ops->install handler
728 * @port: tty_port of the device
732 * It is the same as tty_standard_install() except the provided @port is linked
736 int tty_port_install(struct tty_port *port, struct tty_driver *driver, in tty_port_install() argument
739 tty->port = port; in tty_port_install()
745 * tty_port_open - generic tty->ops->open handler
746 * @port: tty_port of the device
750 * It is a generic helper to be used in driver's @tty->ops->open. It activates
751 * the devices using @port->ops->activate if not active already. And waits for
755 * Note that @port->ops->shutdown is not called when @port->ops->activate
756 * returns an error (on the contrary, @tty->ops->close is).
761 * @tty and @port may have changed state (eg., may be hung up now).
763 int tty_port_open(struct tty_port *port, struct tty_struct *tty, in tty_port_open() argument
766 spin_lock_irq(&port->lock); in tty_port_open()
767 ++port->count; in tty_port_open()
768 spin_unlock_irq(&port->lock); in tty_port_open()
769 tty_port_tty_set(port, tty); in tty_port_open()
772 * Do the device-specific open only if the hardware isn't in tty_port_open()
774 * port mutex. in tty_port_open()
777 mutex_lock(&port->mutex); in tty_port_open()
779 if (!tty_port_initialized(port)) { in tty_port_open()
780 clear_bit(TTY_IO_ERROR, &tty->flags); in tty_port_open()
781 if (port->ops->activate) { in tty_port_open()
782 int retval = port->ops->activate(port, tty); in tty_port_open()
785 mutex_unlock(&port->mutex); in tty_port_open()
789 tty_port_set_initialized(port, true); in tty_port_open()
791 mutex_unlock(&port->mutex); in tty_port_open()
792 return tty_port_block_til_ready(port, tty, filp); in tty_port_open()