]> www.infradead.org Git - users/willy/xarray.git/commitdiff
spi: Convert spi_master_idr to XArray
authorMatthew Wilcox <willy@infradead.org>
Mon, 18 Feb 2019 22:17:56 +0000 (17:17 -0500)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Fri, 9 Aug 2019 01:38:18 +0000 (21:38 -0400)
Signed-off-by: Matthew Wilcox <willy@infradead.org>
drivers/spi/spi.c

index 75ac046cae5267b712fef17dec0ba1f2d381838d..2ae55af60666d91b957121268af3fd9b907bc19a 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/ioport.h>
 #include <linux/acpi.h>
 #include <linux/highmem.h>
-#include <linux/idr.h>
+#include <linux/xarray.h>
 #include <linux/platform_data/x86/apple.h>
 
 #define CREATE_TRACE_POINTS
@@ -41,7 +41,7 @@ EXPORT_TRACEPOINT_SYMBOL(spi_transfer_stop);
 
 #include "internals.h"
 
-static DEFINE_IDR(spi_master_idr);
+static DEFINE_XARRAY_ALLOC(spi_masters);
 
 static void spidev_release(struct device *dev)
 {
@@ -471,7 +471,6 @@ static LIST_HEAD(spi_controller_list);
 /*
  * Used to protect add/del opertion for board_info list and
  * spi_controller list, and their matching process
- * also used to protect object of type struct idr
  */
 static DEFINE_MUTEX(board_lock);
 
@@ -2379,7 +2378,6 @@ int spi_register_controller(struct spi_controller *ctlr)
        struct device           *dev = ctlr->dev.parent;
        struct boardinfo        *bi;
        int                     status;
-       int                     id, first_dynamic;
 
        if (!dev)
                return -ENODEV;
@@ -2392,43 +2390,36 @@ int spi_register_controller(struct spi_controller *ctlr)
        if (status)
                return status;
 
+       if ((ctlr->bus_num < 0) && ctlr->dev.of_node) {
+               status = of_alias_get_id(ctlr->dev.of_node, "spi");
+               if (status >= 0)
+                       ctlr->bus_num = status;
+       }
+
        if (ctlr->bus_num >= 0) {
                /* devices with a fixed bus num must check-in with the num */
                mutex_lock(&board_lock);
-               id = idr_alloc(&spi_master_idr, ctlr, ctlr->bus_num,
-                       ctlr->bus_num + 1, GFP_KERNEL);
+               status = xa_insert(&spi_masters, ctlr->bus_num, ctlr,
+                               GFP_KERNEL);
                mutex_unlock(&board_lock);
-               if (WARN(id < 0, "couldn't get idr"))
-                       return id == -ENOSPC ? -EBUSY : id;
-               ctlr->bus_num = id;
-       } else if (ctlr->dev.of_node) {
-               /* allocate dynamic bus number using Linux idr */
-               id = of_alias_get_id(ctlr->dev.of_node, "spi");
-               if (id >= 0) {
-                       ctlr->bus_num = id;
-                       mutex_lock(&board_lock);
-                       id = idr_alloc(&spi_master_idr, ctlr, ctlr->bus_num,
-                                      ctlr->bus_num + 1, GFP_KERNEL);
-                       mutex_unlock(&board_lock);
-                       if (WARN(id < 0, "couldn't get idr"))
-                               return id == -ENOSPC ? -EBUSY : id;
-               }
-       }
-       if (ctlr->bus_num < 0) {
-               first_dynamic = of_alias_get_highest_id("spi");
+       } else {
+               int id, first_dynamic = of_alias_get_highest_id("spi");
+
                if (first_dynamic < 0)
                        first_dynamic = 0;
                else
                        first_dynamic++;
 
                mutex_lock(&board_lock);
-               id = idr_alloc(&spi_master_idr, ctlr, first_dynamic,
-                              0, GFP_KERNEL);
+               status = xa_alloc(&spi_masters, &id, ctlr,
+                               XA_LIMIT(first_dynamic, INT_MAX), GFP_KERNEL);
+               if (!status)
+                       ctlr->bus_num = id;
                mutex_unlock(&board_lock);
-               if (WARN(id < 0, "couldn't get idr"))
-                       return id;
-               ctlr->bus_num = id;
        }
+       if (WARN(status < 0, "couldn't get id"))
+               return status;
+
        INIT_LIST_HEAD(&ctlr->queue);
        spin_lock_init(&ctlr->queue_lock);
        spin_lock_init(&ctlr->bus_lock_spinlock);
@@ -2473,7 +2464,7 @@ int spi_register_controller(struct spi_controller *ctlr)
        if (status < 0) {
                /* free bus id */
                mutex_lock(&board_lock);
-               idr_remove(&spi_master_idr, ctlr->bus_num);
+               xa_erase(&spi_masters, ctlr->bus_num);
                mutex_unlock(&board_lock);
                goto done;
        }
@@ -2494,7 +2485,7 @@ int spi_register_controller(struct spi_controller *ctlr)
                        device_del(&ctlr->dev);
                        /* free bus id */
                        mutex_lock(&board_lock);
-                       idr_remove(&spi_master_idr, ctlr->bus_num);
+                       xa_erase(&spi_masters, ctlr->bus_num);
                        mutex_unlock(&board_lock);
                        goto done;
                }
@@ -2580,9 +2571,7 @@ void spi_unregister_controller(struct spi_controller *ctlr)
        int id = ctlr->bus_num;
 
        /* First make sure that this controller was ever added */
-       mutex_lock(&board_lock);
-       found = idr_find(&spi_master_idr, id);
-       mutex_unlock(&board_lock);
+       found = xa_load(&spi_masters, id);
        if (ctlr->queued) {
                if (spi_destroy_queue(ctlr))
                        dev_err(&ctlr->dev, "queue remove failed\n");
@@ -2596,7 +2585,7 @@ void spi_unregister_controller(struct spi_controller *ctlr)
        /* free bus id */
        mutex_lock(&board_lock);
        if (found == ctlr)
-               idr_remove(&spi_master_idr, id);
+               xa_erase(&spi_masters, id);
        mutex_unlock(&board_lock);
 }
 EXPORT_SYMBOL_GPL(spi_unregister_controller);