]> www.infradead.org Git - users/willy/xarray.git/commitdiff
soc/qcom: Convert svcs_idr to XArray
authorMatthew Wilcox <willy@infradead.org>
Mon, 18 Feb 2019 22:08:02 +0000 (17:08 -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/soc/qcom/apr.c

index 4fcc32420c4740d3988339f83dcf923db4cfb709..59142796e244cd81b869fb96b090944f0f2c6a5f 100644 (file)
@@ -6,20 +6,19 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/spinlock.h>
-#include <linux/idr.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/of_device.h>
 #include <linux/soc/qcom/apr.h>
 #include <linux/rpmsg.h>
 #include <linux/of.h>
+#include <linux/xarray.h>
 
 struct apr {
        struct rpmsg_endpoint *ch;
        struct device *dev;
-       spinlock_t svcs_lock;
        spinlock_t rx_lock;
-       struct idr svcs_idr;
+       struct xarray svcs;
        int dest_domain_id;
        struct workqueue_struct *rxwq;
        struct work_struct rx_work;
@@ -140,12 +139,9 @@ static int apr_do_rx_callback(struct apr *apr, struct apr_rx_buf *abuf)
                return -EINVAL;
        }
 
-       svc_id = hdr->dest_svc;
-       spin_lock_irqsave(&apr->svcs_lock, flags);
-       svc = idr_find(&apr->svcs_idr, svc_id);
+       svc = xa_load(&apr->svcs, hdr->dest_svc);
        if (svc && svc->dev.driver)
                adrv = to_apr_driver(svc->dev.driver);
-       spin_unlock_irqrestore(&apr->svcs_lock, flags);
 
        if (!adrv) {
                dev_err(apr->dev, "APR: service is not registered\n");
@@ -225,9 +221,7 @@ static int apr_device_remove(struct device *dev)
                adrv = to_apr_driver(dev->driver);
                if (adrv->remove)
                        adrv->remove(adev);
-               spin_lock(&apr->svcs_lock);
-               idr_remove(&apr->svcs_idr, adev->svc_id);
-               spin_unlock(&apr->svcs_lock);
+               xa_erase(&apr->svcs, adev->svc_id);
        }
 
        return 0;
@@ -284,16 +278,18 @@ static int apr_add_device(struct device *dev, struct device_node *np,
        adev->dev.release = apr_dev_release;
        adev->dev.driver = NULL;
 
-       spin_lock(&apr->svcs_lock);
-       idr_alloc(&apr->svcs_idr, adev, id->svc_id,
-                 id->svc_id + 1, GFP_ATOMIC);
-       spin_unlock(&apr->svcs_lock);
+       ret = xa_insert(&apr->svcs, adev->svc_id, adev, GFP_KERNEL);
+       if (ret < 0) {
+               put_device(&adev->dev);
+               return ret;
+       }
 
        dev_info(dev, "Adding APR dev: %s\n", dev_name(&adev->dev));
 
        ret = device_register(&adev->dev);
        if (ret) {
                dev_err(dev, "device_register failed: %d\n", ret);
+               xa_erase(&apr->svcs, adev->svc_id);
                put_device(&adev->dev);
        }
 
@@ -345,8 +341,7 @@ static int apr_probe(struct rpmsg_device *rpdev)
        INIT_WORK(&apr->rx_work, apr_rxwq);
        INIT_LIST_HEAD(&apr->rx_list);
        spin_lock_init(&apr->rx_lock);
-       spin_lock_init(&apr->svcs_lock);
-       idr_init(&apr->svcs_idr);
+       xa_init(&apr->svcs);
        of_register_apr_devices(dev);
 
        return 0;