NFC is using a number of custom ordered workqueues w/ WQ_MEM_RECLAIM.
WQ_MEM_RECLAIM is unnecessary unless NFC is gonna be used as transport
for storage device, and all use cases match one work item to one
ordered workqueue - IOW, there's no actual ordering going on at all
and using system_nrt_wq gives the same behavior.
There's nothing to be gained by using custom workqueues.  Use
system_nrt_wq instead and drop all the custom ones.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
 
        struct list_head msg_tx_queue;
 
-       struct workqueue_struct *msg_tx_wq;
        struct work_struct msg_tx_work;
 
        struct timer_list cmd_timer;
 
        struct sk_buff_head rx_hcp_frags;
 
-       struct workqueue_struct *msg_rx_wq;
        struct work_struct msg_rx_work;
 
        struct sk_buff_head msg_rx_queue;
 
        int tx_tailroom;
 
        struct timer_list check_pres_timer;
-       struct workqueue_struct *check_pres_wq;
        struct work_struct check_pres_work;
 
        struct nfc_ops *ops;
 
 
        struct sk_buff_head ack_pending_q;
 
-       struct workqueue_struct *sm_wq;
        struct work_struct sm_work;
 
        struct nfc_shdlc_ops *ops;
 
 
        if (dev->ops->check_presence) {
                del_timer_sync(&dev->check_pres_timer);
-               destroy_workqueue(dev->check_pres_wq);
+               cancel_work_sync(&dev->check_pres_work);
        }
 
        nfc_genl_data_exit(&dev->genl_data);
 {
        struct nfc_dev *dev = (struct nfc_dev *)data;
 
-       queue_work(dev->check_pres_wq, &dev->check_pres_work);
+       queue_work(system_nrt_wq, &dev->check_pres_work);
 }
 
 struct class nfc_class = {
        dev->targets_generation = 1;
 
        if (ops->check_presence) {
-               char name[32];
                init_timer(&dev->check_pres_timer);
                dev->check_pres_timer.data = (unsigned long)dev;
                dev->check_pres_timer.function = nfc_check_pres_timeout;
 
                INIT_WORK(&dev->check_pres_work, nfc_check_pres_work);
-               snprintf(name, sizeof(name), "nfc%d_check_pres_wq", dev->idx);
-               dev->check_pres_wq = alloc_workqueue(name, WQ_NON_REENTRANT |
-                                                    WQ_UNBOUND |
-                                                    WQ_MEM_RECLAIM, 1);
-               if (dev->check_pres_wq == NULL) {
-                       kfree(dev);
-                       return NULL;
-               }
        }
 
        return dev;
 
        kfree(hdev->cmd_pending_msg);
        hdev->cmd_pending_msg = NULL;
 
-       queue_work(hdev->msg_tx_wq, &hdev->msg_tx_work);
+       queue_work(system_nrt_wq, &hdev->msg_tx_work);
 }
 
 void nfc_hci_resp_received(struct nfc_hci_dev *hdev, u8 result,
 {
        struct nfc_hci_dev *hdev = (struct nfc_hci_dev *)data;
 
-       queue_work(hdev->msg_tx_wq, &hdev->msg_tx_work);
+       queue_work(system_nrt_wq, &hdev->msg_tx_work);
 }
 
 static int hci_dev_connect_gates(struct nfc_hci_dev *hdev, u8 gate_count,
 
 int nfc_hci_register_device(struct nfc_hci_dev *hdev)
 {
-       struct device *dev = &hdev->ndev->dev;
-       const char *devname = dev_name(dev);
-       char name[32];
-       int r = 0;
-
        mutex_init(&hdev->msg_tx_mutex);
 
        INIT_LIST_HEAD(&hdev->msg_tx_queue);
 
        INIT_WORK(&hdev->msg_tx_work, nfc_hci_msg_tx_work);
-       snprintf(name, sizeof(name), "%s_hci_msg_tx_wq", devname);
-       hdev->msg_tx_wq = alloc_workqueue(name, WQ_NON_REENTRANT | WQ_UNBOUND |
-                                         WQ_MEM_RECLAIM, 1);
-       if (hdev->msg_tx_wq == NULL) {
-               r = -ENOMEM;
-               goto exit;
-       }
 
        init_timer(&hdev->cmd_timer);
        hdev->cmd_timer.data = (unsigned long)hdev;
        skb_queue_head_init(&hdev->rx_hcp_frags);
 
        INIT_WORK(&hdev->msg_rx_work, nfc_hci_msg_rx_work);
-       snprintf(name, sizeof(name), "%s_hci_msg_rx_wq", devname);
-       hdev->msg_rx_wq = alloc_workqueue(name, WQ_NON_REENTRANT | WQ_UNBOUND |
-                                         WQ_MEM_RECLAIM, 1);
-       if (hdev->msg_rx_wq == NULL) {
-               r = -ENOMEM;
-               goto exit;
-       }
 
        skb_queue_head_init(&hdev->msg_rx_queue);
 
-       r = nfc_register_device(hdev->ndev);
-
-exit:
-       if (r < 0) {
-               if (hdev->msg_tx_wq)
-                       destroy_workqueue(hdev->msg_tx_wq);
-               if (hdev->msg_rx_wq)
-                       destroy_workqueue(hdev->msg_rx_wq);
-       }
-
-       return r;
+       return nfc_register_device(hdev->ndev);
 }
 EXPORT_SYMBOL(nfc_hci_register_device);
 
 
        nfc_unregister_device(hdev->ndev);
 
-       destroy_workqueue(hdev->msg_tx_wq);
-
-       destroy_workqueue(hdev->msg_rx_wq);
+       cancel_work_sync(&hdev->msg_tx_work);
+       cancel_work_sync(&hdev->msg_rx_work);
 }
 EXPORT_SYMBOL(nfc_hci_unregister_device);
 
                nfc_hci_hcp_message_rx(hdev, pipe, type, instruction, hcp_skb);
        } else {
                skb_queue_tail(&hdev->msg_rx_queue, hcp_skb);
-               queue_work(hdev->msg_rx_wq, &hdev->msg_rx_work);
+               queue_work(system_nrt_wq, &hdev->msg_rx_work);
        }
 }
 EXPORT_SYMBOL(nfc_hci_recv_frame);
 
        list_add_tail(&cmd->msg_l, &hdev->msg_tx_queue);
        mutex_unlock(&hdev->msg_tx_mutex);
 
-       queue_work(hdev->msg_tx_wq, &hdev->msg_tx_work);
+       queue_work(system_nrt_wq, &hdev->msg_tx_work);
 
        return 0;
 
 
 
        pr_debug("\n");
 
-       queue_work(shdlc->sm_wq, &shdlc->sm_work);
+       queue_work(system_nrt_wq, &shdlc->sm_work);
 }
 
 static void nfc_shdlc_t1_timeout(unsigned long data)
 
        pr_debug("SoftIRQ: need to send ack\n");
 
-       queue_work(shdlc->sm_wq, &shdlc->sm_work);
+       queue_work(system_nrt_wq, &shdlc->sm_work);
 }
 
 static void nfc_shdlc_t2_timeout(unsigned long data)
 
        pr_debug("SoftIRQ: need to retransmit\n");
 
-       queue_work(shdlc->sm_wq, &shdlc->sm_work);
+       queue_work(system_nrt_wq, &shdlc->sm_work);
 }
 
 static void nfc_shdlc_sm_work(struct work_struct *work)
        case SHDLC_NEGOCIATING:
                if (timer_pending(&shdlc->connect_timer) == 0) {
                        shdlc->state = SHDLC_CONNECTING;
-                       queue_work(shdlc->sm_wq, &shdlc->sm_work);
+                       queue_work(system_nrt_wq, &shdlc->sm_work);
                }
 
                nfc_shdlc_handle_rcv_queue(shdlc);
 
        mutex_unlock(&shdlc->state_mutex);
 
-       queue_work(shdlc->sm_wq, &shdlc->sm_work);
+       queue_work(system_nrt_wq, &shdlc->sm_work);
 
        wait_event(connect_wq, shdlc->connect_result != 1);
 
 
        mutex_unlock(&shdlc->state_mutex);
 
