linux-arm-msm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Maulik Shah <mkshah@codeaurora.org>
To: bjorn.andersson@linaro.org, maz@kernel.org,
	linus.walleij@linaro.org, swboyd@chromium.org,
	evgreen@chromium.org, mka@chromium.org
Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
	linux-gpio@vger.kernel.org, agross@kernel.org,
	tglx@linutronix.de, jason@lakedaemon.net, dianders@chromium.org,
	rnayak@codeaurora.org, ilina@codeaurora.org,
	lsrao@codeaurora.org, Maulik Shah <mkshah@codeaurora.org>
Subject: [PATCH v4 3/7] genirq: Introduce irq_suspend_one() and irq_resume_one() callbacks
Date: Mon, 10 Aug 2020 16:50:56 +0530	[thread overview]
Message-ID: <1597058460-16211-4-git-send-email-mkshah@codeaurora.org> (raw)
In-Reply-To: <1597058460-16211-1-git-send-email-mkshah@codeaurora.org>

From: Douglas Anderson <dianders@chromium.org>

The "struct irq_chip" has two callbacks in it: irq_suspend() and
irq_resume().  These two callbacks are interesting because sometimes
an irq chip needs to know about suspend/resume, but they are a bit
awkward because:
1. They are called once for the whole irq_chip, not once per IRQ.
   It's passed data for one of the IRQs enabled on that chip.  That
   means it's up to the irq_chip driver to aggregate.
2. They are only called if you're using "generic-chip", which not
   everyone is.
3. The implementation uses syscore ops, which apparently have problems
   with s2idle.

Probably the old irq_suspend() and irq_resume() callbacks should be
deprecated.

Let's introcuce a nicer API that works for all irq_chip devices.  This
will be called by the core and is called once per IRQ.  The core will
call the suspend callback after doing its normal suspend operations
and the resume before its normal resume operations.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Maulik Shah <mkshah@codeaurora.org>
---
 include/linux/irq.h    | 13 +++++++++++--
 kernel/irq/chip.c      | 16 ++++++++++++++++
 kernel/irq/internals.h |  2 ++
 kernel/irq/pm.c        | 15 ++++++++++++---
 4 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index 1b7f4df..8d37b32 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -468,10 +468,16 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
  * @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips
  * @irq_cpu_online:	configure an interrupt source for a secondary CPU
  * @irq_cpu_offline:	un-configure an interrupt source for a secondary CPU
+ * @irq_suspend_one:	called on an every irq to suspend it; called even if
+ *			this IRQ is configured for wakeup
+ * @irq_resume_one:	called on an every irq to resume it; called even if
+ *			this IRQ is configured for wakeup
  * @irq_suspend:	function called from core code on suspend once per
- *			chip, when one or more interrupts are installed
+ *			chip, when one or more interrupts are installed;
+ *			only works if using irq/generic-chip
  * @irq_resume:		function called from core code on resume once per chip,
- *			when one ore more interrupts are installed
+ *			when one ore more interrupts are installed;
+ *			only works if using irq/generic-chip
  * @irq_pm_shutdown:	function called from core code on shutdown once per chip
  * @irq_calc_mask:	Optional function to set irq_data.mask for special cases
  * @irq_print_chip:	optional to print special chip info in show_interrupts
@@ -515,6 +521,9 @@ struct irq_chip {
 	void		(*irq_cpu_online)(struct irq_data *data);
 	void		(*irq_cpu_offline)(struct irq_data *data);
 
+	void		(*irq_suspend_one)(struct irq_data *data);
+	void		(*irq_resume_one)(struct irq_data *data);
+
 	void		(*irq_suspend)(struct irq_data *data);
 	void		(*irq_resume)(struct irq_data *data);
 	void		(*irq_pm_shutdown)(struct irq_data *data);
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 857f5f4..caf80c1 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -447,6 +447,22 @@ void unmask_threaded_irq(struct irq_desc *desc)
 	unmask_irq(desc);
 }
 
+void suspend_one_irq(struct irq_desc *desc)
+{
+	struct irq_chip *chip = desc->irq_data.chip;
+
+	if (chip->irq_suspend_one)
+		chip->irq_suspend_one(&desc->irq_data);
+}
+
+void resume_one_irq(struct irq_desc *desc)
+{
+	struct irq_chip *chip = desc->irq_data.chip;
+
+	if (chip->irq_resume_one)
+		chip->irq_resume_one(&desc->irq_data);
+}
+
 /*
  *	handle_nested_irq - Handle a nested irq from a irq thread
  *	@irq:	the interrupt number
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index 7db284b..11c2dac 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -90,6 +90,8 @@ extern void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu);
 extern void mask_irq(struct irq_desc *desc);
 extern void unmask_irq(struct irq_desc *desc);
 extern void unmask_threaded_irq(struct irq_desc *desc);
+extern void suspend_one_irq(struct irq_desc *desc);
+extern void resume_one_irq(struct irq_desc *desc);
 
 #ifdef CONFIG_SPARSE_IRQ
 static inline void irq_mark_irq(unsigned int irq) { }
diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c
index 8f557fa..b9e5338 100644
--- a/kernel/irq/pm.c
+++ b/kernel/irq/pm.c
@@ -69,19 +69,23 @@ void irq_pm_remove_action(struct irq_desc *desc, struct irqaction *action)
 
 static bool suspend_device_irq(struct irq_desc *desc)
 {
+	bool sync = false;
+
 	if (!desc->action || irq_desc_is_chained(desc) ||
 	    desc->no_suspend_depth)
-		return false;
+		goto exit;
 
 	if (irqd_is_wakeup_set(&desc->irq_data)) {
 		irqd_set(&desc->irq_data, IRQD_WAKEUP_ARMED);
+
 		/*
 		 * We return true here to force the caller to issue
 		 * synchronize_irq(). We need to make sure that the
 		 * IRQD_WAKEUP_ARMED is visible before we return from
 		 * suspend_device_irqs().
 		 */
