Commit d34f03d4 authored by Arnd Bergmann's avatar Arnd Bergmann

irqchip: exynos: allocate combiner_data dynamically

The number of combiners on a given SoC is a platform specific
constant, and we cannot encode this number on a multiplatform
kernel since the header file defining it is not available.

Allocating the structure dynamically ends up cleaner anyway
since we keep all the data local.
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
parent 6761dcfe
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/export.h> #include <linux/export.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/slab.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
...@@ -37,7 +38,6 @@ struct combiner_chip_data { ...@@ -37,7 +38,6 @@ struct combiner_chip_data {
}; };
static struct irq_domain *combiner_irq_domain; static struct irq_domain *combiner_irq_domain;
static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
static inline void __iomem *combiner_base(struct irq_data *data) static inline void __iomem *combiner_base(struct irq_data *data)
{ {
...@@ -114,26 +114,26 @@ static struct irq_chip combiner_chip = { ...@@ -114,26 +114,26 @@ static struct irq_chip combiner_chip = {
#endif #endif
}; };
static void __init combiner_cascade_irq(unsigned int combiner_nr, static void __init combiner_cascade_irq(struct combiner_chip_data *combiner_data,
unsigned int irq) unsigned int irq)
{ {
if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0) if (irq_set_handler_data(irq, combiner_data) != 0)
BUG(); BUG();
irq_set_chained_handler(irq, combiner_handle_cascade_irq); irq_set_chained_handler(irq, combiner_handle_cascade_irq);
} }
static void __init combiner_init_one(unsigned int combiner_nr, static void __init combiner_init_one(struct combiner_chip_data *combiner_data,
unsigned int combiner_nr,
void __iomem *base, unsigned int irq) void __iomem *base, unsigned int irq)
{ {
combiner_data[combiner_nr].base = base; combiner_data->base = base;
combiner_data[combiner_nr].irq_offset = irq_find_mapping( combiner_data->irq_offset = irq_find_mapping(
combiner_irq_domain, combiner_nr * IRQ_IN_COMBINER); combiner_irq_domain, combiner_nr * IRQ_IN_COMBINER);
combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3); combiner_data->irq_mask = 0xff << ((combiner_nr % 4) << 3);
combiner_data[combiner_nr].parent_irq = irq; combiner_data->parent_irq = irq;
/* Disable all interrupts */ /* Disable all interrupts */
__raw_writel(combiner_data[combiner_nr].irq_mask, __raw_writel(combiner_data->irq_mask, base + COMBINER_ENABLE_CLEAR);
base + COMBINER_ENABLE_CLEAR);
} }
#ifdef CONFIG_OF #ifdef CONFIG_OF
...@@ -168,6 +168,8 @@ static int combiner_irq_domain_xlate(struct irq_domain *d, ...@@ -168,6 +168,8 @@ static int combiner_irq_domain_xlate(struct irq_domain *d,
static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq, static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hw) irq_hw_number_t hw)
{ {
struct combiner_chip_data *combiner_data = d->host_data;
irq_set_chip_and_handler(irq, &combiner_chip, handle_level_irq); irq_set_chip_and_handler(irq, &combiner_chip, handle_level_irq);
irq_set_chip_data(irq, &combiner_data[hw >> 3]); irq_set_chip_data(irq, &combiner_data[hw >> 3]);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
...@@ -202,6 +204,7 @@ void __init combiner_init(void __iomem *combiner_base, ...@@ -202,6 +204,7 @@ void __init combiner_init(void __iomem *combiner_base,
{ {
int i, irq, irq_base; int i, irq, irq_base;
unsigned int nr_irq; unsigned int nr_irq;
struct combiner_chip_data *combiner_data;
nr_irq = max_nr * IRQ_IN_COMBINER; nr_irq = max_nr * IRQ_IN_COMBINER;
...@@ -211,8 +214,14 @@ void __init combiner_init(void __iomem *combiner_base, ...@@ -211,8 +214,14 @@ void __init combiner_init(void __iomem *combiner_base,
pr_warning("%s: irq desc alloc failed. Continuing with %d as linux irq base\n", __func__, irq_base); pr_warning("%s: irq desc alloc failed. Continuing with %d as linux irq base\n", __func__, irq_base);
} }
combiner_data = kcalloc(max_nr, sizeof (*combiner_data), GFP_KERNEL);
if (!combiner_data) {
pr_warning("%s: could not allocate combiner data\n", __func__);
return;
}
combiner_irq_domain = irq_domain_add_legacy(np, nr_irq, irq_base, 0, combiner_irq_domain = irq_domain_add_legacy(np, nr_irq, irq_base, 0,
&combiner_irq_domain_ops, &combiner_data); &combiner_irq_domain_ops, combiner_data);
if (WARN_ON(!combiner_irq_domain)) { if (WARN_ON(!combiner_irq_domain)) {
pr_warning("%s: irq domain init failed\n", __func__); pr_warning("%s: irq domain init failed\n", __func__);
return; return;
...@@ -227,8 +236,9 @@ void __init combiner_init(void __iomem *combiner_base, ...@@ -227,8 +236,9 @@ void __init combiner_init(void __iomem *combiner_base,
if (np) if (np)
irq = irq_of_parse_and_map(np, i); irq = irq_of_parse_and_map(np, i);
#endif #endif
combiner_init_one(i, combiner_base + (i >> 2) * 0x10, irq); combiner_init_one(&combiner_data[i], i,
combiner_cascade_irq(i, irq); combiner_base + (i >> 2) * 0x10, irq);
combiner_cascade_irq(&combiner_data[i], irq);
} }
} }
......
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