static int felica_probe(struct platform_device *pdev)
{
	int ret;
	struct felica_dev *dev;
	struct felica_platform_data *flc_pfdata;

	dev_info(&pdev->dev, "FeliCa driver being loaded\n");

	flc_pfdata = pdev->dev.platform_data;
	if (NULL == flc_pfdata) {
		dev_err(&pdev->dev, "%s: No platform data\n", __func__);
		ret = -EINVAL;
		goto err_get_platform_data;
	}

	dev = kzalloc(sizeof(struct felica_dev), GFP_KERNEL);
	if (!dev) {
		dev_err(&pdev->dev, "%s: no memory\n", __func__);
		ret = -ENOMEM;
		goto err_alloc_data;
	}

	dev->dev = &pdev->dev;
	platform_set_drvdata(pdev, dev);

	dev->device_cen.minor = MISC_DYNAMIC_MINOR;
	dev->device_cen.name = "felica_cen";
	dev->device_cen.fops = &felica_cen_fops;

	dev->device_pon.minor = MISC_DYNAMIC_MINOR;
	dev->device_pon.name = "felica_pon";
	dev->device_pon.fops = &felica_pon_fops;

	dev->device_rfs.minor = MISC_DYNAMIC_MINOR;
	dev->device_rfs.name = "felica_rfs";
	dev->device_rfs.fops = &felica_rfs_fops;

	dev->device_rws.minor = MISC_DYNAMIC_MINOR;
	dev->device_rws.name = "felica_rws";
	dev->device_rws.fops = &felica_rws_fops;

#ifdef CONFIG_SONY_FELICA_NFC_SUPPORT
	dev->device_hsel.minor = MISC_DYNAMIC_MINOR;
	dev->device_hsel.name = "snfc_hsel";
	dev->device_hsel.fops = &snfc_hsel_fops;

	dev->device_intu_poll.minor = MISC_DYNAMIC_MINOR;
	dev->device_intu_poll.name = "snfc_intu_poll";
	dev->device_intu_poll.fops = &snfc_intu_poll_fops;

	dev->device_available_poll.minor = MISC_DYNAMIC_MINOR;
	dev->device_available_poll.name = "snfc_available_poll";
	dev->device_available_poll.fops = &snfc_available_poll_fops;
#endif

	dev->flcen = &flc_pfdata->cen_pfdata;
	dev->flpon = &flc_pfdata->pon_pfdata;
	dev->flrfs = &flc_pfdata->rfs_pfdata;
	dev->flint = &flc_pfdata->int_pfdata;
#ifdef CONFIG_SONY_FELICA_NFC_SUPPORT
	dev->flintu = &flc_pfdata->intu_pfdata;
	dev->flhsel = &flc_pfdata->hsel_pfdata;
	dev->flldo = &flc_pfdata->ldo_pfdata;
#endif

	ret = flc_pfdata->gpio_init(dev);
	if (ret && -EBUSY != ret) {
		dev_err(&pdev->dev, "%s: GPIO init failed\n", __func__);
		goto error_gpio_init;
	}

	ret = felica_cen_probe_func(dev);
	if (ret) {
		dev_err(&pdev->dev, "%s: CEN probe failure\n", __func__);
		goto err_cen_probe;
	}

	ret = felica_pon_probe_func(dev);
	if (ret) {
		dev_err(&pdev->dev, "%s: PON probe failure\n", __func__);
		goto err_pon_probe;
	}

	ret = felica_rfs_probe_func(dev);
	if (ret) {
		dev_err(&pdev->dev, "%s: RFS probe failure\n", __func__);
		goto err_rfs_probe;
	}

	ret = felica_int_probe_func(dev);
	if (ret) {
		dev_err(&pdev->dev, "%s: INT probe failure\n", __func__);
		goto err_int_probe;
	}

	ret = felica_rws_probe_func(dev);
	if (ret) {
		dev_err(&pdev->dev, "%s: RWS probe failure\n", __func__);
		goto err_rws_probe;
	}

#ifdef CONFIG_SONY_FELICA_NFC_SUPPORT
	ret = snfc_hsel_probe_func(dev);
	if (ret) {
		dev_err(&pdev->dev, "%s: SNFC HSEL probe failure\n",
				__func__);
		goto err_snfc_hsel_probe;
	}

	ret = snfc_intu_poll_probe_func(dev);
	if (ret) {
		dev_err(&pdev->dev, "%s: SNFC INTU POLL probe failure\n",
				__func__);
		goto err_snfc_intu_poll_probe;
	}

	ret = snfc_available_poll_probe_func(dev);
	if (ret) {
		dev_err(&pdev->dev, "%s: SNFC AVAILABLE POLL probe failure\n",
				__func__);
		goto err_snfc_available_poll_probe;
	}

	init_waitqueue_head(&dev->available_poll_wait);
	dev->available_poll_snfc = 0;
#endif

	ret = create_sysfs_interfaces(&pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "%s: failed to create dev. attrs\n",
				__func__);
		goto err_create_sysfs;
	}

	return 0;

