Commit de4adddc authored by Marc Zyngier's avatar Marc Zyngier Committed by Rob Herring
Browse files

of/irq: Add a quirk for controllers with their own definition of interrupt-map



Since commit 04128418 ("of/irq: Allow matching of an interrupt-map
local to an interrupt controller"), a handful of interrupt controllers
have stopped working correctly. This is due to the DT exposing a
non-sensical interrupt-map property, and their drivers relying on the
kernel ignoring this property.

Since we cannot realistically fix this terrible behaviour, add a quirk
for the limited set of devices that have implemented this monster,
and document that this is a pretty bad practice.

Fixes: 04128418 ("of/irq: Allow matching of an interrupt-map local to an interrupt controller")
Cc: Rob Herring <robh@kernel.org>
Cc: John Crispin <john@phrozen.org>
Cc: Biwen Li <biwen.li@nxp.com>
Cc: Chris Brandt <chris.brandt@renesas.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Sander Vanheule <sander@svanheule.net>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Tested-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/20211201114102.13446-1-maz@kernel.org


Signed-off-by: default avatarRob Herring <robh@kernel.org>
parent cc5faf26
Loading
Loading
Loading
Loading
+25 −2
Original line number Diff line number Diff line
@@ -76,6 +76,26 @@ struct device_node *of_irq_find_parent(struct device_node *child)
}
EXPORT_SYMBOL_GPL(of_irq_find_parent);

/*
 * These interrupt controllers abuse interrupt-map for unspeakable
 * reasons and rely on the core code to *ignore* it (the drivers do
 * their own parsing of the property).
 *
 * If you think of adding to the list for something *new*, think
 * again. There is a high chance that you will be sent back to the
 * drawing board.
 */
static const char * const of_irq_imap_abusers[] = {
	"CBEA,platform-spider-pic",
	"sti,platform-spider-pic",
	"realtek,rtl-intc",
	"fsl,ls1021a-extirq",
	"fsl,ls1043a-extirq",
	"fsl,ls1088a-extirq",
	"renesas,rza1-irqc",
	NULL,
};

/**
 * of_irq_parse_raw - Low level interrupt tree parsing
 * @addr:	address specifier (start of "reg" property of the device) in be32 format
@@ -159,12 +179,15 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
		/*
		 * Now check if cursor is an interrupt-controller and
		 * if it is then we are done, unless there is an
		 * interrupt-map which takes precedence.
		 * interrupt-map which takes precedence except on one
		 * of these broken platforms that want to parse
		 * interrupt-map themselves for $reason.
		 */
		bool intc = of_property_read_bool(ipar, "interrupt-controller");

		imap = of_get_property(ipar, "interrupt-map", &imaplen);
		if (imap == NULL && intc) {
		if (intc &&
		    (!imap || of_device_compatible_match(ipar, of_irq_imap_abusers))) {
			pr_debug(" -> got it !\n");
			return 0;
		}