void mei_nfc_host_exit(struct mei_device *dev) { struct mei_nfc_dev *ndev; struct mei_cl *cl; struct mei_cl_device *cldev; cl = mei_cl_bus_find_cl_by_uuid(dev, mei_nfc_guid); if (!cl) return; cldev = cl->device; if (!cldev) return; ndev = (struct mei_nfc_dev *)cldev->priv_data; if (ndev) cancel_work_sync(&ndev->init_work); cldev->priv_data = NULL; mutex_lock(&dev->device_lock); /* Need to remove the device here * since mei_nfc_free will unlink the clients */ mei_cl_remove_device(cldev); mei_nfc_free(ndev); mutex_unlock(&dev->device_lock); }
void mei_nfc_host_exit(void) { struct mei_nfc_dev *ndev = &nfc_dev; if (ndev->cl && ndev->cl->device) mei_cl_remove_device(ndev->cl->device); mei_nfc_free(ndev); }
int mei_nfc_host_init(struct mei_device *dev) { struct mei_nfc_dev *ndev; struct mei_cl *cl_info, *cl = NULL; struct mei_me_client *me_cl; int ret; /* in case of internal reset bail out * as the device is already setup */ cl = mei_cl_bus_find_cl_by_uuid(dev, mei_nfc_guid); if (cl) return 0; ndev = kzalloc(sizeof(struct mei_nfc_dev), GFP_KERNEL); if (!ndev) { ret = -ENOMEM; goto err; } ndev->cl_info = mei_cl_allocate(dev); ndev->cl = mei_cl_allocate(dev); cl = ndev->cl; cl_info = ndev->cl_info; if (!cl || !cl_info) { ret = -ENOMEM; goto err; } /* check for valid client id */ me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_info_guid); if (!me_cl) { dev_info(dev->dev, "nfc: failed to find the client\n"); ret = -ENOTTY; goto err; } cl_info->me_client_id = me_cl->client_id; cl_info->cl_uuid = me_cl->props.protocol_name; mei_me_cl_put(me_cl); ret = mei_cl_link(cl_info, MEI_HOST_CLIENT_ID_ANY); if (ret) goto err; list_add_tail(&cl_info->device_link, &dev->device_list); /* check for valid client id */ me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_guid); if (!me_cl) { dev_info(dev->dev, "nfc: failed to find the client\n"); ret = -ENOTTY; goto err; } cl->me_client_id = me_cl->client_id; cl->cl_uuid = me_cl->props.protocol_name; mei_me_cl_put(me_cl); ret = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY); if (ret) goto err; list_add_tail(&cl->device_link, &dev->device_list); ndev->req_id = 1; INIT_WORK(&ndev->init_work, mei_nfc_init); init_waitqueue_head(&ndev->send_wq); schedule_work(&ndev->init_work); return 0; err: mei_nfc_free(ndev); return ret; }
static void mei_nfc_init(struct work_struct *work) { struct mei_device *dev; struct mei_cl_device *cldev; struct mei_nfc_dev *ndev; struct mei_cl *cl_info; ndev = container_of(work, struct mei_nfc_dev, init_work); cl_info = ndev->cl_info; dev = cl_info->dev; mutex_lock(&dev->device_lock); if (mei_cl_connect(cl_info, NULL) < 0) { mutex_unlock(&dev->device_lock); dev_err(dev->dev, "Could not connect to the NFC INFO ME client"); goto err; } mutex_unlock(&dev->device_lock); if (mei_nfc_if_version(ndev) < 0) { dev_err(dev->dev, "Could not get the NFC interface version"); goto err; } dev_info(dev->dev, "NFC MEI VERSION: IVN 0x%x Vendor ID 0x%x Type 0x%x\n", ndev->fw_ivn, ndev->vendor_id, ndev->radio_type); mutex_lock(&dev->device_lock); if (mei_cl_disconnect(cl_info) < 0) { mutex_unlock(&dev->device_lock); dev_err(dev->dev, "Could not disconnect the NFC INFO ME client"); goto err; } mutex_unlock(&dev->device_lock); if (mei_nfc_build_bus_name(ndev) < 0) { dev_err(dev->dev, "Could not build the bus ID name\n"); return; } cldev = mei_cl_add_device(dev, mei_nfc_guid, ndev->bus_name, &nfc_ops); if (!cldev) { dev_err(dev->dev, "Could not add the NFC device to the MEI bus\n"); goto err; } cldev->priv_data = ndev; return; err: mutex_lock(&dev->device_lock); mei_nfc_free(ndev); mutex_unlock(&dev->device_lock); }
int mei_nfc_host_init(struct mei_device *dev) { struct mei_nfc_dev *ndev = &nfc_dev; struct mei_cl *cl_info, *cl = NULL; int i, ret; /* already initialzed */ if (ndev->cl_info) return 0; ndev->cl_info = mei_cl_allocate(dev); ndev->cl = mei_cl_allocate(dev); cl = ndev->cl; cl_info = ndev->cl_info; if (!cl || !cl_info) { ret = -ENOMEM; goto err; } /* check for valid client id */ i = mei_me_cl_by_uuid(dev, &mei_nfc_info_guid); if (i < 0) { dev_info(&dev->pdev->dev, "nfc: failed to find the client\n"); ret = -ENOENT; goto err; } cl_info->me_client_id = dev->me_clients[i].client_id; ret = mei_cl_link(cl_info, MEI_HOST_CLIENT_ID_ANY); if (ret) goto err; cl_info->device_uuid = mei_nfc_info_guid; list_add_tail(&cl_info->device_link, &dev->device_list); /* check for valid client id */ i = mei_me_cl_by_uuid(dev, &mei_nfc_guid); if (i < 0) { dev_info(&dev->pdev->dev, "nfc: failed to find the client\n"); ret = -ENOENT; goto err; } cl->me_client_id = dev->me_clients[i].client_id; ret = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY); if (ret) goto err; cl->device_uuid = mei_nfc_guid; list_add_tail(&cl->device_link, &dev->device_list); ndev->req_id = 1; INIT_WORK(&ndev->init_work, mei_nfc_init); init_waitqueue_head(&ndev->send_wq); schedule_work(&ndev->init_work); return 0; err: mei_nfc_free(ndev); return ret; }