diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-03-29 22:46:19 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-03-29 22:46:19 -0400 |
commit | 0a3108beea9143225119d5e7c72a8e2c64f3eb7d (patch) | |
tree | 89ec500c03f0704799407265db21966b721c6d3f /arch/powerpc/platforms | |
parent | ec78c8ac16e7a5f45e21838ab2f5573200bfcdd3 (diff) | |
parent | df4b6806d35ca6adedd5c0a7e36ac74af1c32d7a (diff) |
Merge commit 'kumar/next' into next
Diffstat (limited to 'arch/powerpc/platforms')
27 files changed, 505 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/83xx/asp834x.c b/arch/powerpc/platforms/83xx/asp834x.c index bb30d67ad0a2..aa0d84d22585 100644 --- a/arch/powerpc/platforms/83xx/asp834x.c +++ b/arch/powerpc/platforms/83xx/asp834x.c | |||
@@ -58,6 +58,7 @@ static struct __initdata of_device_id asp8347_ids[] = { | |||
58 | { .type = "soc", }, | 58 | { .type = "soc", }, |
59 | { .compatible = "soc", }, | 59 | { .compatible = "soc", }, |
60 | { .compatible = "simple-bus", }, | 60 | { .compatible = "simple-bus", }, |
61 | { .compatible = "gianfar", }, | ||
61 | {}, | 62 | {}, |
62 | }; | 63 | }; |
63 | 64 | ||
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c index 76092d37c7d9..81e44fa1c644 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_itx.c +++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c | |||
@@ -42,6 +42,7 @@ | |||
42 | static struct of_device_id __initdata mpc834x_itx_ids[] = { | 42 | static struct of_device_id __initdata mpc834x_itx_ids[] = { |
43 | { .compatible = "fsl,pq2pro-localbus", }, | 43 | { .compatible = "fsl,pq2pro-localbus", }, |
44 | { .compatible = "simple-bus", }, | 44 | { .compatible = "simple-bus", }, |
45 | { .compatible = "gianfar", }, | ||
45 | {}, | 46 | {}, |
46 | }; | 47 | }; |
47 | 48 | ||
diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c index fc3f2ed1f3e9..d0a634b056ca 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c | |||
@@ -112,6 +112,7 @@ static struct of_device_id mpc834x_ids[] = { | |||
112 | { .type = "soc", }, | 112 | { .type = "soc", }, |
113 | { .compatible = "soc", }, | 113 | { .compatible = "soc", }, |
114 | { .compatible = "simple-bus", }, | 114 | { .compatible = "simple-bus", }, |
115 | { .compatible = "gianfar", }, | ||
115 | {}, | 116 | {}, |
116 | }; | 117 | }; |
117 | 118 | ||
diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c index 634785cc4523..51df7e754698 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c | |||
@@ -96,6 +96,7 @@ static struct of_device_id mpc837x_ids[] = { | |||
96 | { .type = "soc", }, | 96 | { .type = "soc", }, |
97 | { .compatible = "soc", }, | 97 | { .compatible = "soc", }, |
98 | { .compatible = "simple-bus", }, | 98 | { .compatible = "simple-bus", }, |
99 | { .compatible = "gianfar", }, | ||
99 | {}, | 100 | {}, |
100 | }; | 101 | }; |
101 | 102 | ||
diff --git a/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/arch/powerpc/platforms/83xx/mpc837x_rdb.c index 3d7b953d40e1..76f3b32a155e 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc837x_rdb.c | |||
@@ -48,6 +48,7 @@ static struct of_device_id mpc837x_ids[] = { | |||
48 | { .type = "soc", }, | 48 | { .type = "soc", }, |
49 | { .compatible = "soc", }, | 49 | { .compatible = "soc", }, |
50 | { .compatible = "simple-bus", }, | 50 | { .compatible = "simple-bus", }, |
51 | { .compatible = "gianfar", }, | ||
51 | {}, | 52 | {}, |
52 | }; | 53 | }; |
53 | 54 | ||
diff --git a/arch/powerpc/platforms/83xx/sbc834x.c b/arch/powerpc/platforms/83xx/sbc834x.c index 156c4e218009..49023dbe1576 100644 --- a/arch/powerpc/platforms/83xx/sbc834x.c +++ b/arch/powerpc/platforms/83xx/sbc834x.c | |||
@@ -84,6 +84,7 @@ static struct __initdata of_device_id sbc834x_ids[] = { | |||
84 | { .type = "soc", }, | 84 | { .type = "soc", }, |
85 | { .compatible = "soc", }, | 85 | { .compatible = "soc", }, |
86 | { .compatible = "simple-bus", }, | 86 | { .compatible = "simple-bus", }, |
87 | { .compatible = "gianfar", }, | ||
87 | {}, | 88 | {}, |
88 | }; | 89 | }; |
89 | 90 | ||
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index b79dc710ed34..7f066adc068c 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig | |||
@@ -51,6 +51,12 @@ config MPC85xx_DS | |||
51 | help | 51 | help |
52 | This option enables support for the MPC85xx DS (MPC8544 DS) board | 52 | This option enables support for the MPC85xx DS (MPC8544 DS) board |
53 | 53 | ||
54 | config SOCRATES | ||
55 | bool "Socrates" | ||
56 | select DEFAULT_UIMAGE | ||
57 | help | ||
58 | This option enables support for the Socrates board. | ||
59 | |||
54 | config KSI8560 | 60 | config KSI8560 |
55 | bool "Emerson KSI8560" | 61 | bool "Emerson KSI8560" |
56 | select DEFAULT_UIMAGE | 62 | select DEFAULT_UIMAGE |
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index f0798c09980f..a857b35b9828 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile | |||
@@ -13,4 +13,5 @@ obj-$(CONFIG_STX_GP3) += stx_gp3.o | |||
13 | obj-$(CONFIG_TQM85xx) += tqm85xx.o | 13 | obj-$(CONFIG_TQM85xx) += tqm85xx.o |
14 | obj-$(CONFIG_SBC8560) += sbc8560.o | 14 | obj-$(CONFIG_SBC8560) += sbc8560.o |
15 | obj-$(CONFIG_SBC8548) += sbc8548.o | 15 | obj-$(CONFIG_SBC8548) += sbc8548.o |
16 | obj-$(CONFIG_SOCRATES) += socrates.o socrates_fpga_pic.o | ||
16 | obj-$(CONFIG_KSI8560) += ksi8560.o | 17 | obj-$(CONFIG_KSI8560) += ksi8560.o |
diff --git a/arch/powerpc/platforms/85xx/ksi8560.c b/arch/powerpc/platforms/85xx/ksi8560.c index 66f29235ff09..f4d36b5a2e00 100644 --- a/arch/powerpc/platforms/85xx/ksi8560.c +++ b/arch/powerpc/platforms/85xx/ksi8560.c | |||
@@ -219,6 +219,7 @@ static struct of_device_id __initdata of_bus_ids[] = { | |||
219 | { .type = "simple-bus", }, | 219 | { .type = "simple-bus", }, |
220 | { .name = "cpm", }, | 220 | { .name = "cpm", }, |
221 | { .name = "localbus", }, | 221 | { .name = "localbus", }, |
222 | { .compatible = "gianfar", }, | ||
222 | {}, | 223 | {}, |
223 | }; | 224 | }; |
224 | 225 | ||
diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c index 1bf5aefdfeb1..63efca20d7bd 100644 --- a/arch/powerpc/platforms/85xx/mpc8536_ds.c +++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c | |||
@@ -92,6 +92,7 @@ static struct of_device_id __initdata mpc8536_ds_ids[] = { | |||
92 | { .type = "soc", }, | 92 | { .type = "soc", }, |
93 | { .compatible = "soc", }, | 93 | { .compatible = "soc", }, |
94 | { .compatible = "simple-bus", }, | 94 | { .compatible = "simple-bus", }, |
95 | { .compatible = "gianfar", }, | ||
95 | {}, | 96 | {}, |
96 | }; | 97 | }; |
97 | 98 | ||
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 21f009023e26..9438a892afc4 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c | |||
@@ -226,6 +226,7 @@ static struct of_device_id __initdata of_bus_ids[] = { | |||
226 | { .name = "cpm", }, | 226 | { .name = "cpm", }, |
227 | { .name = "localbus", }, | 227 | { .name = "localbus", }, |
228 | { .compatible = "simple-bus", }, | 228 | { .compatible = "simple-bus", }, |
229 | { .compatible = "gianfar", }, | ||
229 | {}, | 230 | {}, |
230 | }; | 231 | }; |
231 | 232 | ||
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index aeb6a5bc5522..0a9e49104bdc 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c | |||
@@ -336,6 +336,7 @@ static struct of_device_id __initdata of_bus_ids[] = { | |||
336 | { .type = "soc", }, | 336 | { .type = "soc", }, |
337 | { .compatible = "soc", }, | 337 | { .compatible = "soc", }, |
338 | { .compatible = "simple-bus", }, | 338 | { .compatible = "simple-bus", }, |
339 | { .compatible = "gianfar", }, | ||
339 | {}, | 340 | {}, |
340 | }; | 341 | }; |
341 | 342 | ||
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c index 7326d904202c..de66de7a9ca2 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c | |||
@@ -204,6 +204,7 @@ static struct of_device_id __initdata mpc85xxds_ids[] = { | |||
204 | { .type = "soc", }, | 204 | { .type = "soc", }, |
205 | { .compatible = "soc", }, | 205 | { .compatible = "soc", }, |
206 | { .compatible = "simple-bus", }, | 206 | { .compatible = "simple-bus", }, |
207 | { .compatible = "gianfar", }, | ||
207 | {}, | 208 | {}, |
208 | }; | 209 | }; |
209 | 210 | ||
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 658a36fab3ab..7dd029034aec 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c | |||
@@ -265,6 +265,7 @@ static struct of_device_id mpc85xx_ids[] = { | |||
265 | { .compatible = "simple-bus", }, | 265 | { .compatible = "simple-bus", }, |
266 | { .type = "qe", }, | 266 | { .type = "qe", }, |
267 | { .compatible = "fsl,qe", }, | 267 | { .compatible = "fsl,qe", }, |
268 | { .compatible = "gianfar", }, | ||
268 | {}, | 269 | {}, |
269 | }; | 270 | }; |
270 | 271 | ||
diff --git a/arch/powerpc/platforms/85xx/sbc8548.c b/arch/powerpc/platforms/85xx/sbc8548.c index 7ec77ce12dad..ecdd8c09e4ed 100644 --- a/arch/powerpc/platforms/85xx/sbc8548.c +++ b/arch/powerpc/platforms/85xx/sbc8548.c | |||
@@ -154,6 +154,7 @@ static struct of_device_id __initdata of_bus_ids[] = { | |||
154 | { .name = "soc", }, | 154 | { .name = "soc", }, |
155 | { .type = "soc", }, | 155 | { .type = "soc", }, |
156 | { .compatible = "simple-bus", }, | 156 | { .compatible = "simple-bus", }, |
157 | { .compatible = "gianfar", }, | ||
157 | {}, | 158 | {}, |
158 | }; | 159 | }; |
159 | 160 | ||
diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c index 472f254a19d2..cc27807a8b64 100644 --- a/arch/powerpc/platforms/85xx/sbc8560.c +++ b/arch/powerpc/platforms/85xx/sbc8560.c | |||
@@ -213,6 +213,7 @@ static struct of_device_id __initdata of_bus_ids[] = { | |||
213 | { .name = "cpm", }, | 213 | { .name = "cpm", }, |
214 | { .name = "localbus", }, | 214 | { .name = "localbus", }, |
215 | { .compatible = "simple-bus", }, | 215 | { .compatible = "simple-bus", }, |
216 | { .compatible = "gianfar", }, | ||
216 | {}, | 217 | {}, |
217 | }; | 218 | }; |
218 | 219 | ||
diff --git a/arch/powerpc/platforms/85xx/socrates.c b/arch/powerpc/platforms/85xx/socrates.c new file mode 100644 index 000000000000..d0e8443b12c6 --- /dev/null +++ b/arch/powerpc/platforms/85xx/socrates.c | |||
@@ -0,0 +1,133 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008 Emcraft Systems | ||
3 | * Sergei Poselenov <sposelenov@emcraft.com> | ||
4 | * | ||
5 | * Based on MPC8560 ADS and arch/ppc tqm85xx ports | ||
6 | * | ||
7 | * Maintained by Kumar Gala (see MAINTAINERS for contact information) | ||
8 | * | ||
9 | * Copyright 2008 Freescale Semiconductor Inc. | ||
10 | * | ||
11 | * Copyright (c) 2005-2006 DENX Software Engineering | ||
12 | * Stefan Roese <sr@denx.de> | ||
13 | * | ||
14 | * Based on original work by | ||
15 | * Kumar Gala <kumar.gala@freescale.com> | ||
16 | * Copyright 2004 Freescale Semiconductor Inc. | ||
17 | * | ||
18 | * This program is free software; you can redistribute it and/or modify it | ||
19 | * under the terms of the GNU General Public License as published by the | ||
20 | * Free Software Foundation; either version 2 of the License, or (at your | ||
21 | * option) any later version. | ||
22 | */ | ||
23 | |||
24 | #include <linux/stddef.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/pci.h> | ||
27 | #include <linux/kdev_t.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <linux/seq_file.h> | ||
30 | #include <linux/of_platform.h> | ||
31 | |||
32 | #include <asm/system.h> | ||
33 | #include <asm/time.h> | ||
34 | #include <asm/machdep.h> | ||
35 | #include <asm/pci-bridge.h> | ||
36 | #include <asm/mpic.h> | ||
37 | #include <asm/prom.h> | ||
38 | #include <mm/mmu_decl.h> | ||
39 | #include <asm/udbg.h> | ||
40 | |||
41 | #include <sysdev/fsl_soc.h> | ||
42 | #include <sysdev/fsl_pci.h> | ||
43 | |||
44 | #include "socrates_fpga_pic.h" | ||
45 | |||
46 | static void __init socrates_pic_init(void) | ||
47 | { | ||
48 | struct mpic *mpic; | ||
49 | struct resource r; | ||
50 | struct device_node *np; | ||
51 | |||
52 | np = of_find_node_by_type(NULL, "open-pic"); | ||
53 | if (!np) { | ||
54 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
55 | return; | ||
56 | } | ||
57 | |||
58 | if (of_address_to_resource(np, 0, &r)) { | ||
59 | printk(KERN_ERR "Could not map mpic register space\n"); | ||
60 | of_node_put(np); | ||
61 | return; | ||
62 | } | ||
63 | |||
64 | mpic = mpic_alloc(np, r.start, | ||
65 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
66 | 0, 256, " OpenPIC "); | ||
67 | BUG_ON(mpic == NULL); | ||
68 | of_node_put(np); | ||
69 | |||
70 | mpic_init(mpic); | ||
71 | |||
72 | np = of_find_compatible_node(NULL, NULL, "abb,socrates-fpga-pic"); | ||
73 | if (!np) { | ||
74 | printk(KERN_ERR "Could not find socrates-fpga-pic node\n"); | ||
75 | return; | ||
76 | } | ||
77 | socrates_fpga_pic_init(np); | ||
78 | of_node_put(np); | ||
79 | } | ||
80 | |||
81 | /* | ||
82 | * Setup the architecture | ||
83 | */ | ||
84 | static void __init socrates_setup_arch(void) | ||
85 | { | ||
86 | #ifdef CONFIG_PCI | ||
87 | struct device_node *np; | ||
88 | #endif | ||
89 | |||
90 | if (ppc_md.progress) | ||
91 | ppc_md.progress("socrates_setup_arch()", 0); | ||
92 | |||
93 | #ifdef CONFIG_PCI | ||
94 | for_each_compatible_node(np, "pci", "fsl,mpc8540-pci") | ||
95 | fsl_add_bridge(np, 1); | ||
96 | #endif | ||
97 | } | ||
98 | |||
99 | static struct of_device_id __initdata socrates_of_bus_ids[] = { | ||
100 | { .compatible = "simple-bus", }, | ||
101 | { .compatible = "gianfar", }, | ||
102 | {}, | ||
103 | }; | ||
104 | |||
105 | static void __init socrates_init(void) | ||
106 | { | ||
107 | of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL); | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * Called very early, device-tree isn't unflattened | ||
112 | */ | ||
113 | static int __init socrates_probe(void) | ||
114 | { | ||
115 | unsigned long root = of_get_flat_dt_root(); | ||
116 | |||
117 | if (of_flat_dt_is_compatible(root, "abb,socrates")) | ||
118 | return 1; | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | define_machine(socrates) { | ||
124 | .name = "Socrates", | ||
125 | .probe = socrates_probe, | ||
126 | .setup_arch = socrates_setup_arch, | ||
127 | .init = socrates_init, | ||
128 | .init_IRQ = socrates_pic_init, | ||
129 | .get_irq = mpic_get_irq, | ||
130 | .restart = fsl_rstcr_restart, | ||
131 | .calibrate_decr = generic_calibrate_decr, | ||
132 | .progress = udbg_progress, | ||
133 | }; | ||
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c new file mode 100644 index 000000000000..60edf63d0157 --- /dev/null +++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c | |||
@@ -0,0 +1,327 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Ilya Yanok, Emcraft Systems | ||
3 | * | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/irq.h> | ||
12 | #include <linux/of_platform.h> | ||
13 | #include <linux/io.h> | ||
14 | |||
15 | /* | ||
16 | * The FPGA supports 9 interrupt sources, which can be routed to 3 | ||
17 | * interrupt request lines of the MPIC. The line to be used can be | ||
18 | * specified through the third cell of FDT property "interrupts". | ||
19 | */ | ||
20 | |||
21 | #define SOCRATES_FPGA_NUM_IRQS 9 | ||
22 | |||
23 | #define FPGA_PIC_IRQCFG (0x0) | ||
24 | #define FPGA_PIC_IRQMASK(n) (0x4 + 0x4 * (n)) | ||
25 | |||
26 | #define SOCRATES_FPGA_IRQ_MASK ((1 << SOCRATES_FPGA_NUM_IRQS) - 1) | ||
27 | |||
28 | struct socrates_fpga_irq_info { | ||
29 | unsigned int irq_line; | ||
30 | int type; | ||
31 | }; | ||
32 | |||
33 | /* | ||
34 | * Interrupt routing and type table | ||
35 | * | ||
36 | * IRQ_TYPE_NONE means the interrupt type is configurable, | ||
37 | * otherwise it's fixed to the specified value. | ||
38 | */ | ||
39 | static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = { | ||
40 | [0] = {0, IRQ_TYPE_NONE}, | ||
41 | [1] = {0, IRQ_TYPE_LEVEL_HIGH}, | ||
42 | [2] = {0, IRQ_TYPE_LEVEL_LOW}, | ||
43 | [3] = {0, IRQ_TYPE_NONE}, | ||
44 | [4] = {0, IRQ_TYPE_NONE}, | ||
45 | [5] = {0, IRQ_TYPE_NONE}, | ||
46 | [6] = {0, IRQ_TYPE_NONE}, | ||
47 | [7] = {0, IRQ_TYPE_NONE}, | ||
48 | [8] = {0, IRQ_TYPE_LEVEL_HIGH}, | ||
49 | }; | ||
50 | |||
51 | #define socrates_fpga_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq) | ||
52 | |||
53 | static DEFINE_SPINLOCK(socrates_fpga_pic_lock); | ||
54 | |||
55 | static void __iomem *socrates_fpga_pic_iobase; | ||
56 | static struct irq_host *socrates_fpga_pic_irq_host; | ||
57 | static unsigned int socrates_fpga_irqs[3]; | ||
58 | |||
59 | static inline uint32_t socrates_fpga_pic_read(int reg) | ||
60 | { | ||
61 | return in_be32(socrates_fpga_pic_iobase + reg); | ||
62 | } | ||
63 | |||
64 | static inline void socrates_fpga_pic_write(int reg, uint32_t val) | ||
65 | { | ||
66 | out_be32(socrates_fpga_pic_iobase + reg, val); | ||
67 | } | ||
68 | |||
69 | static inline unsigned int socrates_fpga_pic_get_irq(unsigned int irq) | ||
70 | { | ||
71 | uint32_t cause; | ||
72 | unsigned long flags; | ||
73 | int i; | ||
74 | |||
75 | /* Check irq line routed to the MPIC */ | ||
76 | for (i = 0; i < 3; i++) { | ||
77 | if (irq == socrates_fpga_irqs[i]) | ||
78 | break; | ||
79 | } | ||
80 | if (i == 3) | ||
81 | return NO_IRQ; | ||
82 | |||
83 | spin_lock_irqsave(&socrates_fpga_pic_lock, flags); | ||
84 | cause = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(i)); | ||
85 | spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); | ||
86 | for (i = SOCRATES_FPGA_NUM_IRQS - 1; i >= 0; i--) { | ||
87 | if (cause >> (i + 16)) | ||
88 | break; | ||
89 | } | ||
90 | return irq_linear_revmap(socrates_fpga_pic_irq_host, | ||
91 | (irq_hw_number_t)i); | ||
92 | } | ||
93 | |||
94 | void socrates_fpga_pic_cascade(unsigned int irq, struct irq_desc *desc) | ||
95 | { | ||
96 | unsigned int cascade_irq; | ||
97 | |||
98 | /* | ||
99 | * See if we actually have an interrupt, call generic handling code if | ||
100 | * we do. | ||
101 | */ | ||
102 | cascade_irq = socrates_fpga_pic_get_irq(irq); | ||
103 | |||
104 | if (cascade_irq != NO_IRQ) | ||
105 | generic_handle_irq(cascade_irq); | ||
106 | desc->chip->eoi(irq); | ||
107 | |||
108 | } | ||
109 | |||
110 | static void socrates_fpga_pic_ack(unsigned int virq) | ||
111 | { | ||
112 | unsigned long flags; | ||
113 | unsigned int hwirq, irq_line; | ||
114 | uint32_t mask; | ||
115 | |||
116 | hwirq = socrates_fpga_irq_to_hw(virq); | ||
117 | |||
118 | irq_line = fpga_irqs[hwirq].irq_line; | ||
119 | spin_lock_irqsave(&socrates_fpga_pic_lock, flags); | ||
120 | mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) | ||
121 | & SOCRATES_FPGA_IRQ_MASK; | ||
122 | mask |= (1 << (hwirq + 16)); | ||
123 | socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); | ||
124 | spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); | ||
125 | } | ||
126 | |||
127 | static void socrates_fpga_pic_mask(unsigned int virq) | ||
128 | { | ||
129 | unsigned long flags; | ||
130 | unsigned int hwirq; | ||
131 | int irq_line; | ||
132 | u32 mask; | ||
133 | |||
134 | hwirq = socrates_fpga_irq_to_hw(virq); | ||
135 | |||
136 | irq_line = fpga_irqs[hwirq].irq_line; | ||
137 | spin_lock_irqsave(&socrates_fpga_pic_lock, flags); | ||
138 | mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) | ||
139 | & SOCRATES_FPGA_IRQ_MASK; | ||
140 | mask &= ~(1 << hwirq); | ||
141 | socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); | ||
142 | spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); | ||
143 | } | ||
144 | |||
145 | static void socrates_fpga_pic_mask_ack(unsigned int virq) | ||
146 | { | ||
147 | unsigned long flags; | ||
148 | unsigned int hwirq; | ||
149 | int irq_line; | ||
150 | u32 mask; | ||
151 | |||
152 | hwirq = socrates_fpga_irq_to_hw(virq); | ||
153 | |||
154 | irq_line = fpga_irqs[hwirq].irq_line; | ||
155 | spin_lock_irqsave(&socrates_fpga_pic_lock, flags); | ||
156 | mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) | ||
157 | & SOCRATES_FPGA_IRQ_MASK; | ||
158 | mask &= ~(1 << hwirq); | ||
159 | mask |= (1 << (hwirq + 16)); | ||
160 | socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); | ||
161 | spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); | ||
162 | } | ||
163 | |||
164 | static void socrates_fpga_pic_unmask(unsigned int virq) | ||
165 | { | ||
166 | unsigned long flags; | ||
167 | unsigned int hwirq; | ||
168 | int irq_line; | ||
169 | u32 mask; | ||
170 | |||
171 | hwirq = socrates_fpga_irq_to_hw(virq); | ||
172 | |||
173 | irq_line = fpga_irqs[hwirq].irq_line; | ||
174 | spin_lock_irqsave(&socrates_fpga_pic_lock, flags); | ||
175 | mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) | ||
176 | & SOCRATES_FPGA_IRQ_MASK; | ||
177 | mask |= (1 << hwirq); | ||
178 | socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); | ||
179 | spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); | ||
180 | } | ||
181 | |||
182 | static void socrates_fpga_pic_eoi(unsigned int virq) | ||
183 | { | ||
184 | unsigned long flags; | ||
185 | unsigned int hwirq; | ||
186 | int irq_line; | ||
187 | u32 mask; | ||
188 | |||
189 | hwirq = socrates_fpga_irq_to_hw(virq); | ||
190 | |||
191 | irq_line = fpga_irqs[hwirq].irq_line; | ||
192 | spin_lock_irqsave(&socrates_fpga_pic_lock, flags); | ||
193 | mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) | ||
194 | & SOCRATES_FPGA_IRQ_MASK; | ||
195 | mask |= (1 << (hwirq + 16)); | ||
196 | socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); | ||
197 | spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); | ||
198 | } | ||
199 | |||
200 | static int socrates_fpga_pic_set_type(unsigned int virq, | ||
201 | unsigned int flow_type) | ||
202 | { | ||
203 | unsigned long flags; | ||
204 | unsigned int hwirq; | ||
205 | int polarity; | ||
206 | u32 mask; | ||
207 | |||
208 | hwirq = socrates_fpga_irq_to_hw(virq); | ||
209 | |||
210 | if (fpga_irqs[hwirq].type != IRQ_TYPE_NONE) | ||
211 | return -EINVAL; | ||
212 | |||
213 | switch (flow_type & IRQ_TYPE_SENSE_MASK) { | ||
214 | case IRQ_TYPE_LEVEL_HIGH: | ||
215 | polarity = 1; | ||
216 | break; | ||
217 | case IRQ_TYPE_LEVEL_LOW: | ||
218 | polarity = 0; | ||
219 | break; | ||
220 | default: | ||
221 | return -EINVAL; | ||
222 | } | ||
223 | spin_lock_irqsave(&socrates_fpga_pic_lock, flags); | ||
224 | mask = socrates_fpga_pic_read(FPGA_PIC_IRQCFG); | ||
225 | if (polarity) | ||
226 | mask |= (1 << hwirq); | ||
227 | else | ||
228 | mask &= ~(1 << hwirq); | ||
229 | socrates_fpga_pic_write(FPGA_PIC_IRQCFG, mask); | ||
230 | spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static struct irq_chip socrates_fpga_pic_chip = { | ||
235 | .typename = " FPGA-PIC ", | ||
236 | .ack = socrates_fpga_pic_ack, | ||
237 | .mask = socrates_fpga_pic_mask, | ||
238 | .mask_ack = socrates_fpga_pic_mask_ack, | ||
239 | .unmask = socrates_fpga_pic_unmask, | ||
240 | .eoi = socrates_fpga_pic_eoi, | ||
241 | .set_type = socrates_fpga_pic_set_type, | ||
242 | }; | ||
243 | |||
244 | static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq, | ||
245 | irq_hw_number_t hwirq) | ||
246 | { | ||
247 | /* All interrupts are LEVEL sensitive */ | ||
248 | get_irq_desc(virq)->status |= IRQ_LEVEL; | ||
249 | set_irq_chip_and_handler(virq, &socrates_fpga_pic_chip, | ||
250 | handle_fasteoi_irq); | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | static int socrates_fpga_pic_host_xlate(struct irq_host *h, | ||
256 | struct device_node *ct, u32 *intspec, unsigned int intsize, | ||
257 | irq_hw_number_t *out_hwirq, unsigned int *out_flags) | ||
258 | { | ||
259 | struct socrates_fpga_irq_info *fpga_irq = &fpga_irqs[intspec[0]]; | ||
260 | |||
261 | *out_hwirq = intspec[0]; | ||
262 | if (fpga_irq->type == IRQ_TYPE_NONE) { | ||
263 | /* type is configurable */ | ||
264 | if (intspec[1] != IRQ_TYPE_LEVEL_LOW && | ||
265 | intspec[1] != IRQ_TYPE_LEVEL_HIGH) { | ||
266 | pr_warning("FPGA PIC: invalid irq type, " | ||
267 | "setting default active low\n"); | ||
268 | *out_flags = IRQ_TYPE_LEVEL_LOW; | ||
269 | } else { | ||
270 | *out_flags = intspec[1]; | ||
271 | } | ||
272 | } else { | ||
273 | /* type is fixed */ | ||
274 | *out_flags = fpga_irq->type; | ||
275 | } | ||
276 | |||
277 | /* Use specified interrupt routing */ | ||
278 | if (intspec[2] <= 2) | ||
279 | fpga_irq->irq_line = intspec[2]; | ||
280 | else | ||
281 | pr_warning("FPGA PIC: invalid irq routing\n"); | ||
282 | |||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static struct irq_host_ops socrates_fpga_pic_host_ops = { | ||
287 | .map = socrates_fpga_pic_host_map, | ||
288 | .xlate = socrates_fpga_pic_host_xlate, | ||
289 | }; | ||
290 | |||
291 | void socrates_fpga_pic_init(struct device_node *pic) | ||
292 | { | ||
293 | unsigned long flags; | ||
294 | int i; | ||
295 | |||
296 | /* Setup an irq_host structure */ | ||
297 | socrates_fpga_pic_irq_host = irq_alloc_host(pic, IRQ_HOST_MAP_LINEAR, | ||
298 | SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops, | ||
299 | SOCRATES_FPGA_NUM_IRQS); | ||
300 | if (socrates_fpga_pic_irq_host == NULL) { | ||
301 | pr_err("FPGA PIC: Unable to allocate host\n"); | ||
302 | return; | ||
303 | } | ||
304 | |||
305 | for (i = 0; i < 3; i++) { | ||
306 | socrates_fpga_irqs[i] = irq_of_parse_and_map(pic, i); | ||
307 | if (socrates_fpga_irqs[i] == NO_IRQ) { | ||
308 | pr_warning("FPGA PIC: can't get irq%d.\n", i); | ||
309 | continue; | ||
310 | } | ||
311 | set_irq_chained_handler(socrates_fpga_irqs[i], | ||
312 | socrates_fpga_pic_cascade); | ||
313 | } | ||
314 | |||
315 | socrates_fpga_pic_iobase = of_iomap(pic, 0); | ||
316 | |||
317 | spin_lock_irqsave(&socrates_fpga_pic_lock, flags); | ||
318 | socrates_fpga_pic_write(FPGA_PIC_IRQMASK(0), | ||
319 | SOCRATES_FPGA_IRQ_MASK << 16); | ||
320 | socrates_fpga_pic_write(FPGA_PIC_IRQMASK(1), | ||
321 | SOCRATES_FPGA_IRQ_MASK << 16); | ||
322 | socrates_fpga_pic_write(FPGA_PIC_IRQMASK(2), | ||
323 | SOCRATES_FPGA_IRQ_MASK << 16); | ||
324 | spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); | ||
325 | |||
326 | pr_info("FPGA PIC: Setting up Socrates FPGA PIC\n"); | ||
327 | } | ||
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.h b/arch/powerpc/platforms/85xx/socrates_fpga_pic.h new file mode 100644 index 000000000000..21d7d8e42199 --- /dev/null +++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.h | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Ilya Yanok, Emcraft Systems | ||
3 | * | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #ifndef SOCRATES_FPGA_PIC_H | ||
12 | #define SOCRATES_FPGA_PIC_H | ||
13 | |||
14 | void socrates_fpga_pic_init(struct device_node *pic); | ||
15 | |||
16 | #endif | ||
diff --git a/arch/powerpc/platforms/85xx/stx_gp3.c b/arch/powerpc/platforms/85xx/stx_gp3.c index 0cca8f5cb272..f559918f3c6f 100644 --- a/arch/powerpc/platforms/85xx/stx_gp3.c +++ b/arch/powerpc/platforms/85xx/stx_gp3.c | |||
@@ -145,6 +145,7 @@ static void stx_gp3_show_cpuinfo(struct seq_file *m) | |||
145 | 145 | ||
146 | static struct of_device_id __initdata of_bus_ids[] = { | 146 | static struct of_device_id __initdata of_bus_ids[] = { |
147 | { .compatible = "simple-bus", }, | 147 | { .compatible = "simple-bus", }, |
148 | { .compatible = "gianfar", }, | ||
148 | {}, | 149 | {}, |
149 | }; | 150 | }; |
150 | 151 | ||
diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c index 2933a8e827d9..5b0ab9966e90 100644 --- a/arch/powerpc/platforms/85xx/tqm85xx.c +++ b/arch/powerpc/platforms/85xx/tqm85xx.c | |||
@@ -153,6 +153,7 @@ static void tqm85xx_show_cpuinfo(struct seq_file *m) | |||
153 | 153 | ||
154 | static struct of_device_id __initdata of_bus_ids[] = { | 154 | static struct of_device_id __initdata of_bus_ids[] = { |
155 | { .compatible = "simple-bus", }, | 155 | { .compatible = "simple-bus", }, |
156 | { .compatible = "gianfar", }, | ||
156 | {}, | 157 | {}, |
157 | }; | 158 | }; |
158 | 159 | ||
diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c index 830fd9a23b5a..d79104669cdc 100644 --- a/arch/powerpc/platforms/86xx/gef_ppc9a.c +++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c | |||
@@ -194,6 +194,7 @@ static long __init mpc86xx_time_init(void) | |||
194 | 194 | ||
195 | static __initdata struct of_device_id of_bus_ids[] = { | 195 | static __initdata struct of_device_id of_bus_ids[] = { |
196 | { .compatible = "simple-bus", }, | 196 | { .compatible = "simple-bus", }, |
197 | { .compatible = "gianfar", }, | ||
197 | {}, | 198 | {}, |
198 | }; | 199 | }; |
199 | 200 | ||
diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c index ba3ce4381611..af14f852d747 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc310.c +++ b/arch/powerpc/platforms/86xx/gef_sbc310.c | |||
@@ -205,6 +205,7 @@ static long __init mpc86xx_time_init(void) | |||
205 | 205 | ||
206 | static __initdata struct of_device_id of_bus_ids[] = { | 206 | static __initdata struct of_device_id of_bus_ids[] = { |
207 | { .compatible = "simple-bus", }, | 207 | { .compatible = "simple-bus", }, |
208 | { .compatible = "gianfar", }, | ||
208 | {}, | 209 | {}, |
209 | }; | 210 | }; |
210 | 211 | ||
diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c index d6b772ba3b8f..ea2360639652 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc610.c +++ b/arch/powerpc/platforms/86xx/gef_sbc610.c | |||
@@ -194,6 +194,7 @@ static long __init mpc86xx_time_init(void) | |||
194 | 194 | ||
195 | static __initdata struct of_device_id of_bus_ids[] = { | 195 | static __initdata struct of_device_id of_bus_ids[] = { |
196 | { .compatible = "simple-bus", }, | 196 | { .compatible = "simple-bus", }, |
197 | { .compatible = "gianfar", }, | ||
197 | {}, | 198 | {}, |
198 | }; | 199 | }; |
199 | 200 | ||
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c index e8d54ac5292c..3f49a6f893a3 100644 --- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c +++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c | |||
@@ -46,6 +46,7 @@ static unsigned char *pixis_bdcfg0, *pixis_arch; | |||
46 | static struct of_device_id __initdata mpc8610_ids[] = { | 46 | static struct of_device_id __initdata mpc8610_ids[] = { |
47 | { .compatible = "fsl,mpc8610-immr", }, | 47 | { .compatible = "fsl,mpc8610-immr", }, |
48 | { .compatible = "simple-bus", }, | 48 | { .compatible = "simple-bus", }, |
49 | { .compatible = "gianfar", }, | ||
49 | {} | 50 | {} |
50 | }; | 51 | }; |
51 | 52 | ||
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 27e0e682d8e1..c4ec49b5f7f8 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | |||
@@ -148,6 +148,7 @@ mpc86xx_time_init(void) | |||
148 | static __initdata struct of_device_id of_bus_ids[] = { | 148 | static __initdata struct of_device_id of_bus_ids[] = { |
149 | { .compatible = "simple-bus", }, | 149 | { .compatible = "simple-bus", }, |
150 | { .compatible = "fsl,rapidio-delta", }, | 150 | { .compatible = "fsl,rapidio-delta", }, |
151 | { .compatible = "gianfar", }, | ||
151 | {}, | 152 | {}, |
152 | }; | 153 | }; |
153 | 154 | ||
diff --git a/arch/powerpc/platforms/86xx/sbc8641d.c b/arch/powerpc/platforms/86xx/sbc8641d.c index 5fd7ed40986f..2886a36fc085 100644 --- a/arch/powerpc/platforms/86xx/sbc8641d.c +++ b/arch/powerpc/platforms/86xx/sbc8641d.c | |||
@@ -103,6 +103,7 @@ mpc86xx_time_init(void) | |||
103 | 103 | ||
104 | static __initdata struct of_device_id of_bus_ids[] = { | 104 | static __initdata struct of_device_id of_bus_ids[] = { |
105 | { .compatible = "simple-bus", }, | 105 | { .compatible = "simple-bus", }, |
106 | { .compatible = "gianfar", }, | ||
106 | {}, | 107 | {}, |
107 | }; | 108 | }; |
108 | 109 | ||