static void nfcsim_free_device(struct nfcsim *dev) { nfc_unregister_device(dev->nfc_dev); nfc_free_device(dev->nfc_dev); kfree(dev); }
/** * nci_unregister_device - unregister a nci device in the nfc subsystem * * @dev: The nci device to unregister */ void nci_unregister_device(struct nci_dev *ndev) { nci_close_device(ndev); destroy_workqueue(ndev->cmd_wq); destroy_workqueue(ndev->rx_wq); destroy_workqueue(ndev->tx_wq); nfc_unregister_device(ndev->nfc_dev); }
/** * nci_register_device - register a nci device in the nfc subsystem * * @dev: The nci device to register */ int nci_register_device(struct nci_dev *ndev) { int rc; struct device *dev = &ndev->nfc_dev->dev; char name[32]; rc = nfc_register_device(ndev->nfc_dev); if (rc) goto exit; ndev->flags = 0; INIT_WORK(&ndev->cmd_work, nci_cmd_work); snprintf(name, sizeof(name), "%s_nci_cmd_wq", dev_name(dev)); ndev->cmd_wq = create_singlethread_workqueue(name); if (!ndev->cmd_wq) { rc = -ENOMEM; goto unreg_exit; } INIT_WORK(&ndev->rx_work, nci_rx_work); snprintf(name, sizeof(name), "%s_nci_rx_wq", dev_name(dev)); ndev->rx_wq = create_singlethread_workqueue(name); if (!ndev->rx_wq) { rc = -ENOMEM; goto destroy_cmd_wq_exit; } INIT_WORK(&ndev->tx_work, nci_tx_work); snprintf(name, sizeof(name), "%s_nci_tx_wq", dev_name(dev)); ndev->tx_wq = create_singlethread_workqueue(name); if (!ndev->tx_wq) { rc = -ENOMEM; goto destroy_rx_wq_exit; } skb_queue_head_init(&ndev->cmd_q); skb_queue_head_init(&ndev->rx_q); skb_queue_head_init(&ndev->tx_q); setup_timer(&ndev->cmd_timer, nci_cmd_timer, (unsigned long) ndev); setup_timer(&ndev->data_timer, nci_data_timer, (unsigned long) ndev); mutex_init(&ndev->req_lock); goto exit; destroy_rx_wq_exit: destroy_workqueue(ndev->rx_wq); destroy_cmd_wq_exit: destroy_workqueue(ndev->cmd_wq); unreg_exit: nfc_unregister_device(ndev->nfc_dev); exit: return rc; }