mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
irqchip fixes for 4.13
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 -----BEGIN PGP SIGNATURE----- iQJJBAABCAAzFiEEn9UcU+C1Yxj9lZw9I9DQutE9ekMFAlmNw18VHG1hcmMuenlu Z2llckBhcm0uY29tAAoJECPQ0LrRPXpDcsgP/2fBEBxmjyJ7XCZWqWSUYbdwYdjS BWj5SO5umd/KI5dzPxXqlEf/BLlLyWg97NI3+fzCa6xBtJiGfeJwVgdUeKtFEFdI IckPGdXHQfqAobJyQtVIFitqNiDrrdAxQH9akSQ0XCKTiqhy6tcDUBorXqpkMCQn 5AKMAf8XyjqnDM/rCPa1s+2yJFZxK6AJ+zd2/9XRVu8na7dCYeHfGLnvPbEjAgtE sRLrO+1kHstb+denwhsfm16z+s/mW172H3ZN9g43JA8NULVAf/n7BzVVVqNrNO9Q 6NO315SJFBnG8RN9AY+Ewt7D1s3TR3r9Us20ni1JLLiSE9fEVqU0ajzrO36pS2mm BfWYjKjKHkdqVwVlchENOlLnKcLkC4gM6JLMLhT71a6NC7uUYtte3651Q1UpRHWy 7Ox7HO5rHi5Z75MRM0uFnP/NySvzMucbiINTzu0xuVbrI6YBm7Ov/z4cngvHcie4 pnw1yMFxaUg4/vIWoehsC7ASNLcUoN57xZuihz4WXceR5p2kn5MCnNIM4+Lg5suq +lysBBexWBV3ARaBq5+d8ZrPR/p68B1zEFLEN0u8M5Iwm5jCvWmnCYUmOyvzqx9n o/59jzjdZ6y3kJSpLe5kOlAK2QKz1XJFePw90wxAjGq4tBY9agkBxoBCQbNkjX7H JN4xGXwWAQqULwXs =2HRc -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
9c9947f893
@ -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_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;
|
||||
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)
|
||||
np = of_find_compatible_node(root, NULL,
|
||||
np = of_find_compatible_node(NULL, NULL,
|
||||
"atmel,at91sam9x5-rtc");
|
||||
|
||||
if (!np)
|
||||
@ -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_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;
|
||||
void __iomem *regs;
|
||||
@ -196,11 +196,10 @@ static void __init aic_common_irq_fixup(const struct of_device_id *matches)
|
||||
return;
|
||||
|
||||
match = of_match_node(matches, root);
|
||||
of_node_put(root);
|
||||
|
||||
if (match) {
|
||||
void (*fixup)(struct device_node *) = match->data;
|
||||
fixup(root);
|
||||
void (*fixup)(void) = match->data;
|
||||
fixup();
|
||||
}
|
||||
|
||||
of_node_put(root);
|
||||
|
@ -33,8 +33,8 @@ struct irq_domain *__init aic_common_of_init(struct device_node *node,
|
||||
const char *name, int nirqs,
|
||||
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 */
|
||||
|
@ -209,20 +209,20 @@ static const struct irq_domain_ops aic_irq_ops = {
|
||||
.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_rtt_irq_fixup(root);
|
||||
aic_common_rtc_irq_fixup();
|
||||
aic_common_rtt_irq_fixup();
|
||||
}
|
||||
|
||||
static const struct of_device_id aic_irq_fixups[] __initconst = {
|
||||
|
@ -305,9 +305,9 @@ static const struct irq_domain_ops aic5_irq_ops = {
|
||||
.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 = {
|
||||
|
@ -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_resume = brcmstb_l2_intc_resume;
|
||||
ct->chip.irq_pm_shutdown = brcmstb_l2_intc_suspend;
|
||||
|
||||
if (data->can_wake) {
|
||||
/* 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,
|
||||
*dev_id = args.args[0];
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
} while (!ret);
|
||||
|
||||
return ret;
|
||||
|
@ -1835,7 +1835,7 @@ static int __init its_of_probe(struct device_node *node)
|
||||
|
||||
#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 {
|
||||
/* numa node id */
|
||||
u32 numa_node;
|
||||
@ -1843,7 +1843,7 @@ struct its_srat_map {
|
||||
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 __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;
|
||||
}
|
||||
|
||||
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,
|
||||
const unsigned long end)
|
||||
{
|
||||
@ -1873,12 +1879,6 @@ static int __init gic_acpi_parse_srat_its(struct acpi_subtable_header *header,
|
||||
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);
|
||||
|
||||
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,
|
||||
|
||||
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,
|
||||
sizeof(struct acpi_table_srat),
|
||||
ACPI_SRAT_TYPE_GIC_ITS_AFFINITY,
|
||||
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
|
||||
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 void __init acpi_its_srat_maps_free(void) { }
|
||||
#endif
|
||||
|
||||
static int __init gic_acpi_parse_madt_its(struct acpi_subtable_header *header,
|
||||
@ -1951,6 +1974,7 @@ static void __init its_acpi_probe(void)
|
||||
acpi_table_parse_srat_its();
|
||||
acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
|
||||
gic_acpi_parse_madt_its, 0);
|
||||
acpi_its_srat_maps_free();
|
||||
}
|
||||
#else
|
||||
static void __init its_acpi_probe(void) { }
|
||||
|
@ -353,6 +353,8 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
|
||||
|
||||
if (static_key_true(&supports_deactivate))
|
||||
gic_write_eoir(irqnr);
|
||||
else
|
||||
isb();
|
||||
|
||||
err = handle_domain_irq(gic_data.domain, irqnr, regs);
|
||||
if (err) {
|
||||
@ -640,11 +642,16 @@ static void gic_smp_init(void)
|
||||
static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
|
||||
bool force)
|
||||
{
|
||||
unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
|
||||
unsigned int cpu;
|
||||
void __iomem *reg;
|
||||
int enabled;
|
||||
u64 val;
|
||||
|
||||
if (force)
|
||||
cpu = cpumask_first(mask_val);
|
||||
else
|
||||
cpu = cpumask_any_and(mask_val, cpu_online_mask);
|
||||
|
||||
if (cpu >= nr_cpu_ids)
|
||||
return -EINVAL;
|
||||
|
||||
@ -831,8 +838,11 @@ static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < nr_irqs; i++)
|
||||
gic_irq_domain_map(domain, virq + i, hwirq + i);
|
||||
for (i = 0; i < nr_irqs; i++) {
|
||||
ret = gic_irq_domain_map(domain, virq + i, hwirq + i);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -361,6 +361,7 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
|
||||
if (likely(irqnr > 15 && irqnr < 1020)) {
|
||||
if (static_key_true(&supports_deactivate))
|
||||
writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
|
||||
isb();
|
||||
handle_domain_irq(gic->domain, irqnr, regs);
|
||||
continue;
|
||||
}
|
||||
@ -401,10 +402,12 @@ static void gic_handle_cascade_irq(struct irq_desc *desc)
|
||||
goto out;
|
||||
|
||||
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);
|
||||
else
|
||||
} else {
|
||||
isb();
|
||||
generic_handle_irq(cascade_irq);
|
||||
}
|
||||
|
||||
out:
|
||||
chained_irq_exit(chip, desc);
|
||||
@ -1027,8 +1030,11 @@ static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < nr_irqs; i++)
|
||||
gic_irq_domain_map(domain, virq + i, hwirq + i);
|
||||
for (i = 0; i < nr_irqs; i++) {
|
||||
ret = gic_irq_domain_map(domain, virq + i, hwirq + i);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user