From patchwork Thu Dec 23 12:08:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sander Vanheule X-Patchwork-Id: 527520 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B6DEDC433EF for ; Thu, 23 Dec 2021 12:08:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348149AbhLWMI5 (ORCPT ); Thu, 23 Dec 2021 07:08:57 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42640 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243421AbhLWMIx (ORCPT ); Thu, 23 Dec 2021 07:08:53 -0500 Received: from polaris.svanheule.net (polaris.svanheule.net [IPv6:2a00:c98:2060:a004:1::200]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ECD0BC061756 for ; Thu, 23 Dec 2021 04:08:51 -0800 (PST) Received: from terra.local.svanheule.net (unknown [IPv6:2a02:a03f:eafe:c901:29a7:866a:cac1:4c27]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: sander@svanheule.net) by polaris.svanheule.net (Postfix) with ESMTPSA id 670BF2866B2; Thu, 23 Dec 2021 13:08:49 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=svanheule.net; s=mail1707; t=1640261329; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TpkkGK1HUml0mP08FJk1cHUKfwB7mgaDR1xVUUyYboc=; b=snCbznz6B9FyJgvGHi3VI9smwgA1jzayACciJr7gSexY24/+75qZXVGCc0146QU9A6D9SS gYPYOSeMHXNKYowYDUAgIpOv2+wE4seN7Cw1wHa1EGDVmdqQE8FaAyM0fp6yA1bJmMzpz2 6rdOs+dcUPZWDenYMjOg/duhZrusTTuMSgxFm+yHr+jI0BslyIJrHzBafSCEjGlSVrCXfN F0gMq3JuBHaqWVsrDYk24ELXV8rjq3p1fzw/G3lR/gcyLb80P7mf5ODNJnJIWPsE5HnO30 K89luZAsy3xetCImy2VKqhBAeIY/gV0INDPnb1AjAp/vqt9YepL1tzJqF1S5vQ== From: Sander Vanheule To: Thomas Gleixner , Marc Zyngier , devicetree@vger.kernel.org Cc: Rob Herring , Birger Koblitz , Bert Vermeulen , John Crispin , linux-kernel@vger.kernel.org, Sander Vanheule Subject: [RFC PATCH v1 1/4] irqchip: realtek-rtl: map control data to virq Date: Thu, 23 Dec 2021 13:08:31 +0100 Message-Id: <7f89a2ed75482b8d1d8469d2c6bfd479aba07b9f.1640261161.git.sander@svanheule.net> X-Mailer: git-send-email 2.33.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The driver assigned the irqchip and irq handler to the hardware irq, instead of the virq. This is incorrect, and only worked because these irq numbers happened to be the same on the devices used for testing the original driver. Fixes: 9f3a0f34b84a ("irqchip: Add support for Realtek RTL838x/RTL839x interrupt controller") Signed-off-by: Sander Vanheule --- drivers/irqchip/irq-realtek-rtl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-realtek-rtl.c b/drivers/irqchip/irq-realtek-rtl.c index fd9f275592d2..d6788dd93c7b 100644 --- a/drivers/irqchip/irq-realtek-rtl.c +++ b/drivers/irqchip/irq-realtek-rtl.c @@ -62,7 +62,7 @@ static struct irq_chip realtek_ictl_irq = { static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { - irq_set_chip_and_handler(hw, &realtek_ictl_irq, handle_level_irq); + irq_set_chip_and_handler(irq, &realtek_ictl_irq, handle_level_irq); return 0; } From patchwork Thu Dec 23 12:08:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sander Vanheule X-Patchwork-Id: 527828 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5048FC433FE for ; Thu, 23 Dec 2021 12:09:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348151AbhLWMI7 (ORCPT ); Thu, 23 Dec 2021 07:08:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42642 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348141AbhLWMIx (ORCPT ); Thu, 23 Dec 2021 07:08:53 -0500 Received: from polaris.svanheule.net (polaris.svanheule.net [IPv6:2a00:c98:2060:a004:1::200]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1B744C061757 for ; Thu, 23 Dec 2021 04:08:52 -0800 (PST) Received: from terra.local.svanheule.net (unknown [IPv6:2a02:a03f:eafe:c901:29a7:866a:cac1:4c27]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: sander@svanheule.net) by polaris.svanheule.net (Postfix) with ESMTPSA id 01B3D2866B3; Thu, 23 Dec 2021 13:08:49 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=svanheule.net; s=mail1707; t=1640261330; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=RyaYwva3N7ECDReF1XQQxThXmMLdzOhp3IrMxCfNMtg=; b=3jCetYy93cDkmJ+j9HaPweK+CI5QCIcF1NA8uTeOIsi3gEXDJ6TOgfMmkN+z/UiWLKzBRK snMSq84yzuykuo/nCtIjt0zsGsRy2B6x78XfEFbdNNlJKGG9VFithHwG+FBZBznC6ufDSC YDtW3bDLB8htHyOQYqUE062UcxKER+jzHdg5mZMWsw/EwJr6KWvVSsyYAaYPH9wVdwmcUM uQ96xmFXJvMvvxD0tJ+wBn5KN072uRjyNvBLstgGLkikAHebhUMqBvtk4452WCKqeGuXqU 0YSFtA6GP00nJp0gcZ14z4hkdYC4CDJ8S9sCW7A/6k/sW+rdBkBaXZa18S5Ccw== From: Sander Vanheule To: Thomas Gleixner , Marc Zyngier , devicetree@vger.kernel.org Cc: Rob Herring , Birger Koblitz , Bert Vermeulen , John Crispin , linux-kernel@vger.kernel.org, Sander Vanheule Subject: [RFC PATCH v1 2/4] irqchip: realtek-rtl: use per-parent irq handling Date: Thu, 23 Dec 2021 13:08:32 +0100 Message-Id: <81bebcf62dfdc63155a69c3bdb2acefe4f5995ac.1640261161.git.sander@svanheule.net> X-Mailer: git-send-email 2.33.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The interrupt router controller is used to route 32 SoC interrupts to up to 6 MIPS CPU interrupts. This means that the SoC interrupts inherit the priority of to the target CPU interrupt. Currently the driver handles all SoC interrupts equally, independent of which CPU interrupt it is routed to. The use of __ffs actually gives higher priority to lower IRQ lines, effectively bypassing the CPU interrupt priority. Additionally, this indiscriminate handling of SoC interrupts masked another issue. There is an actually an offset between routing values (1..6) and CPU interrupts (2..7), but the current mapping makes no distinction between these two values. This issue was also hidden during testing, because an interrupt mapping was used where for each required interrupt another (unused) routing was configured, with an offset of +1. Rework the driver to use a separate handler for each used CPU interrupt, and use the correct routing values. Instead of assuming that the parent interrupt controller is the MIPS CPU interrupt controller ("mti,cpu-interrupt-controller"), this is now checked explicitly to correctly handle the timer interrupt. Fixes: 9f3a0f34b84a ("irqchip: Add support for Realtek RTL838x/RTL839x interrupt controller") Signed-off-by: Sander Vanheule --- This patch makes a few changes at the same time, and introduces the *_irr functions, which aren't strictly required. This allows the last patch to be a bit smaller, and seeks to add some clarity to the code. Please let me know if this should be split into separate patches with more incremental changes (in addition to other likely comments). --- drivers/irqchip/irq-realtek-rtl.c | 153 +++++++++++++++++++++--------- 1 file changed, 108 insertions(+), 45 deletions(-) diff --git a/drivers/irqchip/irq-realtek-rtl.c b/drivers/irqchip/irq-realtek-rtl.c index d6788dd93c7b..71366f1cf721 100644 --- a/drivers/irqchip/irq-realtek-rtl.c +++ b/drivers/irqchip/irq-realtek-rtl.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -21,10 +22,43 @@ #define RTL_ICTL_IRR2 0x10 #define RTL_ICTL_IRR3 0x14 -#define REG(x) (realtek_ictl_base + x) +#define RTL_ICTL_NUM_PRIO 6 + +#define REG(x) (realtek_ictl_base + x) static DEFINE_RAW_SPINLOCK(irq_lock); static void __iomem *realtek_ictl_base; +static struct irq_domain *realtek_ictl_domain; + +struct realtek_ictl_priority { + unsigned int routing_value; + u32 child_mask; +}; + +static struct realtek_ictl_priority priorities[RTL_ICTL_NUM_PRIO]; + +/* + * IRR0-IRR3 store 4 bits per interrupt, but Realtek uses inverted + * numbering, placing IRQ 31 in the first four bits. + */ +#define IRR_OFFSET(idx) (4 * (3 - (idx * 4) / 32)) +#define IRR_SHIFT(idx) ((idx * 4) % 32) + +static inline u32 read_irr(void __iomem *irr0, int idx) +{ + return (readl(irr0 + IRR_OFFSET(idx)) >> IRR_SHIFT(idx)) & 0xf; +} + +static inline void write_irr(void __iomem *irr0, int idx, u32 value) +{ + unsigned int offset = IRR_OFFSET(idx); + unsigned int shift = IRR_SHIFT(idx); + u32 irr; + + irr = readl(irr0 + offset) & ~(0xf << shift); + irr |= (value & 0xf) << shift; + writel(irr, irr0 + offset); +} static void realtek_ictl_unmask_irq(struct irq_data *i) { @@ -72,43 +106,67 @@ static const struct irq_domain_ops irq_domain_ops = { .xlate = irq_domain_xlate_onecell, }; -static void realtek_irq_dispatch(struct irq_desc *desc) +static irqreturn_t realtek_irq_dispatch(int irq, void *devid) { - struct irq_chip *chip = irq_desc_get_chip(desc); - struct irq_domain *domain; - unsigned int pending; - - chained_irq_enter(chip, desc); - pending = readl(REG(RTL_ICTL_GIMR)) & readl(REG(RTL_ICTL_GISR)); - if (unlikely(!pending)) { - spurious_interrupt(); - goto out; + struct realtek_ictl_priority *priority = devid; + unsigned long pending; + int soc_irq; + int ret = 0; + + pending = readl(REG(RTL_ICTL_GIMR)) & readl(REG(RTL_ICTL_GISR)) + & priority->child_mask; + + for_each_set_bit(soc_irq, &pending, BITS_PER_LONG) { + generic_handle_domain_irq(realtek_ictl_domain, soc_irq); + ret = 1; } - domain = irq_desc_get_handler_data(desc); - generic_handle_domain_irq(domain, __ffs(pending)); -out: - chained_irq_exit(chip, desc); + return IRQ_RETVAL(ret); } -/* - * SoC interrupts are cascaded to MIPS CPU interrupts according to the - * interrupt-map in the device tree. Each SoC interrupt gets 4 bits for - * the CPU interrupt in an Interrupt Routing Register. Max 32 SoC interrupts - * thus go into 4 IRRs. - */ -static int __init map_interrupts(struct device_node *node, struct irq_domain *domain) +static void __init set_routing(struct realtek_ictl_priority *priority, unsigned int soc_int) { + unsigned int priority_old; + + priority_old = read_irr(REG(RTL_ICTL_IRR0), soc_int); + if (priority_old) { + pr_warn("int %d already routed to %d, not updating\n", soc_int, priority_old); + return; + } + + priority->child_mask |= BIT(soc_int); + write_irr(REG(RTL_ICTL_IRR0), soc_int, priority->routing_value); +} + +static int __init setup_parent_interrupt(struct realtek_ictl_priority *prio_ctl, int parent) +{ + struct device_node *parent_node; + struct irq_data *irqd; + unsigned int flags; + int parent_hwirq; + + irqd = irq_get_irq_data(parent); + if (!irqd) + return -ENOENT; + + parent_node = to_of_node(irqd->domain->fwnode); + parent_hwirq = irqd_to_hwirq(irqd); + + flags = IRQF_PERCPU | IRQF_SHARED; + if (of_device_is_compatible(parent_node, "mti,cpu-interrupt-controller") + && parent_hwirq == 7) + flags |= IRQF_TIMER; + + return request_irq(parent, realtek_irq_dispatch, flags, "rtl-intc", prio_ctl); +} + +static int __init map_interrupts(struct device_node *node) +{ + struct realtek_ictl_priority *prio_ctl; struct device_node *cpu_ictl; const __be32 *imap; - u32 imaplen, soc_int, cpu_int, tmp, regs[4]; - int ret, i, irr_regs[] = { - RTL_ICTL_IRR3, - RTL_ICTL_IRR2, - RTL_ICTL_IRR1, - RTL_ICTL_IRR0, - }; - u8 mips_irqs_set; + u32 imaplen, soc_int, priority, tmp; + int ret, i; ret = of_property_read_u32(node, "#address-cells", &tmp); if (ret || tmp) @@ -118,8 +176,6 @@ static int __init map_interrupts(struct device_node *node, struct irq_domain *do if (!imap || imaplen % 3) return -EINVAL; - mips_irqs_set = 0; - memset(regs, 0, sizeof(regs)); for (i = 0; i < imaplen; i += 3 * sizeof(u32)) { soc_int = be32_to_cpup(imap); if (soc_int > 31) @@ -133,42 +189,49 @@ static int __init map_interrupts(struct device_node *node, struct irq_domain *do return -EINVAL; of_node_put(cpu_ictl); - cpu_int = be32_to_cpup(imap + 2); - if (cpu_int > 7) + /* Map priority (1..6) to MIPS CPU interrupt (2..7) */ + priority = be32_to_cpup(imap + 2); + if (priority > 6 || priority < 1) return -EINVAL; - if (!(mips_irqs_set & BIT(cpu_int))) { - irq_set_chained_handler_and_data(cpu_int, realtek_irq_dispatch, - domain); - mips_irqs_set |= BIT(cpu_int); + prio_ctl = &priorities[priority - 1]; + + if (!prio_ctl->routing_value) { + ret = setup_parent_interrupt(prio_ctl, priority + 1); + if (ret) + return ret; + + prio_ctl->routing_value = priority; } - regs[(soc_int * 4) / 32] |= cpu_int << (soc_int * 4) % 32; + set_routing(prio_ctl, soc_int); + imap += 3; } - for (i = 0; i < 4; i++) - writel(regs[i], REG(irr_regs[i])); return 0; } static int __init realtek_rtl_of_init(struct device_node *node, struct device_node *parent) { - struct irq_domain *domain; + unsigned int soc_irq; int ret; + memset(&priorities, 0, sizeof(priorities)); + realtek_ictl_base = of_iomap(node, 0); if (!realtek_ictl_base) return -ENXIO; /* Disable all cascaded interrupts */ writel(0, REG(RTL_ICTL_GIMR)); + for (soc_irq = 0; soc_irq < 32; soc_irq++) + write_irr(REG(RTL_ICTL_IRR0), soc_irq, 0); - domain = irq_domain_add_simple(node, 32, 0, - &irq_domain_ops, NULL); + realtek_ictl_domain = irq_domain_add_simple(node, 32, 0, &irq_domain_ops, NULL); - ret = map_interrupts(node, domain); + ret = map_interrupts(node); if (ret) { pr_err("invalid interrupt map\n"); return ret; From patchwork Thu Dec 23 12:08:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sander Vanheule X-Patchwork-Id: 527519 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7DA99C433EF for ; Thu, 23 Dec 2021 12:09:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348139AbhLWMJA (ORCPT ); Thu, 23 Dec 2021 07:09:00 -0500 Received: from polaris.svanheule.net ([84.16.241.116]:41762 "EHLO polaris.svanheule.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233851AbhLWMIy (ORCPT ); Thu, 23 Dec 2021 07:08:54 -0500 Received: from terra.local.svanheule.net (unknown [IPv6:2a02:a03f:eafe:c901:29a7:866a:cac1:4c27]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: sander@svanheule.net) by polaris.svanheule.net (Postfix) with ESMTPSA id 6A9252866B4; Thu, 23 Dec 2021 13:08:50 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=svanheule.net; s=mail1707; t=1640261330; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=N3Mn3xMvrNsKG9t4FirRIQpmR0nVLWUMlv6hgLgUkJg=; b=BiCxdQ77GN1gvGMuSb+7oYUL2r4KE8593nrHE6IP8/Ao+7SImTS4OFm3IlobVBILxm0YzU T+JW/i5/U06V9HeGMdkFWSWJI0czmS0SxFJbg6qA3Kb+z0CXjHuZL0CHQea1FHtdA0JB9N DRry3YOo1UqiWJUxOltrVvH/tDMhe8/+lK8WvhKSvVXxX5Uc+OECFydAU4RNrOgkbH0gma A0F/Va2Vv/IZYH8g0Oj3i6JlwYf/fQzkJa+rq/UNZT2iVTMkRm0etTDARyQQ+uBnzG6vf8 vdqzg9RZDK0V9RtbghiIIOu/Zh9QACBKa+nKra8G5iiTvT+RXFeloGMvpOyq+w== From: Sander Vanheule To: Thomas Gleixner , Marc Zyngier , devicetree@vger.kernel.org Cc: Rob Herring , Birger Koblitz , Bert Vermeulen , John Crispin , linux-kernel@vger.kernel.org, Sander Vanheule Subject: [RFC PATCH v1 3/4] dt-bindings: interrupt-controller: realtek,rtl-intc: replace irq mapping Date: Thu, 23 Dec 2021 13:08:33 +0100 Message-Id: <8a5931f18a6f1c92f8c8e4965dc65674d7e5a4c4.1640261161.git.sander@svanheule.net> X-Mailer: git-send-email 2.33.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The binding incorrectly specified the "interrupt-map" property should be used, although the use is non-standard. A quirk had to be introduced in commit de4adddcbcc2 ("of/irq: Add a quirk for controllers with their own definition of interrupt-map") to allow the driver to function again. Update the binding to require a list of parent interrupts instead, and replace the "interrupt-map" property by the custom "realtek,interrupt-routing" property. Signed-off-by: Sander Vanheule --- The registers for this interrupt controller have 4 bits per SoC interrupt. This means that, in theory, 15 output interrupts could be wired up (a value of 0 means 'disconnected'), but we have only ever seen this router being used to map to the six MIPS CPU hardware interrupts. --- .../realtek,rtl-intc.yaml | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/Documentation/devicetree/bindings/interrupt-controller/realtek,rtl-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/realtek,rtl-intc.yaml index 9e76fff20323..4f7f30111a8e 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/realtek,rtl-intc.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/realtek,rtl-intc.yaml @@ -6,6 +6,11 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Realtek RTL SoC interrupt controller devicetree bindings +description: + Interrupt router for Realtek MIPS SoCs, allowing up to 32 SoC interrupts to + be routed to one of up to 15 parent interrupts, or left disconnected. Most + commonly, the CPU's six hardware interrupts are used as parent interrupts. + maintainers: - Birger Koblitz - Bert Vermeulen @@ -15,30 +20,40 @@ properties: compatible: const: realtek,rtl-intc - "#interrupt-cells": - const: 1 - reg: maxItems: 1 - interrupts: - maxItems: 1 + "#interrupt-cells": + const: 1 interrupt-controller: true - "#address-cells": - const: 0 + interrupts: + minItems: 1 + maxItems: 15 + description: + List of interrupts where SoC interrupts inputs can be routed to. Must be + provided in the same order as the output lines. The first interrupt is + thus selected via routing value 0, etc. - interrupt-map: - description: Describes mapping from SoC interrupts to CPU interrupts + realtek,interrupt-routing: + $ref: /schemas/types.yaml#/definitions/uint32-matrix + description: + List of pairs, where "soc_int" is the interrupt line + number as provided by this controller. "irq_idx" is the index of the + interrupt in the list as specified the interrupts property. + items: + items: + - description: SoC interrupt index + - description: parent interrupt index required: - compatible - reg - "#interrupt-cells" - interrupt-controller - - "#address-cells" - - interrupt-map + - interrupts + - realtek,interrupt-routing additionalProperties: false @@ -49,9 +64,11 @@ examples: #interrupt-cells = <1>; interrupt-controller; reg = <0x3000 0x20>; - #address-cells = <0>; - interrupt-map = - <31 &cpuintc 2>, - <30 &cpuintc 1>, - <29 &cpuintc 5>; + + interrupt-parent = <&cpu_intc>; + interrupts = <2>, <3>, <4>; + realtek,interrupt-routing = + <31 0>, /* route to cpu_intc interrupt 2 */ + <30 1>, /* route to cpu_intc interrupt 3 */ + <29 2>; /* route to cpu_intc interrupt 4 */ }; From patchwork Thu Dec 23 12:08:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sander Vanheule X-Patchwork-Id: 527827 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 92145C4332F for ; Thu, 23 Dec 2021 12:09:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348155AbhLWMJC (ORCPT ); Thu, 23 Dec 2021 07:09:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42662 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348145AbhLWMI4 (ORCPT ); Thu, 23 Dec 2021 07:08:56 -0500 Received: from polaris.svanheule.net (polaris.svanheule.net [IPv6:2a00:c98:2060:a004:1::200]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AB76FC06175B for ; Thu, 23 Dec 2021 04:08:52 -0800 (PST) Received: from terra.local.svanheule.net (unknown [IPv6:2a02:a03f:eafe:c901:29a7:866a:cac1:4c27]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: sander@svanheule.net) by polaris.svanheule.net (Postfix) with ESMTPSA id E4C292866B5; Thu, 23 Dec 2021 13:08:50 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=svanheule.net; s=mail1707; t=1640261331; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1em+x8emmOQHJWrevz6ZnKRMz4D+64SPUIqqFXJFNjw=; b=hdHdmMl+XnxcLO+RcCPLd5mCF4gZdJHlaNZQq+zxdXjbodOB47Jq3jGL09JkK6kx2lVib2 y/moD9fDm1bXChCRSKHKKLvB0r4kSDlc+Ld9qjkefIlVzCBZUogxyUOGbItHXYW40co+9T txisnMzyrxfcOG2v230K03+6h0DtXGkVj7jXobSOCIfDvBeEehfNxAjt+u3qnN4a3sBwWH ruVPzlEZOVJfXCA+YwgUnpANhLIEUnB4ygPFE4T0l7uD0I4NZocxO2akRu6cq5gB/eDL0V 06CNgi8590l5GvcgHH7aiHqPb4u6PZVv8EtF50h75EwAe0WTxOi431GMc3Mk8Q== From: Sander Vanheule To: Thomas Gleixner , Marc Zyngier , devicetree@vger.kernel.org Cc: Rob Herring , Birger Koblitz , Bert Vermeulen , John Crispin , linux-kernel@vger.kernel.org, Sander Vanheule Subject: [RFC PATCH v1 4/4] irqchip: realtek-rtl: replace custom interrupt-map Date: Thu, 23 Dec 2021 13:08:34 +0100 Message-Id: <97c90aa00c1bf31152585d204636a569bd86d745.1640261161.git.sander@svanheule.net> X-Mailer: git-send-email 2.33.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org To match the updated realtek,rtl-intc devicetree binding, replace the interrupt routing parsing. Signed-off-by: Sander Vanheule --- drivers/irqchip/irq-realtek-rtl.c | 77 +++++++++++++++---------------- 1 file changed, 36 insertions(+), 41 deletions(-) diff --git a/drivers/irqchip/irq-realtek-rtl.c b/drivers/irqchip/irq-realtek-rtl.c index 71366f1cf721..d80fbc5e651b 100644 --- a/drivers/irqchip/irq-realtek-rtl.c +++ b/drivers/irqchip/irq-realtek-rtl.c @@ -160,55 +160,50 @@ static int __init setup_parent_interrupt(struct realtek_ictl_priority *prio_ctl, return request_irq(parent, realtek_irq_dispatch, flags, "rtl-intc", prio_ctl); } -static int __init map_interrupts(struct device_node *node) +static int __init route_interrupts(struct device_node *node) { struct realtek_ictl_priority *prio_ctl; - struct device_node *cpu_ictl; - const __be32 *imap; - u32 imaplen, soc_int, priority, tmp; - int ret, i; - - ret = of_property_read_u32(node, "#address-cells", &tmp); - if (ret || tmp) - return -EINVAL; - - imap = of_get_property(node, "interrupt-map", &imaplen); - if (!imap || imaplen % 3) - return -EINVAL; - - for (i = 0; i < imaplen; i += 3 * sizeof(u32)) { - soc_int = be32_to_cpup(imap); - if (soc_int > 31) - return -EINVAL; + unsigned int num_prio, parent_idx; + const __be32 *routing_table; + int table_len; + u32 hw_irq; + int ret; - cpu_ictl = of_find_node_by_phandle(be32_to_cpup(imap + 1)); - if (!cpu_ictl) - return -EINVAL; - ret = of_property_read_u32(cpu_ictl, "#interrupt-cells", &tmp); - if (ret || tmp != 1) - return -EINVAL; - of_node_put(cpu_ictl); + num_prio = of_irq_count(node); + if (num_prio > RTL_ICTL_NUM_PRIO) { + pr_err("too many parent interrupts\n"); + return -ENODEV; + } - /* Map priority (1..6) to MIPS CPU interrupt (2..7) */ - priority = be32_to_cpup(imap + 2); - if (priority > 6 || priority < 1) - return -EINVAL; + for (parent_idx = 0; parent_idx < num_prio; parent_idx++) { + prio_ctl = &priorities[parent_idx]; - prio_ctl = &priorities[priority - 1]; + ret = irq_of_parse_and_map(node, parent_idx); + if (ret < 0) + return ret; - if (!prio_ctl->routing_value) { - ret = setup_parent_interrupt(prio_ctl, priority + 1); - if (ret) - return ret; + ret = setup_parent_interrupt(prio_ctl, ret); + if (ret) + return ret; - prio_ctl->routing_value = priority; - } + prio_ctl->routing_value = parent_idx + 1; + } - set_routing(prio_ctl, soc_int); + routing_table = of_get_property(node, "realtek,interrupt-routing", &table_len); + if (!routing_table) + return -ENOENT; - imap += 3; - } + for (table_len /= sizeof(*routing_table); table_len >= 2; table_len -= 2) { + hw_irq = be32_to_cpup(routing_table++); + if (hw_irq > 31) + return -EINVAL; + parent_idx = be32_to_cpup(routing_table++); + if (parent_idx >= num_prio) + return -EINVAL; + + set_routing(&priorities[parent_idx], hw_irq); + } return 0; } @@ -231,9 +226,9 @@ static int __init realtek_rtl_of_init(struct device_node *node, struct device_no realtek_ictl_domain = irq_domain_add_simple(node, 32, 0, &irq_domain_ops, NULL); - ret = map_interrupts(node); + ret = route_interrupts(node); if (ret) { - pr_err("invalid interrupt map\n"); + pr_err("invalid interrupt routing\n"); return ret; }