Lines Matching +full:nfc +full:- +full:uart
1 // SPDX-License-Identifier: GPL-2.0-or-later
7 * Copyright (C) 2000-2001 Qualcomm Incorporated
8 * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
9 * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
30 #include <net/nfc/nci.h>
31 #include <net/nfc/nci_core.h>
41 struct sk_buff *skb = nu->tx_skb; in nci_uart_dequeue()
44 skb = skb_dequeue(&nu->tx_q); in nci_uart_dequeue()
46 nu->tx_skb = NULL; in nci_uart_dequeue()
53 if (nu->tx_skb) in nci_uart_queue_empty()
56 return skb_queue_empty(&nu->tx_q); in nci_uart_queue_empty()
61 if (test_and_set_bit(NCI_UART_SENDING, &nu->tx_state)) { in nci_uart_tx_wakeup()
62 set_bit(NCI_UART_TX_WAKEUP, &nu->tx_state); in nci_uart_tx_wakeup()
66 schedule_work(&nu->write_work); in nci_uart_tx_wakeup()
74 struct tty_struct *tty = nu->tty; in nci_uart_write_work()
78 clear_bit(NCI_UART_TX_WAKEUP, &nu->tx_state); in nci_uart_write_work()
80 if (nu->ops.tx_start) in nci_uart_write_work()
81 nu->ops.tx_start(nu); in nci_uart_write_work()
86 set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); in nci_uart_write_work()
87 len = tty->ops->write(tty, skb->data, skb->len); in nci_uart_write_work()
89 if (skb->len) { in nci_uart_write_work()
90 nu->tx_skb = skb; in nci_uart_write_work()
96 if (test_bit(NCI_UART_TX_WAKEUP, &nu->tx_state)) in nci_uart_write_work()
99 if (nu->ops.tx_done && nci_uart_queue_empty(nu)) in nci_uart_write_work()
100 nu->ops.tx_done(nu); in nci_uart_write_work()
102 clear_bit(NCI_UART_SENDING, &nu->tx_state); in nci_uart_write_work()
111 return -EINVAL; in nci_uart_set_driver()
114 return -ENOENT; in nci_uart_set_driver()
118 return -ENOMEM; in nci_uart_set_driver()
121 nu->tty = tty; in nci_uart_set_driver()
122 tty->disc_data = nu; in nci_uart_set_driver()
123 skb_queue_head_init(&nu->tx_q); in nci_uart_set_driver()
124 INIT_WORK(&nu->write_work, nci_uart_write_work); in nci_uart_set_driver()
125 spin_lock_init(&nu->rx_lock); in nci_uart_set_driver()
127 ret = nu->ops.open(nu); in nci_uart_set_driver()
129 tty->disc_data = NULL; in nci_uart_set_driver()
131 } else if (!try_module_get(nu->owner)) { in nci_uart_set_driver()
132 nu->ops.close(nu); in nci_uart_set_driver()
133 tty->disc_data = NULL; in nci_uart_set_driver()
135 return -ENOENT; in nci_uart_set_driver()
140 /* ------ LDISC part ------ */
156 if (!tty->ops->write) in nci_uart_tty_open()
157 return -EOPNOTSUPP; in nci_uart_tty_open()
159 tty->disc_data = NULL; in nci_uart_tty_open()
160 tty->receive_room = 65536; in nci_uart_tty_open()
175 struct nci_uart *nu = (void *)tty->disc_data; in nci_uart_tty_close()
178 tty->disc_data = NULL; in nci_uart_tty_close()
183 kfree_skb(nu->tx_skb); in nci_uart_tty_close()
184 kfree_skb(nu->rx_skb); in nci_uart_tty_close()
186 skb_queue_purge(&nu->tx_q); in nci_uart_tty_close()
188 nu->ops.close(nu); in nci_uart_tty_close()
189 nu->tty = NULL; in nci_uart_tty_close()
190 module_put(nu->owner); in nci_uart_tty_close()
192 cancel_work_sync(&nu->write_work); in nci_uart_tty_close()
207 struct nci_uart *nu = (void *)tty->disc_data; in nci_uart_tty_wakeup()
212 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); in nci_uart_tty_wakeup()
214 if (tty != nu->tty) in nci_uart_tty_wakeup()
220 /* -- Default recv_buf handler --
222 * This handler supposes that NCI frames are sent over UART link without any
231 if (!nu->ndev) { in nci_uart_default_recv_buf()
232 nfc_err(nu->tty->dev, in nci_uart_default_recv_buf()
242 if (!nu->rx_skb) { in nci_uart_default_recv_buf()
243 nu->rx_packet_len = -1; in nci_uart_default_recv_buf()
244 nu->rx_skb = nci_skb_alloc(nu->ndev, in nci_uart_default_recv_buf()
247 if (!nu->rx_skb) in nci_uart_default_recv_buf()
248 return -ENOMEM; in nci_uart_default_recv_buf()
252 if (nu->rx_skb->len < NCI_CTRL_HDR_SIZE) { in nci_uart_default_recv_buf()
253 skb_put_u8(nu->rx_skb, *data++); in nci_uart_default_recv_buf()
254 --count; in nci_uart_default_recv_buf()
259 if (nu->rx_packet_len < 0) in nci_uart_default_recv_buf()
260 nu->rx_packet_len = NCI_CTRL_HDR_SIZE + in nci_uart_default_recv_buf()
261 nci_plen(nu->rx_skb->data); in nci_uart_default_recv_buf()
266 chunk_len = nu->rx_packet_len - nu->rx_skb->len; in nci_uart_default_recv_buf()
269 skb_put_data(nu->rx_skb, data, chunk_len); in nci_uart_default_recv_buf()
271 count -= chunk_len; in nci_uart_default_recv_buf()
274 if (nu->rx_packet_len == nu->rx_skb->len) { in nci_uart_default_recv_buf()
276 if (nu->ops.recv(nu, nu->rx_skb) != 0) in nci_uart_default_recv_buf()
277 nfc_err(nu->tty->dev, "corrupted RX packet\n"); in nci_uart_default_recv_buf()
279 nu->rx_skb = NULL; in nci_uart_default_recv_buf()
301 struct nci_uart *nu = (void *)tty->disc_data; in nci_uart_tty_receive()
303 if (!nu || tty != nu->tty) in nci_uart_tty_receive()
306 spin_lock(&nu->rx_lock); in nci_uart_tty_receive()
308 spin_unlock(&nu->rx_lock); in nci_uart_tty_receive()
328 struct nci_uart *nu = (void *)tty->disc_data; in nci_uart_tty_ioctl()
336 return -EBUSY; in nci_uart_tty_ioctl()
369 skb_queue_tail(&nu->tx_q, skb); in nci_uart_send()
379 if (!nu || !nu->ops.open || in nci_uart_register()
380 !nu->ops.recv || !nu->ops.close) in nci_uart_register()
381 return -EINVAL; in nci_uart_register()
384 nu->ops.send = nci_uart_send; in nci_uart_register()
387 if (nci_uart_drivers[nu->driver]) { in nci_uart_register()
388 pr_err("driver %d is already registered\n", nu->driver); in nci_uart_register()
389 return -EBUSY; in nci_uart_register()
391 nci_uart_drivers[nu->driver] = nu; in nci_uart_register()
393 pr_info("NCI uart driver '%s [%d]' registered\n", nu->name, nu->driver); in nci_uart_register()
401 pr_info("NCI uart driver '%s [%d]' unregistered\n", nu->name, in nci_uart_unregister()
402 nu->driver); in nci_uart_unregister()
405 nci_uart_drivers[nu->driver] = NULL; in nci_uart_unregister()
413 if (!nu->tty) in nci_uart_set_config()
416 down_read(&nu->tty->termios_rwsem); in nci_uart_set_config()
417 new_termios = nu->tty->termios; in nci_uart_set_config()
418 up_read(&nu->tty->termios_rwsem); in nci_uart_set_config()
426 tty_set_termios(nu->tty, &new_termios); in nci_uart_set_config()
459 MODULE_DESCRIPTION("NFC NCI UART driver");