* [PATCH v4 0/2] Add support for AST2700 INTC driver @ 2024-10-16 2:24 Kevin Chen 2024-10-16 2:24 ` [PATCH v4 1/2] dt-bindings: interrupt-controller: Add support for ASPEED AST27XX INTC Kevin Chen 2024-10-16 2:24 ` [PATCH v4 2/2] irqchip/aspeed-intc: Add AST27XX INTC support Kevin Chen 0 siblings, 2 replies; 6+ messages in thread From: Kevin Chen @ 2024-10-16 2:24 UTC (permalink / raw) To: tglx, robh, krzk+dt, conor+dt, joel, andrew, kevin_chen, linux-kernel, devicetree, linux-arm-kernel, linux-aspeed --- v4: aspeed,ast2700-intc.yaml: - Add |' to preserve formatting. - Remove the interrupt nubmer accroding to maxItems of interrupts. drivers/irqchip/irq-aspeed-intc.c - Reduce scope of variables, which are bit and status. - Replace 32 with INTC_IRQS_PER_WORD define. - Remove reduendant tab. v3: aspeed,ast2700-intc.yaml: - Change reg with maxIntems:10 only. - Change interrupt with maxIntems:10 only. - Add description of INT0 and INTC1. - Fix the indentation. drivers/irqchip/irq-aspeed-intc.c: - Change to use CONFIG_ARCH_ASPEED. - Fix indentation. - Remove irq_domain name assignment. - Check all irq numbers first, and set chained. Kevin Chen (2): dt-bindings: interrupt-controller: Add support for ASPEED AST27XX INTC irqchip/aspeed-intc: Add AST27XX INTC support .../aspeed,ast2700-intc.yaml | 86 +++++++++++ drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-aspeed-intc.c | 140 ++++++++++++++++++ 3 files changed, 227 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml create mode 100644 drivers/irqchip/irq-aspeed-intc.c -- 2.34.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 1/2] dt-bindings: interrupt-controller: Add support for ASPEED AST27XX INTC 2024-10-16 2:24 [PATCH v4 0/2] Add support for AST2700 INTC driver Kevin Chen @ 2024-10-16 2:24 ` Kevin Chen 2024-10-16 17:27 ` Rob Herring (Arm) 2024-10-17 19:43 ` [tip: irq/core] " tip-bot2 for Kevin Chen 2024-10-16 2:24 ` [PATCH v4 2/2] irqchip/aspeed-intc: Add AST27XX INTC support Kevin Chen 1 sibling, 2 replies; 6+ messages in thread From: Kevin Chen @ 2024-10-16 2:24 UTC (permalink / raw) To: tglx, robh, krzk+dt, conor+dt, joel, andrew, kevin_chen, linux-kernel, devicetree, linux-arm-kernel, linux-aspeed The ASPEED AST27XX interrupt controller(INTC) contains second level and third level interrupt controller. INTC0: The second level INTC, which used to assert GIC if interrupt in INTC1 asserted. INTC1_x: The third level INTC, which used to assert INTC0 if interrupt in modules of INTC asserted. The relationship is like the following: +-----+ +-------+ +---------+---module0 | GIC |---| INTC0 |--+--| INTC1_0 |---module1 | | | | | | |---... +-----+ +-------+ | +---------+---module31 | | +---------+---module0 +---| INTC1_1 |---module1 | | |---... | +---------+---module31 ... | +---------+---module0 +---| INTC1_5 |---module1 | |---... +---------+---module31 Signed-off-by: Kevin Chen <kevin_chen@aspeedtech.com> --- .../aspeed,ast2700-intc.yaml | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml diff --git a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml new file mode 100644 index 000000000000..55636d06a674 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2700-intc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Aspeed AST2700 Interrupt Controller + +description: + This interrupt controller hardware is second level interrupt controller that + is hooked to a parent interrupt controller. It's useful to combine multiple + interrupt sources into 1 interrupt to parent interrupt controller. + +maintainers: + - Kevin Chen <kevin_chen@aspeedtech.com> + +properties: + compatible: + enum: + - aspeed,ast2700-intc-ic + + reg: + maxItems: 1 + + interrupt-controller: true + + '#interrupt-cells': + const: 2 + description: + The first cell is the IRQ number, the second cell is the trigger + type as defined in interrupt.txt in this directory. + + interrupts: + maxItems: 6 + description: | + Depend to which INTC0 or INTC1 used. + INTC0 and INTC1 are two kinds of interrupt controller with enable and raw + status registers for use. + INTC0 is used to assert GIC if interrupt in INTC1 asserted. + INTC1 is used to assert INTC0 if interrupt of modules asserted. + +-----+ +-------+ +---------+---module0 + | GIC |---| INTC0 |--+--| INTC1_0 |---module2 + | | | | | | |---... + +-----+ +-------+ | +---------+---module31 + | + | +---------+---module0 + +---| INTC1_1 |---module2 + | | |---... + | +---------+---module31 + ... + | +---------+---module0 + +---| INTC1_5 |---module2 + | |---... + +---------+---module31 + + +required: + - compatible + - reg + - interrupt-controller + - '#interrupt-cells' + - interrupts + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + + bus { + #address-cells = <2>; + #size-cells = <2>; + + interrupt-controller@12101b00 { + compatible = "aspeed,ast2700-intc-ic"; + reg = <0 0x12101b00 0 0x10>; + #interrupt-cells = <2>; + interrupt-controller; + interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>; + }; + }; -- 2.34.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: interrupt-controller: Add support for ASPEED AST27XX INTC 2024-10-16 2:24 ` [PATCH v4 1/2] dt-bindings: interrupt-controller: Add support for ASPEED AST27XX INTC Kevin Chen @ 2024-10-16 17:27 ` Rob Herring (Arm) 2024-10-17 19:43 ` [tip: irq/core] " tip-bot2 for Kevin Chen 1 sibling, 0 replies; 6+ messages in thread From: Rob Herring (Arm) @ 2024-10-16 17:27 UTC (permalink / raw) To: Kevin Chen Cc: joel, conor+dt, krzk+dt, linux-kernel, linux-arm-kernel, andrew, devicetree, linux-aspeed, tglx On Wed, 16 Oct 2024 10:24:09 +0800, Kevin Chen wrote: > The ASPEED AST27XX interrupt controller(INTC) contains second level and > third level interrupt controller. > > INTC0: > The second level INTC, which used to assert GIC if interrupt in INTC1 asserted. > > INTC1_x: > The third level INTC, which used to assert INTC0 if interrupt in modules > of INTC asserted. > > The relationship is like the following: > +-----+ +-------+ +---------+---module0 > | GIC |---| INTC0 |--+--| INTC1_0 |---module1 > | | | | | | |---... > +-----+ +-------+ | +---------+---module31 > | > | +---------+---module0 > +---| INTC1_1 |---module1 > | | |---... > | +---------+---module31 > ... > | +---------+---module0 > +---| INTC1_5 |---module1 > | |---... > +---------+---module31 > > Signed-off-by: Kevin Chen <kevin_chen@aspeedtech.com> > --- > .../aspeed,ast2700-intc.yaml | 86 +++++++++++++++++++ > 1 file changed, 86 insertions(+) > create mode 100644 Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml > Reviewed-by: Rob Herring (Arm) <robh@kernel.org> ^ permalink raw reply [flat|nested] 6+ messages in thread
* [tip: irq/core] dt-bindings: interrupt-controller: Add support for ASPEED AST27XX INTC 2024-10-16 2:24 ` [PATCH v4 1/2] dt-bindings: interrupt-controller: Add support for ASPEED AST27XX INTC Kevin Chen 2024-10-16 17:27 ` Rob Herring (Arm) @ 2024-10-17 19:43 ` tip-bot2 for Kevin Chen 1 sibling, 0 replies; 6+ messages in thread From: tip-bot2 for Kevin Chen @ 2024-10-17 19:43 UTC (permalink / raw) To: linux-tip-commits Cc: Kevin Chen, Thomas Gleixner, Rob Herring (Arm), x86, linux-kernel, maz The following commit has been merged into the irq/core branch of tip: Commit-ID: 37a99ff53d1d913ec5b435cbe977a811b7b37995 Gitweb: https://git.kernel.org/tip/37a99ff53d1d913ec5b435cbe977a811b7b37995 Author: Kevin Chen <kevin_chen@aspeedtech.com> AuthorDate: Wed, 16 Oct 2024 10:24:09 +08:00 Committer: Thomas Gleixner <tglx@linutronix.de> CommitterDate: Thu, 17 Oct 2024 21:35:28 +02:00 dt-bindings: interrupt-controller: Add support for ASPEED AST27XX INTC The ASPEED AST27XX interrupt controller(INTC) contains second level and third level interrupt controller. INTC0: The second level INTC, which used to assert GIC if interrupt in INTC1 asserted. INTC1_x: The third level INTC, which used to assert INTC0 if interrupt in modules of INTC asserted. The relationship is like the following: +-----+ +-------+ +---------+---module0 | GIC |---| INTC0 |--+--| INTC1_0 |---module1 | | | | | | |---... +-----+ +-------+ | +---------+---module31 | | +---------+---module0 +---| INTC1_1 |---module1 | | |---... | +---------+---module31 ... | +---------+---module0 +---| INTC1_5 |---module1 | |---... +---------+---module31 Signed-off-by: Kevin Chen <kevin_chen@aspeedtech.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Rob Herring (Arm) <robh@kernel.org> Link: https://lore.kernel.org/all/20241016022410.1154574-2-kevin_chen@aspeedtech.com --- Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml diff --git a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml new file mode 100644 index 0000000..55636d0 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2700-intc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Aspeed AST2700 Interrupt Controller + +description: + This interrupt controller hardware is second level interrupt controller that + is hooked to a parent interrupt controller. It's useful to combine multiple + interrupt sources into 1 interrupt to parent interrupt controller. + +maintainers: + - Kevin Chen <kevin_chen@aspeedtech.com> + +properties: + compatible: + enum: + - aspeed,ast2700-intc-ic + + reg: + maxItems: 1 + + interrupt-controller: true + + '#interrupt-cells': + const: 2 + description: + The first cell is the IRQ number, the second cell is the trigger + type as defined in interrupt.txt in this directory. + + interrupts: + maxItems: 6 + description: | + Depend to which INTC0 or INTC1 used. + INTC0 and INTC1 are two kinds of interrupt controller with enable and raw + status registers for use. + INTC0 is used to assert GIC if interrupt in INTC1 asserted. + INTC1 is used to assert INTC0 if interrupt of modules asserted. + +-----+ +-------+ +---------+---module0 + | GIC |---| INTC0 |--+--| INTC1_0 |---module2 + | | | | | | |---... + +-----+ +-------+ | +---------+---module31 + | + | +---------+---module0 + +---| INTC1_1 |---module2 + | | |---... + | +---------+---module31 + ... + | +---------+---module0 + +---| INTC1_5 |---module2 + | |---... + +---------+---module31 + + +required: + - compatible + - reg + - interrupt-controller + - '#interrupt-cells' + - interrupts + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + + bus { + #address-cells = <2>; + #size-cells = <2>; + + interrupt-controller@12101b00 { + compatible = "aspeed,ast2700-intc-ic"; + reg = <0 0x12101b00 0 0x10>; + #interrupt-cells = <2>; + interrupt-controller; + interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>; + }; + }; ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 2/2] irqchip/aspeed-intc: Add AST27XX INTC support 2024-10-16 2:24 [PATCH v4 0/2] Add support for AST2700 INTC driver Kevin Chen 2024-10-16 2:24 ` [PATCH v4 1/2] dt-bindings: interrupt-controller: Add support for ASPEED AST27XX INTC Kevin Chen @ 2024-10-16 2:24 ` Kevin Chen 2024-10-17 19:43 ` [tip: irq/core] " tip-bot2 for Kevin Chen 1 sibling, 1 reply; 6+ messages in thread From: Kevin Chen @ 2024-10-16 2:24 UTC (permalink / raw) To: tglx, robh, krzk+dt, conor+dt, joel, andrew, kevin_chen, linux-kernel, devicetree, linux-arm-kernel, linux-aspeed Support Aspeed Interrupt Controller on Aspeed Silicon SoCs. ASPEED interrupt controller(INTC) maps the internal interrupt sources to a parent interrupt controller, which can be GIC or INTC. Signed-off-by: Kevin Chen <kevin_chen@aspeedtech.com> --- drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-aspeed-intc.c | 140 ++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 drivers/irqchip/irq-aspeed-intc.c diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index e3679ec2b9f7..086911bf4db6 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -84,6 +84,7 @@ obj-$(CONFIG_MVEBU_SEI) += irq-mvebu-sei.o obj-$(CONFIG_LS_EXTIRQ) += irq-ls-extirq.o obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o irq-aspeed-i2c-ic.o irq-aspeed-scu-ic.o +obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-intc.o obj-$(CONFIG_STM32MP_EXTI) += irq-stm32mp-exti.o obj-$(CONFIG_STM32_EXTI) += irq-stm32-exti.o obj-$(CONFIG_QCOM_IRQ_COMBINER) += qcom-irq-combiner.o diff --git a/drivers/irqchip/irq-aspeed-intc.c b/drivers/irqchip/irq-aspeed-intc.c new file mode 100644 index 000000000000..faf18a675395 --- /dev/null +++ b/drivers/irqchip/irq-aspeed-intc.c @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Aspeed Interrupt Controller. + * + * Copyright (C) 2023 ASPEED Technology Inc. + */ + +#include <linux/bitops.h> +#include <linux/irq.h> +#include <linux/irqchip.h> +#include <linux/irqchip/chained_irq.h> +#include <linux/irqdomain.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/io.h> +#include <linux/spinlock.h> + +#define INTC_INT_ENABLE_REG 0x00 +#define INTC_INT_STATUS_REG 0x04 +#define INTC_IRQS_PER_WORD 32 + +struct aspeed_intc_ic { + void __iomem *base; + raw_spinlock_t gic_lock; + raw_spinlock_t intc_lock; + struct irq_domain *irq_domain; +}; + +static void aspeed_intc_ic_irq_handler(struct irq_desc *desc) +{ + struct aspeed_intc_ic *intc_ic = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); + + chained_irq_enter(chip, desc); + + scoped_guard(raw_spinlock, &intc_ic->gic_lock) { + unsigned long bit, status; + + status = readl(intc_ic->base + INTC_INT_STATUS_REG); + for_each_set_bit(bit, &status, INTC_IRQS_PER_WORD) { + generic_handle_domain_irq(intc_ic->irq_domain, bit); + writel(BIT(bit), intc_ic->base + INTC_INT_STATUS_REG); + } + } + + chained_irq_exit(chip, desc); +} + +static void aspeed_intc_irq_mask(struct irq_data *data) +{ + struct aspeed_intc_ic *intc_ic = irq_data_get_irq_chip_data(data); + unsigned int mask = readl(intc_ic->base + INTC_INT_ENABLE_REG) & ~BIT(data->hwirq); + + guard(raw_spinlock)(&intc_ic->intc_lock); + writel(mask, intc_ic->base + INTC_INT_ENABLE_REG); +} + +static void aspeed_intc_irq_unmask(struct irq_data *data) +{ + struct aspeed_intc_ic *intc_ic = irq_data_get_irq_chip_data(data); + unsigned int unmask = readl(intc_ic->base + INTC_INT_ENABLE_REG) | BIT(data->hwirq); + + guard(raw_spinlock)(&intc_ic->intc_lock); + writel(unmask, intc_ic->base + INTC_INT_ENABLE_REG); +} + +static struct irq_chip aspeed_intc_chip = { + .name = "ASPEED INTC", + .irq_mask = aspeed_intc_irq_mask, + .irq_unmask = aspeed_intc_irq_unmask, +}; + +static int aspeed_intc_ic_map_irq_domain(struct irq_domain *domain, unsigned int irq, + irq_hw_number_t hwirq) +{ + irq_set_chip_and_handler(irq, &aspeed_intc_chip, handle_level_irq); + irq_set_chip_data(irq, domain->host_data); + + return 0; +} + +static const struct irq_domain_ops aspeed_intc_ic_irq_domain_ops = { + .map = aspeed_intc_ic_map_irq_domain, +}; + +static int __init aspeed_intc_ic_of_init(struct device_node *node, + struct device_node *parent) +{ + struct aspeed_intc_ic *intc_ic; + int ret = 0; + int irq, i; + + intc_ic = kzalloc(sizeof(*intc_ic), GFP_KERNEL); + if (!intc_ic) + return -ENOMEM; + + intc_ic->base = of_iomap(node, 0); + if (!intc_ic->base) { + pr_err("Failed to iomap intc_ic base\n"); + ret = -ENOMEM; + goto err_free_ic; + } + writel(0xffffffff, intc_ic->base + INTC_INT_STATUS_REG); + writel(0x0, intc_ic->base + INTC_INT_ENABLE_REG); + + intc_ic->irq_domain = irq_domain_add_linear(node, INTC_IRQS_PER_WORD, + &aspeed_intc_ic_irq_domain_ops, intc_ic); + if (!intc_ic->irq_domain) { + ret = -ENOMEM; + goto err_iounmap; + } + + raw_spin_lock_init(&intc_ic->gic_lock); + raw_spin_lock_init(&intc_ic->intc_lock); + + /* Check all the irq numbers valid. If not, unmaps all the base and frees the data. */ + for (i = 0; i < of_irq_count(node); i++) { + irq = irq_of_parse_and_map(node, i); + if (!irq) { + pr_err("Failed to get irq number\n"); + ret = -EINVAL; + goto err_iounmap; + } + } + + for (i = 0; i < of_irq_count(node); i++) { + irq = irq_of_parse_and_map(node, i); + irq_set_chained_handler_and_data(irq, aspeed_intc_ic_irq_handler, intc_ic); + } + + return 0; + +err_iounmap: + iounmap(intc_ic->base); +err_free_ic: + kfree(intc_ic); + return ret; +} + +IRQCHIP_DECLARE(ast2700_intc_ic, "aspeed,ast2700-intc-ic", aspeed_intc_ic_of_init); -- 2.34.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [tip: irq/core] irqchip/aspeed-intc: Add AST27XX INTC support 2024-10-16 2:24 ` [PATCH v4 2/2] irqchip/aspeed-intc: Add AST27XX INTC support Kevin Chen @ 2024-10-17 19:43 ` tip-bot2 for Kevin Chen 0 siblings, 0 replies; 6+ messages in thread From: tip-bot2 for Kevin Chen @ 2024-10-17 19:43 UTC (permalink / raw) To: linux-tip-commits; +Cc: Kevin Chen, Thomas Gleixner, x86, linux-kernel, maz The following commit has been merged into the irq/core branch of tip: Commit-ID: 010863f40fc3c3650eded3d5ebd7af7521b3c3fa Gitweb: https://git.kernel.org/tip/010863f40fc3c3650eded3d5ebd7af7521b3c3fa Author: Kevin Chen <kevin_chen@aspeedtech.com> AuthorDate: Wed, 16 Oct 2024 10:24:10 +08:00 Committer: Thomas Gleixner <tglx@linutronix.de> CommitterDate: Thu, 17 Oct 2024 21:35:28 +02:00 irqchip/aspeed-intc: Add AST27XX INTC support Support Aspeed Interrupt Controller on Aspeed Silicon SoCs. ASPEED interrupt controller(INTC) maps the internal interrupt sources to a parent interrupt controller, which can be GIC or INTC. Signed-off-by: Kevin Chen <kevin_chen@aspeedtech.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/all/20241016022410.1154574-3-kevin_chen@aspeedtech.com --- drivers/irqchip/Makefile | 1 +- drivers/irqchip/irq-aspeed-intc.c | 139 +++++++++++++++++++++++++++++- 2 files changed, 140 insertions(+) create mode 100644 drivers/irqchip/irq-aspeed-intc.c diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 94ecaeb..15ed6e9 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -85,6 +85,7 @@ obj-$(CONFIG_MVEBU_SEI) += irq-mvebu-sei.o obj-$(CONFIG_LS_EXTIRQ) += irq-ls-extirq.o obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o irq-aspeed-i2c-ic.o irq-aspeed-scu-ic.o +obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-intc.o obj-$(CONFIG_STM32MP_EXTI) += irq-stm32mp-exti.o obj-$(CONFIG_STM32_EXTI) += irq-stm32-exti.o obj-$(CONFIG_QCOM_IRQ_COMBINER) += qcom-irq-combiner.o diff --git a/drivers/irqchip/irq-aspeed-intc.c b/drivers/irqchip/irq-aspeed-intc.c new file mode 100644 index 0000000..bd3b759 --- /dev/null +++ b/drivers/irqchip/irq-aspeed-intc.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Aspeed Interrupt Controller. + * + * Copyright (C) 2023 ASPEED Technology Inc. + */ + +#include <linux/bitops.h> +#include <linux/irq.h> +#include <linux/irqchip.h> +#include <linux/irqchip/chained_irq.h> +#include <linux/irqdomain.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/io.h> +#include <linux/spinlock.h> + +#define INTC_INT_ENABLE_REG 0x00 +#define INTC_INT_STATUS_REG 0x04 +#define INTC_IRQS_PER_WORD 32 + +struct aspeed_intc_ic { + void __iomem *base; + raw_spinlock_t gic_lock; + raw_spinlock_t intc_lock; + struct irq_domain *irq_domain; +}; + +static void aspeed_intc_ic_irq_handler(struct irq_desc *desc) +{ + struct aspeed_intc_ic *intc_ic = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); + + chained_irq_enter(chip, desc); + + scoped_guard(raw_spinlock, &intc_ic->gic_lock) { + unsigned long bit, status; + + status = readl(intc_ic->base + INTC_INT_STATUS_REG); + for_each_set_bit(bit, &status, INTC_IRQS_PER_WORD) { + generic_handle_domain_irq(intc_ic->irq_domain, bit); + writel(BIT(bit), intc_ic->base + INTC_INT_STATUS_REG); + } + } + + chained_irq_exit(chip, desc); +} + +static void aspeed_intc_irq_mask(struct irq_data *data) +{ + struct aspeed_intc_ic *intc_ic = irq_data_get_irq_chip_data(data); + unsigned int mask = readl(intc_ic->base + INTC_INT_ENABLE_REG) & ~BIT(data->hwirq); + + guard(raw_spinlock)(&intc_ic->intc_lock); + writel(mask, intc_ic->base + INTC_INT_ENABLE_REG); +} + +static void aspeed_intc_irq_unmask(struct irq_data *data) +{ + struct aspeed_intc_ic *intc_ic = irq_data_get_irq_chip_data(data); + unsigned int unmask = readl(intc_ic->base + INTC_INT_ENABLE_REG) | BIT(data->hwirq); + + guard(raw_spinlock)(&intc_ic->intc_lock); + writel(unmask, intc_ic->base + INTC_INT_ENABLE_REG); +} + +static struct irq_chip aspeed_intc_chip = { + .name = "ASPEED INTC", + .irq_mask = aspeed_intc_irq_mask, + .irq_unmask = aspeed_intc_irq_unmask, +}; + +static int aspeed_intc_ic_map_irq_domain(struct irq_domain *domain, unsigned int irq, + irq_hw_number_t hwirq) +{ + irq_set_chip_and_handler(irq, &aspeed_intc_chip, handle_level_irq); + irq_set_chip_data(irq, domain->host_data); + + return 0; +} + +static const struct irq_domain_ops aspeed_intc_ic_irq_domain_ops = { + .map = aspeed_intc_ic_map_irq_domain, +}; + +static int __init aspeed_intc_ic_of_init(struct device_node *node, + struct device_node *parent) +{ + struct aspeed_intc_ic *intc_ic; + int irq, i, ret = 0; + + intc_ic = kzalloc(sizeof(*intc_ic), GFP_KERNEL); + if (!intc_ic) + return -ENOMEM; + + intc_ic->base = of_iomap(node, 0); + if (!intc_ic->base) { + pr_err("Failed to iomap intc_ic base\n"); + ret = -ENOMEM; + goto err_free_ic; + } + writel(0xffffffff, intc_ic->base + INTC_INT_STATUS_REG); + writel(0x0, intc_ic->base + INTC_INT_ENABLE_REG); + + intc_ic->irq_domain = irq_domain_add_linear(node, INTC_IRQS_PER_WORD, + &aspeed_intc_ic_irq_domain_ops, intc_ic); + if (!intc_ic->irq_domain) { + ret = -ENOMEM; + goto err_iounmap; + } + + raw_spin_lock_init(&intc_ic->gic_lock); + raw_spin_lock_init(&intc_ic->intc_lock); + + /* Check all the irq numbers valid. If not, unmaps all the base and frees the data. */ + for (i = 0; i < of_irq_count(node); i++) { + irq = irq_of_parse_and_map(node, i); + if (!irq) { + pr_err("Failed to get irq number\n"); + ret = -EINVAL; + goto err_iounmap; + } + } + + for (i = 0; i < of_irq_count(node); i++) { + irq = irq_of_parse_and_map(node, i); + irq_set_chained_handler_and_data(irq, aspeed_intc_ic_irq_handler, intc_ic); + } + + return 0; + +err_iounmap: + iounmap(intc_ic->base); +err_free_ic: + kfree(intc_ic); + return ret; +} + +IRQCHIP_DECLARE(ast2700_intc_ic, "aspeed,ast2700-intc-ic", aspeed_intc_ic_of_init); ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-10-17 19:43 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2024-10-16 2:24 [PATCH v4 0/2] Add support for AST2700 INTC driver Kevin Chen 2024-10-16 2:24 ` [PATCH v4 1/2] dt-bindings: interrupt-controller: Add support for ASPEED AST27XX INTC Kevin Chen 2024-10-16 17:27 ` Rob Herring (Arm) 2024-10-17 19:43 ` [tip: irq/core] " tip-bot2 for Kevin Chen 2024-10-16 2:24 ` [PATCH v4 2/2] irqchip/aspeed-intc: Add AST27XX INTC support Kevin Chen 2024-10-17 19:43 ` [tip: irq/core] " tip-bot2 for Kevin Chen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®