--- x/net/nfc/nci/core.c +++ n/net/nfc/nci/core.c @@ -559,6 +559,8 @@ static int nci_close_device(struct nci_d */ mutex_lock(&ndev->req_lock); + set_bit(NCI_UNREG, &ndev->flags); + if (!test_and_clear_bit(NCI_UP, &ndev->flags)) { /* Need to flush the cmd wq in case * there is a queued/running cmd_work @@ -595,11 +597,8 @@ static int nci_close_device(struct nci_d /* Flush cmd wq */ flush_workqueue(ndev->cmd_wq); - del_timer_sync(&ndev->cmd_timer); - - /* Clear flags except NCI_UNREG */ - ndev->flags &= BIT(NCI_UNREG); + flush_workqueue(ndev->cmd_wq); mutex_unlock(&ndev->req_lock); @@ -1282,12 +1281,6 @@ void nci_unregister_device(struct nci_de { struct nci_conn_info *conn_info, *n; - /* This set_bit is not protected with specialized barrier, - * However, it is fine because the mutex_lock(&ndev->req_lock); - * in nci_close_device() will help to emit one. - */ - set_bit(NCI_UNREG, &ndev->flags); - nci_close_device(ndev); destroy_workqueue(ndev->cmd_wq); @@ -1543,6 +1536,8 @@ static void nci_cmd_work(struct work_str struct nci_dev *ndev = container_of(work, struct nci_dev, cmd_work); struct sk_buff *skb; + if (test_bit(NCI_UNREG, &ndev->flags)) + return; pr_debug("cmd_cnt %d\n", atomic_read(&ndev->cmd_cnt)); /* Send queued command */