* @name: unique channel name/identifier
* @lcid: channel id, in local space
* @rcid: channel id, in remote space
- * @intent_lock: lock for protection of @liids, @riids
- * @liids: idr of all local intents
+ * @intent_lock: lock for protection of @riids
+ * @liids: all local intents
* @riids: idr of all remote intents
* @intent_work: worker responsible for transmitting rx_done packets
* @done_intents: list of intents that needs to be announced rx_done
unsigned int rcid;
spinlock_t intent_lock;
- struct idr liids;
+ struct xarray liids;
struct idr riids;
struct work_struct intent_work;
+ u32 liid_next;
struct list_head done_intents;
struct glink_core_rx_intent *buf;
INIT_LIST_HEAD(&channel->done_intents);
INIT_WORK(&channel->intent_work, qcom_glink_rx_done_work);
- idr_init(&channel->liids);
+ xa_init_flags(&channel->liids, XA_FLAGS_ALLOC1 | XA_FLAGS_LOCK_IRQ);
+ channel->liid_next = 1;
idr_init(&channel->riids);
kref_init(&channel->refcount);
refcount);
unsigned long flags;
+ xa_destroy(&channel->liids);
spin_lock_irqsave(&channel->intent_lock, flags);
- idr_destroy(&channel->liids);
idr_destroy(&channel->riids);
spin_unlock_irqrestore(&channel->intent_lock, flags);
}
/* Take it off the tree of receive intents */
- if (!intent->reuse) {
- spin_lock(&channel->intent_lock);
- idr_remove(&channel->liids, intent->id);
- spin_unlock(&channel->intent_lock);
- }
+ if (!intent->reuse)
+ xa_erase(&channel->liids, intent->id);
/* Schedule the sending of a rx_done indication */
spin_lock(&channel->intent_lock);
{
struct glink_core_rx_intent *intent;
int ret;
- unsigned long flags;
intent = kzalloc(sizeof(*intent), GFP_KERNEL);
if (!intent)
if (!intent->data)
goto free_intent;
- spin_lock_irqsave(&channel->intent_lock, flags);
- ret = idr_alloc_cyclic(&channel->liids, intent, 1, -1, GFP_ATOMIC);
- if (ret < 0) {
- spin_unlock_irqrestore(&channel->intent_lock, flags);
+ ret = xa_alloc_cyclic_irq(&channel->liids, &intent->id, intent,
+ xa_limit_32b, &channel->liid_next, GFP_KERNEL);
+ if (ret < 0)
goto free_data;
- }
- spin_unlock_irqrestore(&channel->intent_lock, flags);
- intent->id = ret;
intent->size = size;
intent->reuse = reuseable;
unsigned int rcid;
unsigned int liid;
int ret = 0;
- unsigned long flags;
if (avail < sizeof(hdr)) {
dev_dbg(glink->dev, "Not enough data in fifo\n");
}
} else {
liid = le32_to_cpu(hdr.msg.param2);
-
- spin_lock_irqsave(&channel->intent_lock, flags);
- intent = idr_find(&channel->liids, liid);
- spin_unlock_irqrestore(&channel->intent_lock, flags);
-
+ intent = xa_load(&channel->liids, liid);
if (!intent) {
dev_err(glink->dev,
"no intent found for channel %s intent %d",