Commit 1519610b authored by Linus Torvalds's avatar Linus Torvalds

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
parents 9c6913b7 63ef1a8a
...@@ -433,6 +433,7 @@ config QCOM_PDC ...@@ -433,6 +433,7 @@ config QCOM_PDC
config QCOM_MPM config QCOM_MPM
tristate "QCOM MPM" tristate "QCOM MPM"
depends on ARCH_QCOM depends on ARCH_QCOM
depends on MAILBOX
select IRQ_DOMAIN_HIERARCHY select IRQ_DOMAIN_HIERARCHY
help help
MSM Power Manager driver to manage and configure wakeup MSM Power Manager driver to manage and configure wakeup
......
...@@ -3011,18 +3011,12 @@ static int __init allocate_lpi_tables(void) ...@@ -3011,18 +3011,12 @@ static int __init allocate_lpi_tables(void)
return 0; return 0;
} }
static u64 its_clear_vpend_valid(void __iomem *vlpi_base, u64 clr, u64 set) static u64 read_vpend_dirty_clear(void __iomem *vlpi_base)
{ {
u32 count = 1000000; /* 1s! */ u32 count = 1000000; /* 1s! */
bool clean; bool clean;
u64 val; u64 val;
val = gicr_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
val &= ~GICR_VPENDBASER_Valid;
val &= ~clr;
val |= set;
gicr_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
do { do {
val = gicr_read_vpendbaser(vlpi_base + GICR_VPENDBASER); val = gicr_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
clean = !(val & GICR_VPENDBASER_Dirty); clean = !(val & GICR_VPENDBASER_Dirty);
...@@ -3033,10 +3027,26 @@ static u64 its_clear_vpend_valid(void __iomem *vlpi_base, u64 clr, u64 set) ...@@ -3033,10 +3027,26 @@ static u64 its_clear_vpend_valid(void __iomem *vlpi_base, u64 clr, u64 set)
} }
} while (!clean && count); } while (!clean && count);
if (unlikely(val & GICR_VPENDBASER_Dirty)) { if (unlikely(!clean))
pr_err_ratelimited("ITS virtual pending table not cleaning\n"); pr_err_ratelimited("ITS virtual pending table not cleaning\n");
return val;
}
static u64 its_clear_vpend_valid(void __iomem *vlpi_base, u64 clr, u64 set)
{
u64 val;
/* Make sure we wait until the RD is done with the initial scan */
val = read_vpend_dirty_clear(vlpi_base);
val &= ~GICR_VPENDBASER_Valid;
val &= ~clr;
val |= set;
gicr_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
val = read_vpend_dirty_clear(vlpi_base);
if (unlikely(val & GICR_VPENDBASER_Dirty))
val |= GICR_VPENDBASER_PendingLast; val |= GICR_VPENDBASER_PendingLast;
}
return val; return val;
} }
......
...@@ -206,11 +206,11 @@ static inline void __iomem *gic_dist_base(struct irq_data *d) ...@@ -206,11 +206,11 @@ static inline void __iomem *gic_dist_base(struct irq_data *d)
} }
} }
static void gic_do_wait_for_rwp(void __iomem *base) static void gic_do_wait_for_rwp(void __iomem *base, u32 bit)
{ {
u32 count = 1000000; /* 1s! */ u32 count = 1000000; /* 1s! */
while (readl_relaxed(base + GICD_CTLR) & GICD_CTLR_RWP) { while (readl_relaxed(base + GICD_CTLR) & bit) {
count--; count--;
if (!count) { if (!count) {
pr_err_ratelimited("RWP timeout, gone fishing\n"); pr_err_ratelimited("RWP timeout, gone fishing\n");
...@@ -224,13 +224,13 @@ static void gic_do_wait_for_rwp(void __iomem *base) ...@@ -224,13 +224,13 @@ static void gic_do_wait_for_rwp(void __iomem *base)
/* Wait for completion of a distributor change */ /* Wait for completion of a distributor change */
static void gic_dist_wait_for_rwp(void) static void gic_dist_wait_for_rwp(void)
{ {
gic_do_wait_for_rwp(gic_data.dist_base); gic_do_wait_for_rwp(gic_data.dist_base, GICD_CTLR_RWP);
} }
/* Wait for completion of a redistributor change */ /* Wait for completion of a redistributor change */
static void gic_redist_wait_for_rwp(void) static void gic_redist_wait_for_rwp(void)
{ {
gic_do_wait_for_rwp(gic_data_rdist_rd_base()); gic_do_wait_for_rwp(gic_data_rdist_rd_base(), GICR_CTLR_RWP);
} }
#ifdef CONFIG_ARM64 #ifdef CONFIG_ARM64
...@@ -1466,6 +1466,12 @@ static int gic_irq_domain_translate(struct irq_domain *d, ...@@ -1466,6 +1466,12 @@ static int gic_irq_domain_translate(struct irq_domain *d,
if(fwspec->param_count != 2) if(fwspec->param_count != 2)
return -EINVAL; return -EINVAL;
if (fwspec->param[0] < 16) {
pr_err(FW_BUG "Illegal GSI%d translation request\n",
fwspec->param[0]);
return -EINVAL;
}
*hwirq = fwspec->param[0]; *hwirq = fwspec->param[0];
*type = fwspec->param[1]; *type = fwspec->param[1];
......
...@@ -1123,6 +1123,12 @@ static int gic_irq_domain_translate(struct irq_domain *d, ...@@ -1123,6 +1123,12 @@ static int gic_irq_domain_translate(struct irq_domain *d,
if(fwspec->param_count != 2) if(fwspec->param_count != 2)
return -EINVAL; return -EINVAL;
if (fwspec->param[0] < 16) {
pr_err(FW_BUG "Illegal GSI%d translation request\n",
fwspec->param[0]);
return -EINVAL;
}
*hwirq = fwspec->param[0]; *hwirq = fwspec->param[0];
*type = fwspec->param[1]; *type = fwspec->param[1];
......
...@@ -375,7 +375,7 @@ static int qcom_mpm_init(struct device_node *np, struct device_node *parent) ...@@ -375,7 +375,7 @@ static int qcom_mpm_init(struct device_node *np, struct device_node *parent)
raw_spin_lock_init(&priv->lock); raw_spin_lock_init(&priv->lock);
priv->base = devm_platform_ioremap_resource(pdev, 0); priv->base = devm_platform_ioremap_resource(pdev, 0);
if (!priv->base) if (IS_ERR(priv->base))
return PTR_ERR(priv->base); return PTR_ERR(priv->base);
for (i = 0; i < priv->reg_stride; i++) { for (i = 0; i < priv->reg_stride; i++) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment