Skip to content

Commit e718026

Browse files
anderssonAndy Gross
authored andcommitted
soc: qcom: smp2p: Access APCS as mailbox client
Attempt to acquire the APCS IPC through the mailbox framework and fall back to the old syscon based approach, to allow us to move away from using the syscon. Signed-off-by: Bjorn Andersson <[email protected]> Signed-off-by: Andy Gross <[email protected]>
1 parent 3b229bd commit e718026

File tree

3 files changed

+41
-7
lines changed

3 files changed

+41
-7
lines changed

Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,15 @@ processor ID) and a string identifier.
1717
Value type: <prop-encoded-array>
1818
Definition: one entry specifying the smp2p notification interrupt
1919

20-
- qcom,ipc:
20+
- mboxes:
2121
Usage: required
2222
Value type: <prop-encoded-array>
23+
Definition: reference to the associated doorbell in APCS, as described
24+
in mailbox/mailbox.txt
25+
26+
- qcom,ipc:
27+
Usage: required, unless mboxes is specified
28+
Value type: <prop-encoded-array>
2329
Definition: three entries specifying the outgoing ipc bit used for
2430
signaling the remote end of the smp2p edge:
2531
- phandle to a syscon node representing the apcs registers

drivers/soc/qcom/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ config QCOM_SMEM_STATE
7575

7676
config QCOM_SMP2P
7777
tristate "Qualcomm Shared Memory Point to Point support"
78+
depends on MAILBOX
7879
depends on QCOM_SMEM
7980
select QCOM_SMEM_STATE
8081
help

drivers/soc/qcom/smp2p.c

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/of.h>
1919
#include <linux/irq.h>
2020
#include <linux/irqdomain.h>
21+
#include <linux/mailbox_client.h>
2122
#include <linux/mfd/syscon.h>
2223
#include <linux/module.h>
2324
#include <linux/platform_device.h>
@@ -126,6 +127,8 @@ struct smp2p_entry {
126127
* @ipc_regmap: regmap for the outbound ipc
127128
* @ipc_offset: offset within the regmap
128129
* @ipc_bit: bit in regmap@offset to kick to signal remote processor
130+
* @mbox_client: mailbox client handle
131+
* @mbox_chan: apcs ipc mailbox channel handle
129132
* @inbound: list of inbound entries
130133
* @outbound: list of outbound entries
131134
*/
@@ -146,6 +149,9 @@ struct qcom_smp2p {
146149
int ipc_offset;
147150
int ipc_bit;
148151

152+
struct mbox_client mbox_client;
153+
struct mbox_chan *mbox_chan;
154+
149155
struct list_head inbound;
150156
struct list_head outbound;
151157
};
@@ -154,7 +160,13 @@ static void qcom_smp2p_kick(struct qcom_smp2p *smp2p)
154160
{
155161
/* Make sure any updated data is written before the kick */
156162
wmb();
157-
regmap_write(smp2p->ipc_regmap, smp2p->ipc_offset, BIT(smp2p->ipc_bit));
163+
164+
if (smp2p->mbox_chan) {
165+
mbox_send_message(smp2p->mbox_chan, NULL);
166+
mbox_client_txdone(smp2p->mbox_chan, 0);
167+
} else {
168+
regmap_write(smp2p->ipc_regmap, smp2p->ipc_offset, BIT(smp2p->ipc_bit));
169+
}
158170
}
159171

160172
/**
@@ -453,10 +465,6 @@ static int qcom_smp2p_probe(struct platform_device *pdev)
453465

454466
platform_set_drvdata(pdev, smp2p);
455467

456-
ret = smp2p_parse_ipc(smp2p);
457-
if (ret)
458-
return ret;
459-
460468
key = "qcom,smem";
461469
ret = of_property_read_u32_array(pdev->dev.of_node, key,
462470
smp2p->smem_items, 2);
@@ -483,9 +491,23 @@ static int qcom_smp2p_probe(struct platform_device *pdev)
483491
return irq;
484492
}
485493

494+
smp2p->mbox_client.dev = &pdev->dev;
495+
smp2p->mbox_client.knows_txdone = true;
496+
smp2p->mbox_chan = mbox_request_channel(&smp2p->mbox_client, 0);
497+
if (IS_ERR(smp2p->mbox_chan)) {
498+
if (PTR_ERR(smp2p->mbox_chan) != -ENODEV)
499+
return PTR_ERR(smp2p->mbox_chan);
500+
501+
smp2p->mbox_chan = NULL;
502+
503+
ret = smp2p_parse_ipc(smp2p);
504+
if (ret)
505+
return ret;
506+
}
507+
486508
ret = qcom_smp2p_alloc_outbound_item(smp2p);
487509
if (ret < 0)
488-
return ret;
510+
goto release_mbox;
489511

490512
for_each_available_child_of_node(pdev->dev.of_node, node) {
491513
entry = devm_kzalloc(&pdev->dev, sizeof(*entry), GFP_KERNEL);
@@ -540,6 +562,9 @@ static int qcom_smp2p_probe(struct platform_device *pdev)
540562

541563
smp2p->out->valid_entries = 0;
542564

565+
release_mbox:
566+
mbox_free_channel(smp2p->mbox_chan);
567+
543568
return ret;
544569
}
545570

@@ -554,6 +579,8 @@ static int qcom_smp2p_remove(struct platform_device *pdev)
554579
list_for_each_entry(entry, &smp2p->outbound, node)
555580
qcom_smem_state_unregister(entry->state);
556581

582+
mbox_free_channel(smp2p->mbox_chan);
583+
557584
smp2p->out->valid_entries = 0;
558585

559586
return 0;

0 commit comments

Comments
 (0)