-       queue_work(shdlc->sm_wq, &shdlc->sm_work);
+       queue_work(system_nrt_wq, &shdlc->sm_work);
 }
 
 /*
                skb_queue_tail(&shdlc->rcv_q, skb);
        }
 
-       queue_work(shdlc->sm_wq, &shdlc->sm_work);
+       queue_work(system_nrt_wq, &shdlc->sm_work);
 }
 EXPORT_SYMBOL(nfc_shdlc_recv_frame);
 
 
        skb_queue_tail(&shdlc->send_q, skb);
 
-       queue_work(shdlc->sm_wq, &shdlc->sm_work);
+       queue_work(system_nrt_wq, &shdlc->sm_work);
 
        return 0;
 }
 {
        struct nfc_shdlc *shdlc;
        int r;
-       char name[32];
 
        if (ops->xmit == NULL)
                return NULL;
        skb_queue_head_init(&shdlc->ack_pending_q);
 
        INIT_WORK(&shdlc->sm_work, nfc_shdlc_sm_work);
-       snprintf(name, sizeof(name), "%s_shdlc_sm_wq", devname);
-       shdlc->sm_wq = alloc_workqueue(name, WQ_NON_REENTRANT | WQ_UNBOUND |
-                                      WQ_MEM_RECLAIM, 1);
-       if (shdlc->sm_wq == NULL)
-               goto err_allocwq;
 
        shdlc->client_headroom = tx_headroom;
        shdlc->client_tailroom = tx_tailroom;
        nfc_hci_free_device(shdlc->hdev);
 
 err_allocdev:
-       destroy_workqueue(shdlc->sm_wq);
-
-err_allocwq:
        kfree(shdlc);
 
        return NULL;
        nfc_hci_unregister_device(shdlc->hdev);
        nfc_hci_free_device(shdlc->hdev);
 
-       destroy_workqueue(shdlc->sm_wq);
+       cancel_work_sync(&shdlc->sm_work);
 
        skb_queue_purge(&shdlc->rcv_q);
        skb_queue_purge(&shdlc->send_q);
 
        nfc_llcp_socket_release(local, false);
        del_timer_sync(&local->link_timer);
        skb_queue_purge(&local->tx_queue);
-       destroy_workqueue(local->tx_wq);
-       destroy_workqueue(local->rx_wq);
-       destroy_workqueue(local->timeout_wq);
+       cancel_work_sync(&local->tx_work);
+       cancel_work_sync(&local->rx_work);
+       cancel_work_sync(&local->timeout_work);
        kfree_skb(local->rx_pending);
        kfree(local);
 }
 
        pr_err("SYMM timeout\n");
 
-       queue_work(local->timeout_wq, &local->timeout_work);
+       queue_work(system_nrt_wq, &local->timeout_work);
 }
 
 struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev)
 
        }
 
-       queue_work(local->tx_wq, &local->tx_work);
+       queue_work(system_nrt_wq, &local->tx_work);
        kfree_skb(local->rx_pending);
        local->rx_pending = NULL;
 
 
        local->rx_pending = skb_get(skb);
        del_timer(&local->link_timer);
-       queue_work(local->rx_wq, &local->rx_work);
+       queue_work(system_nrt_wq, &local->rx_work);
 
        return;
 }
 
        local->rx_pending = skb_get(skb);
        del_timer(&local->link_timer);
-       queue_work(local->rx_wq, &local->rx_work);
+       queue_work(system_nrt_wq, &local->rx_work);
 
        return 0;
 }
        if (rf_mode == NFC_RF_INITIATOR) {
                pr_debug("Queueing Tx work\n");
 
-               queue_work(local->tx_wq, &local->tx_work);
+               queue_work(system_nrt_wq, &local->tx_work);
        } else {
                mod_timer(&local->link_timer,
                          jiffies + msecs_to_jiffies(local->remote_lto));
 
 int nfc_llcp_register_device(struct nfc_dev *ndev)
 {
-       struct device *dev = &ndev->dev;
        struct nfc_llcp_local *local;
-       char name[32];
-       int err;
 
        local = kzalloc(sizeof(struct nfc_llcp_local), GFP_KERNEL);
        if (local == NULL)
 
        skb_queue_head_init(&local->tx_queue);
        INIT_WORK(&local->tx_work, nfc_llcp_tx_work);
-       snprintf(name, sizeof(name), "%s_llcp_tx_wq", dev_name(dev));
-       local->tx_wq =
-               alloc_workqueue(name,
-                               WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM,
-                               1);
-       if (local->tx_wq == NULL) {
-               err = -ENOMEM;
-               goto err_local;
-       }
 
        local->rx_pending = NULL;
        INIT_WORK(&local->rx_work, nfc_llcp_rx_work);
-       snprintf(name, sizeof(name), "%s_llcp_rx_wq", dev_name(dev));
-       local->rx_wq =
-               alloc_workqueue(name,
-                               WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM,
-                               1);
-       if (local->rx_wq == NULL) {
-               err = -ENOMEM;
-               goto err_tx_wq;
-       }
 
        INIT_WORK(&local->timeout_work, nfc_llcp_timeout_work);
-       snprintf(name, sizeof(name), "%s_llcp_timeout_wq", dev_name(dev));
-       local->timeout_wq =
-               alloc_workqueue(name,
-                               WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM,
-                               1);
-       if (local->timeout_wq == NULL) {
-               err = -ENOMEM;
-               goto err_rx_wq;
-       }
 
        local->sockets.lock = __RW_LOCK_UNLOCKED(local->sockets.lock);
        local->connecting_sockets.lock = __RW_LOCK_UNLOCKED(local->connecting_sockets.lock);
 
        list_add(&llcp_devices, &local->list);
 
-       return 0;
-
-err_rx_wq:
-       destroy_workqueue(local->rx_wq);
-
-err_tx_wq:
-       destroy_workqueue(local->tx_wq);
-
-err_local:
-       kfree(local);
-
        return 0;
 }
 
 
 
        struct timer_list link_timer;
        struct sk_buff_head tx_queue;
-       struct workqueue_struct *tx_wq;
        struct work_struct       tx_work;
-       struct workqueue_struct *rx_wq;
        struct work_struct       rx_work;
        struct sk_buff *rx_pending;
-       struct workqueue_struct *timeout_wq;
        struct work_struct       timeout_work;
 
        u32 target_idx;