struct nfc_dev *nfc_allocate_device(const struct nfc_ops *ops,
				    u32 supported_protocols,
				    int tx_headroom, int tx_tailroom)
{
	struct nfc_dev *dev;
	int rc;

	if (!ops->start_poll || !ops->stop_poll || !ops->activate_target ||
	    !ops->deactivate_target || !ops->im_transceive)
		return NULL;

	if (!supported_protocols)
		return NULL;

	dev = kzalloc(sizeof(struct nfc_dev), GFP_KERNEL);
	if (!dev)
		return NULL;

	rc = ida_simple_get(&nfc_index_ida, 0, 0, GFP_KERNEL);
	if (rc < 0)
		goto err_free_dev;
	dev->idx = rc;

	dev->dev.class = &nfc_class;
	dev_set_name(&dev->dev, "nfc%d", dev->idx);
	device_initialize(&dev->dev);

	dev->ops = ops;
	dev->supported_protocols = supported_protocols;
	dev->tx_headroom = tx_headroom;
	dev->tx_tailroom = tx_tailroom;
	INIT_LIST_HEAD(&dev->secure_elements);

	nfc_genl_data_init(&dev->genl_data);

	dev->rf_mode = NFC_RF_NONE;

	/* first generation must not be 0 */
	dev->targets_generation = 1;

	if (ops->check_presence) {
		timer_setup(&dev->check_pres_timer, nfc_check_pres_timeout, 0);
		INIT_WORK(&dev->check_pres_work, nfc_check_pres_work);
	}

	return dev;

err_free_dev:
	kfree(dev);

	return NULL;
}
struct nfc_dev *nfc_allocate_device(const struct nfc_ops *ops,
				    u32 supported_protocols,
				    int tx_headroom, int tx_tailroom)
{
	struct nfc_dev *dev;
	int rc;

	if (!ops->start_poll || !ops->stop_poll || !ops->activate_target ||
	    !ops->deactivate_target || !ops->im_transceive)
		return NULL;

	if (!supported_protocols)
		return NULL;

	dev = kzalloc(sizeof(struct nfc_dev), GFP_KERNEL);
	if (!dev)
		return NULL;

	rc = ida_simple_get(&nfc_index_ida, 0, 0, GFP_KERNEL);
	if (rc < 0)
		goto err_free_dev;
	dev->idx = rc;

	dev->dev.class = &nfc_class;
	dev_set_name(&dev->dev, "nfc%d", dev->idx);
	device_initialize(&dev->dev);

	dev->ops = ops;
	dev->supported_protocols = supported_protocols;
	dev->tx_headroom = tx_headroom;
	dev->tx_tailroom = tx_tailroom;
	INIT_LIST_HEAD(&dev->secure_elements);

	nfc_genl_data_init(&dev->genl_data);

	dev->rf_mode = NFC_RF_NONE;

	 
	dev->targets_generation = 1;

	if (ops->check_presence) {
		timer_setup(&dev->check_pres_timer, nfc_check_pres_timeout, 0);
		INIT_WORK(&dev->check_pres_work, nfc_check_pres_work);
	}

	return dev;

err_free_dev:
	kfree(dev);

	return NULL;
}