All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eliav Farber <farbere@amazon.com>
To: Thomas Gleixner <tglx@kernel.org>, Talel Shenhar <talel@amazon.com>
Cc: Radu Rendec <radu@rendec.net>, Rob Herring <robh@kernel.org>,
	"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	"Eliav Farber" <farbere@amazon.com>, <devicetree@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>
Subject: [PATCH v2 4/8] irqchip/al-fic: switch to shared parent interrupt
Date: Sun, 27 Sep 2026 08:06:33 +0000	[thread overview]
Message-ID: <20260927080637.27285-5-farbere@amazon.com> (raw)
In-Reply-To: <20260927080637.27285-1-farbere@amazon.com>

Until now the driver requested its parent interrupt using the chained IRQ
API (irq_set_chained_handler_and_data()), which only works when each
parent interrupt is wired to a single FIC instance.

A FIC controller is built from groups, each described by its own DT node,
and the groups of one controller share that controller's output line
toward the parent. So a real devicetree has several FIC nodes on one
parent GIC SPI, and a chained handler can only be installed once per
parent. Cascading compounds this: an aggregating group collects several
peripherals' outputs onto the line above it.

To support that, request the parent interrupt as a shared interrupt
(IRQF_SHARED) instead of installing a chained handler. The handler now has
the standard irqreturn_t prototype and reports whether it handled any
child interrupt, so the shared-IRQ core can dispatch to the correct
instance. IRQF_NO_THREAD is set because the handler only demultiplexes to
the child domain and must not be forced-threaded; all instances sharing a
parent line agree on this flag, as the shared-IRQ core requires.

generic_handle_domain_irq() is retained for dispatch; its return value is
used to determine whether a pending child was actually handled so the
handler can return IRQ_HANDLED/IRQ_NONE correctly.

request_irq() can fail, unlike irq_set_chained_handler_and_data(), so add
an error path for it. It calls irq_domain_remove_generic_chips() before
irq_domain_remove(), because irq_domain_remove() frees the generic chips
only when the domain carries IRQ_DOMAIN_FLAG_DESTROY_GC.

Co-developed-by: Talel Shenhar <talel@amazon.com>
Signed-off-by: Talel Shenhar <talel@amazon.com>
Signed-off-by: Eliav Farber <farbere@amazon.com>
---
v2:
 - Fix the request_irq() error path: v1 called irq_free_generic_chip(gc),
   which is kfree(gc) on an interior pointer into the single allocation
   made by irq_domain_alloc_generic_chips() - an invalid free reachable
   when request_irq() fails at probe. Replace it with
   irq_domain_remove_generic_chips() before irq_domain_remove(), and add a
   commit-message paragraph explaining the teardown ordering.
 - Add Co-developed-by/Signed-off-by: Talel Shenhar.
 - Reworded to state the hardware reason for the shared parent (the groups
   of one controller share that controller's output line).

 drivers/irqchip/irq-al-fic.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/irqchip/irq-al-fic.c b/drivers/irqchip/irq-al-fic.c
index c7cc2631caf8..091a06abc0bb 100644
--- a/drivers/irqchip/irq-al-fic.c
+++ b/drivers/irqchip/irq-al-fic.c
@@ -4,9 +4,9 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/irqchip.h>
-#include <linux/irqchip/chained_irq.h>
 #include <linux/irqdomain.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -95,24 +95,24 @@ static int al_fic_irq_set_type(struct irq_data *data, unsigned int flow_type)
 	return 0;
 }
 
-static void al_fic_irq_handler(struct irq_desc *desc)
+static irqreturn_t al_fic_irq_handler(int irq, void *data)
 {
-	struct al_fic *fic = irq_desc_get_handler_data(desc);
+	struct al_fic *fic = data;
 	struct irq_domain *domain = fic->domain;
-	struct irq_chip *irqchip = irq_desc_get_chip(desc);
 	struct irq_chip_generic *gc = irq_get_domain_generic_chip(domain, 0);
+	irqreturn_t ret = IRQ_NONE;
 	unsigned long pending;
 	u32 hwirq;
 
-	chained_irq_enter(irqchip, desc);
-
 	pending = readl_relaxed(fic->base + AL_FIC_CAUSE);
 	pending &= ~gc->mask_cache;
 
-	for_each_set_bit(hwirq, &pending, NR_FIC_IRQS)
-		generic_handle_domain_irq(domain, hwirq);
+	for_each_set_bit(hwirq, &pending, NR_FIC_IRQS) {
+		if (!generic_handle_domain_irq(domain, hwirq))
+			ret = IRQ_HANDLED;
+	}
 
-	chained_irq_exit(irqchip, desc);
+	return ret;
 }
 
 static int al_fic_irq_retrigger(struct irq_data *data)
@@ -162,11 +162,18 @@ static int al_fic_register(struct device_node *node,
 	gc->chip_types->chip.flags = IRQCHIP_SKIP_SET_WAKE;
 	gc->private = fic;
 
-	irq_set_chained_handler_and_data(fic->parent_irq,
-					 al_fic_irq_handler,
-					 fic);
+	ret = request_irq(fic->parent_irq, al_fic_irq_handler,
+			  IRQF_NO_THREAD | IRQF_SHARED, fic->node->full_name,
+			  fic);
+	if (ret) {
+		pr_err("fail to request irq (%d)\n", ret);
+		goto err_remove_generic_chips;
+	}
+
 	return 0;
 
+err_remove_generic_chips:
+	irq_domain_remove_generic_chips(fic->domain);
 err_domain_remove:
 	irq_domain_remove(fic->domain);
 
-- 
2.47.3


  parent reply	other threads:[~2026-09-27  8:06 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-27  8:06 [PATCH v2 0/8] irqchip/al-fic: shared parent IRQ, error/fatal outputs and affinity Eliav Farber
2026-09-27  8:06 ` [PATCH v2 1/8] irqchip/al-fic: fix argument alignment and a repeated word Eliav Farber
2026-10-04 16:15   ` Radu Rendec
2026-09-27  8:06 ` [PATCH v2 2/8] irqchip/al-fic: use %pOF and raise init log level Eliav Farber
2026-10-04 16:25   ` Radu Rendec
2026-09-27  8:06 ` [PATCH v2 3/8] irqchip/al-fic: keep the device_node instead of a cached name string Eliav Farber
2026-10-04 17:40   ` Radu Rendec
2026-10-05 11:17     ` Farber, Eliav
2026-10-08  1:14       ` Radu Rendec
2026-09-27  8:06 ` Eliav Farber [this message]
2026-10-04 19:30   ` [PATCH v2 4/8] irqchip/al-fic: switch to shared parent interrupt Radu Rendec
2026-10-05 11:18     ` Farber, Eliav
2026-09-27  8:06 ` [PATCH v2 5/8] dt-bindings: interrupt-controller: amazon,al-fic: add mask selection Eliav Farber
2026-09-28 16:50   ` Conor Dooley
2026-10-04 21:06   ` Radu Rendec
2026-09-27  8:06 ` [PATCH v2 6/8] irqchip/al-fic: support error and fatal outputs and FIC v2 Eliav Farber
2026-10-05  1:01   ` Radu Rendec
2026-10-05 11:19     ` Farber, Eliav
2026-10-08  1:19       ` Radu Rendec
2026-10-08  8:20         ` Farber, Eliav
2026-09-27  8:06 ` [PATCH v2 7/8] irqchip/al-fic: add support for FIC v3 Eliav Farber
2026-10-05  1:04   ` Radu Rendec
2026-09-27  8:06 ` [PATCH v2 8/8] irqchip/al-fic: add irq_set_affinity callback Eliav Farber
2026-10-05  1:25   ` Radu Rendec
2026-10-05 11:20     ` Farber, Eliav

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=20260927080637.27285-5-farbere@amazon.com \
    --to=farbere@amazon.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=radu@rendec.net \
    --cc=robh@kernel.org \
    --cc=talel@amazon.com \
    --cc=tglx@kernel.org \
    /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 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.