Boring updates for interrupt drivers:

- Support for a couple of new ARM64 and RISCV SoC variants and their
     magic interrupt controllers which either can reuse existing code or
     require quirks due to a botched hardware implementation.
 
   - More section mismatch fixes.
 
   - The usual cleanups and fixes all over the place.
 -----BEGIN PGP SIGNATURE-----
 
 iQJHBAABCgAxFiEEQp8+kY+LLUocC4bMphj1TA10mKEFAmkswMYTHHRnbHhAbGlu
 dXRyb25peC5kZQAKCRCmGPVMDXSYoZvSEACZdCx7vO2XX7oef7DxQ6EKFA/NQvd0
 xJGFTBlrxIucp26yUxWKkuDVdhu8WYe13zJG6+LVl9IxH3IIBa2duQ4HhIyqxuz6
 z74IDjBlOcKAHu2xLFJmBIS4vGTd6UPOg1KvSrIFd9oiuMXikphbnFgyrFGAFiSQ
 J1gP7mKZATUH08mTXK5k1pmBIbMjEHpyyTdBEJKoVgiN/MB/qsq95dy0Oxal+C13
 1cOKBaFreTMdX+77U5RucBcGaLHW4SdoaAVaqc/UXw2c2TAezbt/gPYexRpkdVaG
 2tuYTWIfCUuHbjUoOOYwI+ILnuiBMzjxlIUx3uSvcvtUVO4YuMDR4JOWVsevtfgI
 uUV+4OPq9kBI6PNqAyo16NhDdZ9rmjg3q14F9oyidQfR5gRbsZPPDmtCB/M2jbE1
 n3LlsHUJt0UYo8ZqCPrGhiw9hkGXv4wsEl10FKkyoNrQ0Y4SCUrdzGdr6vwhAAub
 yxMe1+BrFQT23R9l+qVrUZmDmpV9tlFNr6rPwtucrQX3PMWEfAeCc6a/vjY3eqJl
 sZ4pGyFEx0cwfKzHu1/SmNpnjSNdyc7niiN8HAQ7AnxzRW13fDdGQuuVGsKxHyJc
 Tke9wJsyUO4MxpSQDI+cmpsF8OeJDHuRDKMBdLFxlLPhABECdLUO0qKq9l0Ry/Ji
 uDkc3WvM14zKpw==
 =kdyt
 -----END PGP SIGNATURE-----

Merge tag 'irq-drivers-2025-11-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq driver updates from Thomas Gleixner:
 "Boring updates for interrupt drivers:

   - Support for a couple of new ARM64 and RISCV SoC variants and their
     magic interrupt controllers which either can reuse existing code or
     require quirks due to a botched hardware implementation

   - More section mismatch fixes

   - The usual cleanups and fixes all over the place"

* tag 'irq-drivers-2025-11-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (32 commits)
  irqchip/meson-gpio: Add support for Amlogic S6 S7 and S7D SoCs
  dt-bindings: interrupt-controller: Add support for Amlogic S6 S7 and S7D SoCs
  dt-bindings: interrupt-controller: aspeed,ast2700: Correct #interrupt-cells and interrupts count
  irqchip/aclint-sswi: Add Nuclei UX900 support
  dt-bindings: interrupt-controller: Add Anlogic DR1V90 ACLINT SSWI
  dt-bindings: interrupt-controller: Add Anlogic DR1V90 ACLINT MSWI
  dt-bindings: interrupt-controller: Add Anlogic DR1V90 PLIC
  irqchip/irq-bcm7038-l1: Remove unused reg_mask_status()
  irqchip/sifive-plic: Fix call to __plic_toggle() in M-Mode code path
  irqchip/sifive-plic: Add support for UltraRISC DP1000 PLIC
  irqchip/sifive-plic: Cache the interrupt enable state
  dt-bindings: interrupt-controller: Add UltraRISC DP1000 PLIC
  dt-bindings: vendor-prefixes: Add UltraRISC
  irqchip/qcom-irq-combiner: Rename driver structure
  irqchip/riscv-imsic: Inline imsic_vector_from_local_id()
  irqchip/riscv-imsic: Embed the vector array in lpriv
  irqchip/riscv-imsic: Remove redundant irq_data lookups
  irqchip/ts4800: Drop unused module alias
  irqchip/mvebu-pic: Drop unused module alias
  irqchip/meson-gpio: Drop unused module alias
  ...
This commit is contained in:
Linus Torvalds 2025-12-02 09:32:53 -08:00
commit 15b87bec89
30 changed files with 264 additions and 223 deletions

View File

@ -39,6 +39,9 @@ properties:
- amlogic,a4-gpio-ao-intc
- amlogic,a5-gpio-intc
- amlogic,c3-gpio-intc
- amlogic,s6-gpio-intc
- amlogic,s7-gpio-intc
- amlogic,s7d-gpio-intc
- amlogic,t7-gpio-intc
- const: amlogic,meson-gpio-intc

View File

@ -25,13 +25,14 @@ properties:
interrupt-controller: true
'#interrupt-cells':
const: 2
const: 1
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
minItems: 1
maxItems: 10
description: |
Depend to which INTC0 or INTC1 used.
INTC0 and INTC1 are two kinds of interrupt controller with enable and raw
@ -74,13 +75,17 @@ examples:
interrupt-controller@12101b00 {
compatible = "aspeed,ast2700-intc-ic";
reg = <0 0x12101b00 0 0x10>;
#interrupt-cells = <2>;
#interrupt-cells = <1>;
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>;
<GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>;
};
};

View File

@ -58,6 +58,7 @@ properties:
- const: andestech,nceplic100
- items:
- enum:
- anlogic,dr1v90-plic
- canaan,k210-plic
- eswin,eic7700-plic
- sifive,fu540-c000-plic
@ -75,6 +76,9 @@ properties:
- sophgo,sg2044-plic
- thead,th1520-plic
- const: thead,c900-plic
- items:
- const: ultrarisc,dp1000-plic
- const: ultrarisc,cp100-plic
- items:
- const: sifive,plic-1.0.0
- const: riscv,plic0

