diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-11 18:28:06 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-11 18:28:06 -0800 |
commit | 3d116a66ed9df0271b8d267093b3bfde2be19b3a (patch) | |
tree | 8415b051c87b44ea9f7ecd50bf850155b028737e /drivers/irqchip/irq-gic.c | |
parent | b4cee21ee057ff3e5c9014fb6a175bd932c5ce62 (diff) | |
parent | d3b421cd07e4c0d4d6c0bbd55ca169c054fc081d (diff) | |
download | linux-3d116a66ed9df0271b8d267093b3bfde2be19b3a.tar.gz linux-3d116a66ed9df0271b8d267093b3bfde2be19b3a.tar.bz2 linux-3d116a66ed9df0271b8d267093b3bfde2be19b3a.zip |
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner:
"The irq department provides:
- Support for MSI to wire bridges and a first user of it
- More ACPI support for ARM/GIC
- A new TS-4800 interrupt controller driver
- RCU based free of interrupt descriptors to support the upcoming
Intel VMD technology without introducing a locking nightmare
- The usual pile of fixes and updates to drivers and core code"
* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (41 commits)
irqchip/omap-intc: Add support for spurious irq handling
irqchip/zevio: Use irq_data_get_chip_type() helper
irqchip/omap-intc: Remove duplicate setup for IRQ chip type handler
irqchip/ts4800: Add TS-4800 interrupt controller
irqchip/ts4800: Add documentation for TS-4800 interrupt controller
irq/platform-MSI: Increase the maximum MSIs the MSI framework can support
irqchip/gicv2m: Miscellaneous fixes for v2m resources and SPI ranges
irqchip/bcm2836: Make code more readable
irqchip/bcm2836: Tolerate IRQs while no flag is set in ISR
irqchip/bcm2836: Add SMP support for the 2836
irqchip/bcm2836: Fix initialization of the LOCAL_IRQ_CNT timers
irqchip/gic-v2m: acpi: Introducing GICv2m ACPI support
irqchip/gic-v2m: Refactor to prepare for ACPI support
irqdomain: Introduce is_fwnode_irqchip helper
acpi: pci: Setup MSI domain for ACPI based pci devices
genirq/msi: Export functions to allow MSI domains in modules
irqchip/mbigen: Implement the mbigen irq chip operation functions
irqchip/mbigen: Create irq domain for each mbigen device
irqchip/mgigen: Add platform device driver for mbigen device
dt-bindings: Documents the mbigen bindings
...
Diffstat (limited to 'drivers/irqchip/irq-gic.c')
-rw-r--r-- | drivers/irqchip/irq-gic.c | 64 |
1 files changed, 31 insertions, 33 deletions
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index abf2ffaed392..911758c056c1 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -69,6 +69,7 @@ union gic_base { }; struct gic_chip_data { + struct irq_chip chip; union gic_base dist_base; union gic_base cpu_base; #ifdef CONFIG_CPU_PM @@ -99,11 +100,7 @@ static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly; static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE; -#ifndef MAX_GIC_NR -#define MAX_GIC_NR 1 -#endif - -static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly; +static struct gic_chip_data gic_data[CONFIG_ARM_GIC_MAX_NR] __read_mostly; #ifdef CONFIG_GIC_NON_BANKED static void __iomem *gic_get_percpu_base(union gic_base *base) @@ -336,7 +333,7 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK); irqnr = irqstat & GICC_IAR_INT_ID_MASK; - if (likely(irqnr > 15 && irqnr < 1021)) { + if (likely(irqnr > 15 && irqnr < 1020)) { if (static_key_true(&supports_deactivate)) writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI); handle_domain_irq(gic->domain, irqnr, regs); @@ -383,7 +380,6 @@ static void gic_handle_cascade_irq(struct irq_desc *desc) } static struct irq_chip gic_chip = { - .name = "GIC", .irq_mask = gic_mask_irq, .irq_unmask = gic_unmask_irq, .irq_eoi = gic_eoi_irq, @@ -417,8 +413,7 @@ static struct irq_chip gic_eoimode1_chip = { void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) { - if (gic_nr >= MAX_GIC_NR) - BUG(); + BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR); irq_set_chained_handler_and_data(irq, gic_handle_cascade_irq, &gic_data[gic_nr]); } @@ -524,7 +519,7 @@ int gic_cpu_if_down(unsigned int gic_nr) void __iomem *cpu_base; u32 val = 0; - if (gic_nr >= MAX_GIC_NR) + if (gic_nr >= CONFIG_ARM_GIC_MAX_NR) return -EINVAL; cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); @@ -548,8 +543,7 @@ static void gic_dist_save(unsigned int gic_nr) void __iomem *dist_base; int i; - if (gic_nr >= MAX_GIC_NR) - BUG(); + BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR); gic_irqs = gic_data[gic_nr].gic_irqs; dist_base = gic_data_dist_base(&gic_data[gic_nr]); @@ -587,8 +581,7 @@ static void gic_dist_restore(unsigned int gic_nr) unsigned int i; void __iomem *dist_base; - if (gic_nr >= MAX_GIC_NR) - BUG(); + BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR); gic_irqs = gic_data[gic_nr].gic_irqs; dist_base = gic_data_dist_base(&gic_data[gic_nr]); @@ -634,8 +627,7 @@ static void gic_cpu_save(unsigned int gic_nr) void __iomem *dist_base; void __iomem *cpu_base; - if (gic_nr >= MAX_GIC_NR) - BUG(); + BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR); dist_base = gic_data_dist_base(&gic_data[gic_nr]); cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); @@ -664,8 +656,7 @@ static void gic_cpu_restore(unsigned int gic_nr) void __iomem *dist_base; void __iomem *cpu_base; - if (gic_nr >= MAX_GIC_NR) - BUG(); + BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR); dist_base = gic_data_dist_base(&gic_data[gic_nr]); cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); @@ -703,7 +694,7 @@ static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) { int i; - for (i = 0; i < MAX_GIC_NR; i++) { + for (i = 0; i < CONFIG_ARM_GIC_MAX_NR; i++) { #ifdef CONFIG_GIC_NON_BANKED /* Skip over unused GICs */ if (!gic_data[i].get_base) @@ -835,8 +826,7 @@ void gic_migrate_target(unsigned int new_cpu_id) int i, ror_val, cpu = smp_processor_id(); u32 val, cur_target_mask, active_mask; - if (gic_nr >= MAX_GIC_NR) - BUG(); + BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR); dist_base = gic_data_dist_base(&gic_data[gic_nr]); if (!dist_base) @@ -925,20 +915,15 @@ void __init gic_init_physaddr(struct device_node *node) static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { - struct irq_chip *chip = &gic_chip; - - if (static_key_true(&supports_deactivate)) { - if (d->host_data == (void *)&gic_data[0]) - chip = &gic_eoimode1_chip; - } + struct gic_chip_data *gic = d->host_data; if (hw < 32) { irq_set_percpu_devid(irq); - irq_domain_set_info(d, irq, hw, chip, d->host_data, + irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data, handle_percpu_devid_irq, NULL, NULL); irq_set_status_flags(irq, IRQ_NOAUTOEN); } else { - irq_domain_set_info(d, irq, hw, chip, d->host_data, + irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data, handle_fasteoi_irq, NULL, NULL); irq_set_probe(irq); } @@ -972,7 +957,7 @@ static int gic_irq_domain_translate(struct irq_domain *d, return 0; } - if (fwspec->fwnode->type == FWNODE_IRQCHIP) { + if (is_fwnode_irqchip(fwspec->fwnode)) { if(fwspec->param_count != 2) return -EINVAL; @@ -1040,11 +1025,20 @@ static void __init __gic_init_bases(unsigned int gic_nr, int irq_start, struct gic_chip_data *gic; int gic_irqs, irq_base, i; - BUG_ON(gic_nr >= MAX_GIC_NR); + BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR); gic_check_cpu_features(); gic = &gic_data[gic_nr]; + + /* Initialize irq_chip */ + if (static_key_true(&supports_deactivate) && gic_nr == 0) { + gic->chip = gic_eoimode1_chip; + } else { + gic->chip = gic_chip; + gic->chip.name = kasprintf(GFP_KERNEL, "GIC-%d", gic_nr); + } + #ifdef CONFIG_GIC_NON_BANKED if (percpu_offset) { /* Frankein-GIC without banked registers... */ unsigned int cpu; @@ -1196,7 +1190,7 @@ static bool gic_check_eoimode(struct device_node *node, void __iomem **base) return true; } -static int __init +int __init gic_of_init(struct device_node *node, struct device_node *parent) { void __iomem *cpu_base; @@ -1234,7 +1228,7 @@ gic_of_init(struct device_node *node, struct device_node *parent) } if (IS_ENABLED(CONFIG_ARM_GIC_V2M)) - gicv2m_of_init(node, gic_data[gic_cnt].domain); + gicv2m_init(&node->fwnode, gic_data[gic_cnt].domain); gic_cnt++; return 0; @@ -1359,6 +1353,10 @@ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header, __gic_init_bases(0, -1, dist_base, cpu_base, 0, domain_handle); acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, domain_handle); + + if (IS_ENABLED(CONFIG_ARM_GIC_V2M)) + gicv2m_init(NULL, gic_data[0].domain); + return 0; } IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, |