Skip to content

Commit c5fe9de

Browse files
committed
Merge tag 'irq_urgent_for_v5.17_rc2_p2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq fixes from Borislav Petkov: - Drop an unused private data field in the AIC driver - Various fixes to the realtek-rtl driver - Make the GICv3 ITS driver compile again in !SMP configurations - Force reset of the GICv3 ITSs at probe time to avoid issues during kexec - Yet another kfree/bitmap_free conversion - Various DT updates (Renesas, SiFive) * tag 'irq_urgent_for_v5.17_rc2_p2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: dt-bindings: interrupt-controller: sifive,plic: Group interrupt tuples dt-bindings: interrupt-controller: sifive,plic: Fix number of interrupts dt-bindings: irqchip: renesas-irqc: Add R-Car V3U support irqchip/gic-v3-its: Reset each ITS's BASERn register before probe irqchip/gic-v3-its: Fix build for !SMP irqchip/loongson-pch-ms: Use bitmap_free() to free bitmap irqchip/realtek-rtl: Service all pending interrupts irqchip/realtek-rtl: Fix off-by-one in routing irqchip/realtek-rtl: Map control data to virq irqchip/apple-aic: Drop unused ipi_hwirq field
2 parents 27a96c4 + 243d308 commit c5fe9de

File tree

6 files changed

+121
-36
lines changed

6 files changed

+121
-36
lines changed

Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ properties:
3636
- renesas,intc-ex-r8a77980 # R-Car V3H
3737
- renesas,intc-ex-r8a77990 # R-Car E3
3838
- renesas,intc-ex-r8a77995 # R-Car D3
39+
- renesas,intc-ex-r8a779a0 # R-Car V3U
3940
- const: renesas,irqc
4041

4142
'#interrupt-cells':

Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ properties:
6262

6363
interrupts-extended:
6464
minItems: 1
65+
maxItems: 15872
6566
description:
6667
Specifies which contexts are connected to the PLIC, with "-1" specifying
6768
that a context is not present. Each node pointed to should be a
@@ -90,12 +91,11 @@ examples:
9091
#interrupt-cells = <1>;
9192
compatible = "sifive,fu540-c000-plic", "sifive,plic-1.0.0";
9293
interrupt-controller;
93-
interrupts-extended = <
94-
&cpu0_intc 11
95-
&cpu1_intc 11 &cpu1_intc 9
96-
&cpu2_intc 11 &cpu2_intc 9
97-
&cpu3_intc 11 &cpu3_intc 9
98-
&cpu4_intc 11 &cpu4_intc 9>;
94+
interrupts-extended = <&cpu0_intc 11>,
95+
<&cpu1_intc 11>, <&cpu1_intc 9>,
96+
<&cpu2_intc 11>, <&cpu2_intc 9>,
97+
<&cpu3_intc 11>, <&cpu3_intc 9>,
98+
<&cpu4_intc 11>, <&cpu4_intc 9>;
9999
reg = <0xc000000 0x4000000>;
100100
riscv,ndev = <10>;
101101
};

drivers/irqchip/irq-apple-aic.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,6 @@ struct aic_irq_chip {
178178
struct irq_domain *hw_domain;
179179
struct irq_domain *ipi_domain;
180180
int nr_hw;
181-
int ipi_hwirq;
182181
};
183182

184183
static DEFINE_PER_CPU(uint32_t, aic_fiq_unmasked);

drivers/irqchip/irq-gic-v3-its.c

Lines changed: 101 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4856,6 +4856,38 @@ static struct syscore_ops its_syscore_ops = {
48564856
.resume = its_restore_enable,
48574857
};
48584858

4859+
static void __init __iomem *its_map_one(struct resource *res, int *err)
4860+
{
4861+
void __iomem *its_base;
4862+
u32 val;
4863+
4864+
its_base = ioremap(res->start, SZ_64K);
4865+
if (!its_base) {
4866+
pr_warn("ITS@%pa: Unable to map ITS registers\n", &res->start);
4867+
*err = -ENOMEM;
4868+
return NULL;
4869+
}
4870+
4871+
val = readl_relaxed(its_base + GITS_PIDR2) & GIC_PIDR2_ARCH_MASK;
4872+
if (val != 0x30 && val != 0x40) {
4873+
pr_warn("ITS@%pa: No ITS detected, giving up\n", &res->start);
4874+
*err = -ENODEV;
4875+
goto out_unmap;
4876+
}
4877+
4878+
*err = its_force_quiescent(its_base);
4879+
if (*err) {
4880+
pr_warn("ITS@%pa: Failed to quiesce, giving up\n", &res->start);
4881+
goto out_unmap;
4882+
}
4883+
4884+
return its_base;
4885+
4886+
out_unmap:
4887+
iounmap(its_base);
4888+
return NULL;
4889+
}
4890+
48594891
static int its_init_domain(struct fwnode_handle *handle, struct its_node *its)
48604892
{
48614893
struct irq_domain *inner_domain;
@@ -4963,29 +4995,14 @@ static int __init its_probe_one(struct resource *res,
49634995
{
49644996
struct its_node *its;
49654997
void __iomem *its_base;
4966-
u32 val, ctlr;
49674998
u64 baser, tmp, typer;
49684999
struct page *page;
5000+
u32 ctlr;
49695001
int err;
49705002

4971-
its_base = ioremap(res->start, SZ_64K);
4972-
if (!its_base) {
4973-
pr_warn("ITS@%pa: Unable to map ITS registers\n", &res->start);
4974-
return -ENOMEM;
4975-
}
4976-
4977-
val = readl_relaxed(its_base + GITS_PIDR2) & GIC_PIDR2_ARCH_MASK;
4978-
if (val != 0x30 && val != 0x40) {
4979-
pr_warn("ITS@%pa: No ITS detected, giving up\n", &res->start);
4980-
err = -ENODEV;
4981-
goto out_unmap;
4982-
}
4983-
4984-
err = its_force_quiescent(its_base);
4985-
if (err) {
4986-
pr_warn("ITS@%pa: Failed to quiesce, giving up\n", &res->start);
4987-
goto out_unmap;
4988-
}
5003+
its_base = its_map_one(res, &err);
5004+
if (!its_base)
5005+
return err;
49895006

49905007
pr_info("ITS %pR\n", res);
49915008

@@ -5241,13 +5258,31 @@ static int its_cpu_memreserve_lpi(unsigned int cpu)
52415258

52425259
out:
52435260
/* Last CPU being brought up gets to issue the cleanup */
5244-
if (cpumask_equal(&cpus_booted_once_mask, cpu_possible_mask))
5261+
if (!IS_ENABLED(CONFIG_SMP) ||
5262+
cpumask_equal(&cpus_booted_once_mask, cpu_possible_mask))
52455263
schedule_work(&rdist_memreserve_cpuhp_cleanup_work);
52465264

52475265
gic_data_rdist()->flags |= RD_LOCAL_MEMRESERVE_DONE;
52485266
return ret;
52495267
}
52505268

5269+
/* Mark all the BASER registers as invalid before they get reprogrammed */
5270+
static int __init its_reset_one(struct resource *res)
5271+
{
5272+
void __iomem *its_base;
5273+
int err, i;
5274+
5275+
its_base = its_map_one(res, &err);
5276+
if (!its_base)
5277+
return err;
5278+
5279+
for (i = 0; i < GITS_BASER_NR_REGS; i++)
5280+
gits_write_baser(0, its_base + GITS_BASER + (i << 3));
5281+
5282+
iounmap(its_base);
5283+
return 0;
5284+
}
5285+
52515286
static const struct of_device_id its_device_id[] = {
52525287
{ .compatible = "arm,gic-v3-its", },
52535288
{},
@@ -5258,6 +5293,26 @@ static int __init its_of_probe(struct device_node *node)
52585293
struct device_node *np;
52595294
struct resource res;
52605295

5296+
/*
5297+
* Make sure *all* the ITS are reset before we probe any, as
5298+
* they may be sharing memory. If any of the ITS fails to
5299+
* reset, don't even try to go any further, as this could
5300+
* result in something even worse.
5301+
*/
5302+
for (np = of_find_matching_node(node, its_device_id); np;
5303+
np = of_find_matching_node(np, its_device_id)) {
5304+
int err;
5305+
5306+
if (!of_device_is_available(np) ||
5307+
!of_property_read_bool(np, "msi-controller") ||
5308+
of_address_to_resource(np, 0, &res))
5309+
continue;
5310+
5311+
err = its_reset_one(&res);
5312+
if (err)
5313+
return err;
5314+
}
5315+
52615316
for (np = of_find_matching_node(node, its_device_id); np;
52625317
np = of_find_matching_node(np, its_device_id)) {
52635318
if (!of_device_is_available(np))
@@ -5420,11 +5475,35 @@ static int __init gic_acpi_parse_madt_its(union acpi_subtable_headers *header,
54205475
return err;
54215476
}
54225477

5478+
static int __init its_acpi_reset(union acpi_subtable_headers *header,
5479+
const unsigned long end)
5480+
{
5481+
struct acpi_madt_generic_translator *its_entry;
5482+
struct resource res;
5483+
5484+
its_entry = (struct acpi_madt_generic_translator *)header;
5485+
res = (struct resource) {
5486+
.start = its_entry->base_address,
5487+
.end = its_entry->base_address + ACPI_GICV3_ITS_MEM_SIZE - 1,
5488+
.flags = IORESOURCE_MEM,
5489+
};
5490+
5491+
return its_reset_one(&res);
5492+
}
5493+
54235494
static void __init its_acpi_probe(void)
54245495
{
54255496
acpi_table_parse_srat_its();
5426-
acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
5427-
gic_acpi_parse_madt_its, 0);
5497+
/*
5498+
* Make sure *all* the ITS are reset before we probe any, as
5499+
* they may be sharing memory. If any of the ITS fails to
5500+
* reset, don't even try to go any further, as this could
5501+
* result in something even worse.
5502+
*/
5503+
if (acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
5504+
its_acpi_reset, 0) > 0)
5505+
acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
5506+
gic_acpi_parse_madt_its, 0);
54285507
acpi_its_srat_maps_free();
54295508
}
54305509
#else

drivers/irqchip/irq-loongson-pch-msi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ static int pch_msi_init(struct device_node *node,
241241
return 0;
242242

243243
err_map:
244-
kfree(priv->msi_map);
244+
bitmap_free(priv->msi_map);
245245
err_priv:
246246
kfree(priv);
247247
return ret;

drivers/irqchip/irq-realtek-rtl.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static struct irq_chip realtek_ictl_irq = {
6262

6363
static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
6464
{
65-
irq_set_chip_and_handler(hw, &realtek_ictl_irq, handle_level_irq);
65+
irq_set_chip_and_handler(irq, &realtek_ictl_irq, handle_level_irq);
6666

6767
return 0;
6868
}
@@ -76,16 +76,20 @@ static void realtek_irq_dispatch(struct irq_desc *desc)
7676
{
7777
struct irq_chip *chip = irq_desc_get_chip(desc);
7878
struct irq_domain *domain;
79-
unsigned int pending;
79+
unsigned long pending;
80+
unsigned int soc_int;
8081

8182
chained_irq_enter(chip, desc);
8283
pending = readl(REG(RTL_ICTL_GIMR)) & readl(REG(RTL_ICTL_GISR));
84+
8385
if (unlikely(!pending)) {
8486
spurious_interrupt();
8587
goto out;
8688
}
89+
8790
domain = irq_desc_get_handler_data(desc);
88-
generic_handle_domain_irq(domain, __ffs(pending));
91+
for_each_set_bit(soc_int, &pending, 32)
92+
generic_handle_domain_irq(domain, soc_int);
8993

9094
out:
9195
chained_irq_exit(chip, desc);
@@ -95,7 +99,8 @@ static void realtek_irq_dispatch(struct irq_desc *desc)
9599
* SoC interrupts are cascaded to MIPS CPU interrupts according to the
96100
* interrupt-map in the device tree. Each SoC interrupt gets 4 bits for
97101
* the CPU interrupt in an Interrupt Routing Register. Max 32 SoC interrupts
98-
* thus go into 4 IRRs.
102+
* thus go into 4 IRRs. A routing value of '0' means the interrupt is left
103+
* disconnected. Routing values {1..15} connect to output lines {0..14}.
99104
*/
100105
static int __init map_interrupts(struct device_node *node, struct irq_domain *domain)
101106
{
@@ -134,7 +139,7 @@ static int __init map_interrupts(struct device_node *node, struct irq_domain *do
134139
of_node_put(cpu_ictl);
135140

136141
cpu_int = be32_to_cpup(imap + 2);
137-
if (cpu_int > 7)
142+
if (cpu_int > 7 || cpu_int < 2)
138143
return -EINVAL;
139144

140145
if (!(mips_irqs_set & BIT(cpu_int))) {
@@ -143,7 +148,8 @@ static int __init map_interrupts(struct device_node *node, struct irq_domain *do
143148
mips_irqs_set |= BIT(cpu_int);
144149
}
145150

146-
regs[(soc_int * 4) / 32] |= cpu_int << (soc_int * 4) % 32;
151+
/* Use routing values (1..6) for CPU interrupts (2..7) */
152+
regs[(soc_int * 4) / 32] |= (cpu_int - 1) << (soc_int * 4) % 32;
147153
imap += 3;
148154
}
149155

0 commit comments

Comments
 (0)