View File

@ -4,18 +4,23 @@
$id: http://devicetree.org/schemas/interrupt-controller/thead,c900-aclint-mswi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Sophgo sg2042 CLINT Machine-level Software Interrupt Device
title: ACLINT Machine-level Software Interrupt Device
maintainers:
- Inochi Amaoto <inochiama@outlook.com>
properties:
compatible:
items:
- enum:
- sophgo,sg2042-aclint-mswi
- sophgo,sg2044-aclint-mswi
- const: thead,c900-aclint-mswi
oneOf:
- items:
- enum:
- sophgo,sg2042-aclint-mswi
- sophgo,sg2044-aclint-mswi
- const: thead,c900-aclint-mswi
- items:
- enum:
- anlogic,dr1v90-aclint-mswi
- const: nuclei,ux900-aclint-mswi
reg:
maxItems: 1

View File

@ -30,6 +30,10 @@ properties:
- const: thead,c900-aclint-sswi
- items:
- const: mips,p8700-aclint-sswi
- items:
- enum:
- anlogic,dr1v90-aclint-sswi
- const: nuclei,ux900-aclint-sswi
reg:
maxItems: 1

View File

@ -1705,6 +1705,8 @@ patternProperties:
description: Universal Scientific Industrial Co., Ltd.
"^usr,.*":
description: U.S. Robotics Corporation
"^ultrarisc,.*":
description: UltraRISC Technology Co., Ltd.
"^ultratronik,.*":
description: Ultratronik GmbH
"^utoo,.*":

View File

@ -150,7 +150,7 @@ config BCM6345_L1_IRQ
config BCM7038_L1_IRQ
tristate "Broadcom STB 7038-style L1/L2 interrupt controller driver"
depends on ARCH_BRCMSTB || BMIPS_GENERIC
depends on ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST
default ARCH_BRCMSTB || BMIPS_GENERIC
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
@ -158,14 +158,14 @@ config BCM7038_L1_IRQ
config BCM7120_L2_IRQ
tristate "Broadcom STB 7120-style L2 interrupt controller driver"
depends on ARCH_BRCMSTB || BMIPS_GENERIC
depends on ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST
default ARCH_BRCMSTB || BMIPS_GENERIC
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
config BRCMSTB_L2_IRQ
tristate "Broadcom STB generic L2 interrupt controller driver"
depends on ARCH_BCM2835 || ARCH_BRCMSTB || BMIPS_GENERIC
depends on ARCH_BCM2835 || ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST
default ARCH_BCM2835 || ARCH_BRCMSTB || BMIPS_GENERIC
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN

View File

@ -175,7 +175,8 @@ static int __init generic_aclint_sswi_early_probe(struct device_node *node,
{
return generic_aclint_sswi_probe(&node->fwnode);
}
IRQCHIP_DECLARE(generic_aclint_sswi, "mips,p8700-aclint-sswi", generic_aclint_sswi_early_probe);
IRQCHIP_DECLARE(mips_p8700_sswi, "mips,p8700-aclint-sswi", generic_aclint_sswi_early_probe);
IRQCHIP_DECLARE(nuclei_ux900_sswi, "nuclei,ux900-aclint-sswi", generic_aclint_sswi_early_probe);
/* THEAD variant */
#define THEAD_C9XX_CSR_SXSTATUS 0x5c0

View File

@ -232,17 +232,12 @@ static int mip_parse_dt(struct mip_priv *mip, struct device_node *np)
return ret;
}
static int __init mip_of_msi_init(struct device_node *node, struct device_node *parent)
static int mip_msi_probe(struct platform_device *pdev, struct device_node *parent)
{
struct platform_device *pdev;
struct device_node *node = pdev->dev.of_node;
struct mip_priv *mip;
int ret;
pdev = of_find_device_by_node(node);
of_node_put(node);
if (!pdev)
return -EPROBE_DEFER;
mip = kzalloc(sizeof(*mip), GFP_KERNEL);
if (!mip)
return -ENOMEM;
@ -285,7 +280,7 @@ static int __init mip_of_msi_init(struct device_node *node, struct device_node *
}
IRQCHIP_PLATFORM_DRIVER_BEGIN(mip_msi)
IRQCHIP_MATCH("brcm,bcm2712-mip", mip_of_msi_init)
IRQCHIP_MATCH("brcm,bcm2712-mip", mip_msi_probe)
IRQCHIP_PLATFORM_DRIVER_END(mip_msi)
MODULE_DESCRIPTION("Broadcom BCM2712 MSI-X interrupt controller");
MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.com>");

View File

@ -82,12 +82,6 @@ static inline unsigned int reg_status(struct bcm7038_l1_chip *intc,
return (0 * intc->n_words + word) * sizeof(u32);
}
static inline unsigned int reg_mask_status(struct bcm7038_l1_chip *intc,
unsigned int word)
{
return (1 * intc->n_words + word) * sizeof(u32);
}
static inline unsigned int reg_mask_set(struct bcm7038_l1_chip *intc,
unsigned int word)
{
@ -219,9 +213,8 @@ static int bcm7038_l1_set_affinity(struct irq_data *d,
}
#endif
static int __init bcm7038_l1_init_one(struct device_node *dn,
unsigned int idx,
struct bcm7038_l1_chip *intc)
static int bcm7038_l1_init_one(struct device_node *dn, unsigned int idx,
struct bcm7038_l1_chip *intc)
{
struct resource res;
resource_size_t sz;
@ -395,9 +388,9 @@ static const struct irq_domain_ops bcm7038_l1_domain_ops = {
.map = bcm7038_l1_map,
};
static int __init bcm7038_l1_of_init(struct device_node *dn,
struct device_node *parent)
static int bcm7038_l1_probe(struct platform_device *pdev, struct device_node *parent)
{
struct device_node *dn = pdev->dev.of_node;
struct bcm7038_l1_chip *intc;
int idx, ret;
@ -455,7 +448,7 @@ static int __init bcm7038_l1_of_init(struct device_node *dn,
}
IRQCHIP_PLATFORM_DRIVER_BEGIN(bcm7038_l1)
IRQCHIP_MATCH("brcm,bcm7038-l1-intc", bcm7038_l1_of_init)
IRQCHIP_MATCH("brcm,bcm7038-l1-intc", bcm7038_l1_probe)
IRQCHIP_PLATFORM_DRIVER_END(bcm7038_l1)
MODULE_DESCRIPTION("Broadcom STB 7038-style L1/L2 interrupt controller");
MODULE_LICENSE("GPL v2");

View File

@ -143,8 +143,7 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn,
return 0;
}
static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn,
struct bcm7120_l2_intc_data *data)
static int bcm7120_l2_intc_iomap_7120(struct device_node *dn, struct bcm7120_l2_intc_data *data)
{
int ret;
@ -177,8 +176,7 @@ static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn,
return 0;
}
static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn,
struct bcm7120_l2_intc_data *data)
static int bcm7120_l2_intc_iomap_3380(struct device_node *dn, struct bcm7120_l2_intc_data *data)
{
unsigned int gc_idx;
@ -208,15 +206,14 @@ static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn,
return 0;
}
static int __init bcm7120_l2_intc_probe(struct device_node *dn,
struct device_node *parent,
static int bcm7120_l2_intc_probe(struct platform_device *pdev, struct device_node *parent,
int (*iomap_regs_fn)(struct device_node *,
struct bcm7120_l2_intc_data *),
struct bcm7120_l2_intc_data *),
const char *intc_name)
{
unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
struct device_node *dn = pdev->dev.of_node;
struct bcm7120_l2_intc_data *data;
struct platform_device *pdev;
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
int ret = 0;
@ -227,14 +224,7 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn,
if (!data)
return -ENOMEM;
pdev = of_find_device_by_node(dn);
if (!pdev) {
ret = -ENODEV;
goto out_free_data;
}
data->num_parent_irqs = platform_irq_count(pdev);
put_device(&pdev->dev);
if (data->num_parent_irqs <= 0) {
pr_err("invalid number of parent interrupts\n");
ret = -ENOMEM;
@ -334,22 +324,19 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn,
if (data->map_base[idx])
iounmap(data->map_base[idx]);
}
out_free_data:
kfree(data);
return ret;
}
static int __init bcm7120_l2_intc_probe_7120(struct device_node *dn,
struct device_node *parent)
static int bcm7120_l2_intc_probe_7120(struct platform_device *pdev, struct device_node *parent)
{
return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_7120,
return bcm7120_l2_intc_probe(pdev, parent, bcm7120_l2_intc_iomap_7120,
"BCM7120 L2");
}
static int __init bcm7120_l2_intc_probe_3380(struct device_node *dn,
struct device_node *parent)
static int bcm7120_l2_intc_probe_3380(struct platform_device *pdev, struct device_node *parent)
{
return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_3380,
return bcm7120_l2_intc_probe(pdev, parent, bcm7120_l2_intc_iomap_3380,
"BCM3380 L2");
}

View File

@ -138,13 +138,12 @@ static void brcmstb_l2_intc_resume(struct irq_data *d)
irq_reg_writel(gc, ~b->saved_mask, ct->regs.enable);
}
static int __init brcmstb_l2_intc_of_init(struct device_node *np,
struct device_node *parent,
const struct brcmstb_intc_init_params
*init_params)
static int brcmstb_l2_intc_probe(struct platform_device *pdev, struct device_node *parent,
const struct brcmstb_intc_init_params *init_params)
{
unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
unsigned int set = 0;
struct device_node *np = pdev->dev.of_node;
struct brcmstb_l2_intc_data *data;
struct irq_chip_type *ct;
int ret;
@ -257,23 +256,21 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np,
return ret;
}
static int __init brcmstb_l2_edge_intc_of_init(struct device_node *np,
struct device_node *parent)
static int brcmstb_l2_edge_intc_probe(struct platform_device *pdev, struct device_node *parent)
{
return brcmstb_l2_intc_of_init(np, parent, &l2_edge_intc_init);
return brcmstb_l2_intc_probe(pdev, parent, &l2_edge_intc_init);
}
static int __init brcmstb_l2_lvl_intc_of_init(struct device_node *np,
struct device_node *parent)
static int brcmstb_l2_lvl_intc_probe(struct platform_device *pdev, struct device_node *parent)
{
return brcmstb_l2_intc_of_init(np, parent, &l2_lvl_intc_init);
return brcmstb_l2_intc_probe(pdev, parent, &l2_lvl_intc_init);
}
IRQCHIP_PLATFORM_DRIVER_BEGIN(brcmstb_l2)
IRQCHIP_MATCH("brcm,l2-intc", brcmstb_l2_edge_intc_of_init)
IRQCHIP_MATCH("brcm,hif-spi-l2-intc", brcmstb_l2_edge_intc_of_init)
IRQCHIP_MATCH("brcm,upg-aux-aon-l2-intc", brcmstb_l2_edge_intc_of_init)
IRQCHIP_MATCH("brcm,bcm7271-l2-intc", brcmstb_l2_lvl_intc_of_init)
IRQCHIP_MATCH("brcm,l2-intc", brcmstb_l2_edge_intc_probe)
IRQCHIP_MATCH("brcm,hif-spi-l2-intc", brcmstb_l2_edge_intc_probe)
IRQCHIP_MATCH("brcm,upg-aux-aon-l2-intc", brcmstb_l2_edge_intc_probe)
IRQCHIP_MATCH("brcm,bcm7271-l2-intc", brcmstb_l2_lvl_intc_probe)
IRQCHIP_PLATFORM_DRIVER_END(brcmstb_l2)
MODULE_DESCRIPTION("Broadcom STB generic L2 interrupt controller");
MODULE_LICENSE("GPL v2");

View File

@ -296,11 +296,9 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = {
},
};
static int __init imx_mu_of_init(struct device_node *dn,
struct device_node *parent,
const struct imx_mu_dcfg *cfg)
static int imx_mu_probe(struct platform_device *pdev, struct device_node *parent,
const struct imx_mu_dcfg *cfg)
{
struct platform_device *pdev = of_find_device_by_node(dn);
struct device_link *pd_link_a;
struct device_link *pd_link_b;
struct imx_mu_msi *msi_data;
@ -416,31 +414,27 @@ static const struct dev_pm_ops imx_mu_pm_ops = {
imx_mu_runtime_resume, NULL)
};
static int __init imx_mu_imx7ulp_of_init(struct device_node *dn,
struct device_node *parent)
static int imx_mu_imx7ulp_probe(struct platform_device *pdev, struct device_node *parent)
{
return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx7ulp);
return imx_mu_probe(pdev, parent, &imx_mu_cfg_imx7ulp);
}
static int __init imx_mu_imx6sx_of_init(struct device_node *dn,
struct device_node *parent)
static int imx_mu_imx6sx_probe(struct platform_device *pdev, struct device_node *parent)
{
return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx6sx);
return imx_mu_probe(pdev, parent, &imx_mu_cfg_imx6sx);
}
static int __init imx_mu_imx8ulp_of_init(struct device_node *dn,
struct device_node *parent)
static int imx_mu_imx8ulp_probe(struct platform_device *pdev, struct device_node *parent)
{
return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx8ulp);
return imx_mu_probe(pdev, parent, &imx_mu_cfg_imx8ulp);
}
IRQCHIP_PLATFORM_DRIVER_BEGIN(imx_mu_msi)
IRQCHIP_MATCH("fsl,imx7ulp-mu-msi", imx_mu_imx7ulp_of_init)
IRQCHIP_MATCH("fsl,imx6sx-mu-msi", imx_mu_imx6sx_of_init)
IRQCHIP_MATCH("fsl,imx8ulp-mu-msi", imx_mu_imx8ulp_of_init)
IRQCHIP_MATCH("fsl,imx7ulp-mu-msi", imx_mu_imx7ulp_probe)
IRQCHIP_MATCH("fsl,imx6sx-mu-msi", imx_mu_imx6sx_probe)
IRQCHIP_MATCH("fsl,imx8ulp-mu-msi", imx_mu_imx8ulp_probe)
IRQCHIP_PLATFORM_DRIVER_END(imx_mu_msi, .pm = &imx_mu_pm_ops)
MODULE_AUTHOR("Frank Li <Frank.Li@nxp.com>");
MODULE_DESCRIPTION("Freescale MU MSI controller driver");
MODULE_LICENSE("GPL");

View File

@ -199,8 +199,9 @@ static const struct irq_domain_ops mchp_eic_domain_ops = {
.free = irq_domain_free_irqs_common,
};
static int mchp_eic_init(struct device_node *node, struct device_node *parent)
static int mchp_eic_probe(struct platform_device *pdev, struct device_node *parent)
{
struct device_node *node = pdev->dev.of_node;
struct irq_domain *parent_domain = NULL;
int ret, i;
@ -273,7 +274,7 @@ static int mchp_eic_init(struct device_node *node, struct device_node *parent)
}
IRQCHIP_PLATFORM_DRIVER_BEGIN(mchp_eic)
IRQCHIP_MATCH("microchip,sama7g5-eic", mchp_eic_init)
IRQCHIP_MATCH("microchip,sama7g5-eic", mchp_eic_probe)
IRQCHIP_PLATFORM_DRIVER_END(mchp_eic)
MODULE_DESCRIPTION("Microchip External Interrupt Controller");

View File

@ -174,6 +174,14 @@ static const struct meson_gpio_irq_params s4_params = {
INIT_MESON_S4_COMMON_DATA(82)
};
static const struct meson_gpio_irq_params s6_params = {
INIT_MESON_S4_COMMON_DATA(100)
};
static const struct meson_gpio_irq_params s7_params = {
INIT_MESON_S4_COMMON_DATA(84)
};
static const struct meson_gpio_irq_params c3_params = {
INIT_MESON_S4_COMMON_DATA(55)
};
@ -195,6 +203,9 @@ static const struct of_device_id meson_irq_gpio_matches[] __maybe_unused = {
{ .compatible = "amlogic,a4-gpio-ao-intc", .data = &a4_ao_params },
{ .compatible = "amlogic,a4-gpio-intc", .data = &a4_params },
{ .compatible = "amlogic,a5-gpio-intc", .data = &a5_params },
{ .compatible = "amlogic,s6-gpio-intc", .data = &s6_params },
{ .compatible = "amlogic,s7-gpio-intc", .data = &s7_params },
{ .compatible = "amlogic,s7d-gpio-intc", .data = &s7_params },
{ .compatible = "amlogic,c3-gpio-intc", .data = &c3_params },
{ .compatible = "amlogic,t7-gpio-intc", .data = &t7_params },
{ }
@ -572,8 +583,9 @@ static int meson_gpio_irq_parse_dt(struct device_node *node, struct meson_gpio_i
return 0;
}
static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *parent)
static int meson_gpio_irq_probe(struct platform_device *pdev, struct device_node *parent)
{
struct device_node *node = pdev->dev.of_node;
struct irq_domain *domain, *parent_domain;
struct meson_gpio_irq_controller *ctl;
int ret;
@ -630,10 +642,9 @@ static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *
}
IRQCHIP_PLATFORM_DRIVER_BEGIN(meson_gpio_intc)
IRQCHIP_MATCH("amlogic,meson-gpio-intc", meson_gpio_irq_of_init)
IRQCHIP_MATCH("amlogic,meson-gpio-intc", meson_gpio_irq_probe)
IRQCHIP_PLATFORM_DRIVER_END(meson_gpio_intc)
MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
MODULE_DESCRIPTION("Meson GPIO Interrupt Multiplexer driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:meson-gpio-intc");

View File

@ -195,5 +195,3 @@ MODULE_AUTHOR("Yehuda Yitschak <yehuday@marvell.com>");
MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
MODULE_DESCRIPTION("Marvell Armada 7K/8K PIC driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:mvebu_pic");

View File

@ -320,9 +320,9 @@ static bool gic_hwirq_is_mapped(struct mpm_gic_map *maps, int cnt, u32 hwirq)
return false;
}
static int qcom_mpm_init(struct device_node *np, struct device_node *parent)
static int qcom_mpm_probe(struct platform_device *pdev, struct device_node *parent)
{
struct platform_device *pdev = of_find_device_by_node(np);
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
struct irq_domain *parent_domain;
struct generic_pm_domain *genpd;
@ -478,7 +478,7 @@ static int qcom_mpm_init(struct device_node *np, struct device_node *parent)
}
IRQCHIP_PLATFORM_DRIVER_BEGIN(qcom_mpm)
IRQCHIP_MATCH("qcom,mpm", qcom_mpm_init)
IRQCHIP_MATCH("qcom,mpm", qcom_mpm_probe)
IRQCHIP_PLATFORM_DRIVER_END(qcom_mpm)
MODULE_DESCRIPTION("Qualcomm Technologies, Inc. MSM Power Manager");
MODULE_LICENSE("GPL v2");

View File

@ -8,7 +8,6 @@
*/
#include <linux/bitfield.h>
#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
@ -528,18 +527,15 @@ static int rzg2l_irqc_parse_interrupts(struct rzg2l_irqc_priv *priv,
return 0;
}
static int rzg2l_irqc_common_init(struct device_node *node, struct device_node *parent,
const struct irq_chip *irq_chip)
static int rzg2l_irqc_common_probe(struct platform_device *pdev, struct device_node *parent,
const struct irq_chip *irq_chip)
{
struct platform_device *pdev = of_find_device_by_node(node);
struct device *dev __free(put_device) = pdev ? &pdev->dev : NULL;
struct irq_domain *irq_domain, *parent_domain;
struct device_node *node = pdev->dev.of_node;
struct device *dev = &pdev->dev;
struct reset_control *resetn;
int ret;
if (!pdev)
return -ENODEV;
parent_domain = irq_find_host(parent);
if (!parent_domain)
return dev_err_probe(dev, -ENODEV, "cannot find parent domain\n");
@ -583,35 +579,22 @@ static int rzg2l_irqc_common_init(struct device_node *node, struct device_node *
register_syscore_ops(&rzg2l_irqc_syscore_ops);
/*
* Prevent the cleanup function from invoking put_device by assigning
* NULL to dev.
*
* make coccicheck will complain about missing put_device calls, but
* those are false positives, as dev will be automatically "put" via
* __free_put_device on the failing path.
* On the successful path we don't actually want to "put" dev.
*/
dev = NULL;
return 0;
}
static int __init rzg2l_irqc_init(struct device_node *node,
struct device_node *parent)
static int rzg2l_irqc_probe(struct platform_device *pdev, struct device_node *parent)
{
return rzg2l_irqc_common_init(node, parent, &rzg2l_irqc_chip);
return rzg2l_irqc_common_probe(pdev, parent, &rzg2l_irqc_chip);
}
static int __init rzfive_irqc_init(struct device_node *node,
struct device_node *parent)
static int rzfive_irqc_probe(struct platform_device *pdev, struct device_node *parent)
{
return rzg2l_irqc_common_init(node, parent, &rzfive_irqc_chip);
return rzg2l_irqc_common_probe(pdev, parent, &rzfive_irqc_chip);
}
IRQCHIP_PLATFORM_DRIVER_BEGIN(rzg2l_irqc)
IRQCHIP_MATCH("renesas,rzg2l-irqc", rzg2l_irqc_init)
IRQCHIP_MATCH("renesas,r9a07g043f-irqc", rzfive_irqc_init)
IRQCHIP_MATCH("renesas,rzg2l-irqc", rzg2l_irqc_probe)
IRQCHIP_MATCH("renesas,r9a07g043f-irqc", rzfive_irqc_probe)
IRQCHIP_PLATFORM_DRIVER_END(rzg2l_irqc)
MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>");
MODULE_DESCRIPTION("Renesas RZ/G2L IRQC Driver");

View File

@ -490,29 +490,15 @@ static int rzv2h_icu_parse_interrupts(struct rzv2h_icu_priv *priv, struct device
return 0;
}
static void rzv2h_icu_put_device(void *data)
{
put_device(data);
}
static int rzv2h_icu_init_common(struct device_node *node, struct device_node *parent,
const struct rzv2h_hw_info *hw_info)
static int rzv2h_icu_probe_common(struct platform_device *pdev, struct device_node *parent,
const struct rzv2h_hw_info *hw_info)
{
struct irq_domain *irq_domain, *parent_domain;
struct device_node *node = pdev->dev.of_node;
struct rzv2h_icu_priv *rzv2h_icu_data;
struct platform_device *pdev;
struct reset_control *resetn;
int ret;
pdev = of_find_device_by_node(node);
if (!pdev)
return -ENODEV;
ret = devm_add_action_or_reset(&pdev->dev, rzv2h_icu_put_device,
&pdev->dev);
if (ret < 0)
return ret;
parent_domain = irq_find_host(parent);
if (!parent_domain) {
dev_err(&pdev->dev, "cannot find parent domain\n");
@ -618,19 +604,19 @@ static const struct rzv2h_hw_info rzv2h_hw_params = {
.field_width = 8,
};
static int rzg3e_icu_init(struct device_node *node, struct device_node *parent)
static int rzg3e_icu_probe(struct platform_device *pdev, struct device_node *parent)
{
return rzv2h_icu_init_common(node, parent, &rzg3e_hw_params);
return rzv2h_icu_probe_common(pdev, parent, &rzg3e_hw_params);
}
static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
static int rzv2h_icu_probe(struct platform_device *pdev, struct device_node *parent)
{
return rzv2h_icu_init_common(node, parent, &rzv2h_hw_params);
return rzv2h_icu_probe_common(pdev, parent, &rzv2h_hw_params);
}
IRQCHIP_PLATFORM_DRIVER_BEGIN(rzv2h_icu)
IRQCHIP_MATCH("renesas,r9a09g047-icu", rzg3e_icu_init)
IRQCHIP_MATCH("renesas,r9a09g057-icu", rzv2h_icu_init)
IRQCHIP_MATCH("renesas,r9a09g047-icu", rzg3e_icu_probe)
IRQCHIP_MATCH("renesas,r9a09g057-icu", rzv2h_icu_probe)
IRQCHIP_PLATFORM_DRIVER_END(rzv2h_icu)
MODULE_AUTHOR("Fabrizio Castro <fabrizio.castro.jz@renesas.com>");
MODULE_DESCRIPTION("Renesas RZ/V2H(P) ICU Driver");

View File

@ -91,9 +91,8 @@ static int __init imsic_ipi_domain_init(void) { return 0; }
*/
static void imsic_handle_irq(struct irq_desc *desc)
{
struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
struct irq_chip *chip = irq_desc_get_chip(desc);
int cpu = smp_processor_id();
struct imsic_vector *vec;
unsigned long local_id;
/*
@ -113,16 +112,12 @@ static void imsic_handle_irq(struct irq_desc *desc)
continue;
}
if (unlikely(!imsic->base_domain))
continue;
vec = imsic_vector_from_local_id(cpu, local_id);
if (!vec) {
if (unlikely(local_id > imsic->global.nr_ids)) {
pr_warn_ratelimited("vector not found for local ID 0x%lx\n", local_id);
continue;
}
generic_handle_irq(vec->irq);
generic_handle_irq(lpriv->vectors[local_id].irq);
}
chained_irq_exit(chip, desc);

View File

@ -158,11 +158,11 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
tmp_vec.local_id = new_vec->local_id;
/* Point device to the temporary vector */
imsic_msi_update_msg(irq_get_irq_data(d->irq), &tmp_vec);
imsic_msi_update_msg(d, &tmp_vec);
}
/* Point device to the new vector */
imsic_msi_update_msg(irq_get_irq_data(d->irq), new_vec);
imsic_msi_update_msg(d, new_vec);
/* Update irq descriptors with the new vector */
d->chip_data = new_vec;

View File

@ -434,16 +434,6 @@ void imsic_vector_debug_show_summary(struct seq_file *m, int ind)
}
#endif
struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id)
{
struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, cpu);
if (!lpriv || imsic->global.nr_ids < local_id)
return NULL;
return &lpriv->vectors[local_id];
}
struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpumask *mask)
{
struct imsic_vector *vec = NULL;
@ -487,7 +477,6 @@ static void __init imsic_local_cleanup(void)
lpriv = per_cpu_ptr(imsic->lpriv, cpu);
bitmap_free(lpriv->dirty_bitmap);
kfree(lpriv->vectors);
}
free_percpu(imsic->lpriv);
@ -501,7 +490,8 @@ static int __init imsic_local_init(void)
int cpu, i;
/* Allocate per-CPU private state */
imsic->lpriv = alloc_percpu(typeof(*imsic->lpriv));
imsic->lpriv = __alloc_percpu(struct_size(imsic->lpriv, vectors, global->nr_ids + 1),
__alignof__(*imsic->lpriv));
if (!imsic->lpriv)
return -ENOMEM;
@ -521,12 +511,6 @@ static int __init imsic_local_init(void)
timer_setup(&lpriv->timer, imsic_local_timer_callback, TIMER_PINNED);
#endif
/* Allocate vector array */
lpriv->vectors = kcalloc(global->nr_ids + 1, sizeof(*lpriv->vectors),
GFP_KERNEL);
if (!lpriv->vectors)
goto fail_local_cleanup;
/* Setup vector array */
for (i = 0; i <= global->nr_ids; i++) {
vec = &lpriv->vectors[i];

View File

@ -40,7 +40,7 @@ struct imsic_local_priv {
#endif
/* Local vector table */
struct imsic_vector *vectors;
struct imsic_vector vectors[];
};
struct imsic_priv {
@ -95,8 +95,6 @@ static inline struct imsic_vector *imsic_vector_get_move(struct imsic_vector *ve
void imsic_vector_force_move_cleanup(struct imsic_vector *vec);
void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec);
struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id);
struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpumask *mask);
void imsic_vector_free(struct imsic_vector *vector);

