Commit fbea7541 authored by Paul Burton's avatar Paul Burton Committed by Ralf Baechle

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: default avatarPaul Burton <paul.burton@imgtec.com>
Acked-by: default avatarMarc 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: default avatarRalf Baechle <ralf@linux-mips.org>
parent 1fad12cd
...@@ -648,15 +648,54 @@ static const struct irq_domain_ops gic_ipi_domain_ops = { ...@@ -648,15 +648,54 @@ static const struct irq_domain_ops gic_ipi_domain_ops = {
.match = gic_ipi_domain_match, .match = gic_ipi_domain_match,
}; };
static void __init __gic_init(unsigned long gic_base_addr,
unsigned long gic_addrspace_size, static int __init gic_of_init(struct device_node *node,
unsigned int cpu_vec, unsigned int irqbase, struct device_node *parent)
struct device_node *node)
{ {
unsigned int gicconfig, cpu; unsigned int cpu_vec, i, reserved, gicconfig, cpu, v[2];
unsigned int 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(); gicconfig = read_gic_config();
gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS; gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS;
...@@ -707,17 +746,21 @@ static void __init __gic_init(unsigned long gic_base_addr, ...@@ -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_irq_domain = irq_domain_add_simple(node, GIC_NUM_LOCAL_INTRS +
gic_shared_intrs, irqbase, gic_shared_intrs, 0,
&gic_irq_domain_ops, NULL); &gic_irq_domain_ops, NULL);
if (!gic_irq_domain) if (!gic_irq_domain) {
panic("Failed to add GIC IRQ domain"); pr_err("Failed to add GIC IRQ domain");
return -ENXIO;
}
gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain, gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain,
IRQ_DOMAIN_FLAG_IPI_PER_CPU, IRQ_DOMAIN_FLAG_IPI_PER_CPU,
GIC_NUM_LOCAL_INTRS + gic_shared_intrs, GIC_NUM_LOCAL_INTRS + gic_shared_intrs,
node, &gic_ipi_domain_ops, NULL); node, &gic_ipi_domain_ops, NULL);
if (!gic_ipi_domain) if (!gic_ipi_domain) {
panic("Failed to add GIC IPI domain"); pr_err("Failed to add GIC IPI domain");
return -ENXIO;
}
irq_domain_update_bus_token(gic_ipi_domain, DOMAIN_BUS_IPI); 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, ...@@ -733,54 +776,6 @@ static void __init __gic_init(unsigned long gic_base_addr,
bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS); bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS);
gic_basic_init(); 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; 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