diff options
author | Chanho Park <chanho60.park@samsung.com> | 2012-12-12 14:02:45 +0900 |
---|---|---|
committer | Kukjin Kim <kgene.kim@samsung.com> | 2013-04-09 01:47:44 +0900 |
commit | df7ef462a2f8036430940b69871c762a92efead2 (patch) | |
tree | 7aa5596bc42a90c06316ca42ccdd25bf41cbf413 | |
parent | da821eb7d42935b0f7056d98c75fd1150f6636f4 (diff) |
irqchip: exynos-combiner: Add set_irq_affinity function for combiner_irq
This patch adds set_irq_affinity function for combiner_irq. We need this
function to enable a arm-pmu because the pmu of exynos has combined type
irqs.
Reviewed-by: Thomas Abraham <thomas.abraham@linaro.org>
Signed-off-by: Chanho Park <chanho61.park@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
[kgene.kim@samsung.com: changes moved into drivers/irqchip/]
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
-rw-r--r-- | drivers/irqchip/exynos-combiner.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c index 04d86a9803f..b5ff271bfd6 100644 --- a/drivers/irqchip/exynos-combiner.c +++ b/drivers/irqchip/exynos-combiner.c @@ -31,6 +31,7 @@ struct combiner_chip_data { unsigned int irq_offset; unsigned int irq_mask; void __iomem *base; + unsigned int parent_irq; }; static struct irq_domain *combiner_irq_domain; @@ -87,10 +88,28 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) chained_irq_exit(chip, desc); } +#ifdef CONFIG_SMP +static int combiner_set_affinity(struct irq_data *d, + const struct cpumask *mask_val, bool force) +{ + struct combiner_chip_data *chip_data = irq_data_get_irq_chip_data(d); + struct irq_chip *chip = irq_get_chip(chip_data->parent_irq); + struct irq_data *data = irq_get_irq_data(chip_data->parent_irq); + + if (chip && chip->irq_set_affinity) + return chip->irq_set_affinity(data, mask_val, force); + else + return -EINVAL; +} +#endif + static struct irq_chip combiner_chip = { - .name = "COMBINER", - .irq_mask = combiner_mask_irq, - .irq_unmask = combiner_unmask_irq, + .name = "COMBINER", + .irq_mask = combiner_mask_irq, + .irq_unmask = combiner_unmask_irq, +#ifdef CONFIG_SMP + .irq_set_affinity = combiner_set_affinity, +#endif }; static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq) @@ -110,12 +129,13 @@ static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int i } static void __init combiner_init_one(unsigned int combiner_nr, - void __iomem *base) + void __iomem *base, unsigned int irq) { combiner_data[combiner_nr].base = base; combiner_data[combiner_nr].irq_offset = irq_find_mapping( combiner_irq_domain, combiner_nr * MAX_IRQ_IN_COMBINER); combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3); + combiner_data[combiner_nr].parent_irq = irq; /* Disable all interrupts */ __raw_writel(combiner_data[combiner_nr].irq_mask, @@ -199,12 +219,12 @@ void __init combiner_init(void __iomem *combiner_base, } for (i = 0; i < max_nr; i++) { - combiner_init_one(i, combiner_base + (i >> 2) * 0x10); irq = IRQ_SPI(i); #ifdef CONFIG_OF if (np) irq = irq_of_parse_and_map(np, i); #endif + combiner_init_one(i, combiner_base + (i >> 2) * 0x10, irq); combiner_cascade_irq(i, irq); } } |