err_create_sysfs:
#ifdef CONFIG_SONY_FELICA_NFC_SUPPORT
	snfc_available_poll_remove_func(dev);
err_snfc_available_poll_probe:
	snfc_intu_poll_remove_func(dev);
err_snfc_intu_poll_probe:
	snfc_hsel_remove_func(dev);
err_snfc_hsel_probe:
#endif
	felica_rws_remove_func(dev);
err_rws_probe:
	felica_int_remove_func(dev);
err_int_probe:
	felica_rfs_remove_func(dev);
err_rfs_probe:
	felica_pon_remove_func(dev);
err_pon_probe:
	felica_cen_remove_func(dev);
err_cen_probe:
	flc_pfdata->reg_release(dev);
error_gpio_init:
	kfree(dev);
err_alloc_data:
err_get_platform_data:

	return ret;
}
Esempio n. 2
0
static int felica_probe(struct platform_device *pdev)
{
	int	ret;
	struct felica_dev *dev;
	struct felica_platform_data	*flc_pfdata;

	dev_info(&pdev->dev, "FeliCa driver ver %s being loaded\n",
							DRV_VERSION);

	flc_pfdata = pdev->dev.platform_data;
	if (NULL == flc_pfdata) {
		dev_err(&pdev->dev, "%s: No platform data\n", __func__);
		ret = -EINVAL;
		goto err_get_platform_data;
	}

	dev = kzalloc(sizeof(struct felica_dev), GFP_KERNEL);
	if (!dev) {
		dev_err(&pdev->dev, "%s: no memory\n", __func__);
		ret = -ENOMEM;
		goto err_alloc_data;
	}

	dev->dev = &pdev->dev;
	platform_set_drvdata(pdev, dev);

	dev->device_cen.minor = MISC_DYNAMIC_MINOR;
	dev->device_cen.name = "felica_cen";
	dev->device_cen.fops = &felica_cen_fops;

	dev->device_pon.minor = MISC_DYNAMIC_MINOR;
	dev->device_pon.name = "felica_pon";
	dev->device_pon.fops = &felica_pon_fops;

	dev->device_rfs.minor = MISC_DYNAMIC_MINOR;
	dev->device_rfs.name = "felica_rfs";
	dev->device_rfs.fops = &felica_rfs_fops;

	dev->device_rws.minor = MISC_DYNAMIC_MINOR;
	dev->device_rws.name = "felica_rws";
	dev->device_rws.fops = &felica_rws_fops;

	dev->flcen = &flc_pfdata->cen_pfdata;
	dev->flpon = &flc_pfdata->pon_pfdata;
	dev->flrfs = &flc_pfdata->rfs_pfdata;
	dev->flint = &flc_pfdata->int_pfdata;

	/* GPIO setting of MSM & PM */
	ret = flc_pfdata->gpio_init(dev);
	if (ret && -EBUSY != ret) {
		dev_err(&pdev->dev, "%s: GPIO init failed\n", __func__);
		goto error_gpio_init;
	}

	/* Call initialization functions of each controller */
	ret = felica_cen_probe_func(dev);
	if (ret) {
		dev_err(&pdev->dev, "%s: CEN probe failure\n", __func__);
		goto err_cen_probe;
	}

	ret = felica_pon_probe_func(dev);
	if (ret) {
		dev_err(&pdev->dev, "%s: PON probe failure\n", __func__);
		goto err_pon_probe;
	}

	ret = felica_rfs_probe_func(dev);
	if (ret) {
		dev_err(&pdev->dev, "%s: RFS probe failure\n", __func__);
		goto err_rfs_probe;
	}

	ret = felica_int_probe_func(dev);
	if (ret) {
		dev_err(&pdev->dev, "%s: INT probe failure\n", __func__);
		goto err_int_probe;
	}

	ret = felica_rws_probe_func(dev);
	if (ret) {
		dev_err(&pdev->dev, "%s: RWS probe failure\n", __func__);
		goto err_rws_probe;
	}

	/* Create dev. attrs for Reader/Writer mode */
	ret = create_sysfs_interfaces(&pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "%s: failed to create dev. attrs\n",
				__func__);
		goto err_create_sysfs;
	}

	return 0;

