diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-04-06 03:02:57 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-06 03:02:57 -0400 |
commit | f541ae326fa120fa5c57433e4d9a133df212ce41 (patch) | |
tree | bdbd94ec72cfc601118051cb35e8617d55510177 /arch/powerpc/platforms/85xx | |
parent | e255357764f92afcafafbd4879b222b8c752065a (diff) | |
parent | 0221c81b1b8eb0cbb6b30a0ced52ead32d2b4e4c (diff) |
Merge branch 'linus' into perfcounters/core-v2
Merge reason: we have gathered quite a few conflicts, need to merge upstream
Conflicts:
arch/powerpc/kernel/Makefile
arch/x86/ia32/ia32entry.S
arch/x86/include/asm/hardirq.h
arch/x86/include/asm/unistd_32.h
arch/x86/include/asm/unistd_64.h
arch/x86/kernel/cpu/common.c
arch/x86/kernel/irq.c
arch/x86/kernel/syscall_table_32.S
arch/x86/mm/iomap_32.c
include/linux/sched.h
kernel/Makefile
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/powerpc/platforms/85xx')
-rw-r--r-- | arch/powerpc/platforms/85xx/Kconfig | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/ksi8560.c | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc8536_ds.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_ads.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_cds.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_ds.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_mds.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/sbc8548.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/sbc8560.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/smp.c | 43 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/socrates.c | 133 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/socrates_fpga_pic.c | 327 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/socrates_fpga_pic.h | 16 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/stx_gp3.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/tqm85xx.c | 1 |
16 files changed, 528 insertions, 11 deletions
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 81cee7bbf2d2..f4d36b5a2e00 100644 --- a/arch/powerpc/platforms/85xx/ksi8560.c +++ b/arch/powerpc/platforms/85xx/ksi8560.c | |||
@@ -106,8 +106,6 @@ static void __init ksi8560_pic_init(void) | |||
106 | cpm2_pic_init(np); | 106 | cpm2_pic_init(np); |
107 | of_node_put(np); | 107 | of_node_put(np); |
108 | set_irq_chained_handler(irq, cpm2_cascade); | 108 | set_irq_chained_handler(irq, cpm2_cascade); |
109 | |||
110 | setup_irq(0, NULL); | ||
111 | #endif | 109 | #endif |
112 | } | 110 | } |
113 | 111 | ||
@@ -221,6 +219,7 @@ static struct of_device_id __initdata of_bus_ids[] = { | |||
221 | { .type = "simple-bus", }, | 219 | { .type = "simple-bus", }, |
222 | { .name = "cpm", }, | 220 | { .name = "cpm", }, |
223 | { .name = "localbus", }, | 221 | { .name = "localbus", }, |
222 | { .compatible = "gianfar", }, | ||
224 | {}, | 223 | {}, |
225 | }; | 224 | }; |
226 | 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..458d91fba91d 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c | |||
@@ -179,7 +179,6 @@ static irqreturn_t mpc85xx_8259_cascade_action(int irq, void *dev_id) | |||
179 | static struct irqaction mpc85xxcds_8259_irqaction = { | 179 | static struct irqaction mpc85xxcds_8259_irqaction = { |
180 | .handler = mpc85xx_8259_cascade_action, | 180 | .handler = mpc85xx_8259_cascade_action, |
181 | .flags = IRQF_SHARED, | 181 | .flags = IRQF_SHARED, |
182 | .mask = CPU_MASK_NONE, | ||
183 | .name = "8259 cascade", | 182 | .name = "8259 cascade", |
184 | }; | 183 | }; |
185 | #endif /* PPC_I8259 */ | 184 | #endif /* PPC_I8259 */ |
@@ -336,6 +335,7 @@ static struct of_device_id __initdata of_bus_ids[] = { | |||
336 | { .type = "soc", }, | 335 | { .type = "soc", }, |
337 | { .compatible = "soc", }, | 336 | { .compatible = "soc", }, |
338 | { .compatible = "simple-bus", }, | 337 | { .compatible = "simple-bus", }, |
338 | { .compatible = "gianfar", }, | ||
339 | {}, | 339 | {}, |
340 | }; | 340 | }; |
341 | 341 | ||
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/smp.c b/arch/powerpc/platforms/85xx/smp.c index 79a0df17078b..cc0b0db8a6f3 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/page.h> | 21 | #include <asm/page.h> |
22 | #include <asm/mpic.h> | 22 | #include <asm/mpic.h> |
23 | #include <asm/cacheflush.h> | 23 | #include <asm/cacheflush.h> |
24 | #include <asm/dbell.h> | ||
24 | 25 | ||
25 | #include <sysdev/fsl_soc.h> | 26 | #include <sysdev/fsl_soc.h> |
26 | 27 | ||
@@ -80,10 +81,8 @@ smp_85xx_kick_cpu(int nr) | |||
80 | } | 81 | } |
81 | 82 | ||
82 | static void __init | 83 | static void __init |
83 | smp_85xx_setup_cpu(int cpu_nr) | 84 | smp_85xx_basic_setup(int cpu_nr) |
84 | { | 85 | { |
85 | mpic_setup_this_cpu(); | ||
86 | |||
87 | /* Clear any pending timer interrupts */ | 86 | /* Clear any pending timer interrupts */ |
88 | mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); | 87 | mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); |
89 | 88 | ||
@@ -91,15 +90,43 @@ smp_85xx_setup_cpu(int cpu_nr) | |||
91 | mtspr(SPRN_TCR, TCR_DIE); | 90 | mtspr(SPRN_TCR, TCR_DIE); |
92 | } | 91 | } |
93 | 92 | ||
93 | static void __init | ||
94 | smp_85xx_setup_cpu(int cpu_nr) | ||
95 | { | ||
96 | mpic_setup_this_cpu(); | ||
97 | |||
98 | smp_85xx_basic_setup(cpu_nr); | ||
99 | } | ||
100 | |||
94 | struct smp_ops_t smp_85xx_ops = { | 101 | struct smp_ops_t smp_85xx_ops = { |
95 | .message_pass = smp_mpic_message_pass, | ||
96 | .probe = smp_mpic_probe, | ||
97 | .kick_cpu = smp_85xx_kick_cpu, | 102 | .kick_cpu = smp_85xx_kick_cpu, |
98 | .setup_cpu = smp_85xx_setup_cpu, | ||
99 | }; | 103 | }; |
100 | 104 | ||
101 | void __init | 105 | static int __init smp_dummy_probe(void) |
102 | mpc85xx_smp_init(void) | ||
103 | { | 106 | { |
107 | return NR_CPUS; | ||
108 | } | ||
109 | |||
110 | void __init mpc85xx_smp_init(void) | ||
111 | { | ||
112 | struct device_node *np; | ||
113 | |||
114 | smp_85xx_ops.message_pass = NULL; | ||
115 | |||
116 | np = of_find_node_by_type(NULL, "open-pic"); | ||
117 | if (np) { | ||
118 | smp_85xx_ops.probe = smp_mpic_probe; | ||
119 | smp_85xx_ops.setup_cpu = smp_85xx_setup_cpu; | ||
120 | smp_85xx_ops.message_pass = smp_mpic_message_pass; | ||
121 | } else { | ||
122 | smp_85xx_ops.probe = smp_dummy_probe; | ||
123 | smp_85xx_ops.setup_cpu = smp_85xx_basic_setup; | ||
124 | } | ||
125 | |||
126 | if (cpu_has_feature(CPU_FTR_DBELL)) | ||
127 | smp_85xx_ops.message_pass = smp_dbell_message_pass; | ||
128 | |||
129 | BUG_ON(!smp_85xx_ops.message_pass); | ||
130 | |||
104 | smp_ops = &smp_85xx_ops; | 131 | smp_ops = &smp_85xx_ops; |
105 | } | 132 | } |
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 | ||