Merge tag 'irq-drivers-2026-04-12' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull interrupt chip driver updates from Thomas Gleixner:

 - A large refactoring for the Renesas RZV2H driver to add new interrupt
   types cleanly

 - A large refactoring for the Renesas RZG2L driver to add support the
   new RZ/G3L variant

 - Add support for the new NXP S32N79 chip in the IMX irq-steer driver

 - Add support for the Apple AICv3 variant

 - Enhance the Loongson PCH LPC driver so it can be used on MIPS with
   device tree firmware

 - Allow the PIC32 EVIC driver to be built independent of MIPS in
   compile tests

 - The usual small fixes and enhancements all over the place

* tag 'irq-drivers-2026-04-12' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (46 commits)
  irqchip/irq-pic32-evic: Add __maybe_unused for board_bind_eic_interrupt in COMPILE_TEST
  irqchip/renesas-rzv2h: Kill icu_err string
  irqchip/renesas-rzv2h: Kill swint_names[]
  irqchip/renesas-rzv2h: Kill swint_idx[]
  irqchip/renesas-rzg2l: Add NMI support
  irqchip/renesas-rzg2l: Clear the shared interrupt bit in rzg2l_irqc_free()
  irqchip/renesas-rzg2l: Replace raw_spin_{lock,unlock} with guard() in rzg2l_irq_set_type()
  irqchip/gic-v3: Print a warning for out-of-range interrupt numbers
  irqchip/renesas-rzg2l: Add shared interrupt support
  irqchip/renesas-rzg2l: Add RZ/G3L support
  irqchip/renesas-rzg2l: Drop IRQC_IRQ_COUNT macro
  irqchip/renesas-rzg2l: Drop IRQC_TINT_START macro
  irqchip/renesas-rzg2l: Drop IRQC_NUM_IRQ macro
  irqchip/renesas-rzg2l: Dynamically allocate fwspec array
  irqchip/renesas-rzg2l: Split rzfive_irqc_{mask,unmask} into separate IRQ and TINT handlers
  irqchip/renesas-rzg2l: Split rzfive_tint_irq_endisable() into separate IRQ and TINT helpers
  irqchip/renesas-rzg2l: Replace rzg2l_irqc_irq_{enable,disable} with TINT-specific handlers
  irqchip/renesas-rzg2l: Split set_type handler into separate IRQ and TINT functions
  irqchip/renesas-rzg2l: Split EOI handler into separate IRQ and TINT functions
  irqchip/renesas-rzg2l: Replace single irq_chip with per-region irq_chip instances
  ...
