diff mbox series

[V3,1/1] soc: qcom: smp2p: Add wakeup capability to SMP2P IRQ

Message ID 1631896288-17281-1-git-send-email-deesin@codeaurora.org (mailing list archive)
State Superseded
Headers show
Series [V3,1/1] soc: qcom: smp2p: Add wakeup capability to SMP2P IRQ | expand

Commit Message

Deepak Kumar Singh Sept. 17, 2021, 4:31 p.m. UTC
Remote susbsystems notify fatal crash throught smp2p interrupt.
When remoteproc crashes it can cause soc to come out of low power
state and may not allow again to enter in low power state until
crash is handled.

Mark smp2p interrupt wakeup capable so that interrupt handler is
executed and remoteproc crash can be handled in system  resume path.
This patch marks interrupt wakeup capable but keeps wakeup disabled
by default and leaves it to user space to enable it according to its
requirement.

Signed-off-by: Deepak Kumar Singh <deesin@codeaurora.org>
---
 drivers/soc/qcom/smp2p.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

Comments

kernel test robot Sept. 18, 2021, 4:09 a.m. UTC | #1
Hi Deepak,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v5.15-rc1 next-20210917]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Deepak-Kumar-Singh/soc-qcom-smp2p-Add-wakeup-capability-to-SMP2P-IRQ/20210918-003323
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git bdb575f872175ed0ecf2638369da1cb7a6e86a14
config: riscv-randconfig-r033-20210918 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project c8b3d7d6d6de37af68b2f379d0e37304f78e115f)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/0day-ci/linux/commit/22bbf691312dc17d566e752b888dfbc6b14b671f
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Deepak-Kumar-Singh/soc-qcom-smp2p-Add-wakeup-capability-to-SMP2P-IRQ/20210918-003323
        git checkout 22bbf691312dc17d566e752b888dfbc6b14b671f
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/soc/qcom/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/soc/qcom/smp2p.c:555:3: error: use of undeclared identifier 'set_wake_irq_fail'
                   set_wake_irq_fail;
                   ^
   1 error generated.


