linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/2] Start getting rid of the GPIO_NO_WAKE_IRQ
@ 2021-08-23  8:04 Maulik Shah
  2021-08-23  8:04 ` [PATCH v3 1/2] irqdomain: Export irq_domain_disconnect_hierarchy() Maulik Shah
  2021-08-23  8:04 ` [PATCH v3 2/2] irqchip/qcom-pdc: Start getting rid of the GPIO_NO_WAKE_IRQ Maulik Shah
  0 siblings, 2 replies; 5+ messages in thread
From: Maulik Shah @ 2021-08-23  8:04 UTC (permalink / raw)
  To: maz, tglx
  Cc: linux-kernel, linux-arm-msm, linux-gpio, bjorn.andersson,
	linus.walleij, tkjos, lsrao, Maulik Shah

v3:
- Address comment to call irq_domain_trim_hierarchy() once on v2 patch 3.
- Remove patch2 of v2 as seen no more needed.

v2:
- Use fix from marc [1] and drop v1 patch 2
- Add new patch for fixes irq_domain_trim_hierarchy()

gpio_to_irq() reports error at irq_domain_trim_hierarchy() for non wakeup
capable GPIOs that do not have dedicated interrupt at GIC.

Since PDC irqchip do not allocate irq at parent GIC domain for such GPIOs
indicate same by using irq_domain_disconnect_hierarchy() for it own domain
and all its parent domains.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?h=irq/qcom-pdc-nowake&id=331b2ba388a4a79b5c40b8addf56cbe35099a410
[2] https://patchwork.kernel.org/project/linux-arm-msm/list/?series=532669


Marc Zyngier (1):
  irqchip/qcom-pdc: Start getting rid of the GPIO_NO_WAKE_IRQ

Maulik Shah (1):
  irqdomain: Export irq_domain_disconnect_hierarchy()

 drivers/irqchip/qcom-pdc.c | 68 ++++++++--------------------------------------
 kernel/irq/irqdomain.c     |  1 +
 2 files changed, 12 insertions(+), 57 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


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

* [PATCH v3 1/2] irqdomain: Export irq_domain_disconnect_hierarchy()
  2021-08-23  8:04 [PATCH v3 0/2] Start getting rid of the GPIO_NO_WAKE_IRQ Maulik Shah
@ 2021-08-23  8:04 ` Maulik Shah
  2021-08-23  8:55   ` [irqchip: irq/irqchip-next] " irqchip-bot for Maulik Shah
  2021-08-23  8:04 ` [PATCH v3 2/2] irqchip/qcom-pdc: Start getting rid of the GPIO_NO_WAKE_IRQ Maulik Shah
  1 sibling, 1 reply; 5+ messages in thread
From: Maulik Shah @ 2021-08-23  8:04 UTC (permalink / raw)
  To: maz, tglx
  Cc: linux-kernel, linux-arm-msm, linux-gpio, bjorn.andersson,
	linus.walleij, tkjos, lsrao, Maulik Shah

Export irq_domain_disconnect_hierarchy() so irqchip module drivers
can use it.

Signed-off-by: Maulik Shah <mkshah@codeaurora.org>
---
 kernel/irq/irqdomain.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 0eee481..19e83e9 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -1216,6 +1216,7 @@ int irq_domain_disconnect_hierarchy(struct irq_domain *domain,
 	irqd->chip = ERR_PTR(-ENOTCONN);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(irq_domain_disconnect_hierarchy);
 
 static int irq_domain_trim_hierarchy(unsigned int virq)
 {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


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

* [PATCH v3 2/2] irqchip/qcom-pdc: Start getting rid of the GPIO_NO_WAKE_IRQ
  2021-08-23  8:04 [PATCH v3 0/2] Start getting rid of the GPIO_NO_WAKE_IRQ Maulik Shah
  2021-08-23  8:04 ` [PATCH v3 1/2] irqdomain: Export irq_domain_disconnect_hierarchy() Maulik Shah
@ 2021-08-23  8:04 ` Maulik Shah
  2021-08-23  8:55   ` [irqchip: irq/irqchip-next] irqchip/qcom-pdc: Trim unused levels of the interrupt hierarchy irqchip-bot for Marc Zyngier
  1 sibling, 1 reply; 5+ messages in thread
From: Maulik Shah @ 2021-08-23  8:04 UTC (permalink / raw)
  To: maz, tglx
  Cc: linux-kernel, linux-arm-msm, linux-gpio, bjorn.andersson,
	linus.walleij, tkjos, lsrao, Maulik Shah

