diff mbox series

soc: qcom: smp2p: Access APCS as mailbox client

Message ID 20171116071832.7441-1-bjorn.andersson@linaro.org
State Superseded
Headers show
Series soc: qcom: smp2p: Access APCS as mailbox client | expand

Commit Message

Bjorn Andersson Nov. 16, 2017, 7:18 a.m. UTC
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 <bjorn.andersson@linaro.org>

---
 drivers/soc/qcom/Kconfig |  1 +
 drivers/soc/qcom/smp2p.c | 38 ++++++++++++++++++++++++++++++++------
 2 files changed, 33 insertions(+), 6 deletions(-)

-- 
2.15.0

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Arun Kumar Neelakantam Nov. 16, 2017, 12:17 p.m. UTC | #1
On 11/16/2017 12:48 PM, Bjorn Andersson wrote:
> 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 <bjorn.andersson@linaro.org>

> ---

>   drivers/soc/qcom/Kconfig |  1 +

>   drivers/soc/qcom/smp2p.c | 38 ++++++++++++++++++++++++++++++++------

>   2 files changed, 33 insertions(+), 6 deletions(-)

>

> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig

> index b00bccddcd3b..e67d9534fca0 100644

> --- a/drivers/soc/qcom/Kconfig

> +++ b/drivers/soc/qcom/Kconfig

> @@ -64,6 +64,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

> diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c

> index f51fb2ea7200..7fdbb64142a0 100644

> --- a/drivers/soc/qcom/smp2p.c

> +++ b/drivers/soc/qcom/smp2p.c

> @@ -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>

> @@ -126,6 +127,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

>    */

> @@ -146,6 +149,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;

>   };

> @@ -154,7 +160,13 @@ static void qcom_smp2p_kick(struct qcom_smp2p *smp2p)

>   {

>   	/* Make sure any updated data is written before the kick */

>   	wmb();

> -	regmap_write(smp2p->ipc_regmap, smp2p->ipc_offset, BIT(smp2p->ipc_bit));

> +

> +	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));

> +	}

>   }

>   

>   /**

> @@ -453,10 +465,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);

> @@ -483,9 +491,22 @@ static int qcom_smp2p_probe(struct platform_device *pdev)

>   		return irq;

>   	}

>   

> +	smp2p->mbox_client.dev = &pdev->dev;

> +	smp2p->mbox_chan = mbox_request_channel(&smp2p->mbox_client, 0);

any reason why we are not using "knows_txdone = true" for SMP2P but 
using for only SMD drivers
> +	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);

> @@ -540,6 +561,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;

>   }

>   

> @@ -554,6 +578,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;


--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox series

Patch

diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index b00bccddcd3b..e67d9534fca0 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -64,6 +64,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
diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c
index f51fb2ea7200..7fdbb64142a0 100644
--- a/drivers/soc/qcom/smp2p.c
+++ b/drivers/soc/qcom/smp2p.c
@@ -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>
@@ -126,6 +127,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
  */
@@ -146,6 +149,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;
 };
@@ -154,7 +160,13 @@  static void qcom_smp2p_kick(struct qcom_smp2p *smp2p)
 {
 	/* Make sure any updated data is written before the kick */
 	wmb();
-	regmap_write(smp2p->ipc_regmap, smp2p->ipc_offset, BIT(smp2p->ipc_bit));
+
+	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));
+	}
 }
 
 /**
@@ -453,10 +465,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);
@@ -483,9 +491,22 @@  static int qcom_smp2p_probe(struct platform_device *pdev)
 		return irq;
 	}
 
+	smp2p->mbox_client.dev = &pdev->dev;
+	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);
@@ -540,6 +561,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;
 }
 
@@ -554,6 +578,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;