View File

@ -49,6 +49,8 @@
#define CONTEXT_ENABLE_BASE 0x2000
#define CONTEXT_ENABLE_SIZE 0x80
#define PENDING_BASE 0x1000
/*
* Each hart context has a set of control registers associated with it. Right
* now there's only two: a source priority threshold over which the hart will
@ -63,6 +65,7 @@
#define PLIC_ENABLE_THRESHOLD 0
#define PLIC_QUIRK_EDGE_INTERRUPT 0
#define PLIC_QUIRK_CP100_CLAIM_REGISTER_ERRATUM 1
struct plic_priv {
struct fwnode_handle *fwnode;
@ -94,15 +97,22 @@ static DEFINE_PER_CPU(struct plic_handler, plic_handlers);
static int plic_irq_set_type(struct irq_data *d, unsigned int type);
static void __plic_toggle(void __iomem *enable_base, int hwirq, int enable)
static void __plic_toggle(struct plic_handler *handler, int hwirq, int enable)
{
u32 __iomem *reg = enable_base + (hwirq / 32) * sizeof(u32);
u32 __iomem *base = handler->enable_base;
u32 hwirq_mask = 1 << (hwirq % 32);
int group = hwirq / 32;
u32 value;
value = readl(base + group);
if (enable)
writel(readl(reg) | hwirq_mask, reg);
value |= hwirq_mask;
else
writel(readl(reg) & ~hwirq_mask, reg);
value &= ~hwirq_mask;
handler->enable_save[group] = value;
writel(value, base + group);
}
static void plic_toggle(struct plic_handler *handler, int hwirq, int enable)
@ -110,7 +120,7 @@ static void plic_toggle(struct plic_handler *handler, int hwirq, int enable)
unsigned long flags;
raw_spin_lock_irqsave(&handler->enable_lock, flags);
__plic_toggle(handler->enable_base, hwirq, enable);
__plic_toggle(handler, hwirq, enable);
raw_spin_unlock_irqrestore(&handler->enable_lock, flags);
}
@ -247,33 +257,16 @@ static int plic_irq_set_type(struct irq_data *d, unsigned int type)
static int plic_irq_suspend(void)
{
unsigned int i, cpu;
unsigned long flags;
u32 __iomem *reg;
struct plic_priv *priv;
priv = per_cpu_ptr(&plic_handlers, smp_processor_id())->priv;
/* irq ID 0 is reserved */
for (i = 1; i < priv->nr_irqs; i++) {
for (unsigned int i = 1; i < priv->nr_irqs; i++) {
__assign_bit(i, priv->prio_save,
readl(priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID));
}
for_each_present_cpu(cpu) {
struct plic_handler *handler = per_cpu_ptr(&plic_handlers, cpu);
if (!handler->present)
continue;
raw_spin_lock_irqsave(&handler->enable_lock, flags);
for (i = 0; i < DIV_ROUND_UP(priv->nr_irqs, 32); i++) {
reg = handler->enable_base + i * sizeof(u32);
handler->enable_save[i] = readl(reg);
}
raw_spin_unlock_irqrestore(&handler->enable_lock, flags);
}
return 0;
}
@ -398,6 +391,98 @@ static void plic_handle_irq(struct irq_desc *desc)
chained_irq_exit(chip, desc);
}
static u32 cp100_isolate_pending_irq(int nr_irq_groups, struct plic_handler *handler)
{
u32 __iomem *pending = handler->priv->regs + PENDING_BASE;
u32 __iomem *enable = handler->enable_base;
u32 pending_irqs = 0;
int i, j;
/* Look for first pending interrupt */
for (i = 0; i < nr_irq_groups; i++) {
/* Any pending interrupts would be annihilated, so skip checking them */
if (!handler->enable_save[i])
continue;
pending_irqs = handler->enable_save[i] & readl_relaxed(pending + i);
if (pending_irqs)
break;
}
if (!pending_irqs)
return 0;
/* Isolate lowest set bit */
pending_irqs &= -pending_irqs;
/* Disable all interrupts but the first pending one */
for (j = 0; j < nr_irq_groups; j++) {
u32 new_mask = j == i ? pending_irqs : 0;
if (new_mask != handler->enable_save[j])
writel_relaxed(new_mask, enable + j);
}
return pending_irqs;
}
static irq_hw_number_t cp100_get_hwirq(struct plic_handler *handler, void __iomem *claim)
{
int nr_irq_groups = DIV_ROUND_UP(handler->priv->nr_irqs, 32);
u32 __iomem *enable = handler->enable_base;
irq_hw_number_t hwirq = 0;
u32 iso_mask;
int i;
guard(raw_spinlock)(&handler->enable_lock);
/* Existing enable state is already cached in enable_save */
iso_mask = cp100_isolate_pending_irq(nr_irq_groups, handler);
if (!iso_mask)
return 0;
/*
* Interrupts delievered to hardware still become pending, but only
* interrupts that are both pending and enabled can be claimed.
* Clearing the enable bit for all interrupts but the first pending
* one avoids a hardware bug that occurs during read from the claim
* register with more than one eligible interrupt.
*/
hwirq = readl(claim);
/* Restore previous state */
for (i = 0; i < nr_irq_groups; i++) {
u32 written = i == hwirq / 32 ? iso_mask : 0;
u32 stored = handler->enable_save[i];
if (stored != written)
writel_relaxed(stored, enable + i);
}
return hwirq;
}
static void plic_handle_irq_cp100(struct irq_desc *desc)
{
struct plic_handler *handler = this_cpu_ptr(&plic_handlers);
struct irq_chip *chip = irq_desc_get_chip(desc);
void __iomem *claim = handler->hart_base + CONTEXT_CLAIM;
irq_hw_number_t hwirq;
WARN_ON_ONCE(!handler->present);
chained_irq_enter(chip, desc);
while ((hwirq = cp100_get_hwirq(handler, claim))) {
int err = generic_handle_domain_irq(handler->priv->irqdomain, hwirq);
if (unlikely(err)) {
pr_warn_ratelimited("%pfwP: can't find mapping for hwirq %lu\n",
handler->priv->fwnode, hwirq);
}
}
chained_irq_exit(chip, desc);
}
static void plic_set_threshold(struct plic_handler *handler, u32 threshold)
{
/* priority must be > threshold to trigger an interrupt */
@ -434,6 +519,8 @@ static const struct of_device_id plic_match[] = {
.data = (const void *)BIT(PLIC_QUIRK_EDGE_INTERRUPT) },
{ .compatible = "thead,c900-plic",
.data = (const void *)BIT(PLIC_QUIRK_EDGE_INTERRUPT) },
{ .compatible = "ultrarisc,cp100-plic",
.data = (const void *)BIT(PLIC_QUIRK_CP100_CLAIM_REGISTER_ERRATUM) },
{}
};
@ -592,12 +679,11 @@ static int plic_probe(struct fwnode_handle *fwnode)
if (parent_hwirq != RV_IRQ_EXT) {
/* Disable S-mode enable bits if running in M-mode. */
if (IS_ENABLED(CONFIG_RISCV_M_MODE)) {
void __iomem *enable_base = priv->regs +
CONTEXT_ENABLE_BASE +
i * CONTEXT_ENABLE_SIZE;
u32 __iomem *enable_base = priv->regs + CONTEXT_ENABLE_BASE +
i * CONTEXT_ENABLE_SIZE;
for (hwirq = 1; hwirq <= nr_irqs; hwirq++)
__plic_toggle(enable_base, hwirq, 0);
for (int j = 0; j <= nr_irqs / 32; j++)
writel(0, enable_base + j);
}
continue;
}
@ -668,12 +754,17 @@ static int plic_probe(struct fwnode_handle *fwnode)
}
if (global_setup) {
void (*handler_fn)(struct irq_desc *) = plic_handle_irq;
if (test_bit(PLIC_QUIRK_CP100_CLAIM_REGISTER_ERRATUM, &handler->priv->plic_quirks))
handler_fn = plic_handle_irq_cp100;
/* Find parent domain and register chained handler */
domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(), DOMAIN_BUS_ANY);
if (domain)
plic_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
if (plic_parent_irq)
irq_set_chained_handler(plic_parent_irq, plic_handle_irq);
irq_set_chained_handler(plic_parent_irq, handler_fn);
cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
"irqchip/sifive/plic:starting",

