Skip to content

Commit 9bd5386

Browse files
committed
Merge tag 'irq-urgent-2023-05-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq fixes from Thomas Gleixner: "A set of fixes for interrupt chip drivers: - Prevent loss of state in the MIPS GIC interrupt controller - Disable pseudo NMIs on Mediatek based Chromebooks as they have firmware issues which cause instantenous chrashes and freezes wen pseudo NMIs are used - Fix the error handling path in the MBIGEN driver and a defined but not used warning in the meson-gpio interrupt chip driver" * tag 'irq-urgent-2023-05-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: irqchip/mbigen: Unify the error handling in mbigen_of_create_domain() irqchip/meson-gpio: Mark OF related data as maybe unused irqchip/mips-gic: Use raw spinlock for gic_lock irqchip/mips-gic: Don't touch vl_map if a local interrupt is not routable irqchip/gic-v3: Disable pseudo NMIs on Mediatek devices w/ firmware issues dt-bindings: interrupt-controller: arm,gic-v3: Add quirk for Mediatek SoCs w/ broken FW
2 parents 045049c + 4115af4 commit 9bd5386

File tree

7 files changed

+69
-31
lines changed

7 files changed

+69
-31
lines changed

Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,12 @@ properties:
166166
resets:
167167
maxItems: 1
168168

169+
mediatek,broken-save-restore-fw:
170+
type: boolean
171+
description:
172+
Asserts that the firmware on this device has issues saving and restoring
173+
GICR registers when the GIC redistributors are powered off.
174+
169175
dependencies:
170176
mbi-ranges: [ msi-controller ]
171177
msi-controller: [ mbi-ranges ]

drivers/irqchip/irq-gic-common.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ void gic_enable_of_quirks(const struct device_node *np,
1616
const struct gic_quirk *quirks, void *data)
1717
{
1818
for (; quirks->desc; quirks++) {
19-
if (!of_device_is_compatible(np, quirks->compatible))
19+
if (quirks->compatible &&
20+
!of_device_is_compatible(np, quirks->compatible))
21+
continue;
22+
if (quirks->property &&
23+
!of_property_read_bool(np, quirks->property))
2024
continue;
2125
if (quirks->init(data))
2226
pr_info("GIC: enabling workaround for %s\n",
@@ -28,7 +32,7 @@ void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
2832
void *data)
2933
{
3034
for (; quirks->desc; quirks++) {
31-
if (quirks->compatible)
35+
if (quirks->compatible || quirks->property)
3236
continue;
3337
if (quirks->iidr != (quirks->mask & iidr))
3438
continue;

drivers/irqchip/irq-gic-common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
struct gic_quirk {
1414
const char *desc;
1515
const char *compatible;
16+
const char *property;
1617
bool (*init)(void *data);
1718
u32 iidr;
1819
u32 mask;

drivers/irqchip/irq-gic-v3.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
#define FLAGS_WORKAROUND_GICR_WAKER_MSM8996 (1ULL << 0)
4141
#define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539 (1ULL << 1)
42+
#define FLAGS_WORKAROUND_MTK_GICR_SAVE (1ULL << 2)
4243

4344
#define GIC_IRQ_TYPE_PARTITION (GIC_IRQ_TYPE_LPI + 1)
4445

@@ -1720,6 +1721,15 @@ static bool gic_enable_quirk_msm8996(void *data)
17201721
return true;
17211722
}
17221723

1724+
static bool gic_enable_quirk_mtk_gicr(void *data)
1725+
{
1726+
struct gic_chip_data *d = data;
1727+
1728+
d->flags |= FLAGS_WORKAROUND_MTK_GICR_SAVE;
1729+
1730+
return true;
1731+
}
1732+
17231733
static bool gic_enable_quirk_cavium_38539(void *data)
17241734
{
17251735
struct gic_chip_data *d = data;
@@ -1792,6 +1802,11 @@ static const struct gic_quirk gic_quirks[] = {
17921802
.compatible = "qcom,msm8996-gic-v3",
17931803
.init = gic_enable_quirk_msm8996,
17941804
},
1805+
{
1806+
.desc = "GICv3: Mediatek Chromebook GICR save problem",
1807+
.property = "mediatek,broken-save-restore-fw",
1808+
.init = gic_enable_quirk_mtk_gicr,
1809+
},
17951810
{
17961811
.desc = "GICv3: HIP06 erratum 161010803",
17971812
.iidr = 0x0204043b,
@@ -1834,6 +1849,11 @@ static void gic_enable_nmi_support(void)
18341849
if (!gic_prio_masking_enabled())
18351850
return;
18361851

1852+
if (gic_data.flags & FLAGS_WORKAROUND_MTK_GICR_SAVE) {
1853+
pr_warn("Skipping NMI enable due to firmware issues\n");
1854+
return;
1855+
}
1856+
18371857
ppi_nmi_refs = kcalloc(gic_data.ppi_nr, sizeof(*ppi_nmi_refs), GFP_KERNEL);
18381858
if (!ppi_nmi_refs)
18391859
return;

drivers/irqchip/irq-mbigen.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -240,39 +240,44 @@ static int mbigen_of_create_domain(struct platform_device *pdev,
240240
struct irq_domain *domain;
241241
struct device_node *np;
242242
u32 num_pins;
243+
int ret = 0;
244+
245+
parent = bus_get_dev_root(&platform_bus_type);
246+
if (!parent)
247+
return -ENODEV;
243248

244249
for_each_child_of_node(pdev->dev.of_node, np) {
245250
if (!of_property_read_bool(np, "interrupt-controller"))
246251
continue;
247252

248-
parent = bus_get_dev_root(&platform_bus_type);
249-
if (parent) {
250-
child = of_platform_device_create(np, NULL, parent);
251-
put_device(parent);
252-
if (!child) {
253-
of_node_put(np);
254-
return -ENOMEM;
255-
}
253+
child = of_platform_device_create(np, NULL, parent);
254+
if (!child) {
255+
ret = -ENOMEM;
256+
break;
256257
}
257258

258259
if (of_property_read_u32(child->dev.of_node, "num-pins",
259260
&num_pins) < 0) {
260261
dev_err(&pdev->dev, "No num-pins property\n");
261-
of_node_put(np);
262-
return -EINVAL;
262+
ret = -EINVAL;
263+
break;
263264
}
264265

265266
domain = platform_msi_create_device_domain(&child->dev, num_pins,
266267
mbigen_write_msg,
267268
&mbigen_domain_ops,
268269
mgn_chip);
269270
if (!domain) {
270-
of_node_put(np);
271-
return -ENOMEM;
271+
ret = -ENOMEM;
272+
break;
272273
}
273274
}
274275

275-
return 0;
276+
put_device(parent);
277+
if (ret)
278+
of_node_put(np);
279+
280+
return ret;
276281
}
277282

278283
#ifdef CONFIG_ACPI

drivers/irqchip/irq-meson-gpio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ static const struct meson_gpio_irq_params s4_params = {
150150
INIT_MESON_S4_COMMON_DATA(82)
151151
};
152152

153-
static const struct of_device_id meson_irq_gpio_matches[] = {
153+
static const struct of_device_id meson_irq_gpio_matches[] __maybe_unused = {
154154
{ .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params },
155155
{ .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params },
156156
{ .compatible = "amlogic,meson-gxbb-gpio-intc", .data = &gxbb_params },

drivers/irqchip/irq-mips-gic.c

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ void __iomem *mips_gic_base;
5050

5151
static DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks);
5252

53-
static DEFINE_SPINLOCK(gic_lock);
53+
static DEFINE_RAW_SPINLOCK(gic_lock);
5454
static struct irq_domain *gic_irq_domain;
5555
static int gic_shared_intrs;
5656
static unsigned int gic_cpu_pin;
@@ -210,7 +210,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
210210

211211
irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
212212

213-
spin_lock_irqsave(&gic_lock, flags);
213+
raw_spin_lock_irqsave(&gic_lock, flags);
214214
switch (type & IRQ_TYPE_SENSE_MASK) {
215215
case IRQ_TYPE_EDGE_FALLING:
216216
pol = GIC_POL_FALLING_EDGE;
@@ -250,7 +250,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
250250
else
251251
irq_set_chip_handler_name_locked(d, &gic_level_irq_controller,
252252
handle_level_irq, NULL);
253-
spin_unlock_irqrestore(&gic_lock, flags);
253+
raw_spin_unlock_irqrestore(&gic_lock, flags);
254254

255255
return 0;
256256
}
@@ -268,7 +268,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
268268
return -EINVAL;
269269

270270
/* Assumption : cpumask refers to a single CPU */
271-
spin_lock_irqsave(&gic_lock, flags);
271+
raw_spin_lock_irqsave(&gic_lock, flags);
272272

273273
/* Re-route this IRQ */
274274
write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpu)));
@@ -279,7 +279,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
279279
set_bit(irq, per_cpu_ptr(pcpu_masks, cpu));
280280

281281
irq_data_update_effective_affinity(d, cpumask_of(cpu));
282-
spin_unlock_irqrestore(&gic_lock, flags);
282+
raw_spin_unlock_irqrestore(&gic_lock, flags);
283283

284284
return IRQ_SET_MASK_OK;
285285
}
@@ -357,12 +357,12 @@ static void gic_mask_local_irq_all_vpes(struct irq_data *d)
357357
cd = irq_data_get_irq_chip_data(d);
358358
cd->mask = false;
359359

360-
spin_lock_irqsave(&gic_lock, flags);
360+
raw_spin_lock_irqsave(&gic_lock, flags);
361361
for_each_online_cpu(cpu) {
362362
write_gic_vl_other(mips_cm_vp_id(cpu));
363363
write_gic_vo_rmask(BIT(intr));
364364
}
365-
spin_unlock_irqrestore(&gic_lock, flags);
365+
raw_spin_unlock_irqrestore(&gic_lock, flags);
366366
}
367367

368368
static void gic_unmask_local_irq_all_vpes(struct irq_data *d)
@@ -375,12 +375,12 @@ static void gic_unmask_local_irq_all_vpes(struct irq_data *d)
375375
cd = irq_data_get_irq_chip_data(d);
376376
cd->mask = true;
377377

378-
spin_lock_irqsave(&gic_lock, flags);
378+
raw_spin_lock_irqsave(&gic_lock, flags);
379379
for_each_online_cpu(cpu) {
380380
write_gic_vl_other(mips_cm_vp_id(cpu));
381381
write_gic_vo_smask(BIT(intr));
382382
}
383-
spin_unlock_irqrestore(&gic_lock, flags);
383+
raw_spin_unlock_irqrestore(&gic_lock, flags);
384384
}
385385

386386
static void gic_all_vpes_irq_cpu_online(void)
@@ -393,19 +393,21 @@ static void gic_all_vpes_irq_cpu_online(void)
393393
unsigned long flags;
394394
int i;
395395

396-
spin_lock_irqsave(&gic_lock, flags);
396+
raw_spin_lock_irqsave(&gic_lock, flags);
397397

398398
for (i = 0; i < ARRAY_SIZE(local_intrs); i++) {
399399
unsigned int intr = local_intrs[i];
400400
struct gic_all_vpes_chip_data *cd;
401401

402+
if (!gic_local_irq_is_routable(intr))
403+
continue;
402404
cd = &gic_all_vpes_chip_data[intr];
403405
write_gic_vl_map(mips_gic_vx_map_reg(intr), cd->map);
404406
if (cd->mask)
405407
write_gic_vl_smask(BIT(intr));
406408
}
407409

408-
spin_unlock_irqrestore(&gic_lock, flags);
410+
raw_spin_unlock_irqrestore(&gic_lock, flags);
409411
}
410412

411413
static struct irq_chip gic_all_vpes_local_irq_controller = {
@@ -435,11 +437,11 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
435437

436438
data = irq_get_irq_data(virq);
437439

438-
spin_lock_irqsave(&gic_lock, flags);
440+
raw_spin_lock_irqsave(&gic_lock, flags);
439441
write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
440442
write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu)));
441443
irq_data_update_effective_affinity(data, cpumask_of(cpu));
442-
spin_unlock_irqrestore(&gic_lock, flags);
444+
raw_spin_unlock_irqrestore(&gic_lock, flags);
443445

444446
return 0;
445447
}
@@ -531,12 +533,12 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
531533
if (!gic_local_irq_is_routable(intr))
532534
return -EPERM;
533535

534-
spin_lock_irqsave(&gic_lock, flags);
536+
raw_spin_lock_irqsave(&gic_lock, flags);
535537
for_each_online_cpu(cpu) {
536538
write_gic_vl_other(mips_cm_vp_id(cpu));
537539
write_gic_vo_map(mips_gic_vx_map_reg(intr), map);
538540
}
539-
spin_unlock_irqrestore(&gic_lock, flags);
541+
raw_spin_unlock_irqrestore(&gic_lock, flags);
540542

541543
return 0;
542544
}

0 commit comments

Comments
 (0)