* @rx_lock: protects the @rx_queue
* @rx_queue: queue of received control messages to be processed in @rx_work
* @tx_lock: synchronizes operations on the tx fifo
- * @idr_lock: synchronizes @rcids modifications
* @lcids: all channels with a known local channel id
- * @rcids: idr of all channels with a known remote channel id
+ * @rcids: all channels with a known remote channel id
* @features: remote features
* @intentless: flag to indicate that there is no intent
*/
spinlock_t tx_lock;
- spinlock_t idr_lock;
u32 lcid_next;
struct xarray lcids;
- struct idr rcids;
+ struct xarray rcids;
unsigned long features;
bool intentless;
struct glink_channel *channel;
unsigned long flags;
- spin_lock_irqsave(&glink->idr_lock, flags);
- channel = idr_find(&glink->rcids, cid);
- spin_unlock_irqrestore(&glink->idr_lock, flags);
+ xa_lock_irqsave(&glink->rcids, flags);
+ channel = xa_load(&glink->rcids, cid);
+ xa_unlock_irqrestore(&glink->rcids, flags);
if (!channel) {
dev_err(glink->dev, "unable to find channel\n");
return;
struct glink_channel *channel;
unsigned long flags;
- spin_lock_irqsave(&glink->idr_lock, flags);
- channel = idr_find(&glink->rcids, cid);
- spin_unlock_irqrestore(&glink->idr_lock, flags);
+ xa_lock_irqsave(&glink->rcids, flags);
+ channel = xa_load(&glink->rcids, cid);
+ xa_unlock_irqrestore(&glink->rcids, flags);
if (!channel) {
dev_err(glink->dev, "invalid channel id received\n");
return;
{
struct glink_core_rx_intent *intent;
struct glink_channel *channel;
- unsigned long flags;
- spin_lock_irqsave(&glink->idr_lock, flags);
- channel = idr_find(&glink->rcids, cid);
- spin_unlock_irqrestore(&glink->idr_lock, flags);
+ channel = xa_load(&glink->rcids, cid);
if (!channel) {
pr_err("%s channel not found for cid %d\n", __func__, cid);
}
rcid = le16_to_cpu(hdr.msg.param1);
- spin_lock_irqsave(&glink->idr_lock, flags);
- channel = idr_find(&glink->rcids, rcid);
- spin_unlock_irqrestore(&glink->idr_lock, flags);
+ channel = xa_load(&glink->rcids, rcid);
if (!channel) {
dev_dbg(glink->dev, "Data on non-existing channel\n");
return;
}
- spin_lock_irqsave(&glink->idr_lock, flags);
- channel = idr_find(&glink->rcids, cid);
- spin_unlock_irqrestore(&glink->idr_lock, flags);
+ channel = xa_load(&glink->rcids, cid);
if (!channel) {
dev_err(glink->dev, "intents for non-existing channel\n");
return;
struct qcom_glink *glink = parent->glink;
struct rpmsg_endpoint *ept;
const char *name = chinfo.name;
- int cid;
+ unsigned long cid;
int ret;
- unsigned long flags;
- spin_lock_irqsave(&glink->idr_lock, flags);
- idr_for_each_entry(&glink->rcids, channel, cid) {
+ xa_for_each(&glink->rcids, cid, channel) {
if (!strcmp(channel->name, name))
break;
}
- spin_unlock_irqrestore(&glink->idr_lock, flags);
if (!channel) {
channel = qcom_glink_create_local(glink, name);
create_device = true;
}
- spin_lock_irq(&glink->idr_lock);
- ret = idr_alloc(&glink->rcids, channel, rcid, rcid + 1, GFP_ATOMIC);
+ channel->rcid = rcid;
+ ret = xa_insert_irq(&glink->rcids, rcid, channel, GFP_KERNEL);
if (ret < 0) {
- dev_err(glink->dev, "Unable to insert channel into rcid list\n");
- spin_unlock_irq(&glink->idr_lock);
+ dev_err(glink->dev, "Unable to insert channel into rcids\n");
goto free_channel;
}
- channel->rcid = ret;
- spin_unlock_irq(&glink->idr_lock);
complete(&channel->open_req);
free_rpdev:
kfree(rpdev);
rcid_remove:
- spin_lock_irq(&glink->idr_lock);
- idr_remove(&glink->rcids, channel->rcid);
+ xa_erase_irq(&glink->rcids, channel->rcid);
channel->rcid = 0;
- spin_unlock_irq(&glink->idr_lock);
free_channel:
/* Release the reference, iff we took it */
if (create_device)
{
struct rpmsg_channel_info chinfo;
struct glink_channel *channel;
- unsigned long flags;
- spin_lock_irqsave(&glink->idr_lock, flags);
- channel = idr_find(&glink->rcids, rcid);
- spin_unlock_irqrestore(&glink->idr_lock, flags);
+ channel = xa_load(&glink->rcids, rcid);
if (WARN(!channel, "close request on unknown channel\n"))
return;
qcom_glink_send_close_ack(glink, channel->rcid);
- spin_lock_irqsave(&glink->idr_lock, flags);
- idr_remove(&glink->rcids, channel->rcid);
+ xa_erase_irq(&glink->rcids, channel->rcid);
channel->rcid = 0;
- spin_unlock_irqrestore(&glink->idr_lock, flags);
kref_put(&channel->refcount, qcom_glink_channel_release);
}
INIT_LIST_HEAD(&glink->rx_queue);
INIT_WORK(&glink->rx_work, qcom_glink_work);
- spin_lock_init(&glink->idr_lock);
xa_init_flags(&glink->lcids, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ);
glink->lcid_next = 0;
- idr_init(&glink->rcids);
+ xa_init_flags(&glink->rcids, XA_FLAGS_LOCK_IRQ);
ret = of_property_read_string(dev->of_node, "label", &glink->name);
if (ret < 0)
xa_unlock_irqrestore(&glink->lcids, flags);
xa_destroy(&glink->lcids);
- idr_destroy(&glink->rcids);
+ xa_destroy(&glink->rcids);
mbox_free_channel(glink->mbox_chan);
}
EXPORT_SYMBOL_GPL(qcom_glink_native_remove);