diff options
author | Andy Gross <agross@codeaurora.org> | 2015-07-13 16:35:56 -0500 |
---|---|---|
committer | Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | 2015-09-01 09:22:07 +0100 |
commit | 9f459b0fac0c4defe83972ba478019c5e7b52ee1 (patch) | |
tree | 3768b99fa79940c0ba7e26ec32ce75e0a5b8197d | |
parent | cea80611803a2473c80f5786726065e0cf5c0700 (diff) | |
download | linux-9f459b0fac0c4defe83972ba478019c5e7b52ee1.tar.gz |
soc: qcom: smd: Use correct smem id
This patch fixes the incorrect table and smem id usage
Signed-off-by: Andy Gross <agross@codeaurora.org>
-rw-r--r-- | drivers/soc/qcom/smd.c | 93 |
1 files changed, 46 insertions, 47 deletions
diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c index 5287d3e1d043..1c416a1c8ffc 100644 --- a/drivers/soc/qcom/smd.c +++ b/drivers/soc/qcom/smd.c @@ -103,6 +103,7 @@ static const struct { * @ipc_bit: bit in the register at @ipc_offset of @ipc_regmap * @channels: list of all channels detected on this edge * @channels_lock: guard for modifications of @channels + * @allocated: array of bitmaps representing already allocated channels * @need_rescan: flag that the @work needs to scan smem for new channels * @smem_available: last available amount of smem triggering a channel scan * @work: work item for edge house keeping @@ -111,6 +112,7 @@ struct qcom_smd_edge { struct qcom_smd *smd; struct device_node *of_node; unsigned edge_id; + unsigned remote_pid; int irq; @@ -121,6 +123,8 @@ struct qcom_smd_edge { struct list_head channels; spinlock_t channels_lock; + DECLARE_BITMAP(allocated[SMD_ALLOC_TBL_COUNT], SMD_ALLOC_TBL_SIZE); + bool need_rescan; unsigned smem_available; @@ -197,19 +201,12 @@ struct qcom_smd_channel { /** * struct qcom_smd - smd struct * @dev: device struct - * @allocated: bitmap representing already allocated channels - * @alloc_tbl: pointer(s) to the allocation table(s) - * @alloc_tbl_entries: number of actual allocation entries found * @num_edges: number of entries in @edges * @edges: array of edges to be handled */ struct qcom_smd { struct device *dev; - DECLARE_BITMAP(allocated, SMD_ALLOC_TBL_COUNT * SMD_ALLOC_TBL_SIZE); - struct qcom_smd_alloc_entry *alloc_tbl[SMD_ALLOC_TBL_COUNT]; - unsigned alloc_tbl_entries; - unsigned num_edges; struct qcom_smd_edge edges[0]; }; @@ -555,7 +552,7 @@ static irqreturn_t qcom_smd_edge_intr(int irq, void *data) * have to scan if the amount of available space in smem have changed * since last scan. */ - available = qcom_smem_get_free_space(edge->edge_id); + available = qcom_smem_get_free_space(edge->remote_pid); if (available != edge->smem_available) { edge->smem_available = available; edge->need_rescan = true; @@ -951,7 +948,7 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed spin_lock_init(&channel->recv_lock); init_waitqueue_head(&channel->fblockread_event); - ret = qcom_smem_get(edge->edge_id, smem_info_item, (void **)&info, &info_size); + ret = qcom_smem_get(edge->remote_pid, smem_info_item, (void **)&info, &info_size); if (ret) goto free_name_and_channel; @@ -972,7 +969,7 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed goto free_name_and_channel; } - ret = qcom_smem_get(edge->edge_id, smem_fifo_item, &fifo_base, &fifo_size); + ret = qcom_smem_get(edge->remote_pid, smem_fifo_item, &fifo_base, &fifo_size); if (ret) goto free_name_and_channel; @@ -1004,47 +1001,56 @@ free_name_and_channel: */ static void qcom_discover_channels(struct qcom_smd_edge *edge) { + struct qcom_smd_alloc_entry *alloc_tbl; struct qcom_smd_alloc_entry *entry; struct qcom_smd_channel *channel; struct qcom_smd *smd = edge->smd; unsigned long flags; unsigned fifo_id; unsigned info_id; + int ret; int tbl; int i; - for (i = 0; i < smd->alloc_tbl_entries; i++) { - tbl = i / SMD_ALLOC_TBL_SIZE; - - entry = &smd->alloc_tbl[tbl][i]; - if (test_bit(i, smd->allocated)) + for (tbl = 0; tbl < SMD_ALLOC_TBL_COUNT; tbl++) { + ret = qcom_smem_get(edge->remote_pid, + smem_items[tbl].alloc_tbl_id, + (void **)&alloc_tbl, + NULL); + if (ret < 0) continue; - if (entry->ref_count == 0) - continue; + for (i = 0; i < SMD_ALLOC_TBL_SIZE; i++) { + entry = &alloc_tbl[i]; + if (test_bit(i, edge->allocated[tbl])) + continue; - if (!entry->name[0]) - continue; + if (entry->ref_count == 0) + continue; - if (!(entry->flags & SMD_CHANNEL_FLAGS_PACKET)) - continue; + if (!entry->name[0]) + continue; - if ((entry->flags & SMD_CHANNEL_FLAGS_EDGE_MASK) != edge->edge_id) - continue; + if (!(entry->flags & SMD_CHANNEL_FLAGS_PACKET)) + continue; - info_id = smem_items[tbl].info_base_id + entry->cid; - fifo_id = smem_items[tbl].fifo_base_id + entry->cid; + if ((entry->flags & SMD_CHANNEL_FLAGS_EDGE_MASK) != edge->edge_id) + continue; - channel = qcom_smd_create_channel(edge, info_id, fifo_id, entry->name); - if (IS_ERR(channel)) - continue; + info_id = smem_items[tbl].info_base_id + entry->cid; + fifo_id = smem_items[tbl].fifo_base_id + entry->cid; - spin_lock_irqsave(&edge->channels_lock, flags); - list_add(&channel->list, &edge->channels); - spin_unlock_irqrestore(&edge->channels_lock, flags); + channel = qcom_smd_create_channel(edge, info_id, fifo_id, entry->name); + if (IS_ERR(channel)) + continue; + + spin_lock_irqsave(&edge->channels_lock, flags); + list_add(&channel->list, &edge->channels); + spin_unlock_irqrestore(&edge->channels_lock, flags); - dev_dbg(smd->dev, "new channel found: '%s'\n", channel->name); - set_bit(i, smd->allocated); + dev_dbg(smd->dev, "new channel found: '%s'\n", channel->name); + set_bit(i, edge->allocated[tbl]); + } } schedule_work(&edge->work); @@ -1150,6 +1156,13 @@ static int qcom_smd_parse_edge(struct device *dev, return -EINVAL; } + key = "qcom,remote-pid"; + ret = of_property_read_u32(node, key, &edge->remote_pid); + if (ret) { + dev_err(dev, "edge missing %s property\n", key); + return -EINVAL; + } + syscon_np = of_parse_phandle(node, "qcom,ipc", 0); if (!syscon_np) { dev_err(dev, "no qcom,ipc node\n"); @@ -1193,20 +1206,6 @@ static int qcom_smd_probe(struct platform_device *pdev) return -ENOMEM; smd->dev = &pdev->dev; - ret = qcom_smem_get(QCOM_SMEM_HOST_ANY, smem_items[0].alloc_tbl_id, - (void **)&smd->alloc_tbl[0], NULL); - if (ret < 0) { - dev_err(smd->dev, "primary allocation table not available\n"); - return ret; - }; - - smd->alloc_tbl_entries = SMD_ALLOC_TBL_SIZE; - - ret = qcom_smem_get(QCOM_SMEM_HOST_ANY, smem_items[1].alloc_tbl_id, - (void **)&smd->alloc_tbl[1], NULL); - if (ret >= 0) - smd->alloc_tbl_entries += SMD_ALLOC_TBL_SIZE; - smd->num_edges = num_edges; for_each_available_child_of_node(pdev->dev.of_node, node) { edge = &smd->edges[i++]; |