View File

@ -114,9 +114,9 @@ static void starfive_intc_irq_handler(struct irq_desc *desc)
chained_irq_exit(chip, desc);
}
static int __init starfive_intc_init(struct device_node *intc,
struct device_node *parent)
static int starfive_intc_probe(struct platform_device *pdev, struct device_node *parent)
{
struct device_node *intc = pdev->dev.of_node;
struct starfive_irq_chip *irqc;
struct reset_control *rst;
struct clk *clk;
@ -199,7 +199,7 @@ static int __init starfive_intc_init(struct device_node *intc,
}
IRQCHIP_PLATFORM_DRIVER_BEGIN(starfive_intc)
IRQCHIP_MATCH("starfive,jh8100-intc", starfive_intc_init)
IRQCHIP_MATCH("starfive,jh8100-intc", starfive_intc_probe)
IRQCHIP_PLATFORM_DRIVER_END(starfive_intc)
MODULE_DESCRIPTION("StarFive JH8100 External Interrupt Controller");

View File

@ -165,4 +165,3 @@ module_platform_driver(ts4800_ic_driver);
MODULE_AUTHOR("Damien Riegel <damien.riegel@savoirfairelinux.com>");
MODULE_DESCRIPTION("Multiplexed-IRQs driver for TS-4800's FPGA");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:ts4800_irqc");

View File

@ -36,11 +36,10 @@ int platform_irqchip_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct device_node *par_np __free(device_node) = of_irq_find_parent(np);
of_irq_init_cb_t irq_init_cb = of_device_get_match_data(&pdev->dev);
platform_irq_probe_t irq_probe = of_device_get_match_data(&pdev->dev);
if (!irq_init_cb) {
if (!irq_probe)
return -EINVAL;
}
if (par_np == np)
par_np = NULL;
@ -53,10 +52,9 @@ int platform_irqchip_probe(struct platform_device *pdev)
* interrupt controller. The actual initialization callback of this
* interrupt controller can check for specific domains as necessary.
*/
if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) {
if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY))
return -EPROBE_DEFER;
}
return irq_init_cb(np, par_np);
return irq_probe(pdev, par_np);
}
EXPORT_SYMBOL_GPL(platform_irqchip_probe);