From: Marc Zyngier <maz@kernel.org>

gpio_to_irq() reports error at irq_domain_trim_hierarchy() for non
wakeup capable GPIOs that do not have dedicated interrupt at GIC.

Since PDC irqchip do not allocate irq at parent GIC domain for such
GPIOs indicate same by using irq_domain_disconnect_hierarchy().

Replace qcom_pdc_gic_mask/unmask() and qcom_pdc_gic_get/set_irqchip_state()
with respective parent forward callbacks since all they were doing is to
check for valid irq and forward to parent.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Maulik Shah <mkshah@codeaurora.org>
Tested-by: Maulik Shah <mkshah@codeaurora.org>
---
 drivers/irqchip/qcom-pdc.c | 68 ++++++++--------------------------------------
 1 file changed, 11 insertions(+), 57 deletions(-)

diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c
index 32d5920..173e652 100644
--- a/drivers/irqchip/qcom-pdc.c
+++ b/drivers/irqchip/qcom-pdc.c
@@ -53,26 +53,6 @@ static u32 pdc_reg_read(int reg, u32 i)
 	return readl_relaxed(pdc_base + reg + i * sizeof(u32));
 }
 
-static int qcom_pdc_gic_get_irqchip_state(struct irq_data *d,
-					  enum irqchip_irq_state which,
-					  bool *state)
-{
-	if (d->hwirq == GPIO_NO_WAKE_IRQ)
-		return 0;
-
-	return irq_chip_get_parent_state(d, which, state);
-}
-
-static int qcom_pdc_gic_set_irqchip_state(struct irq_data *d,
-					  enum irqchip_irq_state which,
-					  bool value)
-{
-	if (d->hwirq == GPIO_NO_WAKE_IRQ)
-		return 0;
-
-	return irq_chip_set_parent_state(d, which, value);
-}
-
 static void pdc_enable_intr(struct irq_data *d, bool on)
 {
 	int pin_out = d->hwirq;
@@ -91,38 +71,16 @@ static void pdc_enable_intr(struct irq_data *d, bool on)
 
 static void qcom_pdc_gic_disable(struct irq_data *d)
 {
-	if (d->hwirq == GPIO_NO_WAKE_IRQ)
-		return;
-
 	pdc_enable_intr(d, false);
 	irq_chip_disable_parent(d);
 }
 
 static void qcom_pdc_gic_enable(struct irq_data *d)
 {
-	if (d->hwirq == GPIO_NO_WAKE_IRQ)
-		return;
-
 	pdc_enable_intr(d, true);
 	irq_chip_enable_parent(d);
 }
 
-static void qcom_pdc_gic_mask(struct irq_data *d)
-{
-	if (d->hwirq == GPIO_NO_WAKE_IRQ)
-		return;
-
-	irq_chip_mask_parent(d);
-}
-
-static void qcom_pdc_gic_unmask(struct irq_data *d)
-{
-	if (d->hwirq == GPIO_NO_WAKE_IRQ)
-		return;
-
-	irq_chip_unmask_parent(d);
-}
-
 /*
  * GIC does not handle falling edge or active low. To allow falling edge and
  * active low interrupts to be handled at GIC, PDC has an inverter that inverts
@@ -159,14 +117,10 @@ enum pdc_irq_config_bits {
  */
 static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
 {
-	int pin_out = d->hwirq;
 	enum pdc_irq_config_bits pdc_type;
 	enum pdc_irq_config_bits old_pdc_type;
 	int ret;
 
-	if (pin_out == GPIO_NO_WAKE_IRQ)
-		return 0;
-
 	switch (type) {
 	case IRQ_TYPE_EDGE_RISING:
 		pdc_type = PDC_EDGE_RISING;
@@ -191,8 +145,8 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
 		return -EINVAL;
 	}
 
-	old_pdc_type = pdc_reg_read(IRQ_i_CFG, pin_out);
-	pdc_reg_write(IRQ_i_CFG, pin_out, pdc_type);
+	old_pdc_type = pdc_reg_read(IRQ_i_CFG, d->hwirq);
+	pdc_reg_write(IRQ_i_CFG, d->hwirq, pdc_type);
 
 	ret = irq_chip_set_type_parent(d, type);
 	if (ret)
@@ -216,12 +170,12 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
 static struct irq_chip qcom_pdc_gic_chip = {
 	.name			= "PDC",
 	.irq_eoi		= irq_chip_eoi_parent,
-	.irq_mask		= qcom_pdc_gic_mask,
-	.irq_unmask		= qcom_pdc_gic_unmask,
+	.irq_mask		= irq_chip_mask_parent,
+	.irq_unmask		= irq_chip_unmask_parent,
 	.irq_disable		= qcom_pdc_gic_disable,
 	.irq_enable		= qcom_pdc_gic_enable,
-	.irq_get_irqchip_state	= qcom_pdc_gic_get_irqchip_state,
-	.irq_set_irqchip_state	= qcom_pdc_gic_set_irqchip_state,
+	.irq_get_irqchip_state	= irq_chip_get_parent_state,
+	.irq_set_irqchip_state	= irq_chip_set_parent_state,
 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
 	.irq_set_type		= qcom_pdc_gic_set_type,
 	.flags			= IRQCHIP_MASK_ON_SUSPEND |
@@ -282,7 +236,7 @@ static int qcom_pdc_alloc(struct irq_domain *domain, unsigned int virq,
 
 	parent_hwirq = get_parent_hwirq(hwirq);
 	if (parent_hwirq == PDC_NO_PARENT_IRQ)
-		return 0;
+		return irq_domain_disconnect_hierarchy(domain->parent, virq);
 
 	if (type & IRQ_TYPE_EDGE_BOTH)
 		type = IRQ_TYPE_EDGE_RISING;
@@ -319,17 +273,17 @@ static int qcom_pdc_gpio_alloc(struct irq_domain *domain, unsigned int virq,
 	if (ret)
 		return ret;
 
+	if (hwirq == GPIO_NO_WAKE_IRQ)
+		return irq_domain_disconnect_hierarchy(domain, virq);
+
 	ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
 					    &qcom_pdc_gic_chip, NULL);
 	if (ret)
 		return ret;
 
-	if (hwirq == GPIO_NO_WAKE_IRQ)
-		return 0;
-
 	parent_hwirq = get_parent_hwirq(hwirq);
 	if (parent_hwirq == PDC_NO_PARENT_IRQ)
-		return 0;
+		return irq_domain_disconnect_hierarchy(domain->parent, virq);
 
 	if (type & IRQ_TYPE_EDGE_BOTH)
 		type = IRQ_TYPE_EDGE_RISING;
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


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

* [irqchip: irq/irqchip-next] irqchip/qcom-pdc: Trim unused levels of the interrupt hierarchy
  2021-08-23  8:04 ` [PATCH v3 2/2] irqchip/qcom-pdc: Start getting rid of the GPIO_NO_WAKE_IRQ Maulik Shah
@ 2021-08-23  8:55   ` irqchip-bot for Marc Zyngier
  0 siblings, 0 replies; 5+ messages in thread
From: irqchip-bot for Marc Zyngier @ 2021-08-23  8:55 UTC (permalink / raw)
  To: linux-kernel; +Cc: Marc Zyngier, Maulik Shah, tglx

The following commit has been merged into the irq/irqchip-next branch of irqchip:

Commit-ID:     9d4f24bfe043274d9274bcfe223b901bd8fb7182
Gitweb:        https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms/9d4f24bfe043274d9274bcfe223b901bd8fb7182
Author:        Marc Zyngier <maz@kernel.org>
AuthorDate:    Mon, 23 Aug 2021 13:34:40 +05:30
Committer:     Marc Zyngier <maz@kernel.org>
CommitterDate: Mon, 23 Aug 2021 09:45:31 +01:00

irqchip/qcom-pdc: Trim unused levels of the interrupt hierarchy

The QCOM PDC driver creates a bunch of unnecessary levels in
the interrupt hierarchy when dealing with non-wakeup-capable
interrupts. By definition, these lines are terminated at the
PDC level, and everything below this is completely fake.

This also results in additional complexity as most of the
callbacks have to check for the validity of the parent level.
Needless to say, this doesn't look very good.

Solve this by disconnecting the interrupt hierarchy below
the last valid level, and considerably simplify the handling
of all the other interrupts by avoiding now unnecessary cheks.
In most cases, the standard irq_*_parent() handlers are directly
used.

This also cures an issue reporting by Maulik where gpio_to_irq()
returns an error after having observed a set of invalid levels.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Maulik Shah <mkshah@codeaurora.org>
Tested-by: Maulik Shah <mkshah@codeaurora.org>
Link: https://lore.kernel.org/r/1629705880-27877-3-git-send-email-mkshah@codeaurora.org
---
 drivers/irqchip/qcom-pdc.c | 68 +++++--------------------------------
 1 file changed, 11 insertions(+), 57 deletions(-)

diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c
index 32d5920..173e652 100644
--- a/drivers/irqchip/qcom-pdc.c
+++ b/drivers/irqchip/qcom-pdc.c
@@ -53,26 +53,6 @@ static u32 pdc_reg_read(int reg, u32 i)
 	return readl_relaxed(pdc_base + reg + i * sizeof(u32));
 }
 
-static int qcom_pdc_gic_get_irqchip_state(struct irq_data *d,
-					  enum irqchip_irq_state which,
-					  bool *state)
-{
-	if (d->hwirq == GPIO_NO_WAKE_IRQ)
-		return 0;
-
-	return irq_chip_get_parent_state(d, which, state);
-}
-
-static int qcom_pdc_gic_set_irqchip_state(struct irq_data *d,
-					  enum irqchip_irq_state which,
-					  bool value)
-{
-	if (d->hwirq == GPIO_NO_WAKE_IRQ)
-		return 0;
-
-	return irq_chip_set_parent_state(d, which, value);
-}
-
 static void pdc_enable_intr(struct irq_data *d, bool on)
 {
 	int pin_out = d->hwirq;
@@ -91,38 +71,16 @@ static void pdc_enable_intr(struct irq_data *d, bool on)
 
 static void qcom_pdc_gic_disable(struct irq_data *d)
 {
-	if (d->hwirq == GPIO_NO_WAKE_IRQ)
-		return;
-
 	pdc_enable_intr(d, false);
 	irq_chip_disable_parent(d);
 }
 
 static void qcom_pdc_gic_enable(struct irq_data *d)
 {
-	if (d->hwirq == GPIO_NO_WAKE_IRQ)
-		return;
-
 	pdc_enable_intr(d, true);
 	irq_chip_enable_parent(d);
 }
 
-static void qcom_pdc_gic_mask(struct irq_data *d)
-{
-	if (d->hwirq == GPIO_NO_WAKE_IRQ)
-		return;
-
-	irq_chip_mask_parent(d);
-}
-
-static void qcom_pdc_gic_unmask(struct irq_data *d)
-{
-	if (d->hwirq == GPIO_NO_WAKE_IRQ)
-		return;
-
-	irq_chip_unmask_parent(d);
-}
-
 /*
  * GIC does not handle falling edge or active low. To allow falling edge and
  * active low interrupts to be handled at GIC, PDC has an inverter that inverts
@@ -159,14 +117,10 @@ enum pdc_irq_config_bits {
  */
 static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
 {
-	int pin_out = d->hwirq;
 	enum pdc_irq_config_bits pdc_type;
 	enum pdc_irq_config_bits old_pdc_type;
 	int ret;
 
-	if (pin_out == GPIO_NO_WAKE_IRQ)
-		return 0;
-
 	switch (type) {
 	case IRQ_TYPE_EDGE_RISING:
 		pdc_type = PDC_EDGE_RISING;
@@ -191,8 +145,8 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
 		return -EINVAL;
 	}
 
-	old_pdc_type = pdc_reg_read(IRQ_i_CFG, pin_out);
-	pdc_reg_write(IRQ_i_CFG, pin_out, pdc_type);
+	old_pdc_type = pdc_reg_read(IRQ_i_CFG, d->hwirq);
+	pdc_reg_write(IRQ_i_CFG, d->hwirq, pdc_type);
 
 	ret = irq_chip_set_type_parent(d, type);
 	if (ret)
@@ -216,12 +170,12 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
 static struct irq_chip qcom_pdc_gic_chip = {
 	.name			= "PDC",
 	.irq_eoi		= irq_chip_eoi_parent,
-	.irq_mask		= qcom_pdc_gic_mask,
-	.irq_unmask		= qcom_pdc_gic_unmask,
+	.irq_mask		= irq_chip_mask_parent,
+	.irq_unmask		= irq_chip_unmask_parent,
 	.irq_disable		= qcom_pdc_gic_disable,
 	.irq_enable		= qcom_pdc_gic_enable,
-	.irq_get_irqchip_state	= qcom_pdc_gic_get_irqchip_state,
-	.irq_set_irqchip_state	= qcom_pdc_gic_set_irqchip_state,
+	.irq_get_irqchip_state	= irq_chip_get_parent_state,
+	.irq_set_irqchip_state	= irq_chip_set_parent_state,
 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
 	.irq_set_type		= qcom_pdc_gic_set_type,
 	.flags			= IRQCHIP_MASK_ON_SUSPEND |
@@ -282,7 +236,7 @@ static int qcom_pdc_alloc(struct irq_domain *domain, unsigned int virq,
 
 	parent_hwirq = get_parent_hwirq(hwirq);
 	if (parent_hwirq == PDC_NO_PARENT_IRQ)
-		return 0;
+		return irq_domain_disconnect_hierarchy(domain->parent, virq);
 
 	if (type & IRQ_TYPE_EDGE_BOTH)
 		type = IRQ_TYPE_EDGE_RISING;
@@ -319,17 +273,17 @@ static int qcom_pdc_gpio_alloc(struct irq_domain *domain, unsigned int virq,
 	if (ret)
 		return ret;
 
+	if (hwirq == GPIO_NO_WAKE_IRQ)
+		return irq_domain_disconnect_hierarchy(domain, virq);
+
 	ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
 					    &qcom_pdc_gic_chip, NULL);
 	if (ret)
 		return ret;
 
-	if (hwirq == GPIO_NO_WAKE_IRQ)
-		return 0;
-
 	parent_hwirq = get_parent_hwirq(hwirq);
 	if (parent_hwirq == PDC_NO_PARENT_IRQ)
-		return 0;
+		return irq_domain_disconnect_hierarchy(domain->parent, virq);
 
 	if (type & IRQ_TYPE_EDGE_BOTH)
 		type = IRQ_TYPE_EDGE_RISING;

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

* [irqchip: irq/irqchip-next] irqdomain: Export irq_domain_disconnect_hierarchy()
  2021-08-23  8:04 ` [PATCH v3 1/2] irqdomain: Export irq_domain_disconnect_hierarchy() Maulik Shah
@ 2021-08-23  8:55   ` irqchip-bot for Maulik Shah
  0 siblings, 0 replies; 5+ messages in thread
From: irqchip-bot for Maulik Shah @ 2021-08-23  8:55 UTC (permalink / raw)
  To: linux-kernel; +Cc: Maulik Shah, Marc Zyngier, tglx

The following commit has been merged into the irq/irqchip-next branch of irqchip:

Commit-ID:     131d326ba969847daa43d708ac11c27978d78566
Gitweb:        https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms/131d326ba969847daa43d708ac11c27978d78566
Author:        Maulik Shah <mkshah@codeaurora.org>
AuthorDate:    Mon, 23 Aug 2021 13:34:39 +05:30
Committer:     Marc Zyngier <maz@kernel.org>
CommitterDate: Mon, 23 Aug 2021 09:24:57 +01:00

irqdomain: Export irq_domain_disconnect_hierarchy()

Export irq_domain_disconnect_hierarchy() so irqchip module drivers
can use it.

Signed-off-by: Maulik Shah <mkshah@codeaurora.org>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/1629705880-27877-2-git-send-email-mkshah@codeaurora.org
---
 kernel/irq/irqdomain.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 51c483c..62be161 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -1215,6 +1215,7 @@ int irq_domain_disconnect_hierarchy(struct irq_domain *domain,
 	irqd->chip = ERR_PTR(-ENOTCONN);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(irq_domain_disconnect_hierarchy);
 
 static int irq_domain_trim_hierarchy(unsigned int virq)
 {

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

end of thread, other threads:[~2021-08-23  8:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-23  8:04 [PATCH v3 0/2] Start getting rid of the GPIO_NO_WAKE_IRQ Maulik Shah
2021-08-23  8:04 ` [PATCH v3 1/2] irqdomain: Export irq_domain_disconnect_hierarchy() Maulik Shah
2021-08-23  8:55   ` [irqchip: irq/irqchip-next] " irqchip-bot for Maulik Shah
2021-08-23  8:04 ` [PATCH v3 2/2] irqchip/qcom-pdc: Start getting rid of the GPIO_NO_WAKE_IRQ Maulik Shah
2021-08-23  8:55   ` [irqchip: irq/irqchip-next] irqchip/qcom-pdc: Trim unused levels of the interrupt hierarchy irqchip-bot for Marc Zyngier

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).