Skip to content

Commit 1519610

Browse files
committed
Merge tag 'irq-urgent-2022-04-10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq fixes from Thomas Gleixner: "A set of interrupt chip driver fixes: - A fix for a long standing bug in the ARM GICv3 redistributor polling which uses the wrong bit number to test. - Prevent translation of bogus ACPI table entries which map device interrupts into the IPI space on ARM GICs. - Don't write into the pending register of ARM GICV4 before the scan in hardware has completed. - A set of build and correctness fixes for the Qualcomm MPM driver" * tag 'irq-urgent-2022-04-10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: irqchip/gic, gic-v3: Prevent GSI to SGI translations irqchip/gic-v3: Fix GICR_CTLR.RWP polling irqchip/gic-v4: Wait for GICR_VPENDBASER.Dirty to clear before descheduling irqchip/irq-qcom-mpm: fix return value check in qcom_mpm_init() irq/qcom-mpm: Fix build error without MAILBOX
2 parents 9c6913b + 63ef1a8 commit 1519610

File tree

5 files changed

+37
-14
lines changed

5 files changed

+37
-14
lines changed

drivers/irqchip/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ config QCOM_PDC
433433
config QCOM_MPM
434434
tristate "QCOM MPM"
435435
depends on ARCH_QCOM
436+
depends on MAILBOX
436437
select IRQ_DOMAIN_HIERARCHY
437438
help
438439
MSM Power Manager driver to manage and configure wakeup

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

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3011,18 +3011,12 @@ static int __init allocate_lpi_tables(void)
30113011
return 0;
30123012
}
30133013

3014-
static u64 its_clear_vpend_valid(void __iomem *vlpi_base, u64 clr, u64 set)
3014+
static u64 read_vpend_dirty_clear(void __iomem *vlpi_base)
30153015
{
30163016
u32 count = 1000000; /* 1s! */
30173017
bool clean;
30183018
u64 val;
30193019

3020-
val = gicr_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
3021-
val &= ~GICR_VPENDBASER_Valid;
3022-
val &= ~clr;
3023-
val |= set;
3024-
gicr_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
3025-
30263020
do {
30273021
val = gicr_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
30283022
clean = !(val & GICR_VPENDBASER_Dirty);
@@ -3033,10 +3027,26 @@ static u64 its_clear_vpend_valid(void __iomem *vlpi_base, u64 clr, u64 set)
30333027
}
30343028
} while (!clean && count);
30353029

3036-
if (unlikely(val & GICR_VPENDBASER_Dirty)) {
3030+
if (unlikely(!clean))
30373031
pr_err_ratelimited("ITS virtual pending table not cleaning\n");
3032+
3033+
return val;
3034+
}
3035+
3036+
static u64 its_clear_vpend_valid(void __iomem *vlpi_base, u64 clr, u64 set)
3037+
{
3038+
u64 val;
3039+
3040+
/* Make sure we wait until the RD is done with the initial scan */
3041+
val = read_vpend_dirty_clear(vlpi_base);
3042+
val &= ~GICR_VPENDBASER_Valid;
3043+
val &= ~clr;
3044+
val |= set;
3045+
gicr_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
3046+
3047+
val = read_vpend_dirty_clear(vlpi_base);
3048+
if (unlikely(val & GICR_VPENDBASER_Dirty))
30383049
val |= GICR_VPENDBASER_PendingLast;
3039-
}
30403050

30413051
return val;
30423052
}

drivers/irqchip/irq-gic-v3.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,11 @@ static inline void __iomem *gic_dist_base(struct irq_data *d)
206206
}
207207
}
208208

209-
static void gic_do_wait_for_rwp(void __iomem *base)
209+
static void gic_do_wait_for_rwp(void __iomem *base, u32 bit)
210210
{
211211
u32 count = 1000000; /* 1s! */
212212

213-
while (readl_relaxed(base + GICD_CTLR) & GICD_CTLR_RWP) {
213+
while (readl_relaxed(base + GICD_CTLR) & bit) {
214214
count--;
215215
if (!count) {
216216
pr_err_ratelimited("RWP timeout, gone fishing\n");
@@ -224,13 +224,13 @@ static void gic_do_wait_for_rwp(void __iomem *base)
224224
/* Wait for completion of a distributor change */
225225
static void gic_dist_wait_for_rwp(void)
226226
{
227-
gic_do_wait_for_rwp(gic_data.dist_base);
227+
gic_do_wait_for_rwp(gic_data.dist_base, GICD_CTLR_RWP);
228228
}
229229

230230
/* Wait for completion of a redistributor change */
231231
static void gic_redist_wait_for_rwp(void)
232232
{
233-
gic_do_wait_for_rwp(gic_data_rdist_rd_base());
233+
gic_do_wait_for_rwp(gic_data_rdist_rd_base(), GICR_CTLR_RWP);
234234
}
235235

236236
#ifdef CONFIG_ARM64
@@ -1466,6 +1466,12 @@ static int gic_irq_domain_translate(struct irq_domain *d,
14661466
if(fwspec->param_count != 2)
14671467
return -EINVAL;
14681468

1469+
if (fwspec->param[0] < 16) {
1470+
pr_err(FW_BUG "Illegal GSI%d translation request\n",
1471+
fwspec->param[0]);
1472+
return -EINVAL;
1473+
}
1474+
14691475
*hwirq = fwspec->param[0];
14701476
*type = fwspec->param[1];
14711477

drivers/irqchip/irq-gic.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,12 @@ static int gic_irq_domain_translate(struct irq_domain *d,
11231123
if(fwspec->param_count != 2)
11241124
return -EINVAL;
11251125

1126+
if (fwspec->param[0] < 16) {
1127+
pr_err(FW_BUG "Illegal GSI%d translation request\n",
1128+
fwspec->param[0]);
1129+
return -EINVAL;
1130+
}
1131+
11261132
*hwirq = fwspec->param[0];
11271133
*type = fwspec->param[1];
11281134

drivers/irqchip/irq-qcom-mpm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ static int qcom_mpm_init(struct device_node *np, struct device_node *parent)
375375
raw_spin_lock_init(&priv->lock);
376376

377377
priv->base = devm_platform_ioremap_resource(pdev, 0);
378-
if (!priv->base)
378+
if (IS_ERR(priv->base))
379379
return PTR_ERR(priv->base);
380380

381381
for (i = 0; i < priv->reg_stride; i++) {

0 commit comments

Comments
 (0)