irqchip fixes for 6.6, take #2
- DT binding updates for Renesas r8a779f0 and rzg2l - Let GICv3 honor the "dma-non-coherent" attribute for systems that rely on SW guessing what the HW supports - Fix the RISC-V INTC probing by marking all devices as initialised at once - Properly translate interrupt numbers from DT on stm32-exti - Use irq_data_get_irq_chip_data() in the rzg2l driver instead of blindly dereferencing the irq_data structure - Add a MAINTAINERS entry for the various ARM GIC irqchip drivers - Remove myself as the top-level irqchip/irqdomain maintainer -----BEGIN PGP SIGNATURE----- iQJDBAABCgAtFiEEn9UcU+C1Yxj9lZw9I9DQutE9ekMFAmUhSIMPHG1hekBrZXJu ZWwub3JnAAoJECPQ0LrRPXpDXgAP/RTbjK5ssKp9aDtxcZo3jBzYHXBAjITI70OL q96gBz7DOEUmETFuNksSccBBOR2fqwC7xQdIAQj8S1nk1Zm5KHa7obxjdPxkJiO6 SzcgGj3W5bTnUsHr6TQrAbvDkXdkrK7phecJ5DzsXPE0wqTXSE9ANIwjc1tnHiXc TGo1/qpvDdR34vh2R/Gn48P5O2/lD6TWRpP2ia00dCw13M40uToojS+aQUVi/eZl RZJiww2aI+iT4gLvG4JSWHlBZJ6j7pI9F+k2aUblbepVF2XudsJ+VaCrCb3tRtax Nwl70p87jq+no36wKGQ647rmrGz2mSsI713ES/pqQ9vIRyste7xTf23yB5s6hwso tTnsqA2Kt7wqwXgyKfZr7MRRUbgpn+SkBFtDyfDHYAeURZISlGlX0tmGw4h+7NIy AqPQiAtl6T11+o9v4BPI1xjoP9dxrIfgU3gaGAY4BwbfVxh79exPBDjkLJASS9MP FXZp36R7If5XyPQhY+Xh8j/oJ/CF9RRiKLDbUttVks3Jb63s8u1JWHVBoq0Aoimi 2mqyaELMyOVheVOFVOPMFD+ifkuZakLkHaHbdiCCtTXm90c4svRUuV4EnxT/m4mq Mjt3BUv78mP6N+JTA/FRKmJHSRNGP+ziWDmls2ro3oJNYarKZpxYZ7IDisdlW43n 1ehjT0fg =2s2R -----END PGP SIGNATURE----- Merge tag 'irqchip-fixes-6.6-2' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent Pull irqchip fixes from Marc Zyngier: - DT binding updates for Renesas r8a779f0 and rzg2l - Let GICv3 honor the "dma-non-coherent" attribute for systems that rely on SW guessing what the HW supports - Fix the RISC-V INTC probing by marking all devices as initialised at once - Properly translate interrupt numbers from DT on stm32-exti - Use irq_data_get_irq_chip_data() in the rzg2l driver instead of blindly dereferencing the irq_data structure - Add a MAINTAINERS entry for the various ARM GIC irqchip drivers - Remove myself as the top-level irqchip/irqdomain maintainer Link: https://lore.kernel.org/all/20231007121933.3840357-1-maz@kernel.org
This commit is contained in:
commit
4dc5af1fee
|
@ -106,6 +106,12 @@ properties:
|
|||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
maximum: 4096
|
||||
|
||||
dma-noncoherent:
|
||||
description:
|
||||
Present if the GIC redistributors permit programming shareability
|
||||
and cacheability attributes but are connected to a non-coherent
|
||||
downstream interconnect.
|
||||
|
||||
msi-controller:
|
||||
description:
|
||||
Only present if the Message Based Interrupt functionality is
|
||||
|
@ -193,6 +199,12 @@ patternProperties:
|
|||
compatible:
|
||||
const: arm,gic-v3-its
|
||||
|
||||
dma-noncoherent:
|
||||
description:
|
||||
Present if the GIC ITS permits programming shareability and
|
||||
cacheability attributes but is connected to a non-coherent
|
||||
downstream interconnect.
|
||||
|
||||
msi-controller: true
|
||||
|
||||
"#msi-cells":
|
||||
|
|
|
@ -37,6 +37,7 @@ properties:
|
|||
- renesas,intc-ex-r8a77990 # R-Car E3
|
||||
- renesas,intc-ex-r8a77995 # R-Car D3
|
||||
- renesas,intc-ex-r8a779a0 # R-Car V3U
|
||||
- renesas,intc-ex-r8a779f0 # R-Car S4-8
|
||||
- renesas,intc-ex-r8a779g0 # R-Car V4H
|
||||
- const: renesas,irqc
|
||||
|
||||
|
|
|
@ -19,13 +19,11 @@ description: |
|
|||
- NMI edge select (NMI is not treated as NMI exception and supports fall edge and
|
||||
stand-up edge detection interrupts)
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/interrupt-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- renesas,r9a07g043u-irqc # RZ/G2UL
|
||||
- renesas,r9a07g044-irqc # RZ/G2{L,LC}
|
||||
- renesas,r9a07g054-irqc # RZ/V2L
|
||||
- const: renesas,rzg2l-irqc
|
||||
|
@ -45,7 +43,96 @@ properties:
|
|||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 41
|
||||
minItems: 41
|
||||
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
|
||||
|
||||
interrupt-names:
|
||||
minItems: 41
|
||||
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
|
||||
|
||||
clocks:
|
||||
maxItems: 2
|
||||
|
@ -73,6 +160,23 @@ required:
|
|||
- power-domains
|
||||
- resets
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/interrupt-controller.yaml#
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: renesas,r9a07g043u-irqc
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 42
|
||||
interrupt-names:
|
||||
minItems: 42
|
||||
required:
|
||||
- interrupt-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
@ -81,55 +185,66 @@ examples:
|
|||
#include <dt-bindings/clock/r9a07g044-cpg.h>
|
||||
|
||||
irqc: interrupt-controller@110a0000 {
|
||||
compatible = "renesas,r9a07g044-irqc", "renesas,rzg2l-irqc";
|
||||
reg = <0x110a0000 0x10000>;
|
||||
#interrupt-cells = <2>;
|
||||
#address-cells = <0>;
|
||||
interrupt-controller;
|
||||
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 450 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 452 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 453 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 454 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 455 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpg CPG_MOD R9A07G044_IA55_CLK>,
|
||||
<&cpg CPG_MOD R9A07G044_IA55_PCLK>;
|
||||
clock-names = "clk", "pclk";
|
||||
power-domains = <&cpg>;
|
||||
resets = <&cpg R9A07G044_IA55_RESETN>;
|
||||
compatible = "renesas,r9a07g044-irqc", "renesas,rzg2l-irqc";
|
||||
reg = <0x110a0000 0x10000>;
|
||||
#interrupt-cells = <2>;
|
||||
#address-cells = <0>;
|
||||
interrupt-controller;
|
||||
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 450 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 452 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 453 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 454 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 455 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "nmi",
|
||||
"irq0", "irq1", "irq2", "irq3",
|
||||
"irq4", "irq5", "irq6", "irq7",
|
||||
"tint0", "tint1", "tint2", "tint3",
|
||||
"tint4", "tint5", "tint6", "tint7",
|
||||
"tint8", "tint9", "tint10", "tint11",
|
||||
"tint12", "tint13", "tint14", "tint15",
|
||||
"tint16", "tint17", "tint18", "tint19",
|
||||
"tint20", "tint21", "tint22", "tint23",
|
||||
"tint24", "tint25", "tint26", "tint27",
|
||||
"tint28", "tint29", "tint30", "tint31";
|
||||
clocks = <&cpg CPG_MOD R9A07G044_IA55_CLK>,
|
||||
<&cpg CPG_MOD R9A07G044_IA55_PCLK>;
|
||||
clock-names = "clk", "pclk";
|
||||
power-domains = <&cpg>;
|
||||
resets = <&cpg R9A07G044_IA55_RESETN>;
|
||||
};
|
||||
|
|
14
MAINTAINERS
14
MAINTAINERS
|
@ -1585,6 +1585,17 @@ F: arch/arm/include/asm/arch_timer.h
|
|||
F: arch/arm64/include/asm/arch_timer.h
|
||||
F: drivers/clocksource/arm_arch_timer.c
|
||||
|
||||
ARM GENERIC INTERRUPT CONTROLLER DRIVERS
|
||||
M: Marc Zyngier <maz@kernel.org>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/interrupt-controller/arm,gic*
|
||||
F: arch/arm/include/asm/arch_gicv3.h
|
||||
F: arch/arm64/include/asm/arch_gicv3.h
|
||||
F: drivers/irqchip/irq-gic*.[ch]
|
||||
F: include/linux/irqchip/arm-gic*.h
|
||||
F: include/linux/irqchip/arm-vgic-info.h
|
||||
|
||||
ARM HDLCD DRM DRIVER
|
||||
M: Liviu Dudau <liviu.dudau@arm.com>
|
||||
S: Supported
|
||||
|
@ -11064,7 +11075,7 @@ F: Documentation/devicetree/bindings/sound/irondevice,*
|
|||
F: sound/soc/codecs/sma*
|
||||
|
||||
IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
|
||||
M: Marc Zyngier <maz@kernel.org>
|
||||
M: Thomas Gleixner <tglx@linutronix.de>
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
|
||||
F: Documentation/core-api/irq/irq-domain.rst
|
||||
|
@ -11083,7 +11094,6 @@ F: lib/group_cpus.c
|
|||
|
||||
IRQCHIP DRIVERS
|
||||
M: Thomas Gleixner <tglx@linutronix.de>
|
||||
M: Marc Zyngier <maz@kernel.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
|
||||
|
|
|
@ -29,4 +29,8 @@ void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
|
|||
void gic_enable_of_quirks(const struct device_node *np,
|
||||
const struct gic_quirk *quirks, void *data);
|
||||
|
||||
#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
|
||||
#define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1)
|
||||
#define RDIST_FLAGS_FORCE_NON_SHAREABLE (1 << 2)
|
||||
|
||||
#endif /* _IRQ_GIC_COMMON_H */
|
||||
|
|
|
@ -44,10 +44,6 @@
|
|||
#define ITS_FLAGS_WORKAROUND_CAVIUM_23144 (1ULL << 2)
|
||||
#define ITS_FLAGS_FORCE_NON_SHAREABLE (1ULL << 3)
|
||||
|
||||
#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
|
||||
#define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1)
|
||||
#define RDIST_FLAGS_FORCE_NON_SHAREABLE (1 << 2)
|
||||
|
||||
#define RD_LOCAL_LPI_ENABLED BIT(0)
|
||||
#define RD_LOCAL_PENDTABLE_PREALLOCATED BIT(1)
|
||||
#define RD_LOCAL_MEMRESERVE_DONE BIT(2)
|
||||
|
@ -4754,6 +4750,14 @@ static bool __maybe_unused its_enable_rk3588001(void *data)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool its_set_non_coherent(void *data)
|
||||
{
|
||||
struct its_node *its = data;
|
||||
|
||||
its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct gic_quirk its_quirks[] = {
|
||||
#ifdef CONFIG_CAVIUM_ERRATUM_22375
|
||||
{
|
||||
|
@ -4808,6 +4812,11 @@ static const struct gic_quirk its_quirks[] = {
|
|||
.init = its_enable_rk3588001,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.desc = "ITS: non-coherent attribute",
|
||||
.property = "dma-noncoherent",
|
||||
.init = its_set_non_coherent,
|
||||
},
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -4817,6 +4826,10 @@ static void its_enable_quirks(struct its_node *its)
|
|||
u32 iidr = readl_relaxed(its->base + GITS_IIDR);
|
||||
|
||||
gic_enable_quirks(iidr, its_quirks, its);
|
||||
|
||||
if (is_of_node(its->fwnode_handle))
|
||||
gic_enable_of_quirks(to_of_node(its->fwnode_handle),
|
||||
its_quirks, its);
|
||||
}
|
||||
|
||||
static int its_save_disable(void)
|
||||
|
@ -4952,7 +4965,7 @@ out_unmap:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int its_init_domain(struct fwnode_handle *handle, struct its_node *its)
|
||||
static int its_init_domain(struct its_node *its)
|
||||
{
|
||||
struct irq_domain *inner_domain;
|
||||
struct msi_domain_info *info;
|
||||
|
@ -4966,7 +4979,7 @@ static int its_init_domain(struct fwnode_handle *handle, struct its_node *its)
|
|||
|
||||
inner_domain = irq_domain_create_hierarchy(its_parent,
|
||||
its->msi_domain_flags, 0,
|
||||
handle, &its_domain_ops,
|
||||
its->fwnode_handle, &its_domain_ops,
|
||||
info);
|
||||
if (!inner_domain) {
|
||||
kfree(info);
|
||||
|
@ -5017,8 +5030,7 @@ static int its_init_vpe_domain(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __init its_compute_its_list_map(struct resource *res,
|
||||
void __iomem *its_base)
|
||||
static int __init its_compute_its_list_map(struct its_node *its)
|
||||
{
|
||||
int its_number;
|
||||
u32 ctlr;
|
||||
|
@ -5032,15 +5044,15 @@ static int __init its_compute_its_list_map(struct resource *res,
|
|||
its_number = find_first_zero_bit(&its_list_map, GICv4_ITS_LIST_MAX);
|
||||
if (its_number >= GICv4_ITS_LIST_MAX) {
|
||||
pr_err("ITS@%pa: No ITSList entry available!\n",
|
||||
&res->start);
|
||||
&its->phys_base);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctlr = readl_relaxed(its_base + GITS_CTLR);
|
||||
ctlr = readl_relaxed(its->base + GITS_CTLR);
|
||||
ctlr &= ~GITS_CTLR_ITS_NUMBER;
|
||||
ctlr |= its_number << GITS_CTLR_ITS_NUMBER_SHIFT;
|
||||
writel_relaxed(ctlr, its_base + GITS_CTLR);
|
||||
ctlr = readl_relaxed(its_base + GITS_CTLR);
|
||||
writel_relaxed(ctlr, its->base + GITS_CTLR);
|
||||
ctlr = readl_relaxed(its->base + GITS_CTLR);
|
||||
if ((ctlr & GITS_CTLR_ITS_NUMBER) != (its_number << GITS_CTLR_ITS_NUMBER_SHIFT)) {
|
||||
its_number = ctlr & GITS_CTLR_ITS_NUMBER;
|
||||
its_number >>= GITS_CTLR_ITS_NUMBER_SHIFT;
|
||||
|
@ -5048,75 +5060,50 @@ static int __init its_compute_its_list_map(struct resource *res,
|
|||
|
||||
if (test_and_set_bit(its_number, &its_list_map)) {
|
||||
pr_err("ITS@%pa: Duplicate ITSList entry %d\n",
|
||||
&res->start, its_number);
|
||||
&its->phys_base, its_number);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return its_number;
|
||||
}
|
||||
|
||||
static int __init its_probe_one(struct resource *res,
|
||||
struct fwnode_handle *handle, int numa_node)
|
||||
static int __init its_probe_one(struct its_node *its)
|
||||
{
|
||||
struct its_node *its;
|
||||
void __iomem *its_base;
|
||||
u64 baser, tmp, typer;
|
||||
u64 baser, tmp;
|
||||
struct page *page;
|
||||
u32 ctlr;
|
||||
int err;
|
||||
|
||||
its_base = its_map_one(res, &err);
|
||||
if (!its_base)
|
||||
return err;
|
||||
|
||||
pr_info("ITS %pR\n", res);
|
||||
|
||||
its = kzalloc(sizeof(*its), GFP_KERNEL);
|
||||
if (!its) {
|
||||
err = -ENOMEM;
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
raw_spin_lock_init(&its->lock);
|
||||
mutex_init(&its->dev_alloc_lock);
|
||||
INIT_LIST_HEAD(&its->entry);
|
||||
INIT_LIST_HEAD(&its->its_device_list);
|
||||
typer = gic_read_typer(its_base + GITS_TYPER);
|
||||
its->typer = typer;
|
||||
its->base = its_base;
|
||||
its->phys_base = res->start;
|
||||
if (is_v4(its)) {
|
||||
if (!(typer & GITS_TYPER_VMOVP)) {
|
||||
err = its_compute_its_list_map(res, its_base);
|
||||
if (!(its->typer & GITS_TYPER_VMOVP)) {
|
||||
err = its_compute_its_list_map(its);
|
||||
if (err < 0)
|
||||
goto out_free_its;
|
||||
goto out;
|
||||
|
||||
its->list_nr = err;
|
||||
|
||||
pr_info("ITS@%pa: Using ITS number %d\n",
|
||||
&res->start, err);
|
||||
&its->phys_base, err);
|
||||
} else {
|
||||
pr_info("ITS@%pa: Single VMOVP capable\n", &res->start);
|
||||
pr_info("ITS@%pa: Single VMOVP capable\n", &its->phys_base);
|
||||
}
|
||||
|
||||
if (is_v4_1(its)) {
|
||||
u32 svpet = FIELD_GET(GITS_TYPER_SVPET, typer);
|
||||
u32 svpet = FIELD_GET(GITS_TYPER_SVPET, its->typer);
|
||||
|
||||
its->sgir_base = ioremap(res->start + SZ_128K, SZ_64K);
|
||||
its->sgir_base = ioremap(its->phys_base + SZ_128K, SZ_64K);
|
||||
if (!its->sgir_base) {
|
||||
err = -ENOMEM;
|
||||
goto out_free_its;
|
||||
goto out;
|
||||
}
|
||||
|
||||
its->mpidr = readl_relaxed(its_base + GITS_MPIDR);
|
||||
its->mpidr = readl_relaxed(its->base + GITS_MPIDR);
|
||||
|
||||
pr_info("ITS@%pa: Using GICv4.1 mode %08x %08x\n",
|
||||
&res->start, its->mpidr, svpet);
|
||||
&its->phys_base, its->mpidr, svpet);
|
||||
}
|
||||
}
|
||||
|
||||
its->numa_node = numa_node;
|
||||
|
||||
page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
|
||||
get_order(ITS_CMD_QUEUE_SZ));
|
||||
if (!page) {
|
||||
|
@ -5125,12 +5112,9 @@ static int __init its_probe_one(struct resource *res,
|
|||
}
|
||||
its->cmd_base = (void *)page_address(page);
|
||||
its->cmd_write = its->cmd_base;
|
||||
its->fwnode_handle = handle;
|
||||
its->get_msi_base = its_irq_get_msi_base;
|
||||
its->msi_domain_flags = IRQ_DOMAIN_FLAG_ISOLATED_MSI;
|
||||
|
||||
its_enable_quirks(its);
|
||||
|
||||
err = its_alloc_tables(its);
|
||||
if (err)
|
||||
goto out_free_cmd;
|
||||
|
@ -5174,7 +5158,7 @@ static int __init its_probe_one(struct resource *res,
|
|||
ctlr |= GITS_CTLR_ImDe;
|
||||
writel_relaxed(ctlr, its->base + GITS_CTLR);
|
||||
|
||||
err = its_init_domain(handle, its);
|
||||
err = its_init_domain(its);
|
||||
if (err)
|
||||
goto out_free_tables;
|
||||
|
||||
|
@ -5191,11 +5175,8 @@ out_free_cmd:
|
|||
out_unmap_sgir:
|
||||
if (its->sgir_base)
|
||||
iounmap(its->sgir_base);
|
||||
out_free_its:
|
||||
kfree(its);
|
||||
out_unmap:
|
||||
iounmap(its_base);
|
||||
pr_err("ITS@%pa: failed probing (%d)\n", &res->start, err);
|
||||
out:
|
||||
pr_err("ITS@%pa: failed probing (%d)\n", &its->phys_base, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -5356,10 +5337,53 @@ static const struct of_device_id its_device_id[] = {
|
|||
{},
|
||||
};
|
||||
|
||||
static struct its_node __init *its_node_init(struct resource *res,
|
||||
struct fwnode_handle *handle, int numa_node)
|
||||
{
|
||||
void __iomem *its_base;
|
||||
struct its_node *its;
|
||||
int err;
|
||||
|
||||
its_base = its_map_one(res, &err);
|
||||
if (!its_base)
|
||||
return NULL;
|
||||
|
||||
pr_info("ITS %pR\n", res);
|
||||
|
||||
its = kzalloc(sizeof(*its), GFP_KERNEL);
|
||||
if (!its)
|
||||
goto out_unmap;
|
||||
|
||||
raw_spin_lock_init(&its->lock);
|
||||
mutex_init(&its->dev_alloc_lock);
|
||||
INIT_LIST_HEAD(&its->entry);
|
||||
INIT_LIST_HEAD(&its->its_device_list);
|
||||
|
||||
its->typer = gic_read_typer(its_base + GITS_TYPER);
|
||||
its->base = its_base;
|
||||
its->phys_base = res->start;
|
||||
|
||||
its->numa_node = numa_node;
|
||||
its->fwnode_handle = handle;
|
||||
|
||||
return its;
|
||||
|
||||
out_unmap:
|
||||
iounmap(its_base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void its_node_destroy(struct its_node *its)
|
||||
{
|
||||
iounmap(its->base);
|
||||
kfree(its);
|
||||
}
|
||||
|
||||
static int __init its_of_probe(struct device_node *node)
|
||||
{
|
||||
struct device_node *np;
|
||||
struct resource res;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* Make sure *all* the ITS are reset before we probe any, as
|
||||
|
@ -5369,8 +5393,6 @@ static int __init its_of_probe(struct device_node *node)
|
|||
*/
|
||||
for (np = of_find_matching_node(node, its_device_id); np;
|
||||
np = of_find_matching_node(np, its_device_id)) {
|
||||
int err;
|
||||
|
||||
if (!of_device_is_available(np) ||
|
||||
!of_property_read_bool(np, "msi-controller") ||
|
||||
of_address_to_resource(np, 0, &res))
|
||||
|
@ -5383,6 +5405,8 @@ static int __init its_of_probe(struct device_node *node)
|
|||
|
||||
for (np = of_find_matching_node(node, its_device_id); np;
|
||||
np = of_find_matching_node(np, its_device_id)) {
|
||||
struct its_node *its;
|
||||
|
||||
if (!of_device_is_available(np))
|
||||
continue;
|
||||
if (!of_property_read_bool(np, "msi-controller")) {
|
||||
|
@ -5396,7 +5420,17 @@ static int __init its_of_probe(struct device_node *node)
|
|||
continue;
|
||||
}
|
||||
|
||||
its_probe_one(&res, &np->fwnode, of_node_to_nid(np));
|
||||
|
||||
its = its_node_init(&res, &np->fwnode, of_node_to_nid(np));
|
||||
if (!its)
|
||||
return -ENOMEM;
|
||||
|
||||
its_enable_quirks(its);
|
||||
err = its_probe_one(its);
|
||||
if (err) {
|
||||
its_node_destroy(its);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -5508,6 +5542,7 @@ static int __init gic_acpi_parse_madt_its(union acpi_subtable_headers *header,
|
|||
{
|
||||
struct acpi_madt_generic_translator *its_entry;
|
||||
struct fwnode_handle *dom_handle;
|
||||
struct its_node *its;
|
||||
struct resource res;
|
||||
int err;
|
||||
|
||||
|
@ -5532,11 +5567,18 @@ static int __init gic_acpi_parse_madt_its(union acpi_subtable_headers *header,
|
|||
goto dom_err;
|
||||
}
|
||||
|
||||
err = its_probe_one(&res, dom_handle,
|
||||
acpi_get_its_numa_node(its_entry->translation_id));
|
||||
its = its_node_init(&res, dom_handle,
|
||||
acpi_get_its_numa_node(its_entry->translation_id));
|
||||
if (!its) {
|
||||
err = -ENOMEM;
|
||||
goto node_err;
|
||||
}
|
||||
|
||||
err = its_probe_one(its);
|
||||
if (!err)
|
||||
return 0;
|
||||
|
||||
node_err:
|
||||
iort_deregister_domain_token(its_entry->translation_id);
|
||||
dom_err:
|
||||
irq_domain_free_fwnode(dom_handle);
|
||||
|
|
|
@ -1857,6 +1857,14 @@ static bool gic_enable_quirk_arm64_2941627(void *data)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool rd_set_non_coherent(void *data)
|
||||
{
|
||||
struct gic_chip_data *d = data;
|
||||
|
||||
d->rdists.flags |= RDIST_FLAGS_FORCE_NON_SHAREABLE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct gic_quirk gic_quirks[] = {
|
||||
{
|
||||
.desc = "GICv3: Qualcomm MSM8996 broken firmware",
|
||||
|
@ -1923,6 +1931,11 @@ static const struct gic_quirk gic_quirks[] = {
|
|||
.mask = 0xff0f0fff,
|
||||
.init = gic_enable_quirk_arm64_2941627,
|
||||
},
|
||||
{
|
||||
.desc = "GICv3: non-coherent attribute",
|
||||
.property = "dma-noncoherent",
|
||||
.init = rd_set_non_coherent,
|
||||
},
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
|
@ -130,8 +130,8 @@ static void rzg2l_irqc_irq_enable(struct irq_data *d)
|
|||
unsigned int hw_irq = irqd_to_hwirq(d);
|
||||
|
||||
if (hw_irq >= IRQC_TINT_START && hw_irq < IRQC_NUM_IRQ) {
|
||||
unsigned long tint = (uintptr_t)irq_data_get_irq_chip_data(d);
|
||||
struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
|
||||
unsigned long tint = (uintptr_t)d->chip_data;
|
||||
u32 offset = hw_irq - IRQC_TINT_START;
|
||||
u32 tssr_offset = TSSR_OFFSET(offset);
|
||||
u8 tssr_index = TSSR_INDEX(offset);
|
||||
|
|
|
@ -155,8 +155,16 @@ static int __init riscv_intc_init(struct device_node *node,
|
|||
* for each INTC DT node. We only need to do INTC initialization
|
||||
* for the INTC DT node belonging to boot CPU (or boot HART).
|
||||
*/
|
||||
if (riscv_hartid_to_cpuid(hartid) != smp_processor_id())
|
||||
if (riscv_hartid_to_cpuid(hartid) != smp_processor_id()) {
|
||||
/*
|
||||
* The INTC nodes of each CPU are suppliers for downstream
|
||||
* interrupt controllers (such as PLIC, IMSIC and APLIC
|
||||
* direct-mode) so we should mark an INTC node as initialized
|
||||
* if we are not creating IRQ domain for it.
|
||||
*/
|
||||
fwnode_dev_initialized(of_fwnode_handle(node), true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return riscv_intc_init_common(of_node_to_fwnode(node));
|
||||
}
|
||||
|
|
|
@ -460,6 +460,7 @@ static const struct irq_domain_ops irq_exti_domain_ops = {
|
|||
.map = irq_map_generic_chip,
|
||||
.alloc = stm32_exti_alloc,
|
||||
.free = stm32_exti_free,
|
||||
.xlate = irq_domain_xlate_twocell,
|
||||
};
|
||||
|
||||
static void stm32_irq_ack(struct irq_data *d)
|
||||
|
|
Loading…
Reference in New Issue