Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7673008 authored by Bjorn Andersson's avatar Bjorn Andersson Committed by Deepak Kumar Singh
Browse files

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.

CR-Fixed: 2330873
Change-Id: I31d8c62d4df3882769656b55e54d968acefde1d3
Signed-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: default avatarAndy Gross <andy.gross@linaro.org>
Git-commit: e71802647bfd639a9f53e49a4ef86a2bfdbeb611
Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git


[deesin@codeaurora.org resolved trivial merge conflicts]
Signed-off-by: default avatarDeepak Kumar Singh <deesin@codeaurora.org>
parent 982dcbe0
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -17,9 +17,15 @@ processor ID) and a string identifier.
	Value type: <prop-encoded-array>
	Definition: one entry specifying the smp2p notification interrupt

- qcom,ipc:
- mboxes:
	Usage: required
	Value type: <prop-encoded-array>
	Definition: reference to the associated doorbell in APCS, as described
		    in mailbox/mailbox.txt

- qcom,ipc:
	Usage: required, unless mboxes is specified
	Value type: <prop-encoded-array>
	Definition: three entries specifying the outgoing ipc bit used for
		    signaling the remote end of the smp2p edge:
		    - phandle to a syscon node representing the apcs registers
+1 −0
Original line number Diff line number Diff line
@@ -277,6 +277,7 @@ config QCOM_SMEM_STATE

config QCOM_SMP2P
	tristate "Qualcomm Shared Memory Point to Point support"
	depends on MAILBOX
	depends on QCOM_SMEM
	select QCOM_SMEM_STATE
	help
+33 −6
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/of.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/mailbox_client.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -133,6 +134,8 @@ struct smp2p_entry {
 * @ipc_regmap:	regmap for the outbound ipc
 * @ipc_offset:	offset within the regmap
 * @ipc_bit:	bit in regmap@offset to kick to signal remote processor
 * @mbox_client: mailbox client handle
 * @mbox_chan:	apcs ipc mailbox channel handle
 * @inbound:	list of inbound entries
 * @outbound:	list of outbound entries
 */
@@ -158,6 +161,9 @@ struct qcom_smp2p {
	int ipc_offset;
	int ipc_bit;

	struct mbox_client mbox_client;
	struct mbox_chan *mbox_chan;

	struct list_head inbound;
	struct list_head outbound;
};
@@ -174,8 +180,14 @@ static void qcom_smp2p_kick(struct qcom_smp2p *smp2p)
{
	/* Make sure any updated data is written before the kick */
	wmb();

	if (smp2p->mbox_chan) {
		mbox_send_message(smp2p->mbox_chan, NULL);
		mbox_client_txdone(smp2p->mbox_chan, 0);
	} else {
		regmap_write(smp2p->ipc_regmap, smp2p->ipc_offset, BIT(smp2p->ipc_bit));
	}
}

static bool qcom_smp2p_check_ssr(struct qcom_smp2p *smp2p)
{
@@ -555,10 +567,6 @@ static int qcom_smp2p_probe(struct platform_device *pdev)

	platform_set_drvdata(pdev, smp2p);

	ret = smp2p_parse_ipc(smp2p);
	if (ret)
		return ret;

	key = "qcom,smem";
	ret = of_property_read_u32_array(pdev->dev.of_node, key,
					 smp2p->smem_items, 2);
@@ -585,9 +593,23 @@ static int qcom_smp2p_probe(struct platform_device *pdev)
		return smp2p->irq;
	}

	smp2p->mbox_client.dev = &pdev->dev;
	smp2p->mbox_client.knows_txdone = true;
	smp2p->mbox_chan = mbox_request_channel(&smp2p->mbox_client, 0);
	if (IS_ERR(smp2p->mbox_chan)) {
		if (PTR_ERR(smp2p->mbox_chan) != -ENODEV)
			return PTR_ERR(smp2p->mbox_chan);

		smp2p->mbox_chan = NULL;

		ret = smp2p_parse_ipc(smp2p);
		if (ret)
			return ret;
	}

	ret = qcom_smp2p_alloc_outbound_item(smp2p);
	if (ret < 0)
		return ret;
		goto release_mbox;

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

	smp2p->out->valid_entries = 0;

release_mbox:
	mbox_free_channel(smp2p->mbox_chan);

	return ret;
}

@@ -656,6 +681,8 @@ static int qcom_smp2p_remove(struct platform_device *pdev)
	list_for_each_entry(entry, &smp2p->outbound, node)
		qcom_smem_state_unregister(entry->state);

	mbox_free_channel(smp2p->mbox_chan);

	smp2p->out->valid_entries = 0;

	return 0;