* Copyright (c) 2016-2017, Linaro Ltd
*/
-#include <linux/idr.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/list.h>
* @name: unique channel name/identifier
* @lcid: channel id, in local space
* @rcid: channel id, in remote space
- * @intent_lock: lock for protection of @riids
* @liids: all local intents
- * @riids: idr of all remote intents
+ * @riids: all remote intents
* @intent_work: worker responsible for transmitting rx_done packets
+ * @intent_lock: protects @done_intents
* @done_intents: list of intents that needs to be announced rx_done
* @buf: receive buffer, for gathering fragments
* @buf_offset: write offset in @buf
unsigned int lcid;
unsigned int rcid;
- spinlock_t intent_lock;
struct xarray liids;
- struct idr riids;
+ struct xarray riids;
struct work_struct intent_work;
u32 liid_next;
+ spinlock_t intent_lock;
struct list_head done_intents;
struct glink_core_rx_intent *buf;
xa_init_flags(&channel->liids, XA_FLAGS_ALLOC1 | XA_FLAGS_LOCK_IRQ);
channel->liid_next = 1;
- idr_init(&channel->riids);
+ xa_init_flags(&channel->riids, XA_FLAGS_LOCK_IRQ);
kref_init(&channel->refcount);
return channel;
{
struct glink_channel *channel = container_of(ref, struct glink_channel,
refcount);
- unsigned long flags;
xa_destroy(&channel->liids);
- spin_lock_irqsave(&channel->intent_lock, flags);
- idr_destroy(&channel->riids);
- spin_unlock_irqrestore(&channel->intent_lock, flags);
-
+ xa_destroy(&channel->riids);
kfree(channel->name);
kfree(channel);
}
return;
}
- spin_lock_irqsave(&channel->intent_lock, flags);
- intent = idr_find(&channel->riids, iid);
+ xa_lock_irqsave(&channel->riids, flags);
+ intent = xa_load(&channel->riids, iid);
if (!intent) {
- spin_unlock_irqrestore(&channel->intent_lock, flags);
+ xa_unlock_irqrestore(&channel->riids, flags);
dev_err(glink->dev, "invalid intent id received\n");
return;
}
intent->in_use = false;
if (!reuse) {
- idr_remove(&channel->riids, intent->id);
+ __xa_erase(&channel->riids, intent->id);
kfree(intent);
}
- spin_unlock_irqrestore(&channel->intent_lock, flags);
+ xa_unlock_irqrestore(&channel->riids, flags);
}
/**
intent->id = le32_to_cpu(msg->intents[i].iid);
intent->size = le32_to_cpu(msg->intents[i].size);
- spin_lock_irqsave(&channel->intent_lock, flags);
- ret = idr_alloc(&channel->riids, intent,
- intent->id, intent->id + 1, GFP_ATOMIC);
- spin_unlock_irqrestore(&channel->intent_lock, flags);
+ xa_lock_irqsave(&channel->riids, flags);
+ ret = __xa_insert(&channel->riids, intent->id, intent,
+ GFP_ATOMIC);
+ xa_unlock_irqrestore(&channel->riids, flags);
if (ret < 0)
dev_err(glink->dev, "failed to store remote intent\n");
struct qcom_glink *glink = channel->glink;
struct glink_core_rx_intent *intent = NULL;
struct glink_core_rx_intent *tmp;
- int iid = 0;
+ unsigned long iid = 0;
struct {
struct glink_msg msg;
__le32 chunk_size;
if (!glink->intentless) {
while (!intent) {
- spin_lock_irqsave(&channel->intent_lock, flags);
- idr_for_each_entry(&channel->riids, tmp, iid) {
+ xa_lock_irqsave(&channel->riids, flags);
+ xa_for_each(&channel->riids, iid, tmp) {
if (tmp->size >= len && !tmp->in_use) {
if (!intent)
intent = tmp;
}
if (intent)
intent->in_use = true;
- spin_unlock_irqrestore(&channel->intent_lock, flags);
+ xa_unlock_irqrestore(&channel->riids, flags);
/* We found an available intent */
if (intent)