Commit 9c9947f8 authored by Thomas Gleixner's avatar Thomas Gleixner

Merge tag 'irqchip-4.13-3' of...

Merge tag 'irqchip-4.13-3' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent

Pull irqchip fixes for 4.13 from Marc Zyngier

Mostly GIC related, again:
- GICv3 ITS NUMA handling fixes
- GICv3 force affinity handling
- Barrier adjustment in both GIC interrupt handling
- Error reporting when the DT presents an incompatible interrupt
- GICv3 platform MSI DT parsing bug fix
- Broadcom L2 PM fix
- Atmel AIC cleanups
parents 83979133 a0088737
...@@ -137,14 +137,14 @@ static void __init aic_common_ext_irq_of_init(struct irq_domain *domain) ...@@ -137,14 +137,14 @@ static void __init aic_common_ext_irq_of_init(struct irq_domain *domain)
#define AT91_RTC_IMR 0x28 #define AT91_RTC_IMR 0x28
#define AT91_RTC_IRQ_MASK 0x1f #define AT91_RTC_IRQ_MASK 0x1f
void __init aic_common_rtc_irq_fixup(struct device_node *root) void __init aic_common_rtc_irq_fixup(void)
{ {
struct device_node *np; struct device_node *np;
void __iomem *regs; void __iomem *regs;
np = of_find_compatible_node(root, NULL, "atmel,at91rm9200-rtc"); np = of_find_compatible_node(NULL, NULL, "atmel,at91rm9200-rtc");
if (!np) if (!np)
np = of_find_compatible_node(root, NULL, np = of_find_compatible_node(NULL, NULL,
"atmel,at91sam9x5-rtc"); "atmel,at91sam9x5-rtc");
if (!np) if (!np)
...@@ -165,7 +165,7 @@ void __init aic_common_rtc_irq_fixup(struct device_node *root) ...@@ -165,7 +165,7 @@ void __init aic_common_rtc_irq_fixup(struct device_node *root)
#define AT91_RTT_ALMIEN (1 << 16) /* Alarm Interrupt Enable */ #define AT91_RTT_ALMIEN (1 << 16) /* Alarm Interrupt Enable */
#define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */ #define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */
void __init aic_common_rtt_irq_fixup(struct device_node *root) void __init aic_common_rtt_irq_fixup(void)
{ {
struct device_node *np; struct device_node *np;
void __iomem *regs; void __iomem *regs;
...@@ -196,11 +196,10 @@ static void __init aic_common_irq_fixup(const struct of_device_id *matches) ...@@ -196,11 +196,10 @@ static void __init aic_common_irq_fixup(const struct of_device_id *matches)
return; return;
match = of_match_node(matches, root); match = of_match_node(matches, root);
of_node_put(root);
if (match) { if (match) {
void (*fixup)(struct device_node *) = match->data; void (*fixup)(void) = match->data;
fixup(root); fixup();
} }
of_node_put(root); of_node_put(root);
......
...@@ -33,8 +33,8 @@ struct irq_domain *__init aic_common_of_init(struct device_node *node, ...@@ -33,8 +33,8 @@ struct irq_domain *__init aic_common_of_init(struct device_node *node,
const char *name, int nirqs, const char *name, int nirqs,
const struct of_device_id *matches); const struct of_device_id *matches);
void __init aic_common_rtc_irq_fixup(struct device_node *root); void __init aic_common_rtc_irq_fixup(void);
void __init aic_common_rtt_irq_fixup(struct device_node *root); void __init aic_common_rtt_irq_fixup(void);
#endif /* __IRQ_ATMEL_AIC_COMMON_H */ #endif /* __IRQ_ATMEL_AIC_COMMON_H */
...@@ -209,20 +209,20 @@ static const struct irq_domain_ops aic_irq_ops = { ...@@ -209,20 +209,20 @@ static const struct irq_domain_ops aic_irq_ops = {
.xlate = aic_irq_domain_xlate, .xlate = aic_irq_domain_xlate,
}; };
static void __init at91rm9200_aic_irq_fixup(struct device_node *root) static void __init at91rm9200_aic_irq_fixup(void)
{ {
aic_common_rtc_irq_fixup(root); aic_common_rtc_irq_fixup();
} }
static void __init at91sam9260_aic_irq_fixup(struct device_node *root) static void __init at91sam9260_aic_irq_fixup(void)
{ {
aic_common_rtt_irq_fixup(root); aic_common_rtt_irq_fixup();
} }
static void __init at91sam9g45_aic_irq_fixup(struct device_node *root) static void __init at91sam9g45_aic_irq_fixup(void)
{ {
aic_common_rtc_irq_fixup(root); aic_common_rtc_irq_fixup();
aic_common_rtt_irq_fixup(root); aic_common_rtt_irq_fixup();
} }
static const struct of_device_id aic_irq_fixups[] __initconst = { static const struct of_device_id aic_irq_fixups[] __initconst = {
......
...@@ -305,9 +305,9 @@ static const struct irq_domain_ops aic5_irq_ops = { ...@@ -305,9 +305,9 @@ static const struct irq_domain_ops aic5_irq_ops = {
.xlate = aic5_irq_domain_xlate, .xlate = aic5_irq_domain_xlate,
}; };
static void __init sama5d3_aic_irq_fixup(struct device_node *root) static void __init sama5d3_aic_irq_fixup(void)
{ {
aic_common_rtc_irq_fixup(root); aic_common_rtc_irq_fixup();
} }
static const struct of_device_id aic5_irq_fixups[] __initconst = { static const struct of_device_id aic5_irq_fixups[] __initconst = {
......
...@@ -189,6 +189,7 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np, ...@@ -189,6 +189,7 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np,
ct->chip.irq_suspend = brcmstb_l2_intc_suspend; ct->chip.irq_suspend = brcmstb_l2_intc_suspend;
ct->chip.irq_resume = brcmstb_l2_intc_resume; ct->chip.irq_resume = brcmstb_l2_intc_resume;
ct->chip.irq_pm_shutdown = brcmstb_l2_intc_suspend;
if (data->can_wake) { if (data->can_wake) {
/* This IRQ chip can wake the system, set all child interrupts /* This IRQ chip can wake the system, set all child interrupts
......
...@@ -43,6 +43,7 @@ static int of_pmsi_get_dev_id(struct irq_domain *domain, struct device *dev, ...@@ -43,6 +43,7 @@ static int of_pmsi_get_dev_id(struct irq_domain *domain, struct device *dev,
*dev_id = args.args[0]; *dev_id = args.args[0];
break; break;
} }
index++;
} while (!ret); } while (!ret);
return ret; return ret;
......
...@@ -1835,7 +1835,7 @@ static int __init its_of_probe(struct device_node *node) ...@@ -1835,7 +1835,7 @@ static int __init its_of_probe(struct device_node *node)
#define ACPI_GICV3_ITS_MEM_SIZE (SZ_128K) #define ACPI_GICV3_ITS_MEM_SIZE (SZ_128K)
#if defined(CONFIG_ACPI_NUMA) && (ACPI_CA_VERSION >= 0x20170531) #ifdef CONFIG_ACPI_NUMA
struct its_srat_map { struct its_srat_map {
/* numa node id */ /* numa node id */
u32 numa_node; u32 numa_node;
...@@ -1843,7 +1843,7 @@ struct its_srat_map { ...@@ -1843,7 +1843,7 @@ struct its_srat_map {
u32 its_id; u32 its_id;
}; };
static struct its_srat_map its_srat_maps[MAX_NUMNODES] __initdata; static struct its_srat_map *its_srat_maps __initdata;
static int its_in_srat __initdata; static int its_in_srat __initdata;
static int __init acpi_get_its_numa_node(u32 its_id) static int __init acpi_get_its_numa_node(u32 its_id)
...@@ -1857,6 +1857,12 @@ static int __init acpi_get_its_numa_node(u32 its_id) ...@@ -1857,6 +1857,12 @@ static int __init acpi_get_its_numa_node(u32 its_id)
return NUMA_NO_NODE; return NUMA_NO_NODE;
} }
static int __init gic_acpi_match_srat_its(struct acpi_subtable_header *header,
const unsigned long end)
{
return 0;
}
static int __init gic_acpi_parse_srat_its(struct acpi_subtable_header *header, static int __init gic_acpi_parse_srat_its(struct acpi_subtable_header *header,
const unsigned long end) const unsigned long end)
{ {
...@@ -1873,12 +1879,6 @@ static int __init gic_acpi_parse_srat_its(struct acpi_subtable_header *header, ...@@ -1873,12 +1879,6 @@ static int __init gic_acpi_parse_srat_its(struct acpi_subtable_header *header,
return -EINVAL; return -EINVAL;
} }
if (its_in_srat >= MAX_NUMNODES) {
pr_err("SRAT: ITS affinity exceeding max count[%d]\n",
MAX_NUMNODES);
return -EINVAL;
}
node = acpi_map_pxm_to_node(its_affinity->proximity_domain); node = acpi_map_pxm_to_node(its_affinity->proximity_domain);
if (node == NUMA_NO_NODE || node >= MAX_NUMNODES) { if (node == NUMA_NO_NODE || node >= MAX_NUMNODES) {
...@@ -1897,14 +1897,37 @@ static int __init gic_acpi_parse_srat_its(struct acpi_subtable_header *header, ...@@ -1897,14 +1897,37 @@ static int __init gic_acpi_parse_srat_its(struct acpi_subtable_header *header,
static void __init acpi_table_parse_srat_its(void) static void __init acpi_table_parse_srat_its(void)
{ {
int count;
count = acpi_table_parse_entries(ACPI_SIG_SRAT,
sizeof(struct acpi_table_srat),
ACPI_SRAT_TYPE_GIC_ITS_AFFINITY,
gic_acpi_match_srat_its, 0);
if (count <= 0)
return;
its_srat_maps = kmalloc(count * sizeof(struct its_srat_map),
GFP_KERNEL);
if (!its_srat_maps) {
pr_warn("SRAT: Failed to allocate memory for its_srat_maps!\n");
return;
}
acpi_table_parse_entries(ACPI_SIG_SRAT, acpi_table_parse_entries(ACPI_SIG_SRAT,
sizeof(struct acpi_table_srat), sizeof(struct acpi_table_srat),
ACPI_SRAT_TYPE_GIC_ITS_AFFINITY, ACPI_SRAT_TYPE_GIC_ITS_AFFINITY,
gic_acpi_parse_srat_its, 0); gic_acpi_parse_srat_its, 0);
} }
/* free the its_srat_maps after ITS probing */
static void __init acpi_its_srat_maps_free(void)
{
kfree(its_srat_maps);
}
#else #else
static void __init acpi_table_parse_srat_its(void) { } static void __init acpi_table_parse_srat_its(void) { }
static int __init acpi_get_its_numa_node(u32 its_id) { return NUMA_NO_NODE; } static int __init acpi_get_its_numa_node(u32 its_id) { return NUMA_NO_NODE; }
static void __init acpi_its_srat_maps_free(void) { }
#endif #endif
static int __init gic_acpi_parse_madt_its(struct acpi_subtable_header *header, static int __init gic_acpi_parse_madt_its(struct acpi_subtable_header *header,
...@@ -1951,6 +1974,7 @@ static void __init its_acpi_probe(void) ...@@ -1951,6 +1974,7 @@ static void __init its_acpi_probe(void)
acpi_table_parse_srat_its(); acpi_table_parse_srat_its();
acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR, acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
gic_acpi_parse_madt_its, 0); gic_acpi_parse_madt_its, 0);
acpi_its_srat_maps_free();
} }
#else #else
static void __init its_acpi_probe(void) { } static void __init its_acpi_probe(void) { }
......
...@@ -353,6 +353,8 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs ...@@ -353,6 +353,8 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
if (static_key_true(&supports_deactivate)) if (static_key_true(&supports_deactivate))
gic_write_eoir(irqnr); gic_write_eoir(irqnr);
else
isb();
err = handle_domain_irq(gic_data.domain, irqnr, regs); err = handle_domain_irq(gic_data.domain, irqnr, regs);
if (err) { if (err) {
...@@ -640,11 +642,16 @@ static void gic_smp_init(void) ...@@ -640,11 +642,16 @@ static void gic_smp_init(void)
static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
bool force) bool force)
{ {
unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask); unsigned int cpu;
void __iomem *reg; void __iomem *reg;
int enabled; int enabled;
u64 val; u64 val;
if (force)
cpu = cpumask_first(mask_val);
else
cpu = cpumask_any_and(mask_val, cpu_online_mask);
if (cpu >= nr_cpu_ids) if (cpu >= nr_cpu_ids)
return -EINVAL; return -EINVAL;
...@@ -831,8 +838,11 @@ static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, ...@@ -831,8 +838,11 @@ static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
if (ret) if (ret)
return ret; return ret;
for (i = 0; i < nr_irqs; i++) for (i = 0; i < nr_irqs; i++) {
gic_irq_domain_map(domain, virq + i, hwirq + i); ret = gic_irq_domain_map(domain, virq + i, hwirq + i);
if (ret)
return ret;
}
return 0; return 0;
} }
......
...@@ -361,6 +361,7 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) ...@@ -361,6 +361,7 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
if (likely(irqnr > 15 && irqnr < 1020)) { if (likely(irqnr > 15 && irqnr < 1020)) {
if (static_key_true(&supports_deactivate)) if (static_key_true(&supports_deactivate))
writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI); writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
isb();
handle_domain_irq(gic->domain, irqnr, regs); handle_domain_irq(gic->domain, irqnr, regs);
continue; continue;
} }
...@@ -401,10 +402,12 @@ static void gic_handle_cascade_irq(struct irq_desc *desc) ...@@ -401,10 +402,12 @@ static void gic_handle_cascade_irq(struct irq_desc *desc)
goto out; goto out;
cascade_irq = irq_find_mapping(chip_data->domain, gic_irq); cascade_irq = irq_find_mapping(chip_data->domain, gic_irq);
if (unlikely(gic_irq < 32 || gic_irq > 1020)) if (unlikely(gic_irq < 32 || gic_irq > 1020)) {
handle_bad_irq(desc); handle_bad_irq(desc);
else } else {
isb();
generic_handle_irq(cascade_irq); generic_handle_irq(cascade_irq);
}
out: out:
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);
...@@ -1027,8 +1030,11 @@ static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, ...@@ -1027,8 +1030,11 @@ static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
if (ret) if (ret)
return ret; return ret;
for (i = 0; i < nr_irqs; i++) for (i = 0; i < nr_irqs; i++) {
gic_irq_domain_map(domain, virq + i, hwirq + i); ret = gic_irq_domain_map(domain, virq + i, hwirq + i);
if (ret)
return ret;
}
return 0; return 0;
} }
......
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