Lines Matching full:port
45 /* Microseconds that thread will delay waiting for a vcc port ref */
107 * vcc_table_add() - Add VCC port to the VCC table
108 * @port: pointer to the VCC port
110 * Return: index of the port in the VCC table on success,
113 static int vcc_table_add(struct vcc_port *port) in vcc_table_add() argument
121 vcc_table[i] = port; in vcc_table_add()
134 * vcc_table_remove() - Removes a VCC port from the VCC table
150 * vcc_get() - Gets a reference to VCC port
154 * Return: reference to the VCC port, if found
155 * NULL, if port not found
159 struct vcc_port *port; in vcc_get() local
165 port = vcc_table[index]; in vcc_get()
166 if (!port) { in vcc_get()
172 if (port->excl_locked) { in vcc_get()
177 port->refcnt++; in vcc_get()
179 return port; in vcc_get()
182 if (port->refcnt) { in vcc_get()
192 port->refcnt++; in vcc_get()
193 port->excl_locked = true; in vcc_get()
196 return port; in vcc_get()
200 * vcc_put() - Returns a reference to VCC port
201 * @port: pointer to VCC port
207 static void vcc_put(struct vcc_port *port, bool excl) in vcc_put() argument
211 if (!port) in vcc_put()
217 if (WARN_ON((excl && !port->excl_locked) || in vcc_put()
218 (!excl && port->excl_locked))) in vcc_put()
221 port->refcnt--; in vcc_put()
224 port->excl_locked = false; in vcc_put()
231 * vcc_get_ne() - Get a non-exclusive reference to VCC port
234 * Gets a non-exclusive reference to VCC port, if it's not removed
236 * Return: pointer to the VCC port, if found
237 * NULL, if port not found
241 struct vcc_port *port; in vcc_get_ne() local
243 port = vcc_get(index, false); in vcc_get_ne()
245 if (port && port->removed) { in vcc_get_ne()
246 vcc_put(port, false); in vcc_get_ne()
250 return port; in vcc_get_ne()
253 static void vcc_kick_rx(struct vcc_port *port) in vcc_kick_rx() argument
255 struct vio_driver_state *vio = &port->vio; in vcc_kick_rx()
257 assert_spin_locked(&port->lock); in vcc_kick_rx()
259 if (!timer_pending(&port->rx_timer) && !port->removed) { in vcc_kick_rx()
261 port->rx_timer.expires = (jiffies + 1); in vcc_kick_rx()
262 add_timer(&port->rx_timer); in vcc_kick_rx()
266 static void vcc_kick_tx(struct vcc_port *port) in vcc_kick_tx() argument
268 assert_spin_locked(&port->lock); in vcc_kick_tx()
270 if (!timer_pending(&port->tx_timer) && !port->removed) { in vcc_kick_tx()
271 port->tx_timer.expires = (jiffies + 1); in vcc_kick_tx()
272 add_timer(&port->tx_timer); in vcc_kick_tx()
278 if (WARN_ON(!tty || !tty->port)) in vcc_rx_check()
285 (tty_buffer_request_room(tty->port, VCC_BUFF_LEN) < VCC_BUFF_LEN)) in vcc_rx_check()
295 if (WARN_ON(!tty || !tty->port)) in vcc_rx()
298 len = tty_insert_flip_string(tty->port, buf, size); in vcc_rx()
300 tty_flip_buffer_push(tty->port); in vcc_rx()
305 static int vcc_ldc_read(struct vcc_port *port) in vcc_ldc_read() argument
307 struct vio_driver_state *vio = &port->vio; in vcc_ldc_read()
312 tty = port->tty; in vcc_ldc_read()
322 vcc_kick_rx(port); in vcc_ldc_read()
358 struct vcc_port *port = from_timer(port, t, rx_timer); in vcc_rx_timer() local
363 spin_lock_irqsave(&port->lock, flags); in vcc_rx_timer()
364 port->rx_timer.expires = 0; in vcc_rx_timer()
366 vio = &port->vio; in vcc_rx_timer()
370 if (!port->tty || port->removed) in vcc_rx_timer()
373 rv = vcc_ldc_read(port); in vcc_rx_timer()
378 spin_unlock_irqrestore(&port->lock, flags); in vcc_rx_timer()
379 vcc_put(port, false); in vcc_rx_timer()
384 struct vcc_port *port = from_timer(port, t, tx_timer); in vcc_tx_timer() local
390 spin_lock_irqsave(&port->lock, flags); in vcc_tx_timer()
391 port->tx_timer.expires = 0; in vcc_tx_timer()
393 if (!port->tty || port->removed) in vcc_tx_timer()
396 tosend = min(VCC_BUFF_LEN, port->chars_in_buffer); in vcc_tx_timer()
400 pkt = &port->buffer; in vcc_tx_timer()
403 vccdbgl(port->vio.lp); in vcc_tx_timer()
405 rv = ldc_write(port->vio.lp, pkt, (VIO_TAG_SIZE + tosend)); in vcc_tx_timer()
410 vcc_kick_tx(port); in vcc_tx_timer()
412 struct tty_struct *tty = port->tty; in vcc_tx_timer()
414 port->chars_in_buffer = 0; in vcc_tx_timer()
420 spin_unlock_irqrestore(&port->lock, flags); in vcc_tx_timer()
421 vcc_put(port, false); in vcc_tx_timer()
434 struct vcc_port *port; in vcc_event() local
438 port = arg; in vcc_event()
439 vio = &port->vio; in vcc_event()
441 spin_lock_irqsave(&port->lock, flags); in vcc_event()
450 rv = vcc_ldc_read(port); in vcc_event()
459 spin_unlock_irqrestore(&port->lock, flags); in vcc_event()
480 struct vcc_port *port; in domain_show() local
483 port = dev_get_drvdata(dev); in domain_show()
484 if (!port) in domain_show()
487 rv = scnprintf(buf, PAGE_SIZE, "%s\n", port->domain); in domain_show()
492 static int vcc_send_ctl(struct vcc_port *port, int ctl) in vcc_send_ctl() argument
501 rv = ldc_write(port->vio.lp, &pkt, sizeof(pkt.tag)); in vcc_send_ctl()
512 struct vcc_port *port; in break_store() local
517 port = dev_get_drvdata(dev); in break_store()
518 if (!port) in break_store()
521 spin_lock_irqsave(&port->lock, flags); in break_store()
525 else if (vcc_send_ctl(port, VCC_CTL_BREAK) < 0) in break_store()
526 vcc_kick_tx(port); in break_store()
528 spin_unlock_irqrestore(&port->lock, flags); in break_store()
548 * vcc_probe() - Initialize VCC port
549 * @vdev: Pointer to VIO device of the new VCC port
552 * Initializes a VCC port to receive serial console data from
562 struct vcc_port *port; in vcc_probe() local
576 port = kzalloc(sizeof(struct vcc_port), GFP_KERNEL); in vcc_probe()
577 if (!port) in vcc_probe()
582 rv = vio_driver_init(&port->vio, vdev, VDEV_CONSOLE_CON, vcc_versions, in vcc_probe()
587 port->vio.debug = vcc_dbg_vio; in vcc_probe()
590 rv = vio_ldc_alloc(&port->vio, &vcc_ldc_cfg, port); in vcc_probe()
594 spin_lock_init(&port->lock); in vcc_probe()
596 port->index = vcc_table_add(port); in vcc_probe()
597 if (port->index == -1) { in vcc_probe()
604 dev = tty_register_device(vcc_tty_driver, port->index, &vdev->dev); in vcc_probe()
625 port->domain = kstrdup(domain, GFP_KERNEL); in vcc_probe()
633 timer_setup(&port->rx_timer, vcc_rx_timer, 0); in vcc_probe()
634 timer_setup(&port->tx_timer, vcc_tx_timer, 0); in vcc_probe()
636 dev_set_drvdata(&vdev->dev, port); in vcc_probe()
639 * IRQs until the port is up. in vcc_probe()
642 vio_port_up(&port->vio); in vcc_probe()
648 kfree(port->domain); in vcc_probe()
650 tty_unregister_device(vcc_tty_driver, port->index); in vcc_probe()
652 vcc_table_remove(port->index); in vcc_probe()
654 vio_ldc_free(&port->vio); in vcc_probe()
657 kfree(port); in vcc_probe()
663 * vcc_remove() - Terminate a VCC port
664 * @vdev: Pointer to VIO device of the VCC port
666 * Terminates a VCC port. Sets up the teardown of TTY and
673 struct vcc_port *port = dev_get_drvdata(&vdev->dev); in vcc_remove() local
675 del_timer_sync(&port->rx_timer); in vcc_remove()
676 del_timer_sync(&port->tx_timer); in vcc_remove()
682 if (port->tty) in vcc_remove()
683 tty_vhangup(port->tty); in vcc_remove()
686 * clients to this port. This cannot fail. in vcc_remove()
688 vcc_get(port->index, true); in vcc_remove()
690 tty_unregister_device(vcc_tty_driver, port->index); in vcc_remove()
692 del_timer_sync(&port->vio.timer); in vcc_remove()
693 vio_ldc_free(&port->vio); in vcc_remove()
696 if (port->tty) { in vcc_remove()
697 port->removed = true; in vcc_remove()
698 vcc_put(port, true); in vcc_remove()
700 vcc_table_remove(port->index); in vcc_remove()
702 kfree(port->vio.name); in vcc_remove()
703 kfree(port->domain); in vcc_remove()
704 kfree(port); in vcc_remove()
710 .type = "vcc-port",
725 struct vcc_port *port; in vcc_open() local
730 port = vcc_get_ne(tty->index); in vcc_open()
731 if (unlikely(!port)) { in vcc_open()
732 pr_err("VCC: open: Failed to find VCC port\n"); in vcc_open()
736 if (unlikely(!port->vio.lp)) { in vcc_open()
738 vcc_put(port, false); in vcc_open()
741 vccdbgl(port->vio.lp); in vcc_open()
743 vcc_put(port, false); in vcc_open()
745 if (unlikely(!tty->port)) { in vcc_open()
746 pr_err("VCC: open: TTY port not found\n"); in vcc_open()
750 if (unlikely(!tty->port->ops)) { in vcc_open()
755 return tty_port_open(tty->port, tty, vcc_file); in vcc_open()
763 if (unlikely(!tty->port)) { in vcc_close()
764 pr_err("VCC: close: TTY port not found\n"); in vcc_close()
768 tty_port_close(tty->port, tty, vcc_file); in vcc_close()
771 static void vcc_ldc_hup(struct vcc_port *port) in vcc_ldc_hup() argument
775 spin_lock_irqsave(&port->lock, flags); in vcc_ldc_hup()
777 if (vcc_send_ctl(port, VCC_CTL_HUP) < 0) in vcc_ldc_hup()
778 vcc_kick_tx(port); in vcc_ldc_hup()
780 spin_unlock_irqrestore(&port->lock, flags); in vcc_ldc_hup()
785 struct vcc_port *port; in vcc_hangup() local
787 port = vcc_get_ne(tty->index); in vcc_hangup()
788 if (unlikely(!port)) { in vcc_hangup()
789 pr_err("VCC: hangup: Failed to find VCC port\n"); in vcc_hangup()
793 if (unlikely(!tty->port)) { in vcc_hangup()
794 pr_err("VCC: hangup: TTY port not found\n"); in vcc_hangup()
795 vcc_put(port, false); in vcc_hangup()
799 vcc_ldc_hup(port); in vcc_hangup()
801 vcc_put(port, false); in vcc_hangup()
803 tty_port_hangup(tty->port); in vcc_hangup()
809 struct vcc_port *port; in vcc_write() local
816 port = vcc_get_ne(tty->index); in vcc_write()
817 if (unlikely(!port)) { in vcc_write()
818 pr_err("VCC: write: Failed to find VCC port"); in vcc_write()
822 spin_lock_irqsave(&port->lock, flags); in vcc_write()
824 pkt = &port->buffer; in vcc_write()
829 tosend = min(count, (VCC_BUFF_LEN - port->chars_in_buffer)); in vcc_write()
834 memcpy(&pkt->data[port->chars_in_buffer], &buf[total_sent], in vcc_write()
836 port->chars_in_buffer += tosend; in vcc_write()
842 vccdbgl(port->vio.lp); in vcc_write()
848 rv = ldc_write(port->vio.lp, pkt, (VIO_TAG_SIZE + tosend)); in vcc_write()
855 vcc_kick_tx(port); in vcc_write()
859 port->chars_in_buffer = 0; in vcc_write()
862 spin_unlock_irqrestore(&port->lock, flags); in vcc_write()
864 vcc_put(port, false); in vcc_write()
873 struct vcc_port *port; in vcc_write_room() local
876 port = vcc_get_ne(tty->index); in vcc_write_room()
877 if (unlikely(!port)) { in vcc_write_room()
878 pr_err("VCC: write_room: Failed to find VCC port\n"); in vcc_write_room()
882 num = VCC_BUFF_LEN - port->chars_in_buffer; in vcc_write_room()
884 vcc_put(port, false); in vcc_write_room()
891 struct vcc_port *port; in vcc_chars_in_buffer() local
894 port = vcc_get_ne(tty->index); in vcc_chars_in_buffer()
895 if (unlikely(!port)) { in vcc_chars_in_buffer()
896 pr_err("VCC: chars_in_buffer: Failed to find VCC port\n"); in vcc_chars_in_buffer()
900 num = port->chars_in_buffer; in vcc_chars_in_buffer()
902 vcc_put(port, false); in vcc_chars_in_buffer()
909 struct vcc_port *port; in vcc_break_ctl() local
912 port = vcc_get_ne(tty->index); in vcc_break_ctl()
913 if (unlikely(!port)) { in vcc_break_ctl()
914 pr_err("VCC: break_ctl: Failed to find VCC port\n"); in vcc_break_ctl()
920 vcc_put(port, false); in vcc_break_ctl()
924 spin_lock_irqsave(&port->lock, flags); in vcc_break_ctl()
926 if (vcc_send_ctl(port, VCC_CTL_BREAK) < 0) in vcc_break_ctl()
927 vcc_kick_tx(port); in vcc_break_ctl()
929 spin_unlock_irqrestore(&port->lock, flags); in vcc_break_ctl()
931 vcc_put(port, false); in vcc_break_ctl()
955 pr_err("VCC: install: Failed to find VCC port\n"); in vcc_install()
956 tty->port = NULL; in vcc_install()
963 tty->port = port_tty; in vcc_install()
974 struct vcc_port *port; in vcc_cleanup() local
976 port = vcc_get(tty->index, true); in vcc_cleanup()
977 if (port) { in vcc_cleanup()
978 port->tty = NULL; in vcc_cleanup()
980 if (port->removed) { in vcc_cleanup()
982 kfree(port->vio.name); in vcc_cleanup()
983 kfree(port->domain); in vcc_cleanup()
984 kfree(port); in vcc_cleanup()
986 vcc_put(port, true); in vcc_cleanup()
990 tty_port_destroy(tty->port); in vcc_cleanup()
991 kfree(tty->port); in vcc_cleanup()
992 tty->port = NULL; in vcc_cleanup()