-		return true;
+		sync = true;
+		goto exit;
 	}
 
 	desc->istate |= IRQS_SUSPENDED;
@@ -95,7 +99,10 @@ static bool suspend_device_irq(struct irq_desc *desc)
 	 */
 	if (irq_desc_get_chip(desc)->flags & IRQCHIP_MASK_ON_SUSPEND)
 		mask_irq(desc);
-	return true;
+
+exit:
+	suspend_one_irq(desc);
+	return sync;
 }
 
 /**
@@ -137,6 +144,8 @@ EXPORT_SYMBOL_GPL(suspend_device_irqs);
 
 static void resume_irq(struct irq_desc *desc)
 {
+	resume_one_irq(desc);
+
 	irqd_clear(&desc->irq_data, IRQD_WAKEUP_ARMED);
 
 	if (desc->istate & IRQS_SUSPENDED)
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


  parent reply	other threads:[~2020-08-10 11:24 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-10 11:20 [PATCH v4 0/7] irqchip: qcom: pdc: Introduce irq_set_wake call Maulik Shah
2020-08-10 11:20 ` [PATCH v4 1/7] pinctrl: qcom: Add msmgpio irqchip flags Maulik Shah
2020-08-11 19:32   ` Stephen Boyd
2020-08-13  5:47     ` Maulik Shah
2020-08-11 20:04   ` Doug Anderson
2020-08-10 11:20 ` [PATCH v4 2/7] pinctrl: qcom: Use return value from irq_set_wake call Maulik Shah
2020-08-11 19:34   ` Stephen Boyd
2020-08-11 20:06     ` Doug Anderson
2020-08-13  7:17     ` Maulik Shah
2020-08-13  7:21       ` Stephen Boyd
2020-08-27 22:46   ` Linus Walleij
2020-08-10 11:20 ` Maulik Shah [this message]
2020-08-11 20:09   ` [PATCH v4 3/7] genirq: Introduce irq_suspend_one() and irq_resume_one() callbacks Doug Anderson
2020-08-13  7:18     ` Maulik Shah
2020-08-13  9:29   ` Thomas Gleixner
2020-08-13 16:09     ` Doug Anderson
2020-08-13 22:09       ` Thomas Gleixner
2020-08-13 22:58         ` Doug Anderson
2020-08-14  2:07           ` Thomas Gleixner
2020-08-14  3:04             ` Doug Anderson
2020-08-14 12:43               ` Thomas Gleixner
2020-08-18  4:35           ` Maulik Shah
2020-08-18 14:40             ` Thomas Gleixner
2020-08-10 11:20 ` [PATCH v4 4/7] genirq: introduce irq_suspend_parent() and irq_resume_parent() Maulik Shah
2020-08-11 20:10   ` Doug Anderson
2020-08-13  7:19     ` Maulik Shah
2020-08-10 11:20 ` [PATCH v4 5/7] pinctrl: qcom: Call our parent for irq_suspend_one / irq_resume_one Maulik Shah
2020-08-10 11:20 ` [PATCH v4 6/7] irqchip: qcom-pdc: Unmask wake up irqs during suspend Maulik Shah
2020-08-10 11:21 ` [PATCH v4 7/7] irqchip: qcom-pdc: Reset all pdc interrupts during init Maulik Shah
2020-08-10 12:09   ` Felipe Balbi
2020-08-13  7:21     ` Maulik Shah
2020-08-11 21:31   ` Stephen Boyd
2020-08-13  7:30     ` Maulik Shah
2020-08-14 20:24       ` Stephen Boyd

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1597058460-16211-4-git-send-email-mkshah@codeaurora.org \
    --to=mkshah@codeaurora.org \
    --cc=agross@kernel.org \
    --cc=bjorn.andersson@linaro.org \
    --cc=dianders@chromium.org \
    --cc=evgreen@chromium.org \
    --cc=ilina@codeaurora.org \
    --cc=jason@lakedaemon.net \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lsrao@codeaurora.org \
    --cc=maz@kernel.org \
    --cc=mka@chromium.org \
    --cc=rnayak@codeaurora.org \
    --cc=swboyd@chromium.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).