All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/2] soc: qcom: aoss: Expose send for generic usecase
@ 2021-06-09 11:18 Sibi Sankar
  2021-06-09 11:18 ` [PATCH v4 1/2] " Sibi Sankar
  2021-06-09 11:18 ` [PATCH v4 2/2] soc: qcom: aoss: Add debugfs entry Sibi Sankar
  0 siblings, 2 replies; 8+ messages in thread
From: Sibi Sankar @ 2021-06-09 11:18 UTC (permalink / raw)
  To: bjorn.andersson
  Cc: agross, linux-kernel, linux-arm-msm, swboyd,
	manivannan.sadhasivam, Sibi Sankar

The patch series exposes functions to enable drivers to send their own
messages to AOSS (Always on Subsystem). It also adds a debugfs node for
qmp so messages can be sent to aoss for debugging and testing purposes.

V4:
 * Fix compilation error due to missing qmp_put
 * Minor typos [s/tarcks/tracks]

V3:
 * Remove devm memory allocation
 * Use refcount for qmp handle
 * Update qmp_get/qmp_put/qmp_remove function with refcount logic

Deepak Kumar Singh (2):
  soc: qcom: aoss: Expose send for generic usecase
  soc: qcom: aoss: Add debugfs entry

 drivers/soc/qcom/qcom_aoss.c       | 109 ++++++++++++++++++++++++++++++++++++-
 include/linux/soc/qcom/qcom_aoss.h |  36 ++++++++++++
 2 files changed, 143 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/soc/qcom/qcom_aoss.h

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v4 1/2] soc: qcom: aoss: Expose send for generic usecase
  2021-06-09 11:18 [PATCH v4 0/2] soc: qcom: aoss: Expose send for generic usecase Sibi Sankar
