diff options
author | Paul Burton <paul.burton@imgtec.com> | 2017-08-12 21:36:40 -0700 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2017-09-04 13:53:14 +0200 |
commit | fbea754123ae5d9678295398c98e91f1b2159e5b (patch) | |
tree | 00b316718181161fa4d33de7c59b5480f4a3e620 /drivers | |
parent | 1fad12cd5ef43755d028f760fa089c87f5533451 (diff) | |
download | linux-fbea754123ae5d9678295398c98e91f1b2159e5b.tar.bz2 |
irqchip: mips-gic: Inline __gic_init()
The __gic_init() function is only called from gic_of_init() now that the
non-DT path has been removed. In order to simplify the code & aid
readability, fold __gic_init() into gic_of_init().
This provides us with the ability to return an error code, which
__gic_init() was previously unable to do. As such the irq_domain_add_*()
error paths are modified to print & return an error rather than panic().
[ralf@linux-mips.org: Resoled reject.]
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/17050/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/irqchip/irq-mips-gic.c | 115 |
1 files changed, 55 insertions, 60 deletions
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index bbf39dcfeda4..58fb876d88d6 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -648,15 +648,54 @@ static const struct irq_domain_ops gic_ipi_domain_ops = { .match = gic_ipi_domain_match, }; -static void __init __gic_init(unsigned long gic_base_addr, - unsigned long gic_addrspace_size, - unsigned int cpu_vec, unsigned int irqbase, - struct device_node *node) + +static int __init gic_of_init(struct device_node *node, + struct device_node *parent) { - unsigned int gicconfig, cpu; - unsigned int v[2]; + unsigned int cpu_vec, i, reserved, gicconfig, cpu, v[2]; + phys_addr_t gic_base; + struct resource res; + size_t gic_len; + + /* Find the first available CPU vector. */ + i = reserved = 0; + while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors", + i++, &cpu_vec)) + reserved |= BIT(cpu_vec); + for (cpu_vec = 2; cpu_vec < 8; cpu_vec++) { + if (!(reserved & BIT(cpu_vec))) + break; + } + if (cpu_vec == 8) { + pr_err("No CPU vectors available for GIC\n"); + return -ENODEV; + } + + if (of_address_to_resource(node, 0, &res)) { + /* + * Probe the CM for the GIC base address if not specified + * in the device-tree. + */ + if (mips_cm_present()) { + gic_base = read_gcr_gic_base() & + ~CM_GCR_GIC_BASE_GICEN; + gic_len = 0x20000; + } else { + pr_err("Failed to get GIC memory range\n"); + return -ENODEV; + } + } else { + gic_base = res.start; + gic_len = resource_size(&res); + } - mips_gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size); + if (mips_cm_present()) { + write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN); + /* Ensure GIC region is enabled before trying to access it */ + __sync(); + } + + mips_gic_base = ioremap_nocache(gic_base, gic_len); gicconfig = read_gic_config(); gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS; @@ -707,17 +746,21 @@ static void __init __gic_init(unsigned long gic_base_addr, } gic_irq_domain = irq_domain_add_simple(node, GIC_NUM_LOCAL_INTRS + - gic_shared_intrs, irqbase, + gic_shared_intrs, 0, &gic_irq_domain_ops, NULL); - if (!gic_irq_domain) - panic("Failed to add GIC IRQ domain"); + if (!gic_irq_domain) { + pr_err("Failed to add GIC IRQ domain"); + return -ENXIO; + } gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain, IRQ_DOMAIN_FLAG_IPI_PER_CPU, GIC_NUM_LOCAL_INTRS + gic_shared_intrs, node, &gic_ipi_domain_ops, NULL); - if (!gic_ipi_domain) - panic("Failed to add GIC IPI domain"); + if (!gic_ipi_domain) { + pr_err("Failed to add GIC IPI domain"); + return -ENXIO; + } irq_domain_update_bus_token(gic_ipi_domain, DOMAIN_BUS_IPI); @@ -733,54 +776,6 @@ static void __init __gic_init(unsigned long gic_base_addr, bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS); gic_basic_init(); -} - -static int __init gic_of_init(struct device_node *node, - struct device_node *parent) -{ - struct resource res; - unsigned int cpu_vec, i = 0, reserved = 0; - phys_addr_t gic_base; - size_t gic_len; - - /* Find the first available CPU vector. */ - while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors", - i++, &cpu_vec)) - reserved |= BIT(cpu_vec); - for (cpu_vec = 2; cpu_vec < 8; cpu_vec++) { - if (!(reserved & BIT(cpu_vec))) - break; - } - if (cpu_vec == 8) { - pr_err("No CPU vectors available for GIC\n"); - return -ENODEV; - } - - if (of_address_to_resource(node, 0, &res)) { - /* - * Probe the CM for the GIC base address if not specified - * in the device-tree. - */ - if (mips_cm_present()) { - gic_base = read_gcr_gic_base() & - ~CM_GCR_GIC_BASE_GICEN; - gic_len = 0x20000; - } else { - pr_err("Failed to get GIC memory range\n"); - return -ENODEV; - } - } else { - gic_base = res.start; - gic_len = resource_size(&res); - } - - if (mips_cm_present()) { - write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN); - /* Ensure GIC region is enabled before trying to access it */ - __sync(); - } - - __gic_init(gic_base, gic_len, cpu_vec, 0, node); return 0; } |