static int pn544_remove(struct i2c_client *client) { struct pn544_dev *pn544_dev; pn544_dev = i2c_get_clientdata(client); free_irq(client->irq, pn544_dev); pn544_gpio_free(pn544_dev); device_remove_file(pn544_dev->pn544_control_device, &dev_attr_pn544_control_dev); misc_deregister(&pn544_dev->pn544_device); mutex_destroy(&pn544_dev->read_mutex); if (pn544_dev->vdd != NULL) { regulator_disable(pn544_dev->vdd); regulator_put(pn544_dev->vdd); } kfree(pn544_dev); return 0; }
static int pn544_remove(struct i2c_client *client) { struct pn544_dev *pn544_dev; pn544_dev = i2c_get_clientdata(client); unregister_reboot_notifier(&pn544_dev->reboot_notify); free_irq(client->irq, pn544_dev); pn544_gpio_free(pn544_dev); device_remove_file(pn544_dev->pn544_control_device, &dev_attr_pn544_control_dev); misc_deregister(&pn544_dev->pn544_device); mutex_destroy(&pn544_dev->read_mutex); mutex_destroy(&pn544_dev->ioctl_mutex); wake_unlock(&pn544_dev->wakelock); wake_lock_destroy(&pn544_dev->wakelock); kfree(pn544_dev); return 0; }
static int pn544_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = -ENODEV; struct pn544_i2c_platform_data *platform_data; struct pn544_dev *pn544_dev; pr_debug("%s : Probing pn544 driver\n", __func__); if (client->dev.of_node) platform_data = pn544_of_init(client); else platform_data = client->dev.platform_data; if (!platform_data) { pr_err("%s : GPIO has value 0, nfc probe fail.\n", __func__); goto err_exit; } if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("%s : i2c_check_functionality I2C_FUNC_I2C failed.\n", __func__); goto err_exit; } pn544_dev = kzalloc(sizeof(*pn544_dev), GFP_KERNEL); if (pn544_dev == NULL) { dev_err(&client->dev, "failed to allocate memory for module data\n"); ret = -ENOMEM; goto err_exit; } ret = pn544_gpio_init(platform_data); if (ret) { dev_err(&client->dev, "gpio init failed\n"); goto err_gpio_init; } pn544_dev->irq_gpio = platform_data->irq_gpio; pn544_dev->ven_gpio = platform_data->ven_gpio; pn544_dev->firmware_gpio = platform_data->firmware_gpio; pn544_dev->ven_polarity = platform_data->ven_polarity; pn544_dev->discharge_delay = platform_data->discharge_delay; pn544_dev->client = client; pn544_dev->vdd = regulator_get(&client->dev, "vdd"); if (IS_ERR(pn544_dev->vdd)) { dev_info(&client->dev, "vdd regulator control absent\n"); pn544_dev->vdd = NULL; } if (pn544_dev->vdd != NULL) { regulator_set_voltage(pn544_dev->vdd, 2950000, 2950000); ret = regulator_enable(pn544_dev->vdd); if (ret < 0) { dev_err(&client->dev, "Error enabling vddswp regulator\n"); goto err_en_regulator_swp; } } /* init mutex and queues */ init_waitqueue_head(&pn544_dev->read_wq); mutex_init(&pn544_dev->read_mutex); spin_lock_init(&pn544_dev->irq_enabled_lock); pn544_dev->pn544_device.minor = MISC_DYNAMIC_MINOR; pn544_dev->pn544_device.name = "pn544"; pn544_dev->pn544_device.fops = &pn544_dev_fops; ret = misc_register(&pn544_dev->pn544_device); if (ret) { pr_err("%s : misc_register failed.\n", __FILE__); goto err_misc_register; } pr_debug("%s : PN544 Misc Minor: %d\n", __func__, pn544_dev->pn544_device.minor); /* Get the device structure */ pn544_dev->pn544_control_device = pn544_dev->pn544_device.this_device; /* Create sysfs device for PN544 control functionality */ ret = device_create_file(pn544_dev->pn544_control_device, &dev_attr_pn544_control_dev); if (ret) { pr_err("%s : device_create_file failed\n", __FILE__); goto err_device_create_file_failed; } /* request irq. the irq is set whenever the chip has data available * for reading. it is cleared when all data has been read. */ pr_debug("%s : requesting IRQ %d\n", __func__, client->irq); pn544_dev->irq_enabled = true; ret = request_irq(client->irq, pn544_dev_irq_handler, IRQF_TRIGGER_HIGH, client->name, pn544_dev); if (ret) { dev_err(&client->dev, "request_irq failed\n"); goto err_request_irq_failed; } if (unlikely(irq_set_irq_wake(client->irq, 1))) pr_err("%s : unable to make irq %d wakeup\n", __func__, client->irq); pn544_disable_irq(pn544_dev); i2c_set_clientdata(client, pn544_dev); return 0; err_request_irq_failed: device_remove_file(pn544_dev->pn544_control_device, &dev_attr_pn544_control_dev); err_device_create_file_failed: misc_deregister(&pn544_dev->pn544_device); err_misc_register: mutex_destroy(&pn544_dev->read_mutex); pn544_gpio_free(pn544_dev); if (pn544_dev->vdd != NULL) regulator_disable(pn544_dev->vdd); err_en_regulator_swp: if (pn544_dev->vdd != NULL) regulator_put(pn544_dev->vdd); err_gpio_init: kfree(pn544_dev); err_exit: return ret; }