| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * The NFC Controller Interface is the communication protocol between an |
|---|
| 3 | 4 | * NFC Controller (NFCC) and a Device Host (DH). |
|---|
| .. | .. |
|---|
| 10 | 11 | * Acknowledgements: |
|---|
| 11 | 12 | * This file is based on hci_core.c, which was written |
|---|
| 12 | 13 | * by Maxim Krasnyansky. |
|---|
| 13 | | - * |
|---|
| 14 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 15 | | - * it under the terms of the GNU General Public License version 2 |
|---|
| 16 | | - * as published by the Free Software Foundation |
|---|
| 17 | | - * |
|---|
| 18 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 19 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 20 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 21 | | - * GNU General Public License for more details. |
|---|
| 22 | | - * |
|---|
| 23 | | - * You should have received a copy of the GNU General Public License |
|---|
| 24 | | - * along with this program; if not, see <http://www.gnu.org/licenses/>. |
|---|
| 25 | | - * |
|---|
| 26 | 14 | */ |
|---|
| 27 | 15 | |
|---|
| 28 | 16 | #define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__ |
|---|
| .. | .. |
|---|
| 542 | 530 | skb_queue_purge(&ndev->tx_q); |
|---|
| 543 | 531 | |
|---|
| 544 | 532 | ndev->ops->close(ndev); |
|---|
| 545 | | - ndev->flags = 0; |
|---|
| 533 | + ndev->flags &= BIT(NCI_UNREG); |
|---|
| 546 | 534 | } |
|---|
| 547 | 535 | |
|---|
| 548 | 536 | done: |
|---|
| .. | .. |
|---|
| 560 | 548 | mutex_lock(&ndev->req_lock); |
|---|
| 561 | 549 | |
|---|
| 562 | 550 | if (!test_and_clear_bit(NCI_UP, &ndev->flags)) { |
|---|
| 551 | + /* Need to flush the cmd wq in case |
|---|
| 552 | + * there is a queued/running cmd_work |
|---|
| 553 | + */ |
|---|
| 554 | + flush_workqueue(ndev->cmd_wq); |
|---|
| 563 | 555 | del_timer_sync(&ndev->cmd_timer); |
|---|
| 564 | 556 | del_timer_sync(&ndev->data_timer); |
|---|
| 565 | 557 | mutex_unlock(&ndev->req_lock); |
|---|
| .. | .. |
|---|
| 589 | 581 | |
|---|
| 590 | 582 | clear_bit(NCI_INIT, &ndev->flags); |
|---|
| 591 | 583 | |
|---|
| 592 | | - del_timer_sync(&ndev->cmd_timer); |
|---|
| 593 | | - |
|---|
| 594 | 584 | /* Flush cmd wq */ |
|---|
| 595 | 585 | flush_workqueue(ndev->cmd_wq); |
|---|
| 586 | + |
|---|
| 587 | + del_timer_sync(&ndev->cmd_timer); |
|---|
| 596 | 588 | |
|---|
| 597 | 589 | /* Clear flags except NCI_UNREG */ |
|---|
| 598 | 590 | ndev->flags &= BIT(NCI_UNREG); |
|---|
| .. | .. |
|---|
| 1207 | 1199 | /** |
|---|
| 1208 | 1200 | * nci_register_device - register a nci device in the nfc subsystem |
|---|
| 1209 | 1201 | * |
|---|
| 1210 | | - * @dev: The nci device to register |
|---|
| 1202 | + * @ndev: The nci device to register |
|---|
| 1211 | 1203 | */ |
|---|
| 1212 | 1204 | int nci_register_device(struct nci_dev *ndev) |
|---|
| 1213 | 1205 | { |
|---|
| .. | .. |
|---|
| 1253 | 1245 | |
|---|
| 1254 | 1246 | rc = nfc_register_device(ndev->nfc_dev); |
|---|
| 1255 | 1247 | if (rc) |
|---|
| 1256 | | - goto destroy_rx_wq_exit; |
|---|
| 1248 | + goto destroy_tx_wq_exit; |
|---|
| 1257 | 1249 | |
|---|
| 1258 | 1250 | goto exit; |
|---|
| 1251 | + |
|---|
| 1252 | +destroy_tx_wq_exit: |
|---|
| 1253 | + destroy_workqueue(ndev->tx_wq); |
|---|
| 1259 | 1254 | |
|---|
| 1260 | 1255 | destroy_rx_wq_exit: |
|---|
| 1261 | 1256 | destroy_workqueue(ndev->rx_wq); |
|---|
| .. | .. |
|---|
| 1271 | 1266 | /** |
|---|
| 1272 | 1267 | * nci_unregister_device - unregister a nci device in the nfc subsystem |
|---|
| 1273 | 1268 | * |
|---|
| 1274 | | - * @dev: The nci device to unregister |
|---|
| 1269 | + * @ndev: The nci device to unregister |
|---|
| 1275 | 1270 | */ |
|---|
| 1276 | 1271 | void nci_unregister_device(struct nci_dev *ndev) |
|---|
| 1277 | 1272 | { |
|---|