@ 2021-06-09 11:18 ` Sibi Sankar
  2021-07-21  6:37   ` Stephen Boyd
  2021-06-09 11:18 ` [PATCH v4 2/2] soc: qcom: aoss: Add debugfs entry Sibi Sankar
  1 sibling, 1 reply; 8+ messages in thread
From: Sibi Sankar @ 2021-06-09 11:18 UTC (permalink / raw)
  To: bjorn.andersson
  Cc: agross, linux-kernel, linux-arm-msm, swboyd,
	manivannan.sadhasivam, Deepak Kumar Singh, Chris Lew,
	Sibi Sankar

From: Deepak Kumar Singh <deesin@codeaurora.org>

Not all upcoming usecases will have an interface to allow the aoss
driver to hook onto. Expose the send api and create a get function to
enable drivers to send their own messages to aoss.

Signed-off-by: Chris Lew <clew@codeaurora.org>
Signed-off-by: Deepak Kumar Singh <deesin@codeaurora.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
---

v4:
 * Fix compilation error due to missing qmp_put
 * Minor typos [s/tarcks/tracks]

 drivers/soc/qcom/qcom_aoss.c       | 70 ++++++++++++++++++++++++++++++++++++--
 include/linux/soc/qcom/qcom_aoss.h | 36 ++++++++++++++++++++
 2 files changed, 104 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/soc/qcom/qcom_aoss.h

diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c
index 934fcc4d2b05..e8f48760bac8 100644
--- a/drivers/soc/qcom/qcom_aoss.c
+++ b/drivers/soc/qcom/qcom_aoss.c
@@ -8,10 +8,12 @@
 #include <linux/io.h>
 #include <linux/mailbox_client.h>
 #include <linux/module.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/thermal.h>
 #include <linux/slab.h>
+#include <linux/soc/qcom/qcom_aoss.h>
 
 #define QMP_DESC_MAGIC			0x0
 #define QMP_DESC_VERSION		0x4
@@ -61,6 +63,7 @@ struct qmp_cooling_device {
  * @mbox_chan: mailbox channel used to ring the doorbell on transmit
  * @offset: offset within @msgram where messages should be written
  * @size: maximum size of the messages to be transmitted
+ * @orphan: tracks whether qmp handle is valid
  * @event: wait_queue for synchronization with the IRQ
  * @tx_lock: provides synchronization between multiple callers of qmp_send()
  * @qdss_clk: QDSS clock hw struct
@@ -76,6 +79,8 @@ struct qmp {
 
 	size_t offset;
 	size_t size;
+	atomic_t  orphan;
+	struct kref refcount;
 
 	wait_queue_head_t event;
 
@@ -223,11 +228,17 @@ static bool qmp_message_empty(struct qmp *qmp)
  *
  * Return: 0 on success, negative errno on failure
  */
-static int qmp_send(struct qmp *qmp, const void *data, size_t len)
+int qmp_send(struct qmp *qmp, const void *data, size_t len)
 {
 	long time_left;
 	int ret;
 
+	if (WARN_ON(IS_ERR_OR_NULL(qmp) || !data))
+		return -EINVAL;
+
+	if (atomic_read(&qmp->orphan))
+		return -EINVAL;
+
 	if (WARN_ON(len + sizeof(u32) > qmp->size))
 		return -EINVAL;
 
@@ -261,6 +272,7 @@ static int qmp_send(struct qmp *qmp, const void *data, size_t len)
 
 	return ret;
 }
+EXPORT_SYMBOL(qmp_send);
 
 static int qmp_qdss_clk_prepare(struct clk_hw *hw)
 {
@@ -515,6 +527,54 @@ static void qmp_cooling_devices_remove(struct qmp *qmp)
 		thermal_cooling_device_unregister(qmp->cooling_devs[i].cdev);
 }
 
+/**
+ * qmp_get() - get a qmp handle from a device
+ * @dev: client device pointer
+ *
+ * Return: handle to qmp device on success, ERR_PTR() on failure
+ */
+struct qmp *qmp_get(struct device *dev)
+{
+	struct platform_device *pdev;
+	struct device_node *np;
+	struct qmp *qmp;
+
+	if (!dev || !dev->of_node)
+		return ERR_PTR(-EINVAL);
+
+	np = of_parse_phandle(dev->of_node, "qcom,qmp", 0);
+	if (!np)
+		return ERR_PTR(-ENODEV);
+
+	pdev = of_find_device_by_node(np);
+	of_node_put(np);
+	if (!pdev)
+		return ERR_PTR(-EINVAL);
+
+	qmp = platform_get_drvdata(pdev);
+	platform_device_put(pdev);
+
+	if (qmp)
+		kref_get(&qmp->refcount);
+
+	return qmp ? qmp : ERR_PTR(-EPROBE_DEFER);
+}
+EXPORT_SYMBOL(qmp_get);
+
+static void qmp_handle_release(struct kref *ref)
+{
+	struct qmp *qmp = container_of(ref, struct qmp, refcount);
+
+	kfree(qmp);
+}
+
+void qmp_put(struct qmp *qmp)
+{
+	if (!IS_ERR_OR_NULL(qmp))
+		kref_put(&qmp->refcount, qmp_handle_release);
+}
+EXPORT_SYMBOL(qmp_put);
+
 static int qmp_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -522,13 +582,14 @@ static int qmp_probe(struct platform_device *pdev)
 	int irq;
 	int ret;
 
-	qmp = devm_kzalloc(&pdev->dev, sizeof(*qmp), GFP_KERNEL);
+	qmp = kzalloc(sizeof(*qmp), GFP_KERNEL);
 	if (!qmp)
 		return -ENOMEM;
 
 	qmp->dev = &pdev->dev;
 	init_waitqueue_head(&qmp->event);
 	mutex_init(&qmp->tx_lock);
+	kref_init(&qmp->refcount);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	qmp->msgram = devm_ioremap_resource(&pdev->dev, res);
@@ -569,6 +630,8 @@ static int qmp_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, qmp);
 
+	atomic_set(&qmp->orphan, 0);
+
 	return 0;
 
 err_remove_qdss_clk:
@@ -577,6 +640,7 @@ static int qmp_probe(struct platform_device *pdev)
 	qmp_close(qmp);
 err_free_mbox:
 	mbox_free_channel(qmp->mbox_chan);
+	kfree(qmp);
 
 	return ret;
 }
@@ -590,7 +654,9 @@ static int qmp_remove(struct platform_device *pdev)
 	qmp_cooling_devices_remove(qmp);
 
 	qmp_close(qmp);
+	atomic_set(&qmp->orphan, 1);
 	mbox_free_channel(qmp->mbox_chan);
+	kref_put(&qmp->refcount, qmp_handle_release);
 
 	return 0;
 }
diff --git a/include/linux/soc/qcom/qcom_aoss.h b/include/linux/soc/qcom/qcom_aoss.h
new file mode 100644
index 000000000000..725c9d12fd11
--- /dev/null
+++ b/include/linux/soc/qcom/qcom_aoss.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __QCOM_AOSS_H__
+#define __QCOM_AOSS_H__
+
+#include <linux/err.h>
+#include <linux/device.h>
+
+struct qmp;
+
+#if IS_ENABLED(CONFIG_QCOM_AOSS_QMP)
+
+int qmp_send(struct qmp *qmp, const void *data, size_t len);
+struct qmp *qmp_get(struct device *dev);
+void qmp_put(struct qmp *qmp);
+
+#else
+
+static inline int qmp_send(struct qmp *qmp, const void *data, size_t len)
+{
+	return -ENODEV;
+}
+
+static inline struct qmp *qmp_get(struct device *dev)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline void qmp_put(struct qmp *qmp) { }
+
+#endif
+
+#endif
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v4 2/2] soc: qcom: aoss: Add debugfs entry
  2021-06-09 11:18 [PATCH v4 0/2] soc: qcom: aoss: Expose send for generic usecase Sibi Sankar
  2021-06-09 11:18 ` [PATCH v4 1/2] " Sibi Sankar
