diff options
Diffstat (limited to 'net/nfc/core.c')
-rw-r--r-- | net/nfc/core.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/net/nfc/core.c b/net/nfc/core.c index 479bee36dc3e..aa64ea441676 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -40,6 +40,9 @@ int nfc_devlist_generation; DEFINE_MUTEX(nfc_devlist_mutex); +/* NFC device ID bitmap */ +static DEFINE_IDA(nfc_index_ida); + /** * nfc_dev_up - turn on the NFC device * @@ -181,6 +184,7 @@ int nfc_stop_poll(struct nfc_dev *dev) dev->ops->stop_poll(dev); dev->polling = false; + dev->rf_mode = NFC_RF_NONE; error: device_unlock(&dev->dev); @@ -194,7 +198,7 @@ static struct nfc_target *nfc_find_target(struct nfc_dev *dev, u32 target_idx) if (dev->n_targets == 0) return NULL; - for (i = 0; i < dev->n_targets ; i++) { + for (i = 0; i < dev->n_targets; i++) { if (dev->targets[i].idx == target_idx) return &dev->targets[i]; } @@ -274,12 +278,14 @@ int nfc_dep_link_down(struct nfc_dev *dev) if (!rc) { dev->dep_link_up = false; dev->active_target = NULL; + dev->rf_mode = NFC_RF_NONE; nfc_llcp_mac_is_down(dev); nfc_genl_dep_link_down_event(dev); } error: device_unlock(&dev->dev); + return rc; } @@ -503,6 +509,7 @@ EXPORT_SYMBOL(nfc_tm_activated); int nfc_tm_deactivated(struct nfc_dev *dev) { dev->dep_link_up = false; + dev->rf_mode = NFC_RF_NONE; return nfc_genl_tm_deactivated(dev); } @@ -697,6 +704,8 @@ static void nfc_check_pres_work(struct work_struct *work) if (dev->active_target && timer_pending(&dev->check_pres_timer) == 0) { rc = dev->ops->check_presence(dev, dev->active_target); + if (rc == -EOPNOTSUPP) + goto exit; if (!rc) { mod_timer(&dev->check_pres_timer, jiffies + msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); @@ -708,6 +717,7 @@ static void nfc_check_pres_work(struct work_struct *work) } } +exit: device_unlock(&dev->dev); } @@ -753,7 +763,6 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, u32 supported_protocols, int tx_headroom, int tx_tailroom) { - static atomic_t dev_no = ATOMIC_INIT(0); struct nfc_dev *dev; if (!ops->start_poll || !ops->stop_poll || !ops->activate_target || @@ -767,11 +776,6 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, if (!dev) return NULL; - dev->dev.class = &nfc_class; - dev->idx = atomic_inc_return(&dev_no) - 1; - 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; @@ -779,6 +783,7 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, nfc_genl_data_init(&dev->genl_data); + dev->rf_mode = NFC_RF_NONE; /* first generation must not be 0 */ dev->targets_generation = 1; @@ -806,6 +811,14 @@ int nfc_register_device(struct nfc_dev *dev) pr_debug("dev_name=%s\n", dev_name(&dev->dev)); + dev->idx = ida_simple_get(&nfc_index_ida, 0, 0, GFP_KERNEL); + if (dev->idx < 0) + return dev->idx; + + dev->dev.class = &nfc_class; + dev_set_name(&dev->dev, "nfc%d", dev->idx); + device_initialize(&dev->dev); + mutex_lock(&nfc_devlist_mutex); nfc_devlist_generation++; rc = device_add(&dev->dev); @@ -834,10 +847,12 @@ EXPORT_SYMBOL(nfc_register_device); */ void nfc_unregister_device(struct nfc_dev *dev) { - int rc; + int rc, id; pr_debug("dev_name=%s\n", dev_name(&dev->dev)); + id = dev->idx; + mutex_lock(&nfc_devlist_mutex); nfc_devlist_generation++; @@ -856,6 +871,8 @@ void nfc_unregister_device(struct nfc_dev *dev) pr_debug("The userspace won't be notified that the device %s was removed\n", dev_name(&dev->dev)); + ida_simple_remove(&nfc_index_ida, id); + } EXPORT_SYMBOL(nfc_unregister_device); |