]> www.infradead.org Git - users/willy/xarray.git/commitdiff
arm_scmi: Convert tx_idr to XArray
authorMatthew Wilcox <willy@infradead.org>
Fri, 15 Feb 2019 18:42:08 +0000 (13:42 -0500)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Fri, 9 Aug 2019 01:38:16 +0000 (21:38 -0400)
Signed-off-by: Matthew Wilcox <willy@infradead.org>
drivers/firmware/arm_scmi/driver.c

index b5bc4c7a8fab2957bb0842b95e32d152f11837aa..22420e220fbf0ae2de94af32fd835fd24ecea261 100644 (file)
@@ -112,7 +112,7 @@ struct scmi_chan_info {
  * @version: SCMI revision information containing protocol version,
  *     implementation version and (sub-)vendor identification.
  * @minfo: Message info
- * @tx_idr: IDR object to map protocol id to channel info pointer
+ * @chans: Channel info pointers, indexed by protocol ID
  * @protocols_imp: List of protocols implemented, currently maximum of
  *     MAX_PROTOCOLS_IMP elements allocated by the base protocol
  * @node: List head
@@ -124,7 +124,7 @@ struct scmi_info {
        struct scmi_revision_info version;
        struct scmi_handle handle;
        struct scmi_xfers_info minfo;
-       struct idr tx_idr;
+       struct xarray chans;
        u8 *protocols_imp;
        struct list_head node;
        int users;
@@ -389,7 +389,7 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer)
        struct device *dev = info->dev;
        struct scmi_chan_info *cinfo;
 
-       cinfo = idr_find(&info->tx_idr, xfer->hdr.protocol_id);
+       cinfo = xa_load(&info->chans, xfer->hdr.protocol_id);
        if (unlikely(!cinfo))
                return -EINVAL;
 
@@ -657,26 +657,12 @@ static int scmi_mailbox_check(struct device_node *np)
        return of_parse_phandle_with_args(np, "mboxes", "#mbox-cells", 0, NULL);
 }
 
-static int scmi_mbox_free_channel(int id, void *p, void *data)
-{
-       struct scmi_chan_info *cinfo = p;
-       struct idr *idr = data;
-
-       if (!IS_ERR_OR_NULL(cinfo->chan)) {
-               mbox_free_channel(cinfo->chan);
-               cinfo->chan = NULL;
-       }
-
-       idr_remove(idr, id);
-
-       return 0;
-}
-
 static int scmi_remove(struct platform_device *pdev)
 {
        int ret = 0;
        struct scmi_info *info = platform_get_drvdata(pdev);
-       struct idr *idr = &info->tx_idr;
+       struct scmi_chan_info *cinfo;
+       unsigned long index;
 
        mutex_lock(&scmi_list_mutex);
        if (info->users)
@@ -689,8 +675,13 @@ static int scmi_remove(struct platform_device *pdev)
                return ret;
 
        /* Safe to free channels since no more users */
-       ret = idr_for_each(idr, scmi_mbox_free_channel, idr);
-       idr_destroy(&info->tx_idr);
+       xa_for_each(&info->chans, index, cinfo) {
+               if (!IS_ERR_OR_NULL(cinfo->chan)) {
+                       mbox_free_channel(cinfo->chan);
+                       cinfo->chan = NULL;
+               }
+       }
+       xa_destroy(&info->chans);
 
        return ret;
 }
@@ -706,8 +697,8 @@ scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev, int prot_id)
        struct mbox_client *cl;
 
        if (scmi_mailbox_check(np)) {
-               cinfo = idr_find(&info->tx_idr, SCMI_PROTOCOL_BASE);
-               goto idr_alloc;
+               cinfo = xa_load(&info->chans, SCMI_PROTOCOL_BASE);
+               goto insert;
        }
 
        cinfo = devm_kzalloc(info->dev, sizeof(*cinfo), GFP_KERNEL);
@@ -747,10 +738,10 @@ scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev, int prot_id)
                return ret;
        }
 
-idr_alloc:
-       ret = idr_alloc(&info->tx_idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL);
-       if (ret != prot_id) {
-               dev_err(dev, "unable to allocate SCMI idr slot err %d\n", ret);
+insert:
+       ret = xa_insert(&info->chans, prot_id, cinfo, GFP_KERNEL);
+       if (ret) {
+               dev_err(dev, "unable to allocate SCMI protocol err %d\n", ret);
                return ret;
        }
 
@@ -813,7 +804,7 @@ static int scmi_probe(struct platform_device *pdev)
                return ret;
 
        platform_set_drvdata(pdev, info);
-       idr_init(&info->tx_idr);
+       xa_init(&info->chans);
 
        handle = &info->handle;
        handle->dev = info->dev;