* @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
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;
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;
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)
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;
}
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);
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;
}
return ret;
platform_set_drvdata(pdev, info);
- idr_init(&info->tx_idr);
+ xa_init(&info->chans);
handle = &info->handle;
handle->dev = info->dev;