/* Error handling */
err_create_sysfs:
	felica_rws_remove_func(dev);
err_rws_probe:
	felica_int_remove_func(dev);
err_int_probe:
	felica_rfs_remove_func(dev);
err_rfs_probe:
	felica_pon_remove_func(dev);
err_pon_probe:
	felica_cen_remove_func(dev);
err_cen_probe:
	flc_pfdata->reg_release(dev);
error_gpio_init:
	kfree(dev);
err_alloc_data:
err_get_platform_data:

	return ret;
}
int felica_snfc_register(struct device *dev, struct felica_data *felica_data)
{
	int ret;
	struct felica_dev *d;

	dev_dbg(dev, "%s\n", __func__);

	if (reg_device) {
		dev_err(dev, "%s: felica_snfc was registered.\n",  __func__);
		ret =  -EBUSY;
		goto err_inval;
	}

	if (!dev) {
		dev_err(dev, "%s: device is null.\n",  __func__);
		ret =  -EINVAL;
		goto err_inval;
	}
	if (!felica_data) {
		dev_err(dev, "%s: felica_data is null.\n",  __func__);
		ret =  -EINVAL;
		goto err_inval;
	}
	if (!felica_data->flcen || !felica_data->flpon ||
		!felica_data->flrfs || !felica_data->flint) {
		dev_err(dev, "%s: felica ops is null.\n",  __func__);
		ret =  -EINVAL;
		goto err_inval;
	}
	if (FELICA_SNFC == felica_data->type &&
		(!felica_data->flintu || !felica_data->flhsel ||
		!felica_data->flldo)) {
		dev_err(dev, "%s: nfc ops is null.\n",  __func__);
		ret =  -EINVAL;
		goto err_inval;
	}

	d = kzalloc(sizeof(struct felica_dev), GFP_KERNEL);
	if (!d) {
		dev_err(dev, "%s: no memory\n", __func__);
		ret = -ENOMEM;
		goto err_alloc;
	}
	d->felica_data = felica_data;
	d->irq_shutdown = true;

	d->device_cen.minor = MISC_DYNAMIC_MINOR;
	d->device_cen.name = "felica_cen";
	d->device_cen.fops = &felica_cen_fops;

	d->device_pon.minor = MISC_DYNAMIC_MINOR;
	d->device_pon.name = "felica_pon";
	d->device_pon.fops = &felica_pon_fops;

	d->device_rfs.minor = MISC_DYNAMIC_MINOR;
	d->device_rfs.name = "felica_rfs";
	d->device_rfs.fops = &felica_rfs_fops;

	d->device_rws.minor = MISC_DYNAMIC_MINOR;
	d->device_rws.name = "felica_rws";
	d->device_rws.fops = &felica_rws_fops;

	if (FELICA_SNFC == felica_data->type) {
		d->device_hsel.minor = MISC_DYNAMIC_MINOR;
		d->device_hsel.name = "snfc_hsel";
		d->device_hsel.fops = &nfc_hsel_fops;

		d->device_intu_poll.minor = MISC_DYNAMIC_MINOR;
		d->device_intu_poll.name = "snfc_intu_poll";
		d->device_intu_poll.fops = &nfc_intu_poll_fops;

		d->device_available_poll.minor = MISC_DYNAMIC_MINOR;
		d->device_available_poll.name = "snfc_available_poll";
		d->device_available_poll.fops = &nfc_available_poll_fops;
	}

	d->dev = dev;
	dev_set_drvdata(dev, d);

	ret = felica_cen_probe_func(d);
	if (ret) {
		dev_err(dev, "%s: CEN probe failure\n", __func__);
		goto err_cen_probe;
	}

	ret = felica_pon_probe_func(d);
	if (ret) {
		dev_err(dev, "%s: PON probe failure\n", __func__);
		goto err_pon_probe;
	}

	ret = felica_rfs_probe_func(d);
	if (ret) {
		dev_err(dev, "%s: RFS probe failure\n", __func__);
		goto err_rfs_probe;
	}

	ret = felica_int_probe_func(d);
	if (ret) {
		dev_err(dev, "%s: INT probe failure\n", __func__);
		goto err_int_probe;
	}

	ret = felica_rws_probe_func(d);
	if (ret) {
		dev_err(dev, "%s: RWS probe failure\n", __func__);
		goto err_rws_probe;
	}

	if (FELICA_SNFC == felica_data->type) {
		ret = nfc_hsel_probe_func(d);
		if (ret) {
			dev_err(dev, "%s: NFC HSEL probe failure\n", __func__);
			goto err_nfc_hsel_probe;
		}

		ret = nfc_intu_poll_probe_func(d);
		if (ret) {
			dev_err(dev, "%s: NFC INTU POLL probe failure\n",
				__func__);
			goto err_nfc_intu_poll_probe;
		}
		init_waitqueue_head(&d->intu_wait_queue);

		ret = nfc_available_poll_probe_func(d);
		if (ret) {
			dev_err(dev, "%s: NFC AVAILABLE POLL probe failure\n",
				__func__);
			goto err_nfc_available_poll_probe;
		}
		init_waitqueue_head(&d->available_poll_wait);
		d->available_poll_nfc = 0;
	}
	d->sysfs_dev.init_name = "felica_snfc";
	dev_set_drvdata(&d->sysfs_dev, d);
	ret = device_register(&d->sysfs_dev);
	if (ret) {
		dev_err(dev, "%s: failed to register device.\n", __func__);
		goto err_register_device;
	}

	ret = create_sysfs_interfaces(&d->sysfs_dev);
	if (ret) {
		dev_err(dev, "%s: failed to create dev.\n", __func__);
		goto err_create_sysfs;
	}

	reg_device = dev;

	return 0;

err_create_sysfs:
	device_unregister(&d->sysfs_dev);
err_register_device:
	nfc_available_poll_remove_func(d);
err_nfc_available_poll_probe:
	nfc_intu_poll_remove_func(d);
err_nfc_intu_poll_probe:
	nfc_hsel_remove_func(d);
err_nfc_hsel_probe:
	felica_rws_remove_func(d);
err_rws_probe:
	felica_int_remove_func(d);
err_int_probe:
	felica_rfs_remove_func(d);
err_rfs_probe:
	felica_pon_remove_func(d);
err_pon_probe:
	felica_cen_remove_func(d);
err_cen_probe:
	kfree(d);
err_alloc:
err_inval:
	return ret;
}