aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2012-02-14 16:06:57 -0500
committerGrant Likely <grant.likely@secretlab.ca>2012-02-16 08:11:23 -0500
commit75294957be1dee7d22dd7d90bd31334ba410e836 (patch)
treeafa8e2905af88ceeba2dccb50b56c42568e18ab9
parent5769089ac72569d024817270ab79fdf0b9046dde (diff)
irq_domain: Remove 'new' irq_domain in favour of the ppc one
This patch removes the simplistic implementation of irq_domains and enables the powerpc infrastructure for all irq_domain users. The powerpc infrastructure includes support for complex mappings between Linux and hardware irq numbers, and can manage allocation of irq_descs. This patch also converts the few users of irq_domain_add()/irq_domain_del() to call irq_domain_add_legacy() instead. v3: Fix bug that set up too many irqs in translation range. v2: Fix removal of irq_alloc_descs() call in gic driver Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Cc: Rob Herring <rob.herring@calxeda.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Milton Miller <miltonm@bga.com> Tested-by: Olof Johansson <olof@lixom.net>
-rw-r--r--arch/arm/common/gic.c85
-rw-r--r--arch/arm/common/vic.c16
-rw-r--r--arch/arm/include/asm/hardware/gic.h4
-rw-r--r--arch/arm/include/asm/hardware/vic.h2
-rw-r--r--arch/arm/mach-exynos/common.c2
-rw-r--r--arch/arm/mach-versatile/core.c7
-rw-r--r--drivers/mfd/twl-core.c14
-rw-r--r--include/linux/irqdomain.h45
-rw-r--r--kernel/irq/irqdomain.c159
9 files changed, 71 insertions, 263 deletions
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index dc19862be0a8..7275d808f76d 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -51,7 +51,6 @@ union gic_base {
51}; 51};
52 52
53struct gic_chip_data { 53struct gic_chip_data {
54 unsigned int irq_offset;
55 union gic_base dist_base; 54 union gic_base dist_base;
56 union gic_base cpu_base; 55 union gic_base cpu_base;
57#ifdef CONFIG_CPU_PM 56#ifdef CONFIG_CPU_PM
@@ -61,9 +60,7 @@ struct gic_chip_data {
61 u32 __percpu *saved_ppi_enable; 60 u32 __percpu *saved_ppi_enable;
62 u32 __percpu *saved_ppi_conf; 61 u32 __percpu *saved_ppi_conf;
63#endif 62#endif
64#ifdef CONFIG_IRQ_DOMAIN 63 struct irq_domain *domain;
65 struct irq_domain domain;
66#endif
67 unsigned int gic_irqs; 64 unsigned int gic_irqs;
68#ifdef CONFIG_GIC_NON_BANKED 65#ifdef CONFIG_GIC_NON_BANKED
69 void __iomem *(*get_base)(union gic_base *); 66 void __iomem *(*get_base)(union gic_base *);
@@ -282,7 +279,7 @@ asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
282 irqnr = irqstat & ~0x1c00; 279 irqnr = irqstat & ~0x1c00;
283 280
284 if (likely(irqnr > 15 && irqnr < 1021)) { 281 if (likely(irqnr > 15 && irqnr < 1021)) {
285 irqnr = irq_domain_to_irq(&gic->domain, irqnr); 282 irqnr = irq_find_mapping(gic->domain, irqnr);
286 handle_IRQ(irqnr, regs); 283 handle_IRQ(irqnr, regs);
287 continue; 284 continue;
288 } 285 }
@@ -314,8 +311,8 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
314 if (gic_irq == 1023) 311 if (gic_irq == 1023)
315 goto out; 312 goto out;
316 313
317 cascade_irq = irq_domain_to_irq(&chip_data->domain, gic_irq); 314 cascade_irq = irq_find_mapping(chip_data->domain, gic_irq);
318 if (unlikely(gic_irq < 32 || gic_irq > 1020 || cascade_irq >= NR_IRQS)) 315 if (unlikely(gic_irq < 32 || gic_irq > 1020))
319 do_bad_IRQ(cascade_irq, desc); 316 do_bad_IRQ(cascade_irq, desc);
320 else 317 else
321 generic_handle_irq(cascade_irq); 318 generic_handle_irq(cascade_irq);
@@ -348,10 +345,9 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
348 345
349static void __init gic_dist_init(struct gic_chip_data *gic) 346static void __init gic_dist_init(struct gic_chip_data *gic)
350{ 347{
351 unsigned int i, irq; 348 unsigned int i;
352 u32 cpumask; 349 u32 cpumask;
353 unsigned int gic_irqs = gic->gic_irqs; 350 unsigned int gic_irqs = gic->gic_irqs;
354 struct irq_domain *domain = &gic->domain;
355 void __iomem *base = gic_data_dist_base(gic); 351 void __iomem *base = gic_data_dist_base(gic);
356 u32 cpu = cpu_logical_map(smp_processor_id()); 352 u32 cpu = cpu_logical_map(smp_processor_id());
357 353
@@ -386,23 +382,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
386 for (i = 32; i < gic_irqs; i += 32) 382 for (i = 32; i < gic_irqs; i += 32)
387 writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); 383 writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
388 384
389 /*
390 * Setup the Linux IRQ subsystem.
391 */
392 irq_domain_for_each_irq(domain, i, irq) {
393 if (i < 32) {
394 irq_set_percpu_devid(irq);
395 irq_set_chip_and_handler(irq, &gic_chip,
396 handle_percpu_devid_irq);
397 set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
398 } else {
399 irq_set_chip_and_handler(irq, &gic_chip,
400 handle_fasteoi_irq);
401 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
402 }
403 irq_set_chip_data(irq, gic);
404 }
405
406 writel_relaxed(1, base + GIC_DIST_CTRL); 385 writel_relaxed(1, base + GIC_DIST_CTRL);
407} 386}
408 387
@@ -618,7 +597,23 @@ static void __init gic_pm_init(struct gic_chip_data *gic)
618} 597}
619#endif 598#endif
620 599
621#ifdef CONFIG_OF 600static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
601 irq_hw_number_t hw)
602{
603 if (hw < 32) {
604 irq_set_percpu_devid(irq);
605 irq_set_chip_and_handler(irq, &gic_chip,
606 handle_percpu_devid_irq);
607 set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
608 } else {
609 irq_set_chip_and_handler(irq, &gic_chip,
610 handle_fasteoi_irq);
611 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
612 }
613 irq_set_chip_data(irq, d->host_data);
614 return 0;
615}
616
622static int gic_irq_domain_xlate(struct irq_domain *d, 617static int gic_irq_domain_xlate(struct irq_domain *d,
623 struct device_node *controller, 618 struct device_node *controller,
624 const u32 *intspec, unsigned int intsize, 619 const u32 *intspec, unsigned int intsize,
@@ -639,26 +634,23 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
639 *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; 634 *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
640 return 0; 635 return 0;
641} 636}
642#endif
643 637
644struct irq_domain_ops gic_irq_domain_ops = { 638struct irq_domain_ops gic_irq_domain_ops = {
645#ifdef CONFIG_OF 639 .map = gic_irq_domain_map,
646 .xlate = gic_irq_domain_xlate, 640 .xlate = gic_irq_domain_xlate,
647#endif
648}; 641};
649 642
650void __init gic_init_bases(unsigned int gic_nr, int irq_start, 643void __init gic_init_bases(unsigned int gic_nr, int irq_start,
651 void __iomem *dist_base, void __iomem *cpu_base, 644 void __iomem *dist_base, void __iomem *cpu_base,
652 u32 percpu_offset) 645 u32 percpu_offset, struct device_node *node)
653{ 646{
647 irq_hw_number_t hwirq_base;
654 struct gic_chip_data *gic; 648 struct gic_chip_data *gic;
655 struct irq_domain *domain; 649 int gic_irqs, irq_base;
656 int gic_irqs;
657 650
658 BUG_ON(gic_nr >= MAX_GIC_NR); 651 BUG_ON(gic_nr >= MAX_GIC_NR);
659 652
660 gic = &gic_data[gic_nr]; 653 gic = &gic_data[gic_nr];
661 domain = &gic->domain;
662#ifdef CONFIG_GIC_NON_BANKED 654#ifdef CONFIG_GIC_NON_BANKED
663 if (percpu_offset) { /* Frankein-GIC without banked registers... */ 655 if (percpu_offset) { /* Frankein-GIC without banked registers... */
664 unsigned int cpu; 656 unsigned int cpu;
@@ -694,10 +686,10 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
694 * For primary GICs, skip over SGIs. 686 * For primary GICs, skip over SGIs.
695 * For secondary GICs, skip over PPIs, too. 687 * For secondary GICs, skip over PPIs, too.
696 */ 688 */
697 domain->hwirq_base = 32; 689 hwirq_base = 32;
698 if (gic_nr == 0) { 690 if (gic_nr == 0) {
699 if ((irq_start & 31) > 0) { 691 if ((irq_start & 31) > 0) {
700 domain->hwirq_base = 16; 692 hwirq_base = 16;
701 if (irq_start != -1) 693 if (irq_start != -1)
702 irq_start = (irq_start & ~31) + 16; 694 irq_start = (irq_start & ~31) + 16;
703 } 695 }
@@ -713,17 +705,17 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
713 gic_irqs = 1020; 705 gic_irqs = 1020;
714 gic->gic_irqs = gic_irqs; 706 gic->gic_irqs = gic_irqs;
715 707
716 domain->nr_irq = gic_irqs - domain->hwirq_base; 708 gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */
717 domain->irq_base = irq_alloc_descs(irq_start, 16, domain->nr_irq, 709 irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, numa_node_id());
718 numa_node_id()); 710 if (IS_ERR_VALUE(irq_base)) {
719 if (IS_ERR_VALUE(domain->irq_base)) {
720 WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n", 711 WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
721 irq_start); 712 irq_start);
722 domain->irq_base = irq_start; 713 irq_base = irq_start;
723 } 714 }
724 domain->host_data = gic; 715 gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base,
725 domain->ops = &gic_irq_domain_ops; 716 hwirq_base, &gic_irq_domain_ops, gic);
726 irq_domain_add(domain); 717 if (WARN_ON(!gic->domain))
718 return;
727 719
728 gic_chip.flags |= gic_arch_extn.flags; 720 gic_chip.flags |= gic_arch_extn.flags;
729 gic_dist_init(gic); 721 gic_dist_init(gic);
@@ -768,7 +760,6 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent)
768 void __iomem *dist_base; 760 void __iomem *dist_base;
769 u32 percpu_offset; 761 u32 percpu_offset;
770 int irq; 762 int irq;
771 struct irq_domain *domain = &gic_data[gic_cnt].domain;
772 763
773 if (WARN_ON(!node)) 764 if (WARN_ON(!node))
774 return -ENODEV; 765 return -ENODEV;
@@ -782,9 +773,7 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent)
782 if (of_property_read_u32(node, "cpu-offset", &percpu_offset)) 773 if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
783 percpu_offset = 0; 774 percpu_offset = 0;
784 775
785 domain->of_node = of_node_get(node); 776 gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, node);
786
787 gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset);
788 777
789 if (parent) { 778 if (parent) {
790 irq = irq_of_parse_and_map(node, 0); 779 irq = irq_of_parse_and_map(node, 0);
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index dcb004a804c7..7a66311f3066 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -56,7 +56,7 @@ struct vic_device {
56 u32 int_enable; 56 u32 int_enable;
57 u32 soft_int; 57 u32 soft_int;
58 u32 protect; 58 u32 protect;
59 struct irq_domain domain; 59 struct irq_domain *domain;
60}; 60};
61 61
62/* we cannot allocate memory when VICs are initially registered */ 62/* we cannot allocate memory when VICs are initially registered */
@@ -192,14 +192,8 @@ static void __init vic_register(void __iomem *base, unsigned int irq,
192 v->resume_sources = resume_sources; 192 v->resume_sources = resume_sources;
193 v->irq = irq; 193 v->irq = irq;
194 vic_id++; 194 vic_id++;
195 195 v->domain = irq_domain_add_legacy(node, 32, irq, 0,
196 v->domain.irq_base = irq; 196 &irq_domain_simple_ops, v);
197 v->domain.nr_irq = 32;
198#ifdef CONFIG_OF_IRQ
199 v->domain.of_node = of_node_get(node);
200#endif /* CONFIG_OF */
201 v->domain.ops = &irq_domain_simple_ops;
202 irq_domain_add(&v->domain);
203} 197}
204 198
205static void vic_ack_irq(struct irq_data *d) 199static void vic_ack_irq(struct irq_data *d)
@@ -348,7 +342,7 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
348 vic_register(base, irq_start, 0, node); 342 vic_register(base, irq_start, 0, node);
349} 343}
350 344
351static void __init __vic_init(void __iomem *base, unsigned int irq_start, 345void __init __vic_init(void __iomem *base, unsigned int irq_start,
352 u32 vic_sources, u32 resume_sources, 346 u32 vic_sources, u32 resume_sources,
353 struct device_node *node) 347 struct device_node *node)
354{ 348{
@@ -444,7 +438,7 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs)
444 stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); 438 stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
445 while (stat) { 439 while (stat) {
446 irq = ffs(stat) - 1; 440 irq = ffs(stat) - 1;
447 handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs); 441 handle_IRQ(irq_find_mapping(vic->domain, irq), regs);
448 stat &= ~(1 << irq); 442 stat &= ~(1 << irq);
449 handled = 1; 443 handled = 1;
450 } 444 }
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 4bdfe0018696..4b1ce6cd477f 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -39,7 +39,7 @@ struct device_node;
39extern struct irq_chip gic_arch_extn; 39extern struct irq_chip gic_arch_extn;
40 40
41void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, 41void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *,
42 u32 offset); 42 u32 offset, struct device_node *);
43int gic_of_init(struct device_node *node, struct device_node *parent); 43int gic_of_init(struct device_node *node, struct device_node *parent);
44void gic_secondary_init(unsigned int); 44void gic_secondary_init(unsigned int);
45void gic_handle_irq(struct pt_regs *regs); 45void gic_handle_irq(struct pt_regs *regs);
@@ -49,7 +49,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
49static inline void gic_init(unsigned int nr, int start, 49static inline void gic_init(unsigned int nr, int start,
50 void __iomem *dist , void __iomem *cpu) 50 void __iomem *dist , void __iomem *cpu)
51{ 51{
52 gic_init_bases(nr, start, dist, cpu, 0); 52 gic_init_bases(nr, start, dist, cpu, 0, NULL);
53} 53}
54 54
55#endif 55#endif
diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
index f42ebd619590..e14af1a1a320 100644
--- a/arch/arm/include/asm/hardware/vic.h
+++ b/arch/arm/include/asm/hardware/vic.h
@@ -47,6 +47,8 @@
47struct device_node; 47struct device_node;
48struct pt_regs; 48struct pt_regs;
49 49
50void __vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources,
51 u32 resume_sources, struct device_node *node);
50void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources); 52void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
51int vic_of_init(struct device_node *node, struct device_node *parent); 53int vic_of_init(struct device_node *node, struct device_node *parent);
52void vic_handle_irq(struct pt_regs *regs); 54void vic_handle_irq(struct pt_regs *regs);
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index c59e18871006..6de298c5d2d3 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -402,7 +402,7 @@ void __init exynos4_init_irq(void)
402 gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; 402 gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
403 403
404 if (!of_have_populated_dt()) 404 if (!of_have_populated_dt())
405 gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset); 405 gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset, NULL);
406#ifdef CONFIG_OF 406#ifdef CONFIG_OF
407 else 407 else
408 of_irq_init(exynos4_dt_irq_match); 408 of_irq_init(exynos4_dt_irq_match);
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 02b7b9303f3b..008ce22b9a06 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -98,8 +98,11 @@ static const struct of_device_id sic_of_match[] __initconst = {
98 98
99void __init versatile_init_irq(void) 99void __init versatile_init_irq(void)
100{ 100{
101 vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0); 101 struct device_node *np;
102 irq_domain_generate_simple(vic_of_match, VERSATILE_VIC_BASE, IRQ_VIC_START); 102
103 np = of_find_matching_node_by_address(NULL, vic_of_match,
104 VERSATILE_VIC_BASE);
105 __vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0, np);
103 106
104 writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); 107 writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
105 108
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 49677339ab5f..66f9bffc50f0 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -263,10 +263,6 @@ struct twl_client {
263 263
264static struct twl_client twl_modules[TWL_NUM_SLAVES]; 264static struct twl_client twl_modules[TWL_NUM_SLAVES];
265 265
266#ifdef CONFIG_IRQ_DOMAIN
267static struct irq_domain domain;
268#endif
269
270/* mapping the module id to slave id and base address */ 266/* mapping the module id to slave id and base address */
271struct twl_mapping { 267struct twl_mapping {
272 unsigned char sid; /* Slave ID */ 268 unsigned char sid; /* Slave ID */
@@ -1227,14 +1223,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
1227 1223
1228 pdata->irq_base = status; 1224 pdata->irq_base = status;
1229 pdata->irq_end = pdata->irq_base + nr_irqs; 1225 pdata->irq_end = pdata->irq_base + nr_irqs;
1230 1226 irq_domain_add_legacy(node, nr_irqs, pdata->irq_base, 0,
1231#ifdef CONFIG_IRQ_DOMAIN 1227 &irq_domain_simple_ops, NULL);
1232 domain.irq_base = pdata->irq_base;
1233 domain.nr_irq = nr_irqs;
1234 domain.of_node = of_node_get(node);
1235 domain.ops = &irq_domain_simple_ops;
1236 irq_domain_add(&domain);
1237#endif
1238 1228
1239 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { 1229 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
1240 dev_dbg(&client->dev, "can't talk I2C?\n"); 1230 dev_dbg(&client->dev, "can't talk I2C?\n");
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 7fef39ed5523..624e9ac89e79 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -55,9 +55,6 @@ typedef unsigned long irq_hw_number_t;
55 * @map: Create or update a mapping between a virtual irq number and a hw 55 * @map: Create or update a mapping between a virtual irq number and a hw
56 * irq number. This is called only once for a given mapping. 56 * irq number. This is called only once for a given mapping.
57 * @unmap: Dispose of such a mapping 57 * @unmap: Dispose of such a mapping
58 * @to_irq: (optional) given a local hardware irq number, return the linux
59 * irq number. If to_irq is not implemented, then the irq_domain
60 * will use this translation: irq = (domain->irq_base + hwirq)
61 * @xlate: Given a device tree node and interrupt specifier, decode 58 * @xlate: Given a device tree node and interrupt specifier, decode
62 * the hardware irq number and linux irq type value. 59 * the hardware irq number and linux irq type value.
63 * 60 *
@@ -70,7 +67,6 @@ struct irq_domain_ops {
70 int (*match)(struct irq_domain *d, struct device_node *node); 67 int (*match)(struct irq_domain *d, struct device_node *node);
71 int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw); 68 int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw);
72 void (*unmap)(struct irq_domain *d, unsigned int virq); 69 void (*unmap)(struct irq_domain *d, unsigned int virq);
73 unsigned int (*to_irq)(struct irq_domain *d, unsigned long hwirq);
74 int (*xlate)(struct irq_domain *d, struct device_node *node, 70 int (*xlate)(struct irq_domain *d, struct device_node *node,
75 const u32 *intspec, unsigned int intsize, 71 const u32 *intspec, unsigned int intsize,
76 unsigned long *out_hwirq, unsigned int *out_type); 72 unsigned long *out_hwirq, unsigned int *out_type);
@@ -114,16 +110,11 @@ struct irq_domain {
114 void *host_data; 110 void *host_data;
115 irq_hw_number_t inval_irq; 111 irq_hw_number_t inval_irq;
116 112
117 unsigned int irq_base;
118 unsigned int nr_irq;
119 unsigned int hwirq_base;
120
121 /* Optional device node pointer */ 113 /* Optional device node pointer */
122 struct device_node *of_node; 114 struct device_node *of_node;
123}; 115};
124 116
125#ifdef CONFIG_IRQ_DOMAIN 117#ifdef CONFIG_IRQ_DOMAIN
126#ifdef CONFIG_PPC
127struct irq_domain *irq_domain_add_legacy(struct device_node *of_node, 118struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
128 unsigned int size, 119 unsigned int size,
129 unsigned int first_irq, 120 unsigned int first_irq,
@@ -153,6 +144,10 @@ static inline struct irq_domain *irq_domain_add_legacy_isa(
153 return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops, 144 return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops,
154 host_data); 145 host_data);
155} 146}
147extern struct irq_domain *irq_find_host(struct device_node *node);
148extern void irq_set_default_host(struct irq_domain *host);
149extern void irq_set_virq_count(unsigned int count);
150
156 151
157extern unsigned int irq_create_mapping(struct irq_domain *host, 152extern unsigned int irq_create_mapping(struct irq_domain *host,
158 irq_hw_number_t hwirq); 153 irq_hw_number_t hwirq);
@@ -167,38 +162,7 @@ extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
167extern unsigned int irq_linear_revmap(struct irq_domain *host, 162extern unsigned int irq_linear_revmap(struct irq_domain *host,
168 irq_hw_number_t hwirq); 163 irq_hw_number_t hwirq);
169 164
170#else /* CONFIG_PPC */
171
172/**
173 * irq_domain_to_irq() - Translate from a hardware irq to a linux irq number
174 *
175 * Returns the linux irq number associated with a hardware irq. By default,
176 * the mapping is irq == domain->irq_base + hwirq, but this mapping can
177 * be overridden if the irq_domain implements a .to_irq() hook.
178 */
179static inline unsigned int irq_domain_to_irq(struct irq_domain *d,
180 unsigned long hwirq)
181{
182 if (d->ops->to_irq)
183 return d->ops->to_irq(d, hwirq);
184 if (WARN_ON(hwirq < d->hwirq_base))
185 return 0;
186 return d->irq_base + hwirq - d->hwirq_base;
187}
188
189#define irq_domain_for_each_hwirq(d, hw) \
190 for (hw = d->hwirq_base; hw < d->hwirq_base + d->nr_irq; hw++)
191
192#define irq_domain_for_each_irq(d, hw, irq) \
193 for (hw = d->hwirq_base, irq = irq_domain_to_irq(d, hw); \
194 hw < d->hwirq_base + d->nr_irq; \
195 hw++, irq = irq_domain_to_irq(d, hw))
196
197extern void irq_domain_add(struct irq_domain *domain);
198extern void irq_domain_del(struct irq_domain *domain);
199
200extern struct irq_domain_ops irq_domain_simple_ops; 165extern struct irq_domain_ops irq_domain_simple_ops;
201
202#if defined(CONFIG_OF_IRQ) 166#if defined(CONFIG_OF_IRQ)
203extern void irq_domain_add_simple(struct device_node *controller, int irq_base); 167extern void irq_domain_add_simple(struct device_node *controller, int irq_base);
204extern void irq_domain_generate_simple(const struct of_device_id *match, 168extern void irq_domain_generate_simple(const struct of_device_id *match,
@@ -207,7 +171,6 @@ extern void irq_domain_generate_simple(const struct of_device_id *match,
207static inline void irq_domain_generate_simple(const struct of_device_id *match, 171static inline void irq_domain_generate_simple(const struct of_device_id *match,
208 u64 phys_base, unsigned int irq_start) { } 172 u64 phys_base, unsigned int irq_start) { }
209#endif /* !CONFIG_OF_IRQ */ 173#endif /* !CONFIG_OF_IRQ */
210#endif /* !CONFIG_PPC */
211#endif /* CONFIG_IRQ_DOMAIN */ 174#endif /* CONFIG_IRQ_DOMAIN */
212 175
213#endif /* _LINUX_IRQDOMAIN_H */ 176#endif /* _LINUX_IRQDOMAIN_H */
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index c6740d72073e..2981ebfeb40c 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -22,7 +22,6 @@
22static LIST_HEAD(irq_domain_list); 22static LIST_HEAD(irq_domain_list);
23static DEFINE_MUTEX(irq_domain_mutex); 23static DEFINE_MUTEX(irq_domain_mutex);
24 24
25#ifdef CONFIG_PPC
26static DEFINE_MUTEX(revmap_trees_mutex); 25static DEFINE_MUTEX(revmap_trees_mutex);
27static unsigned int irq_virq_count = NR_IRQS; 26static unsigned int irq_virq_count = NR_IRQS;
28static struct irq_domain *irq_default_domain; 27static struct irq_domain *irq_default_domain;
@@ -694,124 +693,11 @@ static int __init irq_debugfs_init(void)
694__initcall(irq_debugfs_init); 693__initcall(irq_debugfs_init);
695#endif /* CONFIG_VIRQ_DEBUG */ 694#endif /* CONFIG_VIRQ_DEBUG */
696 695
697#else /* CONFIG_PPC */ 696int irq_domain_simple_map(struct irq_domain *d, unsigned int irq,
698 697 irq_hw_number_t hwirq)
699/**
700 * irq_domain_add() - Register an irq_domain
701 * @domain: ptr to initialized irq_domain structure
702 *
703 * Registers an irq_domain structure. The irq_domain must at a minimum be
704 * initialized with an ops structure pointer, and either a ->to_irq hook or
705 * a valid irq_base value. Everything else is optional.
706 */
707void irq_domain_add(struct irq_domain *domain)
708{
709 struct irq_data *d;
710 int hwirq, irq;
711
712 /*
713 * This assumes that the irq_domain owner has already allocated
714 * the irq_descs. This block will be removed when support for dynamic
715 * allocation of irq_descs is added to irq_domain.
716 */
717 irq_domain_for_each_irq(domain, hwirq, irq) {
718 d = irq_get_irq_data(irq);
719 if (!d) {
720 WARN(1, "error: assigning domain to non existant irq_desc");
721 return;
722 }
723 if (d->domain) {
724 /* things are broken; just report, don't clean up */
725 WARN(1, "error: irq_desc already assigned to a domain");
726 return;
727 }
728 d->domain = domain;
729 d->hwirq = hwirq;
730 }
731
732 mutex_lock(&irq_domain_mutex);
733 list_add(&domain->link, &irq_domain_list);
734 mutex_unlock(&irq_domain_mutex);
735}
736
737/**
738 * irq_domain_del() - Unregister an irq_domain
739 * @domain: ptr to registered irq_domain.
740 */
741void irq_domain_del(struct irq_domain *domain)
742{
743 struct irq_data *d;
744 int hwirq, irq;
745
746 mutex_lock(&irq_domain_mutex);
747 list_del(&domain->link);
748 mutex_unlock(&irq_domain_mutex);
749
750 /* Clear the irq_domain assignments */
751 irq_domain_for_each_irq(domain, hwirq, irq) {
752 d = irq_get_irq_data(irq);
753 d->domain = NULL;
754 }
755}
756
757#if defined(CONFIG_OF_IRQ)
758/**
759 * irq_create_of_mapping() - Map a linux irq number from a DT interrupt spec
760 *
761 * Used by the device tree interrupt mapping code to translate a device tree
762 * interrupt specifier to a valid linux irq number. Returns either a valid
763 * linux IRQ number or 0.
764 *
765 * When the caller no longer need the irq number returned by this function it
766 * should arrange to call irq_dispose_mapping().
767 */
768unsigned int irq_create_of_mapping(struct device_node *controller,
769 const u32 *intspec, unsigned int intsize)
770{
771 struct irq_domain *domain;
772 unsigned long hwirq;
773 unsigned int irq, type;
774 int rc = -EINVAL;
775
776 /* Find a domain which can translate the irq spec */
777 mutex_lock(&irq_domain_mutex);
778 list_for_each_entry(domain, &irq_domain_list, link) {
779 if (!domain->ops->xlate)
780 continue;
781 rc = domain->ops->xlate(domain, controller,
782 intspec, intsize, &hwirq, &type);
783 if (rc == 0)
784 break;
785 }
786 mutex_unlock(&irq_domain_mutex);
787
788 if (rc != 0)
789 return 0;
790
791 irq = irq_domain_to_irq(domain, hwirq);
792 if (type != IRQ_TYPE_NONE)
793 irq_set_irq_type(irq, type);
794 pr_debug("%s: mapped hwirq=%i to irq=%i, flags=%x\n",
795 controller->full_name, (int)hwirq, irq, type);
796 return irq;
797}
798EXPORT_SYMBOL_GPL(irq_create_of_mapping);
799
800/**
801 * irq_dispose_mapping() - Discard a mapping created by irq_create_of_mapping()
802 * @irq: linux irq number to be discarded
803 *
804 * Calling this function indicates the caller no longer needs a reference to
805 * the linux irq number returned by a prior call to irq_create_of_mapping().
806 */
807void irq_dispose_mapping(unsigned int irq)
808{ 698{
809 /* 699 return 0;
810 * nothing yet; will be filled when support for dynamic allocation of
811 * irq_descs is added to irq_domain
812 */
813} 700}
814EXPORT_SYMBOL_GPL(irq_dispose_mapping);
815 701
816int irq_domain_simple_xlate(struct irq_domain *d, 702int irq_domain_simple_xlate(struct irq_domain *d,
817 struct device_node *controller, 703 struct device_node *controller,
@@ -822,10 +708,6 @@ int irq_domain_simple_xlate(struct irq_domain *d,
822 return -EINVAL; 708 return -EINVAL;
823 if (intsize < 1) 709 if (intsize < 1)
824 return -EINVAL; 710 return -EINVAL;
825 if (d->nr_irq && ((intspec[0] < d->hwirq_base) ||
826 (intspec[0] >= d->hwirq_base + d->nr_irq)))
827 return -EINVAL;
828
829 *out_hwirq = intspec[0]; 711 *out_hwirq = intspec[0];
830 *out_type = IRQ_TYPE_NONE; 712 *out_type = IRQ_TYPE_NONE;
831 if (intsize > 1) 713 if (intsize > 1)
@@ -833,23 +715,17 @@ int irq_domain_simple_xlate(struct irq_domain *d,
833 return 0; 715 return 0;
834} 716}
835 717
836/** 718struct irq_domain_ops irq_domain_simple_ops = {
837 * irq_domain_create_simple() - Set up a 'simple' translation range 719 .map = irq_domain_simple_map,
838 */ 720 .xlate = irq_domain_simple_xlate,
721};
722EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
723
724#ifdef CONFIG_OF_IRQ
839void irq_domain_add_simple(struct device_node *controller, int irq_base) 725void irq_domain_add_simple(struct device_node *controller, int irq_base)
840{ 726{
841 struct irq_domain *domain; 727 irq_domain_add_legacy(controller, 32, irq_base, 0,
842 728 &irq_domain_simple_ops, NULL);
843 domain = kzalloc(sizeof(*domain), GFP_KERNEL);
844 if (!domain) {
845 WARN_ON(1);
846 return;
847 }
848
849 domain->irq_base = irq_base;
850 domain->of_node = of_node_get(controller);
851 domain->ops = &irq_domain_simple_ops;
852 irq_domain_add(domain);
853} 729}
854EXPORT_SYMBOL_GPL(irq_domain_add_simple); 730EXPORT_SYMBOL_GPL(irq_domain_add_simple);
855 731
@@ -864,13 +740,4 @@ void irq_domain_generate_simple(const struct of_device_id *match,
864 irq_domain_add_simple(node, irq_start); 740 irq_domain_add_simple(node, irq_start);
865} 741}
866EXPORT_SYMBOL_GPL(irq_domain_generate_simple); 742EXPORT_SYMBOL_GPL(irq_domain_generate_simple);
867#endif /* CONFIG_OF_IRQ */ 743#endif
868
869struct irq_domain_ops irq_domain_simple_ops = {
870#ifdef CONFIG_OF_IRQ
871 .xlate = irq_domain_simple_xlate,
872#endif /* CONFIG_OF_IRQ */
873};
874EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
875
876#endif /* !CONFIG_PPC */