@ 2021-06-09 11:18 ` Sibi Sankar
  2021-08-04 19:06   ` Bjorn Andersson
  1 sibling, 1 reply; 8+ messages in thread
From: Sibi Sankar @ 2021-06-09 11:18 UTC (permalink / raw)
  To: bjorn.andersson
  Cc: agross, linux-kernel, linux-arm-msm, swboyd,
	manivannan.sadhasivam, Deepak Kumar Singh, Chris Lew,
	Sibi Sankar

From: Deepak Kumar Singh <deesin@codeaurora.org>

It can be useful to control the different power states of various
parts of hardware for device testing. Add a debugfs node for qmp so
messages can be sent to aoss for debugging and testing purposes.

Signed-off-by: Chris Lew <clew@codeaurora.org>
Signed-off-by: Deepak Kumar Singh <deesin@codeaurora.org>
Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
---
 drivers/soc/qcom/qcom_aoss.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c
index e8f48760bac8..998ee7605eb2 100644
--- a/drivers/soc/qcom/qcom_aoss.c
+++ b/drivers/soc/qcom/qcom_aoss.c
@@ -4,6 +4,7 @@
  */
 #include <dt-bindings/power/qcom-aoss-qmp.h>
 #include <linux/clk-provider.h>
+#include <linux/debugfs.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/mailbox_client.h>
@@ -89,6 +90,9 @@ struct qmp {
 	struct clk_hw qdss_clk;
 	struct genpd_onecell_data pd_data;
 	struct qmp_cooling_device *cooling_devs;
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+	struct dentry *debugfs_file;
+#endif /* CONFIG_DEBUG_FS */
 };
 
 struct qmp_pd {
@@ -575,6 +579,32 @@ void qmp_put(struct qmp *qmp)
 }
 EXPORT_SYMBOL(qmp_put);
 
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+static ssize_t aoss_dbg_write(struct file *file, const char __user *userstr,
+			      size_t len, loff_t *pos)
+{
+	struct qmp *qmp = file->private_data;
+	char buf[QMP_MSG_LEN] = {};
+	int ret;
+
+	if (!len || len >= QMP_MSG_LEN)
+		return len;
+
+	ret  = copy_from_user(buf, userstr, len);
+	if (ret)
+		return len;
+
+	ret = qmp_send(qmp, buf, QMP_MSG_LEN);
+
+	return ret ? ret : len;
+}
+
+static const struct file_operations aoss_dbg_fops = {
+	.open = simple_open,
+	.write = aoss_dbg_write,
+};
+#endif /* CONFIG_DEBUG_FS */
+
 static int qmp_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -632,6 +662,11 @@ static int qmp_probe(struct platform_device *pdev)
 
 	atomic_set(&qmp->orphan, 0);
 
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+	qmp->debugfs_file = debugfs_create_file("aoss_send_message", 0220, NULL,
+						qmp, &aoss_dbg_fops);
+#endif /* CONFIG_DEBUG_FS */
+
 	return 0;
 
 err_remove_qdss_clk:
@@ -649,6 +684,10 @@ static int qmp_remove(struct platform_device *pdev)
 {
 	struct qmp *qmp = platform_get_drvdata(pdev);
 
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+	debugfs_remove(qmp->debugfs_file);
+#endif /* CONFIG_DEBUG_FS */
+
 	qmp_qdss_clk_remove(qmp);
 	qmp_pd_remove(qmp);
 	qmp_cooling_devices_remove(qmp);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v4 1/2] soc: qcom: aoss: Expose send for generic usecase
  2021-06-09 11:18 ` [PATCH v4 1/2] " Sibi Sankar
@ 2021-07-21  6:37   ` Stephen Boyd
  2021-07-23  9:51     ` Deepak Kumar Singh
  0 siblings, 1 reply; 8+ messages in thread
From: Stephen Boyd @ 2021-07-21  6:37 UTC (permalink / raw)
  To: Sibi Sankar, bjorn.andersson
  Cc: agross, linux-kernel, linux-arm-msm, manivannan.sadhasivam,
	Deepak Kumar Singh, Chris Lew

Quoting Sibi Sankar (2021-06-09 04:18:51)
> From: Deepak Kumar Singh <deesin@codeaurora.org>
>
> Not all upcoming usecases will have an interface to allow the aoss
> driver to hook onto. Expose the send api and create a get function to
> enable drivers to send their own messages to aoss.
>
> Signed-off-by: Chris Lew <clew@codeaurora.org>
> Signed-off-by: Deepak Kumar Singh <deesin@codeaurora.org>
> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
> ---
>
> v4:
>  * Fix compilation error due to missing qmp_put
>  * Minor typos [s/tarcks/tracks]
>
>  drivers/soc/qcom/qcom_aoss.c       | 70 ++++++++++++++++++++++++++++++++++++--
>  include/linux/soc/qcom/qcom_aoss.h | 36 ++++++++++++++++++++
>  2 files changed, 104 insertions(+), 2 deletions(-)
>  create mode 100644 include/linux/soc/qcom/qcom_aoss.h
>
> diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c
> index 934fcc4d2b05..e8f48760bac8 100644
> --- a/drivers/soc/qcom/qcom_aoss.c
> +++ b/drivers/soc/qcom/qcom_aoss.c
> @@ -522,13 +582,14 @@ static int qmp_probe(struct platform_device *pdev)
>         int irq;
>         int ret;
>
> -       qmp = devm_kzalloc(&pdev->dev, sizeof(*qmp), GFP_KERNEL);
> +       qmp = kzalloc(sizeof(*qmp), GFP_KERNEL);
>         if (!qmp)
>                 return -ENOMEM;
>
>         qmp->dev = &pdev->dev;
>         init_waitqueue_head(&qmp->event);
>         mutex_init(&qmp->tx_lock);
> +       kref_init(&qmp->refcount);
>
>         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>         qmp->msgram = devm_ioremap_resource(&pdev->dev, res);
> @@ -569,6 +630,8 @@ static int qmp_probe(struct platform_device *pdev)
>
>         platform_set_drvdata(pdev, qmp);
>
> +       atomic_set(&qmp->orphan, 0);
> +
>         return 0;
>
>  err_remove_qdss_clk:
> @@ -577,6 +640,7 @@ static int qmp_probe(struct platform_device *pdev)
>         qmp_close(qmp);
>  err_free_mbox:
>         mbox_free_channel(qmp->mbox_chan);
> +       kfree(qmp);
>
>         return ret;
>  }
> @@ -590,7 +654,9 @@ static int qmp_remove(struct platform_device *pdev)
>         qmp_cooling_devices_remove(qmp);
>
>         qmp_close(qmp);
> +       atomic_set(&qmp->orphan, 1);

This looks odd. Why are we letting the device be removed while it is in
use by other drivers? Can't we pin the device with get_device() so it
can't be removed and then prevent the driver from being removed until
all the consumer drivers drop the reference, i.e. suppress sysfs unbind?

Otherwise it looks like a generic problem that all provider devices,
clks, regulators, gpios, etc. have to deal with and thus this
hand-rolled mechanism can't be right.

>         mbox_free_channel(qmp->mbox_chan);
> +       kref_put(&qmp->refcount, qmp_handle_release);
>
>         return 0;
>  }

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v4 1/2] soc: qcom: aoss: Expose send for generic usecase
  2021-07-21  6:37   ` Stephen Boyd
@ 2021-07-23  9:51     ` Deepak Kumar Singh
  2021-07-23 19:28       ` Stephen Boyd
  0 siblings, 1 reply; 8+ messages in thread
From: Deepak Kumar Singh @ 2021-07-23  9:51 UTC (permalink / raw)
  To: Stephen Boyd, Sibi Sankar, bjorn.andersson
  Cc: agross, linux-kernel, linux-arm-msm, manivannan.sadhasivam, Chris Lew


On 7/21/2021 12:07 PM, Stephen Boyd wrote:
> Quoting Sibi Sankar (2021-06-09 04:18:51)
>> From: Deepak Kumar Singh <deesin@codeaurora.org>
>>
>> Not all upcoming usecases will have an interface to allow the aoss
>> driver to hook onto. Expose the send api and create a get function to
>> enable drivers to send their own messages to aoss.
>>
>> Signed-off-by: Chris Lew <clew@codeaurora.org>
>> Signed-off-by: Deepak Kumar Singh <deesin@codeaurora.org>
>> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
>> Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
>> ---
>>
>> v4:
>>   * Fix compilation error due to missing qmp_put
>>   * Minor typos [s/tarcks/tracks]
>>
>>   drivers/soc/qcom/qcom_aoss.c       | 70 ++++++++++++++++++++++++++++++++++++--
>>   include/linux/soc/qcom/qcom_aoss.h | 36 ++++++++++++++++++++
>>   2 files changed, 104 insertions(+), 2 deletions(-)
>>   create mode 100644 include/linux/soc/qcom/qcom_aoss.h
>>
>> diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c
>> index 934fcc4d2b05..e8f48760bac8 100644
>> --- a/drivers/soc/qcom/qcom_aoss.c
>> +++ b/drivers/soc/qcom/qcom_aoss.c
>> @@ -522,13 +582,14 @@ static int qmp_probe(struct platform_device *pdev)
>>          int irq;
>>          int ret;
>>
>> -       qmp = devm_kzalloc(&pdev->dev, sizeof(*qmp), GFP_KERNEL);
>> +       qmp = kzalloc(sizeof(*qmp), GFP_KERNEL);
>>          if (!qmp)
>>                  return -ENOMEM;
>>
>>          qmp->dev = &pdev->dev;
>>          init_waitqueue_head(&qmp->event);
>>          mutex_init(&qmp->tx_lock);
>> +       kref_init(&qmp->refcount);
>>
>>          res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>          qmp->msgram = devm_ioremap_resource(&pdev->dev, res);
>> @@ -569,6 +630,8 @@ static int qmp_probe(struct platform_device *pdev)
>>
>>          platform_set_drvdata(pdev, qmp);
>>
>> +       atomic_set(&qmp->orphan, 0);
>> +
>>          return 0;
>>
>>   err_remove_qdss_clk:
>> @@ -577,6 +640,7 @@ static int qmp_probe(struct platform_device *pdev)
>>          qmp_close(qmp);
>>   err_free_mbox:
>>          mbox_free_channel(qmp->mbox_chan);
>> +       kfree(qmp);
>>
>>          return ret;
>>   }
>> @@ -590,7 +654,9 @@ static int qmp_remove(struct platform_device *pdev)
>>          qmp_cooling_devices_remove(qmp);
>>
>>          qmp_close(qmp);
>> +       atomic_set(&qmp->orphan, 1);
> This looks odd. Why are we letting the device be removed while it is in
> use by other drivers? Can't we pin the device with get_device() so it
> can't be removed and then prevent the driver from being removed until
> all the consumer drivers drop the reference, i.e. suppress sysfs unbind?
>
> Otherwise it looks like a generic problem that all provider devices,
> clks, regulators, gpios, etc. have to deal with and thus this
> hand-rolled mechanism can't be right.

As per my earlier discussion with Bjorn, device could be unbound using 
sysfs, in which case

remove() is called irrespective of whether any client driver is holding 
struct device reference

or not. That's why i have added separate refcount for qmp handle and 
marking it invalid if

qmp_remove() is called.

>>          mbox_free_channel(qmp->mbox_chan);
>> +       kref_put(&qmp->refcount, qmp_handle_release);
>>
>>          return 0;
>>   }

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v4 1/2] soc: qcom: aoss: Expose send for generic usecase
  2021-07-23  9:51     ` Deepak Kumar Singh
@ 2021-07-23 19:28       ` Stephen Boyd
  0 siblings, 0 replies; 8+ messages in thread
From: Stephen Boyd @ 2021-07-23 19:28 UTC (permalink / raw)
  To: Deepak Kumar Singh, Sibi Sankar, bjorn.andersson
  Cc: agross, linux-kernel, linux-arm-msm, manivannan.sadhasivam, Chris Lew

Quoting Deepak Kumar Singh (2021-07-23 02:51:50)
>
> On 7/21/2021 12:07 PM, Stephen Boyd wrote:
> > Quoting Sibi Sankar (2021-06-09 04:18:51)
> >> From: Deepak Kumar Singh <deesin@codeaurora.org>
> >>
> >> Not all upcoming usecases will have an interface to allow the aoss
> >> driver to hook onto. Expose the send api and create a get function to
> >> enable drivers to send their own messages to aoss.
> >>
> >> Signed-off-by: Chris Lew <clew@codeaurora.org>
> >> Signed-off-by: Deepak Kumar Singh <deesin@codeaurora.org>
> >> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> >> Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
> >> ---
> >>
> >> v4:
> >>   * Fix compilation error due to missing qmp_put
> >>   * Minor typos [s/tarcks/tracks]
> >>
> >>   drivers/soc/qcom/qcom_aoss.c       | 70 ++++++++++++++++++++++++++++++++++++--
> >>   include/linux/soc/qcom/qcom_aoss.h | 36 ++++++++++++++++++++
> >>   2 files changed, 104 insertions(+), 2 deletions(-)
> >>   create mode 100644 include/linux/soc/qcom/qcom_aoss.h
> >>
> >> diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c
> >> index 934fcc4d2b05..e8f48760bac8 100644
> >> --- a/drivers/soc/qcom/qcom_aoss.c
> >> +++ b/drivers/soc/qcom/qcom_aoss.c
> >> @@ -522,13 +582,14 @@ static int qmp_probe(struct platform_device *pdev)
> >>          int irq;
> >>          int ret;
> >>
> >> -       qmp = devm_kzalloc(&pdev->dev, sizeof(*qmp), GFP_KERNEL);
> >> +       qmp = kzalloc(sizeof(*qmp), GFP_KERNEL);
> >>          if (!qmp)
> >>                  return -ENOMEM;
> >>
> >>          qmp->dev = &pdev->dev;
> >>          init_waitqueue_head(&qmp->event);
> >>          mutex_init(&qmp->tx_lock);
> >> +       kref_init(&qmp->refcount);
> >>
> >>          res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >>          qmp->msgram = devm_ioremap_resource(&pdev->dev, res);
> >> @@ -569,6 +630,8 @@ static int qmp_probe(struct platform_device *pdev)
> >>
> >>          platform_set_drvdata(pdev, qmp);
> >>
> >> +       atomic_set(&qmp->orphan, 0);
> >> +
> >>          return 0;
> >>
> >>   err_remove_qdss_clk:
> >> @@ -577,6 +640,7 @@ static int qmp_probe(struct platform_device *pdev)
> >>          qmp_close(qmp);
> >>   err_free_mbox:
> >>          mbox_free_channel(qmp->mbox_chan);
> >> +       kfree(qmp);
> >>
> >>          return ret;
> >>   }
> >> @@ -590,7 +654,9 @@ static int qmp_remove(struct platform_device *pdev)
> >>          qmp_cooling_devices_remove(qmp);
> >>
> >>          qmp_close(qmp);
> >> +       atomic_set(&qmp->orphan, 1);
> > This looks odd. Why are we letting the device be removed while it is in
> > use by other drivers? Can't we pin the device with get_device() so it
> > can't be removed and then prevent the driver from being removed until
> > all the consumer drivers drop the reference, i.e. suppress sysfs unbind?
> >
> > Otherwise it looks like a generic problem that all provider devices,
> > clks, regulators, gpios, etc. have to deal with and thus this
> > hand-rolled mechanism can't be right.
>
> As per my earlier discussion with Bjorn, device could be unbound using
> sysfs, in which case
>
> remove() is called irrespective of whether any client driver is holding
> struct device reference
>
> or not. That's why i have added separate refcount for qmp handle and
> marking it invalid if
>
> qmp_remove() is called.
>

We have struct device_driver::suppress_bind_attrs for that. Can you set
it?

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v4 2/2] soc: qcom: aoss: Add debugfs entry
  2021-06-09 11:18 ` [PATCH v4 2/2] soc: qcom: aoss: Add debugfs entry Sibi Sankar
@ 2021-08-04 19:06   ` Bjorn Andersson
  0 siblings, 0 replies; 8+ messages in thread
From: Bjorn Andersson @ 2021-08-04 19:06 UTC (permalink / raw)
  To: Sibi Sankar
  Cc: agross, linux-kernel, linux-arm-msm, swboyd,
	manivannan.sadhasivam, Deepak Kumar Singh, Chris Lew

On Wed 09 Jun 06:18 CDT 2021, Sibi Sankar wrote:

> From: Deepak Kumar Singh <deesin@codeaurora.org>
> 
> It can be useful to control the different power states of various
> parts of hardware for device testing. Add a debugfs node for qmp so
> messages can be sent to aoss for debugging and testing purposes.
> 

I thought I replied to this patch, but can't find the reply...

> Signed-off-by: Chris Lew <clew@codeaurora.org>
> Signed-off-by: Deepak Kumar Singh <deesin@codeaurora.org>
> Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
> ---
>  drivers/soc/qcom/qcom_aoss.c | 39 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 39 insertions(+)
> 
> diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c
> index e8f48760bac8..998ee7605eb2 100644
> --- a/drivers/soc/qcom/qcom_aoss.c
> +++ b/drivers/soc/qcom/qcom_aoss.c
> @@ -4,6 +4,7 @@
>   */
>  #include <dt-bindings/power/qcom-aoss-qmp.h>
>  #include <linux/clk-provider.h>
> +#include <linux/debugfs.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/mailbox_client.h>
> @@ -89,6 +90,9 @@ struct qmp {
>  	struct clk_hw qdss_clk;
>  	struct genpd_onecell_data pd_data;
>  	struct qmp_cooling_device *cooling_devs;
> +#if IS_ENABLED(CONFIG_DEBUG_FS)
> +	struct dentry *debugfs_file;
> +#endif /* CONFIG_DEBUG_FS */
>  };
>  
>  struct qmp_pd {
> @@ -575,6 +579,32 @@ void qmp_put(struct qmp *qmp)
>  }
>  EXPORT_SYMBOL(qmp_put);
>  
> +#if IS_ENABLED(CONFIG_DEBUG_FS)
> +static ssize_t aoss_dbg_write(struct file *file, const char __user *userstr,
> +			      size_t len, loff_t *pos)
> +{
> +	struct qmp *qmp = file->private_data;
> +	char buf[QMP_MSG_LEN] = {};
> +	int ret;
> +
> +	if (!len || len >= QMP_MSG_LEN)
> +		return len;
> +
> +	ret  = copy_from_user(buf, userstr, len);
> +	if (ret)
> +		return len;
> +
> +	ret = qmp_send(qmp, buf, QMP_MSG_LEN);
> +
> +	return ret ? ret : len;
> +}
> +
> +static const struct file_operations aoss_dbg_fops = {
> +	.open = simple_open,
> +	.write = aoss_dbg_write,
> +};
> +#endif /* CONFIG_DEBUG_FS */
> +
>  static int qmp_probe(struct platform_device *pdev)
>  {
>  	struct resource *res;
> @@ -632,6 +662,11 @@ static int qmp_probe(struct platform_device *pdev)
>  
>  	atomic_set(&qmp->orphan, 0);
>  
> +#if IS_ENABLED(CONFIG_DEBUG_FS)
> +	qmp->debugfs_file = debugfs_create_file("aoss_send_message", 0220, NULL,
> +						qmp, &aoss_dbg_fops);
> +#endif /* CONFIG_DEBUG_FS */

You shouldn't need the guards, debugfs_create_file() is stubbed if
CONFIG_DEBUG_FS isn't set, so it's better to just rely on that.

Regards,
Bjorn

> +
>  	return 0;
>  
>  err_remove_qdss_clk:
> @@ -649,6 +684,10 @@ static int qmp_remove(struct platform_device *pdev)
>  {
>  	struct qmp *qmp = platform_get_drvdata(pdev);
>  
> +#if IS_ENABLED(CONFIG_DEBUG_FS)
> +	debugfs_remove(qmp->debugfs_file);
> +#endif /* CONFIG_DEBUG_FS */
> +
>  	qmp_qdss_clk_remove(qmp);
>  	qmp_pd_remove(qmp);
>  	qmp_cooling_devices_remove(qmp);
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH V4 1/2] soc: qcom: aoss: Expose send for generic usecase
  2021-06-14 10:21 [PATCH V4 0/2] soc: qcom: aoss: Expose send for generic usecase Deepak Kumar Singh
@ 2021-06-14 10:21 ` Deepak Kumar Singh
  0 siblings, 0 replies; 8+ messages in thread
From: Deepak Kumar Singh @ 2021-06-14 10:21 UTC (permalink / raw)
  To: bjorn.andersson, clew, sibis, manivannan.sadhasivam
  Cc: linux-kernel, linux-arm-msm, linux-remoteproc,
	Deepak Kumar Singh, Andy Gross

Not all upcoming usecases will have an interface to allow the aoss
driver to hook onto. Expose the send api and create a get function to
enable drivers to send their own messages to aoss.

Signed-off-by: Chris Lew <clew@codeaurora.org>
Signed-off-by: Deepak Kumar Singh <deesin@codeaurora.org>
---
 drivers/soc/qcom/qcom_aoss.c       | 70 ++++++++++++++++++++++++++++++++++++--
 include/linux/soc/qcom/qcom_aoss.h | 38 +++++++++++++++++++++
 2 files changed, 106 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/soc/qcom/qcom_aoss.h

diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c
index 53acb94..cd75d4d 100644
--- a/drivers/soc/qcom/qcom_aoss.c
+++ b/drivers/soc/qcom/qcom_aoss.c
@@ -8,10 +8,12 @@
 #include <linux/io.h>
 #include <linux/mailbox_client.h>
 #include <linux/module.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/thermal.h>
 #include <linux/slab.h>
+#include <linux/soc/qcom/qcom_aoss.h>
 
 #define QMP_DESC_MAGIC			0x0
 #define QMP_DESC_VERSION		0x4
@@ -61,6 +63,7 @@ struct qmp_cooling_device {
  * @mbox_chan: mailbox channel used to ring the doorbell on transmit
  * @offset: offset within @msgram where messages should be written
  * @size: maximum size of the messages to be transmitted
+ * @orphan: tarcks whether qmp handle is valid
  * @event: wait_queue for synchronization with the IRQ
  * @tx_lock: provides synchronization between multiple callers of qmp_send()
  * @qdss_clk: QDSS clock hw struct
@@ -76,6 +79,8 @@ struct qmp {
 
 	size_t offset;
 	size_t size;
+	atomic_t  orphan;
+	struct kref refcount;
 
 	wait_queue_head_t event;
 
@@ -223,11 +228,17 @@ static bool qmp_message_empty(struct qmp *qmp)
  *
  * Return: 0 on success, negative errno on failure
  */
-static int qmp_send(struct qmp *qmp, const void *data, size_t len)
+int qmp_send(struct qmp *qmp, const void *data, size_t len)
 {
 	long time_left;
 	int ret;
 
+	if (WARN_ON(IS_ERR_OR_NULL(qmp) || !data))
+		return -EINVAL;
+
+	if (atomic_read(&qmp->orphan))
+		return -EINVAL;
+
 	if (WARN_ON(len + sizeof(u32) > qmp->size))
 		return -EINVAL;
 
@@ -261,6 +272,7 @@ static int qmp_send(struct qmp *qmp, const void *data, size_t len)
 
 	return ret;
 }
+EXPORT_SYMBOL(qmp_send);
 
 static int qmp_qdss_clk_prepare(struct clk_hw *hw)
 {
@@ -515,6 +527,54 @@ static void qmp_cooling_devices_remove(struct qmp *qmp)
 		thermal_cooling_device_unregister(qmp->cooling_devs[i].cdev);
 }
 
+/**
+ * qmp_get() - get a qmp handle from a device
+ * @dev: client device pointer
+ *
+ * Return: handle to qmp device on success, ERR_PTR() on failure
+ */
+struct qmp *qmp_get(struct device *dev)
+{
+	struct platform_device *pdev;
+	struct device_node *np;
+	struct qmp *qmp;
+
+	if (!dev || !dev->of_node)
+		return ERR_PTR(-EINVAL);
+
+	np = of_parse_phandle(dev->of_node, "qcom,qmp", 0);
+	if (!np)
+		return ERR_PTR(-ENODEV);
+
+	pdev = of_find_device_by_node(np);
+	of_node_put(np);
+	if (!pdev)
+		return ERR_PTR(-EINVAL);
+
+	qmp = platform_get_drvdata(pdev);
+	platform_device_put(pdev);
+
+	if (qmp)
+		kref_get(&qmp->refcount);
+
+	return qmp ? qmp : ERR_PTR(-EPROBE_DEFER);
+}
+EXPORT_SYMBOL(qmp_get);
+
+static void qmp_handle_release(struct kref *ref)
+{
+	struct qmp *qmp = container_of(ref, struct qmp, refcount);
+
+	kfree(qmp);
+}
+
+void qmp_put(struct qmp *qmp)
+{
+	if (!IS_ERR_OR_NULL(qmp))
+		kref_put(&qmp->refcount, qmp_handle_release);
+}
+EXPORT_SYMBOL(qmp_put);
+
 static int qmp_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -522,13 +582,14 @@ static int qmp_probe(struct platform_device *pdev)
 	int irq;
 	int ret;
 
-	qmp = devm_kzalloc(&pdev->dev, sizeof(*qmp), GFP_KERNEL);
+	qmp = kzalloc(sizeof(*qmp), GFP_KERNEL);
 	if (!qmp)
 		return -ENOMEM;
 
 	qmp->dev = &pdev->dev;
 	init_waitqueue_head(&qmp->event);
 	mutex_init(&qmp->tx_lock);
+	kref_init(&qmp->refcount);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	qmp->msgram = devm_ioremap_resource(&pdev->dev, res);
@@ -569,6 +630,8 @@ static int qmp_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, qmp);
 
+	atomic_set(&qmp->orphan, 0);
+
 	return 0;
 
 err_remove_qdss_clk:
@@ -577,6 +640,7 @@ static int qmp_probe(struct platform_device *pdev)
 	qmp_close(qmp);
 err_free_mbox:
 	mbox_free_channel(qmp->mbox_chan);
+	kfree(qmp);
 
 	return ret;
 }
@@ -590,7 +654,9 @@ static int qmp_remove(struct platform_device *pdev)
 	qmp_cooling_devices_remove(qmp);
 
 	qmp_close(qmp);
+	atomic_set(&qmp->orphan, 1);
 	mbox_free_channel(qmp->mbox_chan);
+	kref_put(&qmp->refcount, qmp_handle_release);
 
 	return 0;
 }
diff --git a/include/linux/soc/qcom/qcom_aoss.h b/include/linux/soc/qcom/qcom_aoss.h
new file mode 100644
index 0000000..a8d8f07
--- /dev/null
+++ b/include/linux/soc/qcom/qcom_aoss.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __QCOM_AOSS_H__
+#define __QCOM_AOSS_H__
+
+#include <linux/err.h>
+#include <linux/device.h>
+
+struct qmp;
+
+#if IS_ENABLED(CONFIG_QCOM_AOSS_QMP)
+
+int qmp_send(struct qmp *qmp, const void *data, size_t len);
+struct qmp *qmp_get(struct device *dev);
+void qmp_put(struct qmp *qmp);
+
+#else
+
+static inline int qmp_send(struct qmp *qmp, const void *data, size_t len)
+{
+	return -ENODEV;
+}
+
+static inline struct qmp *qmp_get(struct device *dev)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline void qmp_put(struct qmp *qmp)
+{
+}
+
+#endif
+
+#endif
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-08-04 19:06 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-09 11:18 [PATCH v4 0/2] soc: qcom: aoss: Expose send for generic usecase Sibi Sankar
2021-06-09 11:18 ` [PATCH v4 1/2] " Sibi Sankar
2021-07-21  6:37   ` Stephen Boyd
2021-07-23  9:51     ` Deepak Kumar Singh
2021-07-23 19:28       ` Stephen Boyd
2021-06-09 11:18 ` [PATCH v4 2/2] soc: qcom: aoss: Add debugfs entry Sibi Sankar
2021-08-04 19:06   ` Bjorn Andersson
2021-06-14 10:21 [PATCH V4 0/2] soc: qcom: aoss: Expose send for generic usecase Deepak Kumar Singh
2021-06-14 10:21 ` [PATCH V4 1/2] " Deepak Kumar Singh

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.