View File

@ -222,7 +222,7 @@ static int get_registers(struct platform_device *pdev, struct combiner *comb)
return 0;
}
static int __init combiner_probe(struct platform_device *pdev)
static int combiner_probe(struct platform_device *pdev)
{
struct combiner *combiner;
int nregs;
@ -266,11 +266,11 @@ static const struct acpi_device_id qcom_irq_combiner_ids[] = {
{ }
};
static struct platform_driver qcom_irq_combiner_probe = {
static struct platform_driver qcom_irq_combiner_driver = {
.driver = {
.name = "qcom-irq-combiner",
.acpi_match_table = ACPI_PTR(qcom_irq_combiner_ids),
},
.probe = combiner_probe,
};
builtin_platform_driver(qcom_irq_combiner_probe);
builtin_platform_driver(qcom_irq_combiner_driver);

View File

@ -350,9 +350,10 @@ static int pdc_setup_pin_mapping(struct device_node *np)
#define QCOM_PDC_SIZE 0x30000
static int qcom_pdc_init(struct device_node *node, struct device_node *parent)
static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *parent)
{
struct irq_domain *parent_domain, *pdc_domain;
struct device_node *node = pdev->dev.of_node;
resource_size_t res_size;
struct resource res;
int ret;
@ -428,7 +429,7 @@ static int qcom_pdc_init(struct device_node *node, struct device_node *parent)
}
IRQCHIP_PLATFORM_DRIVER_BEGIN(qcom_pdc)
IRQCHIP_MATCH("qcom,pdc", qcom_pdc_init)
IRQCHIP_MATCH("qcom,pdc", qcom_pdc_probe)
IRQCHIP_PLATFORM_DRIVER_END(qcom_pdc)
MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Power Domain Controller");
MODULE_LICENSE("GPL v2");

View File

@ -17,12 +17,18 @@
#include <linux/of_irq.h>
#include <linux/platform_device.h>
typedef int (*platform_irq_probe_t)(struct platform_device *, struct device_node *);
/* Undefined on purpose */
extern of_irq_init_cb_t typecheck_irq_init_cb;
extern platform_irq_probe_t typecheck_irq_probe;
#define typecheck_irq_init_cb(fn) \
(__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
#define typecheck_irq_probe(fn) \
(__typecheck(typecheck_irq_probe, &fn) ? fn : fn)
/*
* This macro must be used by the different irqchip drivers to declare
* the association between their DT compatible string and their
@ -42,7 +48,7 @@ extern int platform_irqchip_probe(struct platform_device *pdev);
static const struct of_device_id drv_name##_irqchip_match_table[] = {
#define IRQCHIP_MATCH(compat, fn) { .compatible = compat, \
.data = typecheck_irq_init_cb(fn), },
.data = typecheck_irq_probe(fn), },
#define IRQCHIP_PLATFORM_DRIVER_END(drv_name, ...) \