NFC: Use IDR library to assing NFC devices IDs
authorSamuel Ortiz <sameo@linux.intel.com>
Mon, 22 Oct 2012 13:57:58 +0000 (15:57 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Fri, 26 Oct 2012 16:26:51 +0000 (18:26 +0200)
As a consequence the NFC device IDs won't be increasing all the time,
as IDR provides the first available ID.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
include/net/nfc/nfc.h
net/nfc/core.c

index f05b10682c9d9bbe0aa65579fc73bd8adf1747df..fce80b2f9be7e5eaf50e5fc5ccf55fde0440f793 100644 (file)
@@ -95,7 +95,7 @@ struct nfc_genl_data {
 };
 
 struct nfc_dev {
-       unsigned int idx;
+       int idx;
        u32 target_next_idx;
        struct nfc_target *targets;
        int n_targets;
index f1c33f23331167603c3cd9d08fa1111355031331..e94363dbbf4a5264520a08a107b16b34f07b008b 100644 (file)
@@ -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
  *
@@ -760,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 ||
@@ -774,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;
@@ -814,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);
@@ -842,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++;
 
@@ -864,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);