vim +/set_wake_irq_fail +555 drivers/soc/qcom/smp2p.c

   443	
   444	static int qcom_smp2p_probe(struct platform_device *pdev)
   445	{
   446		struct smp2p_entry *entry;
   447		struct device_node *node;
   448		struct qcom_smp2p *smp2p;
   449		const char *key;
   450		int irq;
   451		int ret;
   452	
   453		smp2p = devm_kzalloc(&pdev->dev, sizeof(*smp2p), GFP_KERNEL);
   454		if (!smp2p)
   455			return -ENOMEM;
   456	
   457		smp2p->dev = &pdev->dev;
   458		INIT_LIST_HEAD(&smp2p->inbound);
   459		INIT_LIST_HEAD(&smp2p->outbound);
   460	
   461		platform_set_drvdata(pdev, smp2p);
   462	
   463		key = "qcom,smem";
   464		ret = of_property_read_u32_array(pdev->dev.of_node, key,
   465						 smp2p->smem_items, 2);
   466		if (ret)
   467			return ret;
   468	
   469		key = "qcom,local-pid";
   470		ret = of_property_read_u32(pdev->dev.of_node, key, &smp2p->local_pid);
   471		if (ret)
   472			goto report_read_failure;
   473	
   474		key = "qcom,remote-pid";
   475		ret = of_property_read_u32(pdev->dev.of_node, key, &smp2p->remote_pid);
   476		if (ret)
   477			goto report_read_failure;
   478	
   479		irq = platform_get_irq(pdev, 0);
   480		if (irq < 0)
   481			return irq;
   482	
   483		smp2p->mbox_client.dev = &pdev->dev;
   484		smp2p->mbox_client.knows_txdone = true;
   485		smp2p->mbox_chan = mbox_request_channel(&smp2p->mbox_client, 0);
   486		if (IS_ERR(smp2p->mbox_chan)) {
   487			if (PTR_ERR(smp2p->mbox_chan) != -ENODEV)
   488				return PTR_ERR(smp2p->mbox_chan);
   489	
   490			smp2p->mbox_chan = NULL;
   491	
   492			ret = smp2p_parse_ipc(smp2p);
   493			if (ret)
   494				return ret;
   495		}
   496	
   497		ret = qcom_smp2p_alloc_outbound_item(smp2p);
   498		if (ret < 0)
   499			goto release_mbox;
   500	
   501		for_each_available_child_of_node(pdev->dev.of_node, node) {
   502			entry = devm_kzalloc(&pdev->dev, sizeof(*entry), GFP_KERNEL);
   503			if (!entry) {
   504				ret = -ENOMEM;
   505				goto unwind_interfaces;
   506			}
   507	
   508			entry->smp2p = smp2p;
   509			spin_lock_init(&entry->lock);
   510	
   511			ret = of_property_read_string(node, "qcom,entry-name", &entry->name);
   512			if (ret < 0)
   513				goto unwind_interfaces;
   514	
   515			if (of_property_read_bool(node, "interrupt-controller")) {
   516				ret = qcom_smp2p_inbound_entry(smp2p, entry, node);
   517				if (ret < 0)
   518					goto unwind_interfaces;
   519	
   520				list_add(&entry->node, &smp2p->inbound);
   521			} else  {
   522				ret = qcom_smp2p_outbound_entry(smp2p, entry, node);
   523				if (ret < 0)
   524					goto unwind_interfaces;
   525	
   526				list_add(&entry->node, &smp2p->outbound);
   527			}
   528		}
   529	
   530		/* Kick the outgoing edge after allocating entries */
   531		qcom_smp2p_kick(smp2p);
   532	
   533		ret = devm_request_threaded_irq(&pdev->dev, irq,
   534						NULL, qcom_smp2p_intr,
   535						IRQF_ONESHOT,
   536						"smp2p", (void *)smp2p);
   537		if (ret) {
   538			dev_err(&pdev->dev, "failed to request interrupt\n");
   539			goto unwind_interfaces;
   540		}
   541	
   542		/*
   543		 * Treat smp2p interrupt as wakeup source, but keep it disabled
   544		 * by default. User space can decide enabling it depending on its
   545		 * use cases. For example if remoteproc crashes and device wants
   546		 * to handle it immediatedly (e.g. to not miss phone calls) it can
   547		 * enable wakeup source from user space, while other devices which
   548		 * do not have proper autosleep feature may want to handle it with
   549		 * other wakeup events (e.g. Power button) instead waking up immediately.
   550		 */
   551		device_set_wakeup_capable(&pdev->dev, true);
   552	
   553		ret = dev_pm_set_wake_irq(&pdev->dev, irq);
   554		if (ret)
 > 555			set_wake_irq_fail;
   556	
   557		return 0;
   558	
   559	set_wake_irq_fail:
   560		dev_pm_clear_wake_irq(&pdev->dev);
   561	
   562	unwind_interfaces:
   563		list_for_each_entry(entry, &smp2p->inbound, node)
   564			irq_domain_remove(entry->domain);
   565	
   566		list_for_each_entry(entry, &smp2p->outbound, node)
   567			qcom_smem_state_unregister(entry->state);
   568	
   569		smp2p->out->valid_entries = 0;
   570	
   571	release_mbox:
   572		mbox_free_channel(smp2p->mbox_chan);
   573	
   574		return ret;
   575	
   576	report_read_failure:
   577		dev_err(&pdev->dev, "failed to read %s\n", key);
   578		return -EINVAL;
   579	}
   580	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c
index 2df4883..5f8ba96 100644
--- a/drivers/soc/qcom/smp2p.c
+++ b/drivers/soc/qcom/smp2p.c
@@ -14,6 +14,7 @@ 
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/pm_wakeirq.h>
 #include <linux/regmap.h>
 #include <linux/soc/qcom/smem.h>
 #include <linux/soc/qcom/smem_state.h>
@@ -538,9 +539,26 @@  static int qcom_smp2p_probe(struct platform_device *pdev)
 		goto unwind_interfaces;
 	}
 
+	/*
+	 * Treat smp2p interrupt as wakeup source, but keep it disabled
+	 * by default. User space can decide enabling it depending on its
+	 * use cases. For example if remoteproc crashes and device wants
+	 * to handle it immediatedly (e.g. to not miss phone calls) it can
+	 * enable wakeup source from user space, while other devices which
+	 * do not have proper autosleep feature may want to handle it with
+	 * other wakeup events (e.g. Power button) instead waking up immediately.
+	 */
+	device_set_wakeup_capable(&pdev->dev, true);
+
+	ret = dev_pm_set_wake_irq(&pdev->dev, irq);
+	if (ret)
+		set_wake_irq_fail;
 
 	return 0;
 
+set_wake_irq_fail:
+	dev_pm_clear_wake_irq(&pdev->dev);
+
 unwind_interfaces:
 	list_for_each_entry(entry, &smp2p->inbound, node)
 		irq_domain_remove(entry->domain);
@@ -565,6 +583,9 @@  static int qcom_smp2p_remove(struct platform_device *pdev)
 	struct qcom_smp2p *smp2p = platform_get_drvdata(pdev);
 	struct smp2p_entry *entry;
 
+	dev_pm_clear_wake_irq(&pdev->dev);
+	device_init_wakeup(&pdev->dev, false);
+
 	list_for_each_entry(entry, &smp2p->inbound, node)
 		irq_domain_remove(entry->domain);