This commit is contained in:
Linus Torvalds
2026-04-14 10:18:10 -07:00
15 changed files with 1135 additions and 375 deletions
@@ -4,10 +4,10 @@
$id: http://devicetree.org/schemas/interrupt-controller/apple,aic2.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Apple Interrupt Controller 2
title: Apple Interrupt Controller 2 and 3
maintainers:
- Hector Martin <marcan@marcan.st>
- Janne Grunau <j@jannau.net>
description: |
The Apple Interrupt Controller 2 is a simple interrupt controller present on
@@ -28,14 +28,24 @@ description: |
which do not go through a discrete interrupt controller. It also handles
FIQ-based Fast IPIs.
The Apple Interrupt Controller 3 is in its base functionality very similar to
the Apple Interrupt Controller 2 and uses the same device tree bindings. It is
found on Apple ARM SoCs platforms starting with t8122 (M3).
properties:
compatible:
items:
- enum:
- apple,t8112-aic
- apple,t6000-aic
- apple,t6020-aic
- const: apple,aic2
oneOf:
- items:
- enum:
- apple,t6000-aic
- apple,t6020-aic
- apple,t8112-aic
- const: apple,aic2
- items:
- enum:
- apple,t6030-aic3
- const: apple,t8122-aic3
- const: apple,t8122-aic3
interrupt-controller: true
@@ -117,7 +127,9 @@ allOf:
properties:
compatible:
contains:
const: apple,t8112-aic
enum:
- apple,t8112-aic
- apple,t8122-aic3
then:
properties:
'#interrupt-cells':
@@ -0,0 +1,52 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/interrupt-controller/loongson,pch-lpc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Loongson PCH LPC Controller
maintainers:
- Jiaxun Yang <jiaxun.yang@flygoat.com>
description:
This interrupt controller is found in the Loongson LS7A family of PCH for
accepting interrupts sent by LPC-connected peripherals and signalling PIC
via a single interrupt line when interrupts are available.
properties:
compatible:
const: loongson,ls7a-lpc
reg:
maxItems: 1
interrupt-controller: true
interrupts:
maxItems: 1
'#interrupt-cells':
const: 2
required:
- compatible
- reg
- interrupt-controller
- interrupts
- '#interrupt-cells'
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
lpc: interrupt-controller@10002000 {
compatible = "loongson,ls7a-lpc";
reg = <0x10002000 0x400>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&pic>;
interrupts = <19 IRQ_TYPE_LEVEL_HIGH>;
};
...
@@ -30,7 +30,9 @@ properties:
- renesas,r9a08g045-irqc # RZ/G3S
- const: renesas,rzg2l-irqc
- const: renesas,r9a07g043f-irqc # RZ/Five
- enum:
- renesas,r9a07g043f-irqc # RZ/Five
- renesas,r9a08g046-irqc # RZ/G3L
'#interrupt-cells':
description: The first cell should contain a macro RZG2L_{NMI,IRQX} included in the
@@ -48,107 +50,35 @@ properties:
interrupts:
minItems: 45
items:
- description: NMI interrupt
- description: IRQ0 interrupt
- description: IRQ1 interrupt
- description: IRQ2 interrupt
- description: IRQ3 interrupt
- description: IRQ4 interrupt
- description: IRQ5 interrupt
- description: IRQ6 interrupt
- description: IRQ7 interrupt
- description: GPIO interrupt, TINT0
- description: GPIO interrupt, TINT1
- description: GPIO interrupt, TINT2
- description: GPIO interrupt, TINT3
- description: GPIO interrupt, TINT4
- description: GPIO interrupt, TINT5
- description: GPIO interrupt, TINT6
- description: GPIO interrupt, TINT7
- description: GPIO interrupt, TINT8
- description: GPIO interrupt, TINT9
- description: GPIO interrupt, TINT10
- description: GPIO interrupt, TINT11
- description: GPIO interrupt, TINT12
- description: GPIO interrupt, TINT13
- description: GPIO interrupt, TINT14
- description: GPIO interrupt, TINT15
- description: GPIO interrupt, TINT16
- description: GPIO interrupt, TINT17
- description: GPIO interrupt, TINT18
- description: GPIO interrupt, TINT19
- description: GPIO interrupt, TINT20
- description: GPIO interrupt, TINT21
- description: GPIO interrupt, TINT22
- description: GPIO interrupt, TINT23
- description: GPIO interrupt, TINT24
- description: GPIO interrupt, TINT25
- description: GPIO interrupt, TINT26
- description: GPIO interrupt, TINT27
- description: GPIO interrupt, TINT28
- description: GPIO interrupt, TINT29
- description: GPIO interrupt, TINT30
- description: GPIO interrupt, TINT31
- description: Bus error interrupt
- description: ECCRAM0 or combined ECCRAM0/1 1bit error interrupt
- description: ECCRAM0 or combined ECCRAM0/1 2bit error interrupt
- description: ECCRAM0 or combined ECCRAM0/1 error overflow interrupt
- description: ECCRAM1 1bit error interrupt
- description: ECCRAM1 2bit error interrupt
- description: ECCRAM1 error overflow interrupt
maxItems: 61
interrupt-names:
minItems: 45
maxItems: 61
items:
- const: nmi
- const: irq0
- const: irq1
- const: irq2
- const: irq3
- const: irq4
- const: irq5
- const: irq6
- const: irq7
- const: tint0
- const: tint1
- const: tint2
- const: tint3
- const: tint4
- const: tint5
- const: tint6
- const: tint7
- const: tint8
- const: tint9
- const: tint10
- const: tint11
- const: tint12
- const: tint13
- const: tint14
- const: tint15
- const: tint16
- const: tint17
- const: tint18
- const: tint19
- const: tint20
- const: tint21
- const: tint22
- const: tint23
- const: tint24
- const: tint25
- const: tint26
- const: tint27
- const: tint28
- const: tint29
- const: tint30
- const: tint31
- const: bus-err
- const: ec7tie1-0
- const: ec7tie2-0
- const: ec7tiovf-0
- const: ec7tie1-1
- const: ec7tie2-1
- const: ec7tiovf-1
oneOf:
- description: NMI interrupt
const: nmi
- description: External IRQ interrupt
pattern: '^irq([0-9]|1[0-5])$'
- description: GPIO interrupt
pattern: '^tint([0-9]|1[0-9]|2[0-9]|3[0-1])$'
- description: Bus error interrupt
const: bus-err
- description: ECCRAM0 or combined ECCRAM0/1 1bit error interrupt
const: ec7tie1-0
- description: ECCRAM0 or combined ECCRAM0/1 2bit error interrupt
const: ec7tie2-0
- description: ECCRAM0 or combined ECCRAM0/1 error overflow interrupt
const: ec7tiovf-0
- description: ECCRAM1 1bit error interrupt
const: ec7tie1-1
- description: ECCRAM1 2bit error interrupt
const: ec7tie2-1
- description: ECCRAM1 error overflow interrupt
const: ec7tiovf-1
- description: Integrated GPT Error interrupt
pattern: '^ovfunf([0-7])$'
clocks:
maxItems: 2
@@ -180,6 +110,24 @@ required:
allOf:
- $ref: /schemas/interrupt-controller.yaml#
- if:
properties:
compatible:
contains:
enum:
- renesas,r9a07g043f-irqc
- renesas,r9a07g043u-irqc
- renesas,r9a07g044-irqc
- renesas,r9a07g054-irqc
then:
properties:
interrupts:
minItems: 48
maxItems: 48
interrupt-names:
minItems: 48
maxItems: 48
- if:
properties:
compatible:
@@ -192,12 +140,19 @@ allOf:
maxItems: 45
interrupt-names:
maxItems: 45
else:
- if:
properties:
compatible:
contains:
enum:
- renesas,r9a08g046-irqc
then:
properties:
interrupts:
minItems: 48
minItems: 61
interrupt-names:
minItems: 48
minItems: 61
unevaluatedProperties: false
+6
View File
@@ -11,6 +11,7 @@
#include <linux/irqchip.h>
#include <linux/kernel_stat.h>
#include <linux/proc_fs.h>
#include <linux/minmax.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
@@ -99,6 +100,11 @@ int __init arch_probe_nr_irqs(void)
return NR_IRQS_LEGACY;
}
unsigned int arch_dynirq_lower_bound(unsigned int from)
{
return MAX(from, NR_IRQS_LEGACY);
}
void __init init_IRQ(void)
{
int i;
+6
View File
@@ -7,6 +7,7 @@
#include <linux/irqchip.h>
#include <linux/logic_pio.h>
#include <linux/memblock.h>
#include <linux/minmax.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <asm/bootinfo.h>
@@ -227,3 +228,8 @@ void __init arch_init_irq(void)
reserve_pio_range();
irqchip_init();
}
unsigned int arch_dynirq_lower_bound(unsigned int from)
{
return MAX(from, NR_IRQS_LEGACY);
}
-1
View File
@@ -20,7 +20,6 @@ config PIC32MZDA
select LIBFDT
select USE_OF
select PINCTRL
select PIC32_EVIC
help
Support for the Microchip PIC32MZDA microcontroller.
+7 -5
View File
@@ -252,9 +252,12 @@ config ORION_IRQCHIP
select IRQ_DOMAIN
config PIC32_EVIC
bool
def_bool MACH_PIC32 || COMPILE_TEST
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
help
Enable support for the interrupt controller on the Microchip PIC32
family of platforms.
config JCORE_AIC
bool "J-Core integrated AIC" if COMPILE_TEST
@@ -541,11 +544,11 @@ config CSKY_APB_INTC
config IMX_IRQSTEER
bool "i.MX IRQSTEER support"
depends on ARCH_MXC || COMPILE_TEST
default ARCH_MXC
depends on ARCH_MXC || ARCH_S32 || COMPILE_TEST
default y if ARCH_MXC || ARCH_S32
select IRQ_DOMAIN
help
Support for the i.MX IRQSTEER interrupt multiplexer/remapper.
Support for the i.MX and S32 IRQSTEER interrupt multiplexer/remapper.
config IMX_INTMUX
bool "i.MX INTMUX support" if COMPILE_TEST
@@ -761,7 +764,6 @@ config LOONGSON_PCH_MSI
config LOONGSON_PCH_LPC
bool "Loongson PCH LPC Controller"
depends on LOONGARCH
depends on MACH_LOONGSON64 || LOONGARCH
default MACH_LOONGSON64
select IRQ_DOMAIN_HIERARCHY
+21 -3
View File
@@ -134,8 +134,12 @@
#define AIC2_IRQ_CFG 0x2000
/* AIC v3 registers (MMIO) */
#define AIC3_IRQ_CFG 0x10000
/*
* AIC2 registers are laid out like this, starting at AIC2_IRQ_CFG:
* AIC3 registers use the same layout but start at AIC3_IRQ_CFG:
*
* Repeat for each die:
* IRQ_CFG: u32 * MAX_IRQS
@@ -293,6 +297,15 @@ static const struct aic_info aic2_info __initconst = {
.local_fast_ipi = true,
};
static const struct aic_info aic3_info __initconst = {
.version = 3,
.irq_cfg = AIC3_IRQ_CFG,
.fast_ipi = true,
.local_fast_ipi = true,
};
static const struct of_device_id aic_info_match[] = {
{
.compatible = "apple,t8103-aic",
@@ -310,6 +323,10 @@ static const struct of_device_id aic_info_match[] = {
.compatible = "apple,aic2",
.data = &aic2_info,
},
{
.compatible = "apple,t8122-aic3",
.data = &aic3_info,
},
{}
};
@@ -620,7 +637,7 @@ static int aic_irq_domain_map(struct irq_domain *id, unsigned int irq,
u32 type = FIELD_GET(AIC_EVENT_TYPE, hw);
struct irq_chip *chip = &aic_chip;
if (ic->info.version == 2)
if (ic->info.version == 2 || ic->info.version == 3)
chip = &aic2_chip;
if (type == AIC_EVENT_TYPE_IRQ) {
@@ -991,7 +1008,7 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
break;
}
case 2: {
case 2 ... 3: {
u32 info1, info3;
info1 = aic_ic_read(irqc, AIC2_INFO1);
@@ -1065,7 +1082,7 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
off += irqc->info.die_stride;
}
if (irqc->info.version == 2) {
if (irqc->info.version == 2 || irqc->info.version == 3) {
u32 config = aic_ic_read(irqc, AIC2_CONFIG);
config |= AIC2_CONFIG_ENABLE;
@@ -1116,3 +1133,4 @@ err_unmap:
IRQCHIP_DECLARE(apple_aic, "apple,aic", aic_of_ic_init);
IRQCHIP_DECLARE(apple_aic2, "apple,aic2", aic_of_ic_init);
IRQCHIP_DECLARE(apple_aic3, "apple,t8122-aic3", aic_of_ic_init);
+9 -1
View File
@@ -1603,15 +1603,23 @@ static int gic_irq_domain_translate(struct irq_domain *d,
switch (fwspec->param[0]) {
case 0: /* SPI */
if (fwspec->param[1] > 987)
pr_warn_once("SPI %u out of range (use ESPI?)\n", fwspec->param[1]);
*hwirq = fwspec->param[1] + 32;
break;
case 1: /* PPI */
if (fwspec->param[1] > 15)
pr_warn_once("PPI %u out of range (use EPPI?)\n", fwspec->param[1]);
*hwirq = fwspec->param[1] + 16;
break;
case 2: /* ESPI */
if (fwspec->param[1] > 1023)
pr_warn_once("ESPI %u out of range\n", fwspec->param[1]);
*hwirq = fwspec->param[1] + ESPI_BASE_INTID;
break;
case 3: /* EPPI */
if (fwspec->param[1] > 63)
pr_warn_once("EPPI %u out of range\n", fwspec->param[1]);
*hwirq = fwspec->param[1] + EPPI_BASE_INTID;
break;
case GIC_IRQ_TYPE_LPI: /* LPI */
@@ -2252,7 +2260,7 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
out_unmap_rdist:
for (i = 0; i < nr_redist_regions; i++)
if (rdist_regs[i].redist_base && !IS_ERR(rdist_regs[i].redist_base))
if (!IS_ERR_OR_NULL(rdist_regs[i].redist_base))
iounmap(rdist_regs[i].redist_base);
kfree(rdist_regs);
out_unmap_dist:
+41 -14
View File
@@ -26,19 +26,38 @@
#define CHAN_MAX_OUTPUT_INT 0xF
struct irqsteer_data {
void __iomem *regs;
struct clk *ipg_clk;
int irq[CHAN_MAX_OUTPUT_INT];
int irq_count;
raw_spinlock_t lock;
int reg_num;
int channel;
struct irq_domain *domain;
u32 *saved_reg;
struct device *dev;
/* SoC does not implement the CHANCTRL register */
#define IRQSTEER_QUIRK_NO_CHANCTRL BIT(0)
struct irqsteer_devtype_data {
u32 quirks;
};
struct irqsteer_data {
void __iomem *regs;
struct clk *ipg_clk;
int irq[CHAN_MAX_OUTPUT_INT];
int irq_count;
raw_spinlock_t lock;
int reg_num;
int channel;
struct irq_domain *domain;
u32 *saved_reg;
struct device *dev;
const struct irqsteer_devtype_data *devtype_data;
};
static const struct irqsteer_devtype_data imx_data = { };
static const struct irqsteer_devtype_data s32n79_data = {
.quirks = IRQSTEER_QUIRK_NO_CHANCTRL,
};
static bool irqsteer_has_chanctrl(const struct irqsteer_devtype_data *data)
{
return !(data->quirks & IRQSTEER_QUIRK_NO_CHANCTRL);
}
static int imx_irqsteer_get_reg_index(struct irqsteer_data *data,
unsigned long irqnum)
{
@@ -188,6 +207,10 @@ static int imx_irqsteer_probe(struct platform_device *pdev)
if (ret)
return ret;
data->devtype_data = device_get_match_data(&pdev->dev);
if (!data->devtype_data)
return dev_err_probe(&pdev->dev, -ENODEV, "failed to match device data\n");
/*
* There is one output irq for each group of 64 inputs.
* One register bit map can represent 32 input interrupts.
@@ -210,7 +233,8 @@ static int imx_irqsteer_probe(struct platform_device *pdev)
}
/* steer all IRQs into configured channel */
writel_relaxed(BIT(data->channel), data->regs + CHANCTRL);
if (irqsteer_has_chanctrl(data->devtype_data))
writel_relaxed(BIT(data->channel), data->regs + CHANCTRL);
data->domain = irq_domain_create_linear(dev_fwnode(&pdev->dev), data->reg_num * 32,
&imx_irqsteer_domain_ops, data);
@@ -279,7 +303,9 @@ static void imx_irqsteer_restore_regs(struct irqsteer_data *data)
{
int i;
writel_relaxed(BIT(data->channel), data->regs + CHANCTRL);
if (irqsteer_has_chanctrl(data->devtype_data))
writel_relaxed(BIT(data->channel), data->regs + CHANCTRL);
for (i = 0; i < data->reg_num; i++)
writel_relaxed(data->saved_reg[i],
data->regs + CHANMASK(i, data->reg_num));
@@ -319,7 +345,8 @@ static const struct dev_pm_ops imx_irqsteer_pm_ops = {
};
static const struct of_device_id imx_irqsteer_dt_ids[] = {
{ .compatible = "fsl,imx-irqsteer", },
{ .compatible = "fsl,imx-irqsteer", .data = &imx_data },
{ .compatible = "nxp,s32n79-irqsteer", .data = &s32n79_data },
{},
};
+72 -20
View File
@@ -13,6 +13,8 @@
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/kernel.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/syscore_ops.h>
#include "irq-loongson.h"
@@ -175,13 +177,10 @@ static struct syscore pch_lpc_syscore = {
.ops = &pch_lpc_syscore_ops,
};
int __init pch_lpc_acpi_init(struct irq_domain *parent,
struct acpi_madt_lpc_pic *acpi_pchlpc)
static int __init pch_lpc_init(phys_addr_t addr, unsigned long size,
struct fwnode_handle *irq_handle, int parent_irq)
{
int parent_irq;
struct pch_lpc *priv;
struct irq_fwspec fwspec;
struct fwnode_handle *irq_handle;
priv = kzalloc_obj(*priv);
if (!priv)
@@ -189,7 +188,7 @@ int __init pch_lpc_acpi_init(struct irq_domain *parent,
raw_spin_lock_init(&priv->lpc_lock);
priv->base = ioremap(acpi_pchlpc->address, acpi_pchlpc->size);
priv->base = ioremap(addr, size);
if (!priv->base)
goto free_priv;
@@ -198,12 +197,6 @@ int __init pch_lpc_acpi_init(struct irq_domain *parent,
goto iounmap_base;
}
irq_handle = irq_domain_alloc_named_fwnode("lpcintc");
if (!irq_handle) {
pr_err("Unable to allocate domain handle\n");
goto iounmap_base;
}
/*
* The LPC interrupt controller is a legacy i8259-compatible device,
* which requires a static 1:1 mapping for IRQs 0-15.
@@ -213,15 +206,10 @@ int __init pch_lpc_acpi_init(struct irq_domain *parent,
&pch_lpc_domain_ops, priv);
if (!priv->lpc_domain) {
pr_err("Failed to create IRQ domain\n");
goto free_irq_handle;
goto iounmap_base;
}
pch_lpc_reset(priv);
fwspec.fwnode = parent->fwnode;
fwspec.param[0] = acpi_pchlpc->cascade + GSI_MIN_PCH_IRQ;
fwspec.param[1] = IRQ_TYPE_LEVEL_HIGH;
fwspec.param_count = 2;
parent_irq = irq_create_fwspec_mapping(&fwspec);
irq_set_chained_handler_and_data(parent_irq, lpc_irq_dispatch, priv);
pch_lpc_priv = priv;
@@ -230,8 +218,6 @@ int __init pch_lpc_acpi_init(struct irq_domain *parent,
return 0;
free_irq_handle:
irq_domain_free_fwnode(irq_handle);
iounmap_base:
iounmap(priv->base);
free_priv:
@@ -239,3 +225,69 @@ free_priv:
return -ENOMEM;
}
#ifdef CONFIG_ACPI
int __init pch_lpc_acpi_init(struct irq_domain *parent, struct acpi_madt_lpc_pic *acpi_pchlpc)
{
struct fwnode_handle *irq_handle;
struct irq_fwspec fwspec;
int parent_irq, ret;
irq_handle = irq_domain_alloc_named_fwnode("lpcintc");
if (!irq_handle) {
pr_err("Unable to allocate domain handle\n");
return -ENOMEM;
}
fwspec.fwnode = parent->fwnode;
fwspec.param[0] = acpi_pchlpc->cascade + GSI_MIN_PCH_IRQ;
fwspec.param[1] = IRQ_TYPE_LEVEL_HIGH;
fwspec.param_count = 2;
parent_irq = irq_create_fwspec_mapping(&fwspec);
if (parent_irq <= 0) {
pr_err("Unable to map LPC parent interrupt\n");
irq_domain_free_fwnode(irq_handle);
return -ENOMEM;
}
ret = pch_lpc_init(acpi_pchlpc->address, acpi_pchlpc->size, irq_handle, parent_irq);
if (ret) {
irq_dispose_mapping(parent_irq);
irq_domain_free_fwnode(irq_handle);
return ret;
}
return 0;
}
#endif /* CONFIG_ACPI */
#ifdef CONFIG_OF
static int __init pch_lpc_of_init(struct device_node *node, struct device_node *parent)
{
struct fwnode_handle *irq_handle;
struct resource res;
int parent_irq, ret;
if (of_address_to_resource(node, 0, &res))
return -EINVAL;
parent_irq = irq_of_parse_and_map(node, 0);
if (!parent_irq) {
pr_err("Failed to get the parent IRQ for LPC IRQs\n");
return -EINVAL;
}
irq_handle = of_fwnode_handle(node);
ret = pch_lpc_init(res.start, resource_size(&res), irq_handle,
parent_irq);
if (ret) {
irq_dispose_mapping(parent_irq);
return ret;
}
return 0;
}
IRQCHIP_DECLARE(pch_lpc, "loongson,ls7a-lpc", pch_lpc_of_init);
#endif /* CONFIG_OF */
+1 -1
View File
@@ -217,7 +217,7 @@ err_unmap:
for (i = 0; i < odmis_count; i++) {
struct odmi_data *odmi = &odmis[i];
if (odmi->base && !IS_ERR(odmi->base))
if (!IS_ERR_OR_NULL(odmi->base))
iounmap(odmis[i].base);
}
bitmap_free(odmis_bm);
+7 -1
View File
@@ -15,8 +15,10 @@
#include <linux/irq.h>
#include <linux/platform_data/pic32.h>
#ifdef CONFIG_MIPS
#include <asm/irq.h>
#include <asm/traps.h>
#endif
#define REG_INTCON 0x0000
#define REG_INTSTAT 0x0020
@@ -40,6 +42,7 @@ struct evic_chip_data {
static struct irq_domain *evic_irq_domain;
static void __iomem *evic_base;
#ifdef CONFIG_MIPS
asmlinkage void __weak plat_irq_dispatch(void)
{
unsigned int hwirq;
@@ -47,6 +50,9 @@ asmlinkage void __weak plat_irq_dispatch(void)
hwirq = readl(evic_base + REG_INTSTAT) & 0xFF;
do_domain_IRQ(evic_irq_domain, hwirq);
}
#else
static __maybe_unused void (*board_bind_eic_interrupt)(int irq, int regset);
#endif
static struct evic_chip_data *irqd_to_priv(struct irq_data *data)
{
@@ -196,7 +202,7 @@ static void __init pic32_ext_irq_of_init(struct irq_domain *domain)
of_property_for_each_u32(node, pname, hwirq) {
if (i >= ARRAY_SIZE(priv->ext_irqs)) {
pr_warn("More than %d external irq, skip rest\n",
pr_warn("More than %zu external irq, skip rest\n",
ARRAY_SIZE(priv->ext_irqs));
break;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff