aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 11:16:37 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 11:16:37 -0400
commit13bbd8d90647132fc295d73b122567eb8987d298 (patch)
tree466ae1f00a5965308ce2e7695d4bfe88d87b9610 /arch
parent18e6756a6b463e09fd3873592ec6b0579c78103d (diff)
parent9020fc960b8f5fbca0de6e4d11881ddc827aa61d (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (25 commits) [POWERPC] Add support for the mpc832x mds board [POWERPC] Add initial support for the e300c2 core [POWERPC] Add MPC8360EMDS default dts file [POWERPC] Add MPC8360EMDS board support [POWERPC] Add QUICC Engine (QE) infrastructure [POWERPC] Add QE device tree node definition [POWERPC] Don't try to just continue if xmon has no input device [POWERPC] Fix a printk in pseries_mpic_init_IRQ [POWERPC] Get default baud rate in udbg_scc [POWERPC] Fix zImage.coff on oldworld PowerMac [POWERPC] Fix xmon=off and cleanup xmon initialisation [POWERPC] Cleanup include/asm-powerpc/xmon.h [POWERPC] Update swim3 printk after blkdev.h change [POWERPC] Cell interrupt rework POWERPC: mpc82xx merge: board-specific/platform stuff(resend) POWERPC: 8272ads merge to powerpc: common stuff POWERPC: Added devicetree for mpc8272ads board [POWERPC] iSeries has no legacy I/O [POWERPC] implement BEGIN/END_FW_FTR_SECTION [POWERPC] iSeries does not need pcibios_fixup_resources ...
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/Kconfig21
-rw-r--r--arch/powerpc/boot/dts/mpc8272ads.dts223
-rw-r--r--arch/powerpc/boot/dts/mpc8360emds.dts375
-rw-r--r--arch/powerpc/boot/zImage.coff.lds.S1
-rw-r--r--arch/powerpc/configs/mpc8360emds_defconfig1018
-rw-r--r--arch/powerpc/kernel/cputable.c15
-rw-r--r--arch/powerpc/kernel/entry_64.S18
-rw-r--r--arch/powerpc/kernel/head_64.S28
-rw-r--r--arch/powerpc/kernel/misc_64.S46
-rw-r--r--arch/powerpc/kernel/pci_64.c58
-rw-r--r--arch/powerpc/kernel/setup-common.c25
-rw-r--r--arch/powerpc/kernel/setup_32.c8
-rw-r--r--arch/powerpc/kernel/setup_64.c12
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S8
-rw-r--r--arch/powerpc/mm/pgtable_64.c29
-rw-r--r--arch/powerpc/mm/slb_low.S3
-rw-r--r--arch/powerpc/platforms/82xx/Kconfig21
-rw-r--r--arch/powerpc/platforms/82xx/Makefile5
-rw-r--r--arch/powerpc/platforms/82xx/m82xx_pci.h19
-rw-r--r--arch/powerpc/platforms/82xx/mpc82xx.c111
-rw-r--r--arch/powerpc/platforms/82xx/mpc82xx_ads.c661
-rw-r--r--arch/powerpc/platforms/82xx/pq2ads.h67
-rw-r--r--arch/powerpc/platforms/83xx/Kconfig13
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_mds.c215
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_mds.h19
-rw-r--r--arch/powerpc/platforms/83xx/mpc8360e_pb.c219
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c235
-rw-r--r--arch/powerpc/platforms/cell/interrupt.h97
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c9
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c19
-rw-r--r--arch/powerpc/platforms/iseries/pci.c8
-rw-r--r--arch/powerpc/platforms/iseries/setup.c16
-rw-r--r--arch/powerpc/platforms/powermac/udbg_scc.c14
-rw-r--r--arch/powerpc/platforms/pseries/setup.c2
-rw-r--r--arch/powerpc/sysdev/Makefile1
-rw-r--r--arch/powerpc/sysdev/cpm2_pic.c2
-rw-r--r--arch/powerpc/sysdev/cpm2_pic.h2
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c62
-rw-r--r--arch/powerpc/sysdev/qe_lib/Kconfig30
-rw-r--r--arch/powerpc/sysdev/qe_lib/Makefile8
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe.c353
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_ic.c555
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_ic.h106
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_io.c226
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc.c251
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc_fast.c396
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc_slow.c404
-rw-r--r--arch/powerpc/xmon/xmon.c35
48 files changed, 5819 insertions, 250 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 96ef656e4669..8b6910465578 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -338,10 +338,6 @@ config PPC_MULTIPLATFORM
338 RS/6000 machine, an Apple machine, or a PReP, CHRP, 338 RS/6000 machine, an Apple machine, or a PReP, CHRP,
339 Maple or Cell-based machine. 339 Maple or Cell-based machine.
340 340
341config PPC_ISERIES
342 bool "IBM Legacy iSeries"
343 depends on PPC64
344
345config EMBEDDED6xx 341config EMBEDDED6xx
346 bool "Embedded 6xx/7xx/7xxx-based board" 342 bool "Embedded 6xx/7xx/7xxx-based board"
347 depends on PPC32 && (BROKEN||BROKEN_ON_SMP) 343 depends on PPC32 && (BROKEN||BROKEN_ON_SMP)
@@ -355,6 +351,16 @@ config APUS
355 <http://linux-apus.sourceforge.net/>. 351 <http://linux-apus.sourceforge.net/>.
356endchoice 352endchoice
357 353
354config QUICC_ENGINE
355 bool
356 depends on PPC_MPC836x || PPC_MPC832x
357 default y
358 help
359 The QUICC Engine (QE) is a new generation of communications
360 coprocessors on Freescale embedded CPUs (akin to CPM in older chips).
361 Selecting this option means that you wish to build a kernel
362 for a machine with a QE coprocessor.
363
358config PPC_PSERIES 364config PPC_PSERIES
359 depends on PPC_MULTIPLATFORM && PPC64 365 depends on PPC_MULTIPLATFORM && PPC64
360 bool "IBM pSeries & new (POWER5-based) iSeries" 366 bool "IBM pSeries & new (POWER5-based) iSeries"
@@ -365,6 +371,10 @@ config PPC_PSERIES
365 select PPC_UDBG_16550 371 select PPC_UDBG_16550
366 default y 372 default y
367 373
374config PPC_ISERIES
375 bool "IBM Legacy iSeries"
376 depends on PPC_MULTIPLATFORM && PPC64
377
368config PPC_CHRP 378config PPC_CHRP
369 bool "Common Hardware Reference Platform (CHRP) based machines" 379 bool "Common Hardware Reference Platform (CHRP) based machines"
370 depends on PPC_MULTIPLATFORM && PPC32 380 depends on PPC_MULTIPLATFORM && PPC32
@@ -594,6 +604,7 @@ endmenu
594 604
595source arch/powerpc/platforms/embedded6xx/Kconfig 605source arch/powerpc/platforms/embedded6xx/Kconfig
596source arch/powerpc/platforms/4xx/Kconfig 606source arch/powerpc/platforms/4xx/Kconfig
607source arch/powerpc/platforms/82xx/Kconfig
597source arch/powerpc/platforms/83xx/Kconfig 608source arch/powerpc/platforms/83xx/Kconfig
598source arch/powerpc/platforms/85xx/Kconfig 609source arch/powerpc/platforms/85xx/Kconfig
599source arch/powerpc/platforms/86xx/Kconfig 610source arch/powerpc/platforms/86xx/Kconfig
@@ -1058,6 +1069,8 @@ source "fs/Kconfig"
1058 1069
1059# XXX source "arch/ppc/8260_io/Kconfig" 1070# XXX source "arch/ppc/8260_io/Kconfig"
1060 1071
1072source "arch/powerpc/sysdev/qe_lib/Kconfig"
1073
1061source "arch/powerpc/platforms/iseries/Kconfig" 1074source "arch/powerpc/platforms/iseries/Kconfig"
1062 1075
1063source "lib/Kconfig" 1076source "lib/Kconfig"
diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts
new file mode 100644
index 000000000000..34efdd028c4f
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8272ads.dts
@@ -0,0 +1,223 @@
1/*
2 * MPC8272 ADS Device Tree Source
3 *
4 * Copyright 2005 Freescale Semiconductor Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12/ {
13 model = "MPC8272ADS";
14 compatible = "MPC8260ADS";
15 #address-cells = <1>;
16 #size-cells = <1>;
17 linux,phandle = <100>;
18
19 cpus {
20 #cpus = <1>;
21 #address-cells = <1>;
22 #size-cells = <0>;
23 linux,phandle = <200>;
24
25 PowerPC,8272@0 {
26 device_type = "cpu";
27 reg = <0>;
28 d-cache-line-size = <20>; // 32 bytes
29 i-cache-line-size = <20>; // 32 bytes
30 d-cache-size = <4000>; // L1, 16K
31 i-cache-size = <4000>; // L1, 16K
32 timebase-frequency = <0>;
33 bus-frequency = <0>;
34 clock-frequency = <0>;
35 32-bit;
36 linux,phandle = <201>;
37 linux,boot-cpu;
38 };
39 };
40
41 interrupt-controller@f8200000 {
42 linux,phandle = <f8200000>;
43 #address-cells = <0>;
44 #interrupt-cells = <2>;
45 interrupt-controller;
46 reg = <f8200000 f8200004>;
47 built-in;
48 device_type = "pci-pic";
49 };
50 memory {
51 device_type = "memory";
52 linux,phandle = <300>;
53 reg = <00000000 4000000 f4500000 00000020>;
54 };
55
56 soc8272@f0000000 {
57 #address-cells = <1>;
58 #size-cells = <1>;
59 #interrupt-cells = <2>;
60 device_type = "soc";
61 ranges = < 0 0 2 00000000 f0000000 00053000>;
62 reg = <f0000000 0>;
63
64 mdio@0 {
65 device_type = "mdio";
66 compatible = "fs_enet";
67 reg = <0 0>;
68 linux,phandle = <24520>;
69 #address-cells = <1>;
70 #size-cells = <0>;
71 ethernet-phy@0 {
72 linux,phandle = <2452000>;
73 interrupt-parent = <10c00>;
74 interrupts = <19 1>;
75 reg = <0>;
76 bitbang = [ 12 12 13 02 02 01 ];
77 device_type = "ethernet-phy";
78 };
79 ethernet-phy@1 {
80 linux,phandle = <2452001>;
81 interrupt-parent = <10c00>;
82 interrupts = <19 1>;
83 bitbang = [ 12 12 13 02 02 01 ];
84 reg = <3>;
85 device_type = "ethernet-phy";
86 };
87 };
88
89 ethernet@24000 {
90 #address-cells = <1>;
91 #size-cells = <0>;
92 device_type = "network";
93 device-id = <2>;
94 compatible = "fs_enet";
95 model = "FCC";
96 reg = <11300 20 8400 100 11380 30>;
97 mac-address = [ 00 11 2F 99 43 54 ];
98 interrupts = <20 2>;
99 interrupt-parent = <10c00>;
100 phy-handle = <2452000>;
101 rx-clock = <13>;
102 tx-clock = <12>;
103 };
104
105 ethernet@25000 {
106 device_type = "network";
107 device-id = <3>;
108 compatible = "fs_enet";
109 model = "FCC";
110 reg = <11320 20 8500 100 113b0 30>;
111 mac-address = [ 00 11 2F 99 44 54 ];
112 interrupts = <21 2>;
113 interrupt-parent = <10c00>;
114 phy-handle = <2452001>;
115 rx-clock = <17>;
116 tx-clock = <18>;
117 };
118
119 cpm@f0000000 {
120 linux,phandle = <f0000000>;
121 #address-cells = <1>;
122 #size-cells = <1>;
123 #interrupt-cells = <2>;
124 device_type = "cpm";
125 model = "CPM2";
126 ranges = <00000000 00000000 3ffff>;
127 reg = <10d80 3280>;
128 command-proc = <119c0>;
129 brg-frequency = <17D7840>;
130 cpm_clk = <BEBC200>;
131
132 scc@11a00 {
133 device_type = "serial";
134 compatible = "cpm_uart";
135 model = "SCC";
136 device-id = <2>;
137 reg = <11a00 20 8000 100>;
138 current-speed = <1c200>;
139 interrupts = <28 2>;
140 interrupt-parent = <10c00>;
141 clock-setup = <0 00ffffff>;
142 rx-clock = <1>;
143 tx-clock = <1>;
144 };
145
146 scc@11a60 {
147 device_type = "serial";
148 compatible = "cpm_uart";
149 model = "SCC";
150 device-id = <5>;
151 reg = <11a60 20 8300 100>;
152 current-speed = <1c200>;
153 interrupts = <2b 2>;
154 interrupt-parent = <10c00>;
155 clock-setup = <1b ffffff00>;
156 rx-clock = <4>;
157 tx-clock = <4>;
158 };
159
160 };
161 interrupt-controller@10c00 {
162 linux,phandle = <10c00>;
163 #address-cells = <0>;
164 #interrupt-cells = <2>;
165 interrupt-controller;
166 reg = <10c00 80>;
167 built-in;
168 device_type = "cpm-pic";
169 compatible = "CPM2";
170 };
171 pci@0500 {
172 linux,phandle = <0500>;
173 #interrupt-cells = <1>;
174 #size-cells = <2>;
175 #address-cells = <3>;
176 compatible = "8272";
177 device_type = "pci";
178 reg = <10430 4dc>;
179 clock-frequency = <3f940aa>;
180 interrupt-map-mask = <f800 0 0 7>;
181 interrupt-map = <
182
183 /* IDSEL 0x16 */
184 b000 0 0 1 f8200000 40 0
185 b000 0 0 2 f8200000 41 0
186 b000 0 0 3 f8200000 42 0
187 b000 0 0 4 f8200000 43 0
188
189 /* IDSEL 0x17 */
190 b800 0 0 1 f8200000 43 0
191 b800 0 0 2 f8200000 40 0
192 b800 0 0 3 f8200000 41 0
193 b800 0 0 4 f8200000 42 0
194
195 /* IDSEL 0x18 */
196 c000 0 0 1 f8200000 42 0
197 c000 0 0 2 f8200000 43 0
198 c000 0 0 3 f8200000 40 0
199 c000 0 0 4 f8200000 41 0>;
200 interrupt-parent = <10c00>;
201 interrupts = <14 3>;
202 bus-range = <0 0>;
203 ranges = <02000000 0 80000000 80000000 0 40000000
204 01000000 0 00000000 f6000000 0 02000000>;
205 };
206
207/* May need to remove if on a part without crypto engine */
208 crypto@30000 {
209 device_type = "crypto";
210 model = "SEC2";
211 compatible = "talitos";
212 reg = <30000 10000>;
213 interrupts = <b 0>;
214 interrupt-parent = <10c00>;
215 num-channels = <4>;
216 channel-fifo-len = <18>;
217 exec-units-mask = <0000007e>;
218/* desc mask is for rev1.x, we need runtime fixup for >=2.x */
219 descriptor-types-mask = <01010ebf>;
220 };
221
222 };
223};
diff --git a/arch/powerpc/boot/dts/mpc8360emds.dts b/arch/powerpc/boot/dts/mpc8360emds.dts
new file mode 100644
index 000000000000..9022192155b9
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8360emds.dts
@@ -0,0 +1,375 @@
1/*
2 * MPC8360E EMDS Device Tree Source
3 *
4 * Copyright 2006 Freescale Semiconductor Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12
13/*
14/memreserve/ 00000000 1000000;
15*/
16
17/ {
18 model = "MPC8360EPB";
19 compatible = "MPC83xx";
20 #address-cells = <1>;
21 #size-cells = <1>;
22 linux,phandle = <100>;
23
24 cpus {
25 #cpus = <1>;
26 #address-cells = <1>;
27 #size-cells = <0>;
28 linux,phandle = <200>;
29
30 PowerPC,8360@0 {
31 device_type = "cpu";
32 reg = <0>;
33 d-cache-line-size = <20>; // 32 bytes
34 i-cache-line-size = <20>; // 32 bytes
35 d-cache-size = <8000>; // L1, 32K
36 i-cache-size = <8000>; // L1, 32K
37 timebase-frequency = <3EF1480>;
38 bus-frequency = <FBC5200>;
39 clock-frequency = <1F78A400>;
40 32-bit;
41 linux,phandle = <201>;
42 linux,boot-cpu;
43 };
44 };
45
46 memory {
47 device_type = "memory";
48 linux,phandle = <300>;
49 reg = <00000000 10000000>;
50 };
51
52 bcsr@f8000000 {
53 device_type = "board-control";
54 reg = <f8000000 8000>;
55 };
56
57 soc8360@e0000000 {
58 #address-cells = <1>;
59 #size-cells = <1>;
60 #interrupt-cells = <2>;
61 device_type = "soc";
62 ranges = <0 e0000000 00100000>;
63 reg = <e0000000 00000200>;
64 bus-frequency = <FBC5200>;
65
66 wdt@200 {
67 device_type = "watchdog";
68 compatible = "mpc83xx_wdt";
69 reg = <200 100>;
70 };
71
72 i2c@3000 {
73 device_type = "i2c";
74 compatible = "fsl-i2c";
75 reg = <3000 100>;
76 interrupts = <e 8>;
77 interrupt-parent = <700>;
78 dfsrr;
79 };
80
81 i2c@3100 {
82 device_type = "i2c";
83 compatible = "fsl-i2c";
84 reg = <3100 100>;
85 interrupts = <f 8>;
86 interrupt-parent = <700>;
87 dfsrr;
88 };
89
90 serial@4500 {
91 device_type = "serial";
92 compatible = "ns16550";
93 reg = <4500 100>;
94 clock-frequency = <FBC5200>;
95 interrupts = <9 8>;
96 interrupt-parent = <700>;
97 };
98
99 serial@4600 {
100 device_type = "serial";
101 compatible = "ns16550";
102 reg = <4600 100>;
103 clock-frequency = <FBC5200>;
104 interrupts = <a 8>;
105 interrupt-parent = <700>;
106 };
107
108 crypto@30000 {
109 device_type = "crypto";
110 model = "SEC2";
111 compatible = "talitos";
112 reg = <30000 10000>;
113 interrupts = <b 8>;
114 interrupt-parent = <700>;
115 num-channels = <4>;
116 channel-fifo-len = <18>;
117 exec-units-mask = <0000007e>;
118 /* desc mask is for rev1.x, we need runtime fixup for >=2.x */
119 descriptor-types-mask = <01010ebf>;
120 };
121
122 pci@8500 {
123 linux,phandle = <8500>;
124 interrupt-map-mask = <f800 0 0 7>;
125 interrupt-map = <
126
127 /* IDSEL 0x11 AD17 */
128 8800 0 0 1 700 14 8
129 8800 0 0 2 700 15 8
130 8800 0 0 3 700 16 8
131 8800 0 0 4 700 17 8
132
133 /* IDSEL 0x12 AD18 */
134 9000 0 0 1 700 16 8
135 9000 0 0 2 700 17 8
136 9000 0 0 3 700 14 8
137 9000 0 0 4 700 15 8
138
139 /* IDSEL 0x13 AD19 */
140 9800 0 0 1 700 17 8
141 9800 0 0 2 700 14 8
142 9800 0 0 3 700 15 8
143 9800 0 0 4 700 16 8
144
145 /* IDSEL 0x15 AD21*/
146 a800 0 0 1 700 14 8
147 a800 0 0 2 700 15 8
148 a800 0 0 3 700 16 8
149 a800 0 0 4 700 17 8
150
151 /* IDSEL 0x16 AD22*/
152 b000 0 0 1 700 17 8
153 b000 0 0 2 700 14 8
154 b000 0 0 3 700 15 8
155 b000 0 0 4 700 16 8
156
157 /* IDSEL 0x17 AD23*/
158 b800 0 0 1 700 16 8
159 b800 0 0 2 700 17 8
160 b800 0 0 3 700 14 8
161 b800 0 0 4 700 15 8
162
163 /* IDSEL 0x18 AD24*/
164 c000 0 0 1 700 15 8
165 c000 0 0 2 700 16 8
166 c000 0 0 3 700 17 8
167 c000 0 0 4 700 14 8>;
168 interrupt-parent = <700>;
169 interrupts = <42 8>;
170 bus-range = <0 0>;
171 ranges = <02000000 0 a0000000 a0000000 0 10000000
172 42000000 0 80000000 80000000 0 10000000
173 01000000 0 00000000 e2000000 0 00100000>;
174 clock-frequency = <3f940aa>;
175 #interrupt-cells = <1>;
176 #size-cells = <2>;
177 #address-cells = <3>;
178 reg = <8500 100>;
179 compatible = "83xx";
180 device_type = "pci";
181 };
182
183 pic@700 {
184 linux,phandle = <700>;
185 interrupt-controller;
186 #address-cells = <0>;
187 #interrupt-cells = <2>;
188 reg = <700 100>;
189 built-in;
190 device_type = "ipic";
191 };
192
193 par_io@1400 {
194 reg = <1400 100>;
195 device_type = "par_io";
196 num-ports = <7>;
197
198 ucc_pin@01 {
199 linux,phandle = <140001>;
200 pio-map = <
201 /* port pin dir open_drain assignment has_irq */
202 0 3 1 0 1 0 /* TxD0 */
203 0 4 1 0 1 0 /* TxD1 */
204 0 5 1 0 1 0 /* TxD2 */
205 0 6 1 0 1 0 /* TxD3 */
206 1 6 1 0 3 0 /* TxD4 */
207 1 7 1 0 1 0 /* TxD5 */
208 1 9 1 0 2 0 /* TxD6 */
209 1 a 1 0 2 0 /* TxD7 */
210 0 9 2 0 1 0 /* RxD0 */
211 0 a 2 0 1 0 /* RxD1 */
212 0 b 2 0 1 0 /* RxD2 */
213 0 c 2 0 1 0 /* RxD3 */
214 0 d 2 0 1 0 /* RxD4 */
215 1 1 2 0 2 0 /* RxD5 */
216 1 0 2 0 2 0 /* RxD6 */
217 1 4 2 0 2 0 /* RxD7 */
218 0 7 1 0 1 0 /* TX_EN */
219 0 8 1 0 1 0 /* TX_ER */
220 0 f 2 0 1 0 /* RX_DV */
221 0 10 2 0 1 0 /* RX_ER */
222 0 0 2 0 1 0 /* RX_CLK */
223 2 9 1 0 3 0 /* GTX_CLK - CLK10 */
224 2 8 2 0 1 0>; /* GTX125 - CLK9 */
225 };
226 ucc_pin@02 {
227 linux,phandle = <140002>;
228 pio-map = <
229 /* port pin dir open_drain assignment has_irq */
230 0 11 1 0 1 0 /* TxD0 */
231 0 12 1 0 1 0 /* TxD1 */
232 0 13 1 0 1 0 /* TxD2 */
233 0 14 1 0 1 0 /* TxD3 */
234 1 2 1 0 1 0 /* TxD4 */
235 1 3 1 0 2 0 /* TxD5 */
236 1 5 1 0 3 0 /* TxD6 */
237 1 8 1 0 3 0 /* TxD7 */
238 0 17 2 0 1 0 /* RxD0 */
239 0 18 2 0 1 0 /* RxD1 */
240 0 19 2 0 1 0 /* RxD2 */
241 0 1a 2 0 1 0 /* RxD3 */
242 0 1b 2 0 1 0 /* RxD4 */
243 1 c 2 0 2 0 /* RxD5 */
244 1 d 2 0 3 0 /* RxD6 */
245 1 b 2 0 2 0 /* RxD7 */
246 0 15 1 0 1 0 /* TX_EN */
247 0 16 1 0 1 0 /* TX_ER */
248 0 1d 2 0 1 0 /* RX_DV */
249 0 1e 2 0 1 0 /* RX_ER */
250 0 1f 2 0 1 0 /* RX_CLK */
251 2 2 1 0 2 0 /* GTX_CLK - CLK10 */
252 2 3 2 0 1 0 /* GTX125 - CLK4 */
253 0 1 3 0 2 0 /* MDIO */
254 0 2 1 0 1 0>; /* MDC */
255 };
256
257 };
258 };
259
260 qe@e0100000 {
261 #address-cells = <1>;
262 #size-cells = <1>;
263 device_type = "qe";
264 model = "QE";
265 ranges = <0 e0100000 00100000>;
266 reg = <e0100000 480>;
267 brg-frequency = <0>;
268 bus-frequency = <179A7B00>;
269
270 muram@10000 {
271 device_type = "muram";
272 ranges = <0 00010000 0000c000>;
273
274 data-only@0{
275 reg = <0 c000>;
276 };
277 };
278
279 spi@4c0 {
280 device_type = "spi";
281 compatible = "fsl_spi";
282 reg = <4c0 40>;
283 interrupts = <2>;
284 interrupt-parent = <80>;
285 mode = "cpu";
286 };
287
288 spi@500 {
289 device_type = "spi";
290 compatible = "fsl_spi";
291 reg = <500 40>;
292 interrupts = <1>;
293 interrupt-parent = <80>;
294 mode = "cpu";
295 };
296
297 usb@6c0 {
298 device_type = "usb";
299 compatible = "qe_udc";
300 reg = <6c0 40 8B00 100>;
301 interrupts = <b>;
302 interrupt-parent = <80>;
303 mode = "slave";
304 };
305
306 ucc@2000 {
307 device_type = "network";
308 compatible = "ucc_geth";
309 model = "UCC";
310 device-id = <1>;
311 reg = <2000 200>;
312 interrupts = <20>;
313 interrupt-parent = <80>;
314 mac-address = [ 00 04 9f 00 23 23 ];
315 rx-clock = <0>;
316 tx-clock = <19>;
317 phy-handle = <212000>;
318 pio-handle = <140001>;
319 };
320
321 ucc@3000 {
322 device_type = "network";
323 compatible = "ucc_geth";
324 model = "UCC";
325 device-id = <2>;
326 reg = <3000 200>;
327 interrupts = <21>;
328 interrupt-parent = <80>;
329 mac-address = [ 00 11 22 33 44 55 ];
330 rx-clock = <0>;
331 tx-clock = <14>;
332 phy-handle = <212001>;
333 pio-handle = <140002>;
334 };
335
336 mdio@2120 {
337 #address-cells = <1>;
338 #size-cells = <0>;
339 reg = <2120 18>;
340 device_type = "mdio";
341 compatible = "ucc_geth_phy";
342
343 ethernet-phy@00 {
344 linux,phandle = <212000>;
345 interrupt-parent = <700>;
346 interrupts = <11 2>;
347 reg = <0>;
348 device_type = "ethernet-phy";
349 interface = <6>; //ENET_1000_GMII
350 };
351 ethernet-phy@01 {
352 linux,phandle = <212001>;
353 interrupt-parent = <700>;
354 interrupts = <12 2>;
355 reg = <1>;
356 device_type = "ethernet-phy";
357 interface = <6>;
358 };
359 };
360
361 qeic@80 {
362 linux,phandle = <80>;
363 interrupt-controller;
364 device_type = "qeic";
365 #address-cells = <0>;
366 #interrupt-cells = <1>;
367 reg = <80 80>;
368 built-in;
369 big-endian;
370 interrupts = <20 8 21 8>; //high:32 low:33
371 interrupt-parent = <700>;
372 };
373
374 };
375};
diff --git a/arch/powerpc/boot/zImage.coff.lds.S b/arch/powerpc/boot/zImage.coff.lds.S
index 6016251a1a2c..05f32388b953 100644
--- a/arch/powerpc/boot/zImage.coff.lds.S
+++ b/arch/powerpc/boot/zImage.coff.lds.S
@@ -15,6 +15,7 @@ SECTIONS
15 { 15 {
16 *(.rodata*) 16 *(.rodata*)
17 *(.data*) 17 *(.data*)
18 *(__builtin_*)
18 *(.sdata*) 19 *(.sdata*)
19 __got2_start = .; 20 __got2_start = .;
20 *(.got2) 21 *(.got2)
diff --git a/arch/powerpc/configs/mpc8360emds_defconfig b/arch/powerpc/configs/mpc8360emds_defconfig
new file mode 100644
index 000000000000..c0703415d608
--- /dev/null
+++ b/arch/powerpc/configs/mpc8360emds_defconfig
@@ -0,0 +1,1018 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.18
4# Thu Sep 21 18:14:27 2006
5#
6# CONFIG_PPC64 is not set
7CONFIG_PPC32=y
8CONFIG_PPC_MERGE=y
9CONFIG_MMU=y
10CONFIG_GENERIC_HARDIRQS=y
11CONFIG_IRQ_PER_CPU=y
12CONFIG_RWSEM_XCHGADD_ALGORITHM=y
13CONFIG_GENERIC_HWEIGHT=y
14CONFIG_GENERIC_CALIBRATE_DELAY=y
15CONFIG_GENERIC_FIND_NEXT_BIT=y
16CONFIG_PPC=y
17CONFIG_EARLY_PRINTK=y
18CONFIG_GENERIC_NVRAM=y
19CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
20CONFIG_ARCH_MAY_HAVE_PC_FDC=y
21CONFIG_PPC_OF=y
22CONFIG_PPC_UDBG_16550=y
23# CONFIG_GENERIC_TBSYNC is not set
24CONFIG_AUDIT_ARCH=y
25CONFIG_DEFAULT_UIMAGE=y
26
27#
28# Processor support
29#
30# CONFIG_CLASSIC32 is not set
31# CONFIG_PPC_52xx is not set
32# CONFIG_PPC_82xx is not set
33CONFIG_PPC_83xx=y
34# CONFIG_PPC_85xx is not set
35# CONFIG_PPC_86xx is not set
36# CONFIG_40x is not set
37# CONFIG_44x is not set
38# CONFIG_8xx is not set
39# CONFIG_E200 is not set
40CONFIG_6xx=y
41CONFIG_83xx=y
42CONFIG_PPC_FPU=y
43CONFIG_PPC_STD_MMU=y
44CONFIG_PPC_STD_MMU_32=y
45# CONFIG_SMP is not set
46CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
47
48#
49# Code maturity level options
50#
51CONFIG_EXPERIMENTAL=y
52CONFIG_BROKEN_ON_SMP=y
53CONFIG_INIT_ENV_ARG_LIMIT=32
54
55#
56# General setup
57#
58CONFIG_LOCALVERSION=""
59CONFIG_LOCALVERSION_AUTO=y
60CONFIG_SWAP=y
61CONFIG_SYSVIPC=y
62# CONFIG_POSIX_MQUEUE is not set
63# CONFIG_BSD_PROCESS_ACCT is not set
64# CONFIG_TASKSTATS is not set
65# CONFIG_AUDIT is not set
66# CONFIG_IKCONFIG is not set
67# CONFIG_RELAY is not set
68CONFIG_INITRAMFS_SOURCE=""
69# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
70CONFIG_EMBEDDED=y
71CONFIG_SYSCTL=y
72# CONFIG_KALLSYMS is not set
73CONFIG_HOTPLUG=y
74CONFIG_PRINTK=y
75CONFIG_BUG=y
76CONFIG_ELF_CORE=y
77CONFIG_BASE_FULL=y
78CONFIG_FUTEX=y
79# CONFIG_EPOLL is not set
80CONFIG_SHMEM=y
81CONFIG_SLAB=y
82CONFIG_VM_EVENT_COUNTERS=y
83CONFIG_RT_MUTEXES=y
84# CONFIG_TINY_SHMEM is not set
85CONFIG_BASE_SMALL=0
86# CONFIG_SLOB is not set
87
88#
89# Loadable module support
90#
91CONFIG_MODULES=y
92CONFIG_MODULE_UNLOAD=y
93# CONFIG_MODULE_FORCE_UNLOAD is not set
94# CONFIG_MODVERSIONS is not set
95# CONFIG_MODULE_SRCVERSION_ALL is not set
96# CONFIG_KMOD is not set
97
98#
99# Block layer
100#
101# CONFIG_LBD is not set
102# CONFIG_BLK_DEV_IO_TRACE is not set
103# CONFIG_LSF is not set
104
105#
106# IO Schedulers
107#
108CONFIG_IOSCHED_NOOP=y
109CONFIG_IOSCHED_AS=y
110CONFIG_IOSCHED_DEADLINE=y
111CONFIG_IOSCHED_CFQ=y
112CONFIG_DEFAULT_AS=y
113# CONFIG_DEFAULT_DEADLINE is not set
114# CONFIG_DEFAULT_CFQ is not set
115# CONFIG_DEFAULT_NOOP is not set
116CONFIG_DEFAULT_IOSCHED="anticipatory"
117CONFIG_QUICC_ENGINE=y
118CONFIG_PPC_GEN550=y
119# CONFIG_WANT_EARLY_SERIAL is not set
120
121#
122# Platform support
123#
124# CONFIG_MPC834x_SYS is not set
125# CONFIG_MPC834x_ITX is not set
126CONFIG_MPC8360E_PB=y
127CONFIG_PPC_MPC836x=y
128# CONFIG_MPIC is not set
129
130#
131# Kernel options
132#
133# CONFIG_HIGHMEM is not set
134# CONFIG_HZ_100 is not set
135CONFIG_HZ_250=y
136# CONFIG_HZ_1000 is not set
137CONFIG_HZ=250
138CONFIG_PREEMPT_NONE=y
139# CONFIG_PREEMPT_VOLUNTARY is not set
140# CONFIG_PREEMPT is not set
141CONFIG_BINFMT_ELF=y
142# CONFIG_BINFMT_MISC is not set
143CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
144CONFIG_ARCH_FLATMEM_ENABLE=y
145CONFIG_SELECT_MEMORY_MODEL=y
146CONFIG_FLATMEM_MANUAL=y
147# CONFIG_DISCONTIGMEM_MANUAL is not set
148# CONFIG_SPARSEMEM_MANUAL is not set
149CONFIG_FLATMEM=y
150CONFIG_FLAT_NODE_MEM_MAP=y
151# CONFIG_SPARSEMEM_STATIC is not set
152CONFIG_SPLIT_PTLOCK_CPUS=4
153# CONFIG_RESOURCES_64BIT is not set
154CONFIG_PROC_DEVICETREE=y
155# CONFIG_CMDLINE_BOOL is not set
156# CONFIG_PM is not set
157CONFIG_SECCOMP=y
158CONFIG_ISA_DMA_API=y
159
160#
161# Bus options
162#
163CONFIG_GENERIC_ISA_DMA=y
164# CONFIG_MPIC_WEIRD is not set
165# CONFIG_PPC_I8259 is not set
166CONFIG_PPC_INDIRECT_PCI=y
167CONFIG_FSL_SOC=y
168CONFIG_PCI=y
169CONFIG_PCI_DOMAINS=y
170# CONFIG_PCIEPORTBUS is not set
171
172#
173# PCCARD (PCMCIA/CardBus) support
174#
175# CONFIG_PCCARD is not set
176
177#
178# PCI Hotplug Support
179#
180# CONFIG_HOTPLUG_PCI is not set
181
182#
183# Advanced setup
184#
185# CONFIG_ADVANCED_OPTIONS is not set
186
187#
188# Default settings for advanced configuration options are used
189#
190CONFIG_HIGHMEM_START=0xfe000000
191CONFIG_LOWMEM_SIZE=0x30000000
192CONFIG_KERNEL_START=0xc0000000
193CONFIG_TASK_SIZE=0x80000000
194CONFIG_BOOT_LOAD=0x00800000
195
196#
197# Networking
198#
199CONFIG_NET=y
200
201#
202# Networking options
203#
204# CONFIG_NETDEBUG is not set
205CONFIG_PACKET=y
206# CONFIG_PACKET_MMAP is not set
207CONFIG_UNIX=y
208CONFIG_XFRM=y
209# CONFIG_XFRM_USER is not set
210# CONFIG_NET_KEY is not set
211CONFIG_INET=y
212CONFIG_IP_MULTICAST=y
213# CONFIG_IP_ADVANCED_ROUTER is not set
214CONFIG_IP_FIB_HASH=y
215CONFIG_IP_PNP=y
216CONFIG_IP_PNP_DHCP=y
217CONFIG_IP_PNP_BOOTP=y
218# CONFIG_IP_PNP_RARP is not set
219# CONFIG_NET_IPIP is not set
220# CONFIG_NET_IPGRE is not set
221# CONFIG_IP_MROUTE is not set
222# CONFIG_ARPD is not set
223CONFIG_SYN_COOKIES=y
224# CONFIG_INET_AH is not set
225# CONFIG_INET_ESP is not set
226# CONFIG_INET_IPCOMP is not set
227# CONFIG_INET_XFRM_TUNNEL is not set
228# CONFIG_INET_TUNNEL is not set
229CONFIG_INET_XFRM_MODE_TRANSPORT=y
230CONFIG_INET_XFRM_MODE_TUNNEL=y
231CONFIG_INET_DIAG=y
232CONFIG_INET_TCP_DIAG=y
233# CONFIG_TCP_CONG_ADVANCED is not set
234CONFIG_TCP_CONG_BIC=y
235# CONFIG_IPV6 is not set
236# CONFIG_INET6_XFRM_TUNNEL is not set
237# CONFIG_INET6_TUNNEL is not set
238# CONFIG_NETWORK_SECMARK is not set
239# CONFIG_NETFILTER is not set
240
241#
242# DCCP Configuration (EXPERIMENTAL)
243#
244# CONFIG_IP_DCCP is not set
245
246#
247# SCTP Configuration (EXPERIMENTAL)
248#
249# CONFIG_IP_SCTP is not set
250
251#
252# TIPC Configuration (EXPERIMENTAL)
253#
254# CONFIG_TIPC is not set
255# CONFIG_ATM is not set
256# CONFIG_BRIDGE is not set
257# CONFIG_VLAN_8021Q is not set
258# CONFIG_DECNET is not set
259# CONFIG_LLC2 is not set
260# CONFIG_IPX is not set
261# CONFIG_ATALK is not set
262# CONFIG_X25 is not set
263# CONFIG_LAPB is not set
264# CONFIG_ECONET is not set
265# CONFIG_WAN_ROUTER is not set
266
267#
268# QoS and/or fair queueing
269#
270# CONFIG_NET_SCHED is not set
271
272#
273# Network testing
274#
275# CONFIG_NET_PKTGEN is not set
276# CONFIG_HAMRADIO is not set
277# CONFIG_IRDA is not set
278# CONFIG_BT is not set
279# CONFIG_IEEE80211 is not set
280
281#
282# Device Drivers
283#
284
285#
286# Generic Driver Options
287#
288CONFIG_STANDALONE=y
289CONFIG_PREVENT_FIRMWARE_BUILD=y
290# CONFIG_FW_LOADER is not set
291# CONFIG_SYS_HYPERVISOR is not set
292
293#
294# Connector - unified userspace <-> kernelspace linker
295#
296# CONFIG_CONNECTOR is not set
297
298#
299# Memory Technology Devices (MTD)
300#
301# CONFIG_MTD is not set
302
303#
304# Parallel port support
305#
306# CONFIG_PARPORT is not set
307
308#
309# Plug and Play support
310#
311
312#
313# Block devices
314#
315# CONFIG_BLK_DEV_FD is not set
316# CONFIG_BLK_CPQ_DA is not set
317# CONFIG_BLK_CPQ_CISS_DA is not set
318# CONFIG_BLK_DEV_DAC960 is not set
319# CONFIG_BLK_DEV_UMEM is not set
320# CONFIG_BLK_DEV_COW_COMMON is not set
321CONFIG_BLK_DEV_LOOP=y
322# CONFIG_BLK_DEV_CRYPTOLOOP is not set
323# CONFIG_BLK_DEV_NBD is not set
324# CONFIG_BLK_DEV_SX8 is not set
325CONFIG_BLK_DEV_RAM=y
326CONFIG_BLK_DEV_RAM_COUNT=16
327CONFIG_BLK_DEV_RAM_SIZE=32768
328CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
329CONFIG_BLK_DEV_INITRD=y
330# CONFIG_CDROM_PKTCDVD is not set
331# CONFIG_ATA_OVER_ETH is not set
332
333#
334# ATA/ATAPI/MFM/RLL support
335#
336# CONFIG_IDE is not set
337
338#
339# SCSI device support
340#
341# CONFIG_RAID_ATTRS is not set
342CONFIG_SCSI=y
343CONFIG_SCSI_PROC_FS=y
344
345#
346# SCSI support type (disk, tape, CD-ROM)
347#
348# CONFIG_BLK_DEV_SD is not set
349# CONFIG_CHR_DEV_ST is not set
350# CONFIG_CHR_DEV_OSST is not set
351# CONFIG_BLK_DEV_SR is not set
352# CONFIG_CHR_DEV_SG is not set
353# CONFIG_CHR_DEV_SCH is not set
354
355#
356# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
357#
358# CONFIG_SCSI_MULTI_LUN is not set
359# CONFIG_SCSI_CONSTANTS is not set
360# CONFIG_SCSI_LOGGING is not set
361
362#
363# SCSI Transport Attributes
364#
365# CONFIG_SCSI_SPI_ATTRS is not set
366# CONFIG_SCSI_FC_ATTRS is not set
367# CONFIG_SCSI_ISCSI_ATTRS is not set
368# CONFIG_SCSI_SAS_ATTRS is not set
369
370#
371# SCSI low-level drivers
372#
373# CONFIG_ISCSI_TCP is not set
374# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
375# CONFIG_SCSI_3W_9XXX is not set
376# CONFIG_SCSI_ACARD is not set
377# CONFIG_SCSI_AACRAID is not set
378# CONFIG_SCSI_AIC7XXX is not set
379# CONFIG_SCSI_AIC7XXX_OLD is not set
380# CONFIG_SCSI_AIC79XX is not set
381# CONFIG_SCSI_DPT_I2O is not set
382# CONFIG_MEGARAID_NEWGEN is not set
383# CONFIG_MEGARAID_LEGACY is not set
384# CONFIG_MEGARAID_SAS is not set
385# CONFIG_SCSI_SATA is not set
386# CONFIG_SCSI_HPTIOP is not set
387# CONFIG_SCSI_BUSLOGIC is not set
388# CONFIG_SCSI_DMX3191D is not set
389# CONFIG_SCSI_EATA is not set
390# CONFIG_SCSI_FUTURE_DOMAIN is not set
391# CONFIG_SCSI_GDTH is not set
392# CONFIG_SCSI_IPS is not set
393# CONFIG_SCSI_INITIO is not set
394# CONFIG_SCSI_INIA100 is not set
395# CONFIG_SCSI_SYM53C8XX_2 is not set
396# CONFIG_SCSI_IPR is not set
397# CONFIG_SCSI_QLOGIC_1280 is not set
398# CONFIG_SCSI_QLA_FC is not set
399# CONFIG_SCSI_LPFC is not set
400# CONFIG_SCSI_DC395x is not set
401# CONFIG_SCSI_DC390T is not set
402# CONFIG_SCSI_NSP32 is not set
403# CONFIG_SCSI_DEBUG is not set
404
405#
406# Multi-device support (RAID and LVM)
407#
408# CONFIG_MD is not set
409
410#
411# Fusion MPT device support
412#
413# CONFIG_FUSION is not set
414# CONFIG_FUSION_SPI is not set
415# CONFIG_FUSION_FC is not set
416# CONFIG_FUSION_SAS is not set
417
418#
419# IEEE 1394 (FireWire) support
420#
421# CONFIG_IEEE1394 is not set
422
423#
424# I2O device support
425#
426# CONFIG_I2O is not set
427
428#
429# Macintosh device drivers
430#
431# CONFIG_WINDFARM is not set
432
433#
434# Network device support
435#
436CONFIG_NETDEVICES=y
437# CONFIG_DUMMY is not set
438# CONFIG_BONDING is not set
439# CONFIG_EQUALIZER is not set
440# CONFIG_TUN is not set
441
442#
443# ARCnet devices
444#
445# CONFIG_ARCNET is not set
446
447#
448# PHY device support
449#
450# CONFIG_PHYLIB is not set
451
452#
453# Ethernet (10 or 100Mbit)
454#
455CONFIG_NET_ETHERNET=y
456CONFIG_MII=y
457# CONFIG_HAPPYMEAL is not set
458# CONFIG_SUNGEM is not set
459# CONFIG_CASSINI is not set
460# CONFIG_NET_VENDOR_3COM is not set
461
462#
463# Tulip family network device support
464#
465# CONFIG_NET_TULIP is not set
466# CONFIG_HP100 is not set
467# CONFIG_NET_PCI is not set
468
469#
470# Ethernet (1000 Mbit)
471#
472# CONFIG_ACENIC is not set
473# CONFIG_DL2K is not set
474# CONFIG_E1000 is not set
475# CONFIG_NS83820 is not set
476# CONFIG_HAMACHI is not set
477# CONFIG_YELLOWFIN is not set
478# CONFIG_R8169 is not set
479# CONFIG_SIS190 is not set
480# CONFIG_SKGE is not set
481# CONFIG_SKY2 is not set
482# CONFIG_SK98LIN is not set
483# CONFIG_TIGON3 is not set
484# CONFIG_BNX2 is not set
485# CONFIG_GIANFAR is not set
486CONFIG_UCC_GETH=y
487# CONFIG_UGETH_NAPI is not set
488# CONFIG_UGETH_MAGIC_PACKET is not set
489# CONFIG_UGETH_FILTERING is not set
490# CONFIG_UGETH_TX_ON_DEMOND is not set
491
492#
493# Ethernet (10000 Mbit)
494#
495# CONFIG_CHELSIO_T1 is not set
496# CONFIG_IXGB is not set
497# CONFIG_S2IO is not set
498# CONFIG_MYRI10GE is not set
499
500#
501# Token Ring devices
502#
503# CONFIG_TR is not set
504
505#
506# Wireless LAN (non-hamradio)
507#
508# CONFIG_NET_RADIO is not set
509
510#
511# Wan interfaces
512#
513# CONFIG_WAN is not set
514# CONFIG_FDDI is not set
515# CONFIG_HIPPI is not set
516# CONFIG_PPP is not set
517# CONFIG_SLIP is not set
518# CONFIG_NET_FC is not set
519# CONFIG_SHAPER is not set
520# CONFIG_NETCONSOLE is not set
521# CONFIG_NETPOLL is not set
522# CONFIG_NET_POLL_CONTROLLER is not set
523
524#
525# ISDN subsystem
526#
527# CONFIG_ISDN is not set
528
529#
530# Telephony Support
531#
532# CONFIG_PHONE is not set
533
534#
535# Input device support
536#
537CONFIG_INPUT=y
538
539#
540# Userland interfaces
541#
542# CONFIG_INPUT_MOUSEDEV is not set
543# CONFIG_INPUT_JOYDEV is not set
544# CONFIG_INPUT_TSDEV is not set
545# CONFIG_INPUT_EVDEV is not set
546# CONFIG_INPUT_EVBUG is not set
547
548#
549# Input Device Drivers
550#
551# CONFIG_INPUT_KEYBOARD is not set
552# CONFIG_INPUT_MOUSE is not set
553# CONFIG_INPUT_JOYSTICK is not set
554# CONFIG_INPUT_TOUCHSCREEN is not set
555# CONFIG_INPUT_MISC is not set
556
557#
558# Hardware I/O ports
559#
560# CONFIG_SERIO is not set
561# CONFIG_GAMEPORT is not set
562
563#
564# Character devices
565#
566# CONFIG_VT is not set
567# CONFIG_SERIAL_NONSTANDARD is not set
568
569#
570# Serial drivers
571#
572CONFIG_SERIAL_8250=y
573CONFIG_SERIAL_8250_CONSOLE=y
574CONFIG_SERIAL_8250_PCI=y
575CONFIG_SERIAL_8250_NR_UARTS=4
576CONFIG_SERIAL_8250_RUNTIME_UARTS=4
577# CONFIG_SERIAL_8250_EXTENDED is not set
578
579#
580# Non-8250 serial port support
581#
582CONFIG_SERIAL_CORE=y
583CONFIG_SERIAL_CORE_CONSOLE=y
584# CONFIG_SERIAL_JSM is not set
585CONFIG_UNIX98_PTYS=y
586CONFIG_LEGACY_PTYS=y
587CONFIG_LEGACY_PTY_COUNT=256
588
589#
590# IPMI
591#
592# CONFIG_IPMI_HANDLER is not set
593
594#
595# Watchdog Cards
596#
597CONFIG_WATCHDOG=y
598# CONFIG_WATCHDOG_NOWAYOUT is not set
599
600#
601# Watchdog Device Drivers
602#
603# CONFIG_SOFT_WATCHDOG is not set
604CONFIG_83xx_WDT=y
605
606#
607# PCI-based Watchdog Cards
608#
609# CONFIG_PCIPCWATCHDOG is not set
610# CONFIG_WDTPCI is not set
611CONFIG_HW_RANDOM=y
612# CONFIG_NVRAM is not set
613CONFIG_GEN_RTC=y
614# CONFIG_GEN_RTC_X is not set
615# CONFIG_DTLK is not set
616# CONFIG_R3964 is not set
617# CONFIG_APPLICOM is not set
618
619#
620# Ftape, the floppy tape device driver
621#
622# CONFIG_AGP is not set
623# CONFIG_DRM is not set
624# CONFIG_RAW_DRIVER is not set
625
626#
627# TPM devices
628#
629# CONFIG_TCG_TPM is not set
630# CONFIG_TELCLOCK is not set
631
632#
633# I2C support
634#
635CONFIG_I2C=y
636CONFIG_I2C_CHARDEV=y
637
638#
639# I2C Algorithms
640#
641# CONFIG_I2C_ALGOBIT is not set
642# CONFIG_I2C_ALGOPCF is not set
643# CONFIG_I2C_ALGOPCA is not set
644
645#
646# I2C Hardware Bus support
647#
648# CONFIG_I2C_ALI1535 is not set
649# CONFIG_I2C_ALI1563 is not set
650# CONFIG_I2C_ALI15X3 is not set
651# CONFIG_I2C_AMD756 is not set
652# CONFIG_I2C_AMD8111 is not set
653# CONFIG_I2C_I801 is not set
654# CONFIG_I2C_I810 is not set
655# CONFIG_I2C_PIIX4 is not set
656CONFIG_I2C_MPC=y
657# CONFIG_I2C_NFORCE2 is not set
658# CONFIG_I2C_OCORES is not set
659# CONFIG_I2C_PARPORT_LIGHT is not set
660# CONFIG_I2C_PROSAVAGE is not set
661# CONFIG_I2C_SAVAGE4 is not set
662# CONFIG_I2C_SIS5595 is not set
663# CONFIG_I2C_SIS630 is not set
664# CONFIG_I2C_SIS96X is not set
665# CONFIG_I2C_STUB is not set
666# CONFIG_I2C_VIA is not set
667# CONFIG_I2C_VIAPRO is not set
668# CONFIG_I2C_VOODOO3 is not set
669# CONFIG_I2C_PCA_ISA is not set
670
671#
672# Miscellaneous I2C Chip support
673#
674# CONFIG_SENSORS_DS1337 is not set
675# CONFIG_SENSORS_DS1374 is not set
676# CONFIG_SENSORS_EEPROM is not set
677# CONFIG_SENSORS_PCF8574 is not set
678# CONFIG_SENSORS_PCA9539 is not set
679# CONFIG_SENSORS_PCF8591 is not set
680# CONFIG_SENSORS_M41T00 is not set
681# CONFIG_SENSORS_MAX6875 is not set
682# CONFIG_I2C_DEBUG_CORE is not set
683# CONFIG_I2C_DEBUG_ALGO is not set
684# CONFIG_I2C_DEBUG_BUS is not set
685# CONFIG_I2C_DEBUG_CHIP is not set
686
687#
688# SPI support
689#
690# CONFIG_SPI is not set
691# CONFIG_SPI_MASTER is not set
692
693#
694# Dallas's 1-wire bus
695#
696
697#
698# Hardware Monitoring support
699#
700CONFIG_HWMON=y
701# CONFIG_HWMON_VID is not set
702# CONFIG_SENSORS_ABITUGURU is not set
703# CONFIG_SENSORS_ADM1021 is not set
704# CONFIG_SENSORS_ADM1025 is not set
705# CONFIG_SENSORS_ADM1026 is not set
706# CONFIG_SENSORS_ADM1031 is not set
707# CONFIG_SENSORS_ADM9240 is not set
708# CONFIG_SENSORS_ASB100 is not set
709# CONFIG_SENSORS_ATXP1 is not set
710# CONFIG_SENSORS_DS1621 is not set
711# CONFIG_SENSORS_F71805F is not set
712# CONFIG_SENSORS_FSCHER is not set
713# CONFIG_SENSORS_FSCPOS is not set
714# CONFIG_SENSORS_GL518SM is not set
715# CONFIG_SENSORS_GL520SM is not set
716# CONFIG_SENSORS_IT87 is not set
717# CONFIG_SENSORS_LM63 is not set
718# CONFIG_SENSORS_LM75 is not set
719# CONFIG_SENSORS_LM77 is not set
720# CONFIG_SENSORS_LM78 is not set
721# CONFIG_SENSORS_LM80 is not set
722# CONFIG_SENSORS_LM83 is not set
723# CONFIG_SENSORS_LM85 is not set
724# CONFIG_SENSORS_LM87 is not set
725# CONFIG_SENSORS_LM90 is not set
726# CONFIG_SENSORS_LM92 is not set
727# CONFIG_SENSORS_MAX1619 is not set
728# CONFIG_SENSORS_PC87360 is not set
729# CONFIG_SENSORS_SIS5595 is not set
730# CONFIG_SENSORS_SMSC47M1 is not set
731# CONFIG_SENSORS_SMSC47M192 is not set
732# CONFIG_SENSORS_SMSC47B397 is not set
733# CONFIG_SENSORS_VIA686A is not set
734# CONFIG_SENSORS_VT8231 is not set
735# CONFIG_SENSORS_W83781D is not set
736# CONFIG_SENSORS_W83791D is not set
737# CONFIG_SENSORS_W83792D is not set
738# CONFIG_SENSORS_W83L785TS is not set
739# CONFIG_SENSORS_W83627HF is not set
740# CONFIG_SENSORS_W83627EHF is not set
741# CONFIG_HWMON_DEBUG_CHIP is not set
742
743#
744# Misc devices
745#
746
747#
748# Multimedia devices
749#
750# CONFIG_VIDEO_DEV is not set
751CONFIG_VIDEO_V4L2=y
752
753#
754# Digital Video Broadcasting Devices
755#
756# CONFIG_DVB is not set
757
758#
759# Graphics support
760#
761CONFIG_FIRMWARE_EDID=y
762# CONFIG_FB is not set
763# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
764
765#
766# Sound
767#
768# CONFIG_SOUND is not set
769
770#
771# USB support
772#
773CONFIG_USB_ARCH_HAS_HCD=y
774CONFIG_USB_ARCH_HAS_OHCI=y
775CONFIG_USB_ARCH_HAS_EHCI=y
776# CONFIG_USB is not set
777
778#
779# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
780#
781
782#
783# USB Gadget Support
784#
785# CONFIG_USB_GADGET is not set
786
787#
788# MMC/SD Card support
789#
790# CONFIG_MMC is not set
791
792#
793# LED devices
794#
795# CONFIG_NEW_LEDS is not set
796
797#
798# LED drivers
799#
800
801#
802# LED Triggers
803#
804
805#
806# InfiniBand support
807#
808# CONFIG_INFINIBAND is not set
809
810#
811# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
812#
813
814#
815# Real Time Clock
816#
817# CONFIG_RTC_CLASS is not set
818
819#
820# DMA Engine support
821#
822# CONFIG_DMA_ENGINE is not set
823
824#
825# DMA Clients
826#
827
828#
829# DMA Devices
830#
831
832#
833# File systems
834#
835CONFIG_EXT2_FS=y
836# CONFIG_EXT2_FS_XATTR is not set
837# CONFIG_EXT2_FS_XIP is not set
838CONFIG_EXT3_FS=y
839CONFIG_EXT3_FS_XATTR=y
840# CONFIG_EXT3_FS_POSIX_ACL is not set
841# CONFIG_EXT3_FS_SECURITY is not set
842CONFIG_JBD=y
843# CONFIG_JBD_DEBUG is not set
844CONFIG_FS_MBCACHE=y
845# CONFIG_REISERFS_FS is not set
846# CONFIG_JFS_FS is not set
847# CONFIG_FS_POSIX_ACL is not set
848# CONFIG_XFS_FS is not set
849# CONFIG_OCFS2_FS is not set
850# CONFIG_MINIX_FS is not set
851# CONFIG_ROMFS_FS is not set
852CONFIG_INOTIFY=y
853CONFIG_INOTIFY_USER=y
854# CONFIG_QUOTA is not set
855CONFIG_DNOTIFY=y
856# CONFIG_AUTOFS_FS is not set
857# CONFIG_AUTOFS4_FS is not set
858# CONFIG_FUSE_FS is not set
859
860#
861# CD-ROM/DVD Filesystems
862#
863# CONFIG_ISO9660_FS is not set
864# CONFIG_UDF_FS is not set
865
866#
867# DOS/FAT/NT Filesystems
868#
869# CONFIG_MSDOS_FS is not set
870# CONFIG_VFAT_FS is not set
871# CONFIG_NTFS_FS is not set
872
873#
874# Pseudo filesystems
875#
876CONFIG_PROC_FS=y
877CONFIG_PROC_KCORE=y
878CONFIG_SYSFS=y
879CONFIG_TMPFS=y
880# CONFIG_HUGETLB_PAGE is not set
881CONFIG_RAMFS=y
882# CONFIG_CONFIGFS_FS is not set
883
884#
885# Miscellaneous filesystems
886#
887# CONFIG_ADFS_FS is not set
888# CONFIG_AFFS_FS is not set
889# CONFIG_HFS_FS is not set
890# CONFIG_HFSPLUS_FS is not set
891# CONFIG_BEFS_FS is not set
892# CONFIG_BFS_FS is not set
893# CONFIG_EFS_FS is not set
894# CONFIG_CRAMFS is not set
895# CONFIG_VXFS_FS is not set
896# CONFIG_HPFS_FS is not set
897# CONFIG_QNX4FS_FS is not set
898# CONFIG_SYSV_FS is not set
899# CONFIG_UFS_FS is not set
900
901#
902# Network File Systems
903#
904CONFIG_NFS_FS=y
905CONFIG_NFS_V3=y
906# CONFIG_NFS_V3_ACL is not set
907CONFIG_NFS_V4=y
908# CONFIG_NFS_DIRECTIO is not set
909# CONFIG_NFSD is not set
910CONFIG_ROOT_NFS=y
911CONFIG_LOCKD=y
912CONFIG_LOCKD_V4=y
913CONFIG_NFS_COMMON=y
914CONFIG_SUNRPC=y
915CONFIG_SUNRPC_GSS=y
916CONFIG_RPCSEC_GSS_KRB5=y
917# CONFIG_RPCSEC_GSS_SPKM3 is not set
918# CONFIG_SMB_FS is not set
919# CONFIG_CIFS is not set
920# CONFIG_NCP_FS is not set
921# CONFIG_CODA_FS is not set
922# CONFIG_AFS_FS is not set
923# CONFIG_9P_FS is not set
924
925#
926# Partition Types
927#
928CONFIG_PARTITION_ADVANCED=y
929# CONFIG_ACORN_PARTITION is not set
930# CONFIG_OSF_PARTITION is not set
931# CONFIG_AMIGA_PARTITION is not set
932# CONFIG_ATARI_PARTITION is not set
933# CONFIG_MAC_PARTITION is not set
934# CONFIG_MSDOS_PARTITION is not set
935# CONFIG_LDM_PARTITION is not set
936# CONFIG_SGI_PARTITION is not set
937# CONFIG_ULTRIX_PARTITION is not set
938# CONFIG_SUN_PARTITION is not set
939# CONFIG_KARMA_PARTITION is not set
940# CONFIG_EFI_PARTITION is not set
941
942#
943# Native Language Support
944#
945# CONFIG_NLS is not set
946
947#
948# QE Options
949#
950# CONFIG_UCC_SLOW is not set
951CONFIG_UCC_FAST=y
952CONFIG_UCC=y
953
954#
955# Library routines
956#
957# CONFIG_CRC_CCITT is not set
958# CONFIG_CRC16 is not set
959CONFIG_CRC32=y
960# CONFIG_LIBCRC32C is not set
961CONFIG_PLIST=y
962
963#
964# Instrumentation Support
965#
966# CONFIG_PROFILING is not set
967
968#
969# Kernel hacking
970#
971# CONFIG_PRINTK_TIME is not set
972# CONFIG_MAGIC_SYSRQ is not set
973# CONFIG_UNUSED_SYMBOLS is not set
974# CONFIG_DEBUG_KERNEL is not set
975CONFIG_LOG_BUF_SHIFT=14
976# CONFIG_DEBUG_FS is not set
977# CONFIG_BOOTX_TEXT is not set
978# CONFIG_SERIAL_TEXT_DEBUG is not set
979# CONFIG_PPC_EARLY_DEBUG is not set
980
981#
982# Security options
983#
984# CONFIG_KEYS is not set
985# CONFIG_SECURITY is not set
986
987#
988# Cryptographic options
989#
990CONFIG_CRYPTO=y
991# CONFIG_CRYPTO_HMAC is not set
992# CONFIG_CRYPTO_NULL is not set
993# CONFIG_CRYPTO_MD4 is not set
994CONFIG_CRYPTO_MD5=y
995# CONFIG_CRYPTO_SHA1 is not set
996# CONFIG_CRYPTO_SHA256 is not set
997# CONFIG_CRYPTO_SHA512 is not set
998# CONFIG_CRYPTO_WP512 is not set
999# CONFIG_CRYPTO_TGR192 is not set
1000CONFIG_CRYPTO_DES=y
1001# CONFIG_CRYPTO_BLOWFISH is not set
1002# CONFIG_CRYPTO_TWOFISH is not set
1003# CONFIG_CRYPTO_SERPENT is not set
1004# CONFIG_CRYPTO_AES is not set
1005# CONFIG_CRYPTO_CAST5 is not set
1006# CONFIG_CRYPTO_CAST6 is not set
1007# CONFIG_CRYPTO_TEA is not set
1008# CONFIG_CRYPTO_ARC4 is not set
1009# CONFIG_CRYPTO_KHAZAD is not set
1010# CONFIG_CRYPTO_ANUBIS is not set
1011# CONFIG_CRYPTO_DEFLATE is not set
1012# CONFIG_CRYPTO_MICHAEL_MIC is not set
1013# CONFIG_CRYPTO_CRC32C is not set
1014# CONFIG_CRYPTO_TEST is not set
1015
1016#
1017# Hardware crypto devices
1018#
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 190a57e20765..47a613cdd775 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -763,10 +763,10 @@ struct cpu_spec cpu_specs[] = {
763 .cpu_setup = __setup_cpu_603, 763 .cpu_setup = __setup_cpu_603,
764 .platform = "ppc603", 764 .platform = "ppc603",
765 }, 765 },
766 { /* e300 (a 603e core, plus some) on 83xx */ 766 { /* e300c1 (a 603e core, plus some) on 83xx */
767 .pvr_mask = 0x7fff0000, 767 .pvr_mask = 0x7fff0000,
768 .pvr_value = 0x00830000, 768 .pvr_value = 0x00830000,
769 .cpu_name = "e300", 769 .cpu_name = "e300c1",
770 .cpu_features = CPU_FTRS_E300, 770 .cpu_features = CPU_FTRS_E300,
771 .cpu_user_features = COMMON_USER, 771 .cpu_user_features = COMMON_USER,
772 .icache_bsize = 32, 772 .icache_bsize = 32,
@@ -774,6 +774,17 @@ struct cpu_spec cpu_specs[] = {
774 .cpu_setup = __setup_cpu_603, 774 .cpu_setup = __setup_cpu_603,
775 .platform = "ppc603", 775 .platform = "ppc603",
776 }, 776 },
777 { /* e300c2 (an e300c1 core, plus some, minus FPU) on 83xx */
778 .pvr_mask = 0x7fff0000,
779 .pvr_value = 0x00840000,
780 .cpu_name = "e300c2",
781 .cpu_features = CPU_FTRS_E300,
782 .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
783 .icache_bsize = 32,
784 .dcache_bsize = 32,
785 .cpu_setup = __setup_cpu_603,
786 .platform = "ppc603",
787 },
777 { /* default match, we assume split I/D cache & TB (non-601)... */ 788 { /* default match, we assume split I/D cache & TB (non-601)... */
778 .pvr_mask = 0x00000000, 789 .pvr_mask = 0x00000000,
779 .pvr_value = 0x00000000, 790 .pvr_value = 0x00000000,
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2cd872b5283b..748e74fcf541 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -27,10 +27,7 @@
27#include <asm/ppc_asm.h> 27#include <asm/ppc_asm.h>
28#include <asm/asm-offsets.h> 28#include <asm/asm-offsets.h>
29#include <asm/cputable.h> 29#include <asm/cputable.h>
30 30#include <asm/firmware.h>
31#ifdef CONFIG_PPC_ISERIES
32#define DO_SOFT_DISABLE
33#endif
34 31
35/* 32/*
36 * System calls. 33 * System calls.
@@ -91,6 +88,7 @@ system_call_common:
91 ld r11,exception_marker@toc(r2) 88 ld r11,exception_marker@toc(r2)
92 std r11,-16(r9) /* "regshere" marker */ 89 std r11,-16(r9) /* "regshere" marker */
93#ifdef CONFIG_PPC_ISERIES 90#ifdef CONFIG_PPC_ISERIES
91BEGIN_FW_FTR_SECTION
94 /* Hack for handling interrupts when soft-enabling on iSeries */ 92 /* Hack for handling interrupts when soft-enabling on iSeries */
95 cmpdi cr1,r0,0x5555 /* syscall 0x5555 */ 93 cmpdi cr1,r0,0x5555 /* syscall 0x5555 */
96 andi. r10,r12,MSR_PR /* from kernel */ 94 andi. r10,r12,MSR_PR /* from kernel */
@@ -98,6 +96,7 @@ system_call_common:
98 beq hardware_interrupt_entry 96 beq hardware_interrupt_entry
99 lbz r10,PACAPROCENABLED(r13) 97 lbz r10,PACAPROCENABLED(r13)
100 std r10,SOFTE(r1) 98 std r10,SOFTE(r1)
99END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
101#endif 100#endif
102 mfmsr r11 101 mfmsr r11
103 ori r11,r11,MSR_EE 102 ori r11,r11,MSR_EE
@@ -462,6 +461,7 @@ _GLOBAL(ret_from_except_lite)
462 461
463restore: 462restore:
464#ifdef CONFIG_PPC_ISERIES 463#ifdef CONFIG_PPC_ISERIES
464BEGIN_FW_FTR_SECTION
465 ld r5,SOFTE(r1) 465 ld r5,SOFTE(r1)
466 cmpdi 0,r5,0 466 cmpdi 0,r5,0
467 beq 4f 467 beq 4f
@@ -480,6 +480,7 @@ restore:
480 b .ret_from_except_lite /* loop back and handle more */ 480 b .ret_from_except_lite /* loop back and handle more */
481 481
4824: stb r5,PACAPROCENABLED(r13) 4824: stb r5,PACAPROCENABLED(r13)
483END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
483#endif 484#endif
484 485
485 ld r3,_MSR(r1) 486 ld r3,_MSR(r1)
@@ -538,18 +539,23 @@ do_work:
538 lwz r8,TI_PREEMPT(r9) 539 lwz r8,TI_PREEMPT(r9)
539 cmpwi cr1,r8,0 540 cmpwi cr1,r8,0
540#ifdef CONFIG_PPC_ISERIES 541#ifdef CONFIG_PPC_ISERIES
542BEGIN_FW_FTR_SECTION
541 ld r0,SOFTE(r1) 543 ld r0,SOFTE(r1)
542 cmpdi r0,0 544 cmpdi r0,0
543#else 545END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
544 andi. r0,r3,MSR_EE
545#endif 546#endif
547BEGIN_FW_FTR_SECTION
548 andi. r0,r3,MSR_EE
549END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
546 crandc eq,cr1*4+eq,eq 550 crandc eq,cr1*4+eq,eq
547 bne restore 551 bne restore
548 /* here we are preempting the current task */ 552 /* here we are preempting the current task */
5491: 5531:
550#ifdef CONFIG_PPC_ISERIES 554#ifdef CONFIG_PPC_ISERIES
555BEGIN_FW_FTR_SECTION
551 li r0,1 556 li r0,1
552 stb r0,PACAPROCENABLED(r13) 557 stb r0,PACAPROCENABLED(r13)
558END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
553#endif 559#endif
554 ori r10,r10,MSR_EE 560 ori r10,r10,MSR_EE
555 mtmsrd r10,1 /* reenable interrupts */ 561 mtmsrd r10,1 /* reenable interrupts */
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 3065b472b95d..645c7f10fb28 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -33,6 +33,7 @@
33#include <asm/hvcall.h> 33#include <asm/hvcall.h>
34#include <asm/iseries/lpar_map.h> 34#include <asm/iseries/lpar_map.h>
35#include <asm/thread_info.h> 35#include <asm/thread_info.h>
36#include <asm/firmware.h>
36 37
37#ifdef CONFIG_PPC_ISERIES 38#ifdef CONFIG_PPC_ISERIES
38#define DO_SOFT_DISABLE 39#define DO_SOFT_DISABLE
@@ -365,19 +366,28 @@ label##_iSeries: \
365 366
366#ifdef DO_SOFT_DISABLE 367#ifdef DO_SOFT_DISABLE
367#define DISABLE_INTS \ 368#define DISABLE_INTS \
369BEGIN_FW_FTR_SECTION; \
368 lbz r10,PACAPROCENABLED(r13); \ 370 lbz r10,PACAPROCENABLED(r13); \
369 li r11,0; \ 371 li r11,0; \
370 std r10,SOFTE(r1); \ 372 std r10,SOFTE(r1); \
371 mfmsr r10; \ 373 mfmsr r10; \
372 stb r11,PACAPROCENABLED(r13); \ 374 stb r11,PACAPROCENABLED(r13); \
373 ori r10,r10,MSR_EE; \ 375 ori r10,r10,MSR_EE; \
374 mtmsrd r10,1 376 mtmsrd r10,1; \
377END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
375 378
376#define ENABLE_INTS \ 379#define ENABLE_INTS \
380BEGIN_FW_FTR_SECTION; \
377 lbz r10,PACAPROCENABLED(r13); \ 381 lbz r10,PACAPROCENABLED(r13); \
378 mfmsr r11; \ 382 mfmsr r11; \
379 std r10,SOFTE(r1); \ 383 std r10,SOFTE(r1); \
380 ori r11,r11,MSR_EE; \ 384 ori r11,r11,MSR_EE; \
385END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES); \
386BEGIN_FW_FTR_SECTION; \
387 ld r12,_MSR(r1); \
388 mfmsr r11; \
389 rlwimi r11,r12,0,MSR_EE; \
390END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \
381 mtmsrd r11,1 391 mtmsrd r11,1
382 392
383#else /* hard enable/disable interrupts */ 393#else /* hard enable/disable interrupts */
@@ -1071,8 +1081,10 @@ _GLOBAL(slb_miss_realmode)
1071 ld r3,PACA_EXSLB+EX_R3(r13) 1081 ld r3,PACA_EXSLB+EX_R3(r13)
1072 lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ 1082 lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
1073#ifdef CONFIG_PPC_ISERIES 1083#ifdef CONFIG_PPC_ISERIES
1084BEGIN_FW_FTR_SECTION
1074 ld r11,PACALPPACAPTR(r13) 1085 ld r11,PACALPPACAPTR(r13)
1075 ld r11,LPPACASRR0(r11) /* get SRR0 value */ 1086 ld r11,LPPACASRR0(r11) /* get SRR0 value */
1087END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
1076#endif /* CONFIG_PPC_ISERIES */ 1088#endif /* CONFIG_PPC_ISERIES */
1077 1089
1078 mtlr r10 1090 mtlr r10
@@ -1087,8 +1099,10 @@ _GLOBAL(slb_miss_realmode)
1087.machine pop 1099.machine pop
1088 1100
1089#ifdef CONFIG_PPC_ISERIES 1101#ifdef CONFIG_PPC_ISERIES
1102BEGIN_FW_FTR_SECTION
1090 mtspr SPRN_SRR0,r11 1103 mtspr SPRN_SRR0,r11
1091 mtspr SPRN_SRR1,r12 1104 mtspr SPRN_SRR1,r12
1105END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
1092#endif /* CONFIG_PPC_ISERIES */ 1106#endif /* CONFIG_PPC_ISERIES */
1093 ld r9,PACA_EXSLB+EX_R9(r13) 1107 ld r9,PACA_EXSLB+EX_R9(r13)
1094 ld r10,PACA_EXSLB+EX_R10(r13) 1108 ld r10,PACA_EXSLB+EX_R10(r13)
@@ -1301,6 +1315,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
1301 cmpdi r3,0 /* see if hash_page succeeded */ 1315 cmpdi r3,0 /* see if hash_page succeeded */
1302 1316
1303#ifdef DO_SOFT_DISABLE 1317#ifdef DO_SOFT_DISABLE
1318BEGIN_FW_FTR_SECTION
1304 /* 1319 /*
1305 * If we had interrupts soft-enabled at the point where the 1320 * If we had interrupts soft-enabled at the point where the
1306 * DSI/ISI occurred, and an interrupt came in during hash_page, 1321 * DSI/ISI occurred, and an interrupt came in during hash_page,
@@ -1321,12 +1336,14 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
1321 ld r3,SOFTE(r1) 1336 ld r3,SOFTE(r1)
1322 bl .local_irq_restore 1337 bl .local_irq_restore
1323 b 11f 1338 b 11f
1324#else 1339END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
1340#endif
1341BEGIN_FW_FTR_SECTION
1325 beq fast_exception_return /* Return from exception on success */ 1342 beq fast_exception_return /* Return from exception on success */
1326 ble- 12f /* Failure return from hash_page */ 1343 ble- 12f /* Failure return from hash_page */
1327 1344
1328 /* fall through */ 1345 /* fall through */
1329#endif 1346END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
1330 1347
1331/* Here we have a page fault that hash_page can't handle. */ 1348/* Here we have a page fault that hash_page can't handle. */
1332_GLOBAL(handle_page_fault) 1349_GLOBAL(handle_page_fault)
@@ -1861,7 +1878,9 @@ _GLOBAL(__secondary_start)
1861 LOAD_REG_ADDR(r3, .start_secondary_prolog) 1878 LOAD_REG_ADDR(r3, .start_secondary_prolog)
1862 LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) 1879 LOAD_REG_IMMEDIATE(r4, MSR_KERNEL)
1863#ifdef DO_SOFT_DISABLE 1880#ifdef DO_SOFT_DISABLE
1881BEGIN_FW_FTR_SECTION
1864 ori r4,r4,MSR_EE 1882 ori r4,r4,MSR_EE
1883END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
1865#endif 1884#endif
1866 mtspr SPRN_SRR0,r3 1885 mtspr SPRN_SRR0,r3
1867 mtspr SPRN_SRR1,r4 1886 mtspr SPRN_SRR1,r4
@@ -1986,6 +2005,7 @@ _STATIC(start_here_common)
1986 */ 2005 */
1987 li r3,0 2006 li r3,0
1988 bl .do_cpu_ftr_fixups 2007 bl .do_cpu_ftr_fixups
2008 bl .do_fw_ftr_fixups
1989 2009
1990 /* ptr to current */ 2010 /* ptr to current */
1991 LOAD_REG_IMMEDIATE(r4, init_task) 2011 LOAD_REG_IMMEDIATE(r4, init_task)
@@ -2000,11 +2020,13 @@ _STATIC(start_here_common)
2000 /* Load up the kernel context */ 2020 /* Load up the kernel context */
20015: 20215:
2002#ifdef DO_SOFT_DISABLE 2022#ifdef DO_SOFT_DISABLE
2023BEGIN_FW_FTR_SECTION
2003 li r5,0 2024 li r5,0
2004 stb r5,PACAPROCENABLED(r13) /* Soft Disabled */ 2025 stb r5,PACAPROCENABLED(r13) /* Soft Disabled */
2005 mfmsr r5 2026 mfmsr r5
2006 ori r5,r5,MSR_EE /* Hard Enabled */ 2027 ori r5,r5,MSR_EE /* Hard Enabled */
2007 mtmsrd r5 2028 mtmsrd r5
2029END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
2008#endif 2030#endif
2009 2031
2010 bl .start_kernel 2032 bl .start_kernel
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index 9c54eccad993..41521b30c3cd 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -325,6 +325,52 @@ _GLOBAL(do_cpu_ftr_fixups)
325 isync 325 isync
326 b 1b 326 b 1b
327 327
328/*
329 * do_fw_ftr_fixups - goes through the list of firmware feature fixups
330 * and writes nop's over sections of code that don't apply for this firmware.
331 * r3 = data offset (not changed)
332 */
333_GLOBAL(do_fw_ftr_fixups)
334 /* Get firmware features */
335 LOAD_REG_IMMEDIATE(r6,powerpc_firmware_features)
336 sub r6,r6,r3
337 ld r4,0(r6)
338 /* Get the fixup table */
339 LOAD_REG_IMMEDIATE(r6,__start___fw_ftr_fixup)
340 sub r6,r6,r3
341 LOAD_REG_IMMEDIATE(r7,__stop___fw_ftr_fixup)
342 sub r7,r7,r3
343 /* Do the fixup */
3441: cmpld r6,r7
345 bgelr
346 addi r6,r6,32
347 ld r8,-32(r6) /* mask */
348 and r8,r8,r4
349 ld r9,-24(r6) /* value */
350 cmpld r8,r9
351 beq 1b
352 ld r8,-16(r6) /* section begin */
353 ld r9,-8(r6) /* section end */
354 subf. r9,r8,r9
355 beq 1b
356 /* write nops over the section of code */
357 /* todo: if large section, add a branch at the start of it */
358 srwi r9,r9,2
359 mtctr r9
360 sub r8,r8,r3
361 lis r0,0x60000000@h /* nop */
3623: stw r0,0(r8)
363BEGIN_FTR_SECTION
364 dcbst 0,r8 /* suboptimal, but simpler */
365 sync
366 icbi 0,r8
367END_FTR_SECTION_IFSET(CPU_FTR_SPLIT_ID_CACHE)
368 addi r8,r8,4
369 bdnz 3b
370 sync /* additional sync needed on g4 */
371 isync
372 b 1b
373
328#if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) 374#if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE)
329/* 375/*
330 * Do an IO access in real mode 376 * Do an IO access in real mode
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index c1b1e14775e4..78d3c0fc8dfb 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -30,6 +30,7 @@
30#include <asm/byteorder.h> 30#include <asm/byteorder.h>
31#include <asm/machdep.h> 31#include <asm/machdep.h>
32#include <asm/ppc-pci.h> 32#include <asm/ppc-pci.h>
33#include <asm/firmware.h>
33 34
34#ifdef DEBUG 35#ifdef DEBUG
35#include <asm/udbg.h> 36#include <asm/udbg.h>
@@ -209,7 +210,6 @@ void pcibios_free_controller(struct pci_controller *phb)
209 kfree(phb); 210 kfree(phb);
210} 211}
211 212
212#ifndef CONFIG_PPC_ISERIES
213void __devinit pcibios_claim_one_bus(struct pci_bus *b) 213void __devinit pcibios_claim_one_bus(struct pci_bus *b)
214{ 214{
215 struct pci_dev *dev; 215 struct pci_dev *dev;
@@ -238,10 +238,12 @@ static void __init pcibios_claim_of_setup(void)
238{ 238{
239 struct pci_bus *b; 239 struct pci_bus *b;
240 240
241 if (firmware_has_feature(FW_FEATURE_ISERIES))
242 return;
243
241 list_for_each_entry(b, &pci_root_buses, node) 244 list_for_each_entry(b, &pci_root_buses, node)
242 pcibios_claim_one_bus(b); 245 pcibios_claim_one_bus(b);
243} 246}
244#endif
245 247
246#ifdef CONFIG_PPC_MULTIPLATFORM 248#ifdef CONFIG_PPC_MULTIPLATFORM
247static u32 get_int_prop(struct device_node *np, const char *name, u32 def) 249static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
@@ -554,9 +556,8 @@ static int __init pcibios_init(void)
554 */ 556 */
555 ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; 557 ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
556 558
557#ifdef CONFIG_PPC_ISERIES 559 if (firmware_has_feature(FW_FEATURE_ISERIES))
558 iSeries_pcibios_init(); 560 iSeries_pcibios_init();
559#endif
560 561
561 printk(KERN_DEBUG "PCI: Probing PCI hardware\n"); 562 printk(KERN_DEBUG "PCI: Probing PCI hardware\n");
562 563
@@ -566,15 +567,15 @@ static int __init pcibios_init(void)
566 pci_bus_add_devices(hose->bus); 567 pci_bus_add_devices(hose->bus);
567 } 568 }
568 569
569#ifndef CONFIG_PPC_ISERIES 570 if (!firmware_has_feature(FW_FEATURE_ISERIES)) {
570 if (pci_probe_only) 571 if (pci_probe_only)
571 pcibios_claim_of_setup(); 572 pcibios_claim_of_setup();
572 else 573 else
573 /* FIXME: `else' will be removed when 574 /* FIXME: `else' will be removed when
574 pci_assign_unassigned_resources() is able to work 575 pci_assign_unassigned_resources() is able to work
575 correctly with [partially] allocated PCI tree. */ 576 correctly with [partially] allocated PCI tree. */
576 pci_assign_unassigned_resources(); 577 pci_assign_unassigned_resources();
577#endif /* !CONFIG_PPC_ISERIES */ 578 }
578 579
579 /* Call machine dependent final fixup */ 580 /* Call machine dependent final fixup */
580 if (ppc_md.pcibios_fixup) 581 if (ppc_md.pcibios_fixup)
@@ -586,8 +587,9 @@ static int __init pcibios_init(void)
586 printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev)); 587 printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
587 588
588#ifdef CONFIG_PPC_MULTIPLATFORM 589#ifdef CONFIG_PPC_MULTIPLATFORM
589 /* map in PCI I/O space */ 590 if (!firmware_has_feature(FW_FEATURE_ISERIES))
590 phbs_remap_io(); 591 /* map in PCI I/O space */
592 phbs_remap_io();
591#endif 593#endif
592 594
593 printk(KERN_DEBUG "PCI: Probing PCI hardware done\n"); 595 printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
@@ -637,13 +639,13 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
637 */ 639 */
638int pci_domain_nr(struct pci_bus *bus) 640int pci_domain_nr(struct pci_bus *bus)
639{ 641{
640#ifdef CONFIG_PPC_ISERIES 642 if (firmware_has_feature(FW_FEATURE_ISERIES))
641 return 0; 643 return 0;
642#else 644 else {
643 struct pci_controller *hose = pci_bus_to_host(bus); 645 struct pci_controller *hose = pci_bus_to_host(bus);
644 646
645 return hose->global_number; 647 return hose->global_number;
646#endif 648 }
647} 649}
648 650
649EXPORT_SYMBOL(pci_domain_nr); 651EXPORT_SYMBOL(pci_domain_nr);
@@ -651,12 +653,12 @@ EXPORT_SYMBOL(pci_domain_nr);
651/* Decide whether to display the domain number in /proc */ 653/* Decide whether to display the domain number in /proc */
652int pci_proc_domain(struct pci_bus *bus) 654int pci_proc_domain(struct pci_bus *bus)
653{ 655{
654#ifdef CONFIG_PPC_ISERIES 656 if (firmware_has_feature(FW_FEATURE_ISERIES))
655 return 0; 657 return 0;
656#else 658 else {
657 struct pci_controller *hose = pci_bus_to_host(bus); 659 struct pci_controller *hose = pci_bus_to_host(bus);
658 return hose->buid; 660 return hose->buid;
659#endif 661 }
660} 662}
661 663
662/* 664/*
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 0af3fc1bdcc9..89cfaf49d3de 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -442,31 +442,6 @@ void __init smp_setup_cpu_maps(void)
442} 442}
443#endif /* CONFIG_SMP */ 443#endif /* CONFIG_SMP */
444 444
445int __initdata do_early_xmon;
446#ifdef CONFIG_XMON
447extern int xmon_no_auto_backtrace;
448
449static int __init early_xmon(char *p)
450{
451 /* ensure xmon is enabled */
452 if (p) {
453 if (strncmp(p, "on", 2) == 0)
454 xmon_init(1);
455 if (strncmp(p, "off", 3) == 0)
456 xmon_init(0);
457 if (strncmp(p, "nobt", 4) == 0)
458 xmon_no_auto_backtrace = 1;
459 if (strncmp(p, "early", 5) != 0)
460 return 0;
461 }
462 xmon_init(1);
463 do_early_xmon = 1;
464
465 return 0;
466}
467early_param("xmon", early_xmon);
468#endif
469
470static __init int add_pcspkr(void) 445static __init int add_pcspkr(void)
471{ 446{
472 struct device_node *np; 447 struct device_node *np;
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 79a17795d17b..191d0ab09222 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -238,12 +238,11 @@ void __init setup_arch(char **cmdline_p)
238 238
239 smp_setup_cpu_maps(); 239 smp_setup_cpu_maps();
240 240
241#ifdef CONFIG_XMON_DEFAULT
242 xmon_init(1);
243#endif
244 /* Register early console */ 241 /* Register early console */
245 register_early_udbg_console(); 242 register_early_udbg_console();
246 243
244 xmon_setup();
245
247#if defined(CONFIG_KGDB) 246#if defined(CONFIG_KGDB)
248 if (ppc_md.kgdb_map_scc) 247 if (ppc_md.kgdb_map_scc)
249 ppc_md.kgdb_map_scc(); 248 ppc_md.kgdb_map_scc();
@@ -280,9 +279,6 @@ void __init setup_arch(char **cmdline_p)
280 init_mm.end_data = (unsigned long) _edata; 279 init_mm.end_data = (unsigned long) _edata;
281 init_mm.brk = klimit; 280 init_mm.brk = klimit;
282 281
283 if (do_early_xmon)
284 debugger(NULL);
285
286 /* set up the bootmem stuff with available memory */ 282 /* set up the bootmem stuff with available memory */
287 do_init_bootmem(); 283 do_init_bootmem();
288 if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); 284 if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index cda2dbe70a76..4b2e32eab9dc 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -391,18 +391,14 @@ void __init setup_system(void)
391 find_legacy_serial_ports(); 391 find_legacy_serial_ports();
392 392
393 /* 393 /*
394 * Initialize xmon
395 */
396#ifdef CONFIG_XMON_DEFAULT
397 xmon_init(1);
398#endif
399 /*
400 * Register early console 394 * Register early console
401 */ 395 */
402 register_early_udbg_console(); 396 register_early_udbg_console();
403 397
404 if (do_early_xmon) 398 /*
405 debugger(NULL); 399 * Initialize xmon
400 */
401 xmon_setup();
406 402
407 check_smt_enabled(); 403 check_smt_enabled();
408 smp_setup_cpu_maps(); 404 smp_setup_cpu_maps();
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 02665a02130d..cb0e8d46c3e8 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -132,6 +132,14 @@ SECTIONS
132 *(__ftr_fixup) 132 *(__ftr_fixup)
133 __stop___ftr_fixup = .; 133 __stop___ftr_fixup = .;
134 } 134 }
135#ifdef CONFIG_PPC64
136 . = ALIGN(8);
137 __fw_ftr_fixup : {
138 __start___fw_ftr_fixup = .;
139 *(__fw_ftr_fixup)
140 __stop___fw_ftr_fixup = .;
141 }
142#endif
135 143
136 . = ALIGN(PAGE_SIZE); 144 . = ALIGN(PAGE_SIZE);
137 .init.ramfs : { 145 .init.ramfs : {
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index b1da03165496..ac64f4aaa509 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -63,32 +63,13 @@
63#include <asm/iommu.h> 63#include <asm/iommu.h>
64#include <asm/abs_addr.h> 64#include <asm/abs_addr.h>
65#include <asm/vdso.h> 65#include <asm/vdso.h>
66#include <asm/firmware.h>
66 67
67#include "mmu_decl.h" 68#include "mmu_decl.h"
68 69
69unsigned long ioremap_bot = IMALLOC_BASE; 70unsigned long ioremap_bot = IMALLOC_BASE;
70static unsigned long phbs_io_bot = PHBS_IO_BASE; 71static unsigned long phbs_io_bot = PHBS_IO_BASE;
71 72
72#ifdef CONFIG_PPC_ISERIES
73
74void __iomem *ioremap(unsigned long addr, unsigned long size)
75{
76 return (void __iomem *)addr;
77}
78
79extern void __iomem *__ioremap(unsigned long addr, unsigned long size,
80 unsigned long flags)
81{
82 return (void __iomem *)addr;
83}
84
85void iounmap(volatile void __iomem *addr)
86{
87 return;
88}
89
90#else
91
92/* 73/*
93 * map_io_page currently only called by __ioremap 74 * map_io_page currently only called by __ioremap
94 * map_io_page adds an entry to the ioremap page table 75 * map_io_page adds an entry to the ioremap page table
@@ -161,6 +142,9 @@ void __iomem * __ioremap(unsigned long addr, unsigned long size,
161 unsigned long pa, ea; 142 unsigned long pa, ea;
162 void __iomem *ret; 143 void __iomem *ret;
163 144
145 if (firmware_has_feature(FW_FEATURE_ISERIES))
146 return (void __iomem *)addr;
147
164 /* 148 /*
165 * Choose an address to map it to. 149 * Choose an address to map it to.
166 * Once the imalloc system is running, we use it. 150 * Once the imalloc system is running, we use it.
@@ -255,6 +239,9 @@ void iounmap(volatile void __iomem *token)
255{ 239{
256 void *addr; 240 void *addr;
257 241
242 if (firmware_has_feature(FW_FEATURE_ISERIES))
243 return;
244
258 if (!mem_init_done) 245 if (!mem_init_done)
259 return; 246 return;
260 247
@@ -315,8 +302,6 @@ int iounmap_explicit(volatile void __iomem *start, unsigned long size)
315 return 0; 302 return 0;
316} 303}
317 304
318#endif
319
320EXPORT_SYMBOL(ioremap); 305EXPORT_SYMBOL(ioremap);
321EXPORT_SYMBOL(__ioremap); 306EXPORT_SYMBOL(__ioremap);
322EXPORT_SYMBOL(iounmap); 307EXPORT_SYMBOL(iounmap);
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index dbc1abbde038..b10e4707d7c1 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -21,6 +21,7 @@
21#include <asm/page.h> 21#include <asm/page.h>
22#include <asm/mmu.h> 22#include <asm/mmu.h>
23#include <asm/pgtable.h> 23#include <asm/pgtable.h>
24#include <asm/firmware.h>
24 25
25/* void slb_allocate_realmode(unsigned long ea); 26/* void slb_allocate_realmode(unsigned long ea);
26 * 27 *
@@ -183,6 +184,7 @@ slb_finish_load:
183 * dont have any LRU information to help us choose a slot. 184 * dont have any LRU information to help us choose a slot.
184 */ 185 */
185#ifdef CONFIG_PPC_ISERIES 186#ifdef CONFIG_PPC_ISERIES
187BEGIN_FW_FTR_SECTION
186 /* 188 /*
187 * On iSeries, the "bolted" stack segment can be cast out on 189 * On iSeries, the "bolted" stack segment can be cast out on
188 * shared processor switch so we need to check for a miss on 190 * shared processor switch so we need to check for a miss on
@@ -194,6 +196,7 @@ slb_finish_load:
194 li r10,SLB_NUM_BOLTED-1 /* Stack goes in last bolted slot */ 196 li r10,SLB_NUM_BOLTED-1 /* Stack goes in last bolted slot */
195 cmpld r9,r3 197 cmpld r9,r3
196 beq 3f 198 beq 3f
199END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
197#endif /* CONFIG_PPC_ISERIES */ 200#endif /* CONFIG_PPC_ISERIES */
198 201
199 ld r10,PACASTABRR(r13) 202 ld r10,PACASTABRR(r13)
diff --git a/arch/powerpc/platforms/82xx/Kconfig b/arch/powerpc/platforms/82xx/Kconfig
new file mode 100644
index 000000000000..47d841ecf2e2
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/Kconfig
@@ -0,0 +1,21 @@
1menu "Platform support"
2 depends on PPC_82xx
3
4choice
5 prompt "Machine Type"
6 default MPC82xx_ADS
7
8config MPC82xx_ADS
9 bool "Freescale MPC82xx ADS"
10 select DEFAULT_UIMAGE
11 select PQ2ADS
12 select 8272
13 select 8260
14 select CPM2
15 select FSL_SOC
16 help
17 This option enables support for the MPC8272 ADS board
18
19endchoice
20
21endmenu
diff --git a/arch/powerpc/platforms/82xx/Makefile b/arch/powerpc/platforms/82xx/Makefile
new file mode 100644
index 000000000000..d9fd4c84d2e0
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the PowerPC 82xx linux kernel.
3#
4obj-$(CONFIG_PPC_82xx) += mpc82xx.o
5obj-$(CONFIG_MPC82xx_ADS) += mpc82xx_ads.o
diff --git a/arch/powerpc/platforms/82xx/m82xx_pci.h b/arch/powerpc/platforms/82xx/m82xx_pci.h
new file mode 100644
index 000000000000..9cd8893b5a32
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/m82xx_pci.h
@@ -0,0 +1,19 @@
1#ifndef _PPC_KERNEL_M82XX_PCI_H
2#define _PPC_KERNEL_M82XX_PCI_H
3
4/*
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 */
10
11#include <asm/m8260_pci.h>
12
13#define SIU_INT_IRQ1 ((uint)0x13 + CPM_IRQ_OFFSET)
14
15#ifndef _IO_BASE
16#define _IO_BASE isa_io_base
17#endif
18
19#endif /* _PPC_KERNEL_M8260_PCI_H */
diff --git a/arch/powerpc/platforms/82xx/mpc82xx.c b/arch/powerpc/platforms/82xx/mpc82xx.c
new file mode 100644
index 000000000000..89d702de4863
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/mpc82xx.c
@@ -0,0 +1,111 @@
1/*
2 * MPC82xx setup and early boot code plus other random bits.
3 *
4 * Author: Vitaly Bordug <vbordug@ru.mvista.com>
5 *
6 * Copyright (c) 2006 MontaVista Software, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/config.h>
15#include <linux/stddef.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/errno.h>
19#include <linux/reboot.h>
20#include <linux/pci.h>
21#include <linux/interrupt.h>
22#include <linux/kdev_t.h>
23#include <linux/major.h>
24#include <linux/console.h>
25#include <linux/delay.h>
26#include <linux/seq_file.h>
27#include <linux/root_dev.h>
28#include <linux/initrd.h>
29#include <linux/module.h>
30#include <linux/fsl_devices.h>
31#include <linux/fs_uart_pd.h>
32
33#include <asm/system.h>
34#include <asm/pgtable.h>
35#include <asm/page.h>
36#include <asm/atomic.h>
37#include <asm/time.h>
38#include <asm/io.h>
39#include <asm/machdep.h>
40#include <asm/bootinfo.h>
41#include <asm/pci-bridge.h>
42#include <asm/mpc8260.h>
43#include <asm/irq.h>
44#include <mm/mmu_decl.h>
45#include <asm/prom.h>
46#include <asm/cpm2.h>
47#include <asm/udbg.h>
48#include <asm/i8259.h>
49#include <linux/fs_enet_pd.h>
50
51#include <sysdev/fsl_soc.h>
52#include <sysdev/cpm2_pic.h>
53
54#include "pq2ads_pd.h"
55
56static int __init get_freq(char *name, unsigned long *val)
57{
58 struct device_node *cpu;
59 unsigned int *fp;
60 int found = 0;
61
62 /* The cpu node should have timebase and clock frequency properties */
63 cpu = of_find_node_by_type(NULL, "cpu");
64
65 if (cpu) {
66 fp = (unsigned int *)get_property(cpu, name, NULL);
67 if (fp) {
68 found = 1;
69 *val = *fp++;
70 }
71
72 of_node_put(cpu);
73 }
74
75 return found;
76}
77
78void __init m82xx_calibrate_decr(void)
79{
80 ppc_tb_freq = 125000000;
81 if (!get_freq("bus-frequency", &ppc_tb_freq)) {
82 printk(KERN_ERR "WARNING: Estimating decrementer frequency "
83 "(not found)\n");
84 }
85 ppc_tb_freq /= 4;
86 ppc_proc_freq = 1000000000;
87 if (!get_freq("clock-frequency", &ppc_proc_freq))
88 printk(KERN_ERR "WARNING: Estimating processor frequency"
89 "(not found)\n");
90}
91
92void mpc82xx_ads_show_cpuinfo(struct seq_file *m)
93{
94 uint pvid, svid, phid1;
95 uint memsize = total_memory;
96
97 pvid = mfspr(SPRN_PVR);
98 svid = mfspr(SPRN_SVR);
99
100 seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
101 seq_printf(m, "Machine\t\t: %s\n", CPUINFO_MACHINE);
102 seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
103 seq_printf(m, "SVR\t\t: 0x%x\n", svid);
104
105 /* Display cpu Pll setting */
106 phid1 = mfspr(SPRN_HID1);
107 seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
108
109 /* Display the amount of memory */
110 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
111}
diff --git a/arch/powerpc/platforms/82xx/mpc82xx_ads.c b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
new file mode 100644
index 000000000000..4276f087f26e
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
@@ -0,0 +1,661 @@
1/*
2 * MPC82xx_ads setup and early boot code plus other random bits.
3 *
4 * Author: Vitaly Bordug <vbordug@ru.mvista.com>
5 * m82xx_restart fix by Wade Farnsworth <wfarnsworth@mvista.com>
6 *
7 * Copyright (c) 2006 MontaVista Software, Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15
16#include <linux/config.h>
17#include <linux/stddef.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/errno.h>
21#include <linux/reboot.h>
22#include <linux/pci.h>
23#include <linux/interrupt.h>
24#include <linux/kdev_t.h>
25#include <linux/major.h>
26#include <linux/console.h>
27#include <linux/delay.h>
28#include <linux/seq_file.h>
29#include <linux/root_dev.h>
30#include <linux/initrd.h>
31#include <linux/module.h>
32#include <linux/fsl_devices.h>
33#include <linux/fs_uart_pd.h>
34
35#include <asm/system.h>
36#include <asm/pgtable.h>
37#include <asm/page.h>
38#include <asm/atomic.h>
39#include <asm/time.h>
40#include <asm/io.h>
41#include <asm/machdep.h>
42#include <asm/bootinfo.h>
43#include <asm/pci-bridge.h>
44#include <asm/mpc8260.h>
45#include <asm/irq.h>
46#include <mm/mmu_decl.h>
47#include <asm/prom.h>
48#include <asm/cpm2.h>
49#include <asm/udbg.h>
50#include <asm/i8259.h>
51#include <linux/fs_enet_pd.h>
52
53#include <sysdev/fsl_soc.h>
54#include <../sysdev/cpm2_pic.h>
55
56#include "pq2ads_pd.h"
57
58#ifdef CONFIG_PCI
59static uint pci_clk_frq;
60static struct {
61 unsigned long *pci_int_stat_reg;
62 unsigned long *pci_int_mask_reg;
63} pci_regs;
64
65static unsigned long pci_int_base;
66static struct irq_host *pci_pic_host;
67static struct device_node *pci_pic_node;
68#endif
69
70static void __init mpc82xx_ads_pic_init(void)
71{
72 struct device_node *np = of_find_compatible_node(NULL, "cpm-pic", "CPM2");
73 struct resource r;
74 cpm2_map_t *cpm_reg;
75
76 if (np == NULL) {
77 printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
78 return;
79 }
80 if (of_address_to_resource(np, 0, &r)) {
81 printk(KERN_ERR "PIC init: invalid resource\n");
82 of_node_put(np);
83 return;
84 }
85 cpm2_pic_init(np);
86 of_node_put(np);
87
88 /* Initialize the default interrupt mapping priorities,
89 * in case the boot rom changed something on us.
90 */
91 cpm_reg = (cpm2_map_t *) ioremap(get_immrbase(), sizeof(cpm2_map_t));
92 cpm_reg->im_intctl.ic_siprr = 0x05309770;
93 iounmap(cpm_reg);
94#ifdef CONFIG_PCI
95 /* Initialize stuff for the 82xx CPLD IC and install demux */
96 m82xx_pci_init_irq();
97#endif
98}
99
100static void init_fcc1_ioports(struct fs_platform_info *fpi)
101{
102 struct io_port *io;
103 u32 tempval;
104 cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
105 struct device_node *np;
106 struct resource r;
107 u32 *bcsr;
108
109 np = of_find_node_by_type(NULL, "memory");
110 if (!np) {
111 printk(KERN_INFO "No memory node in device tree\n");
112 return;
113 }
114 if (of_address_to_resource(np, 1, &r)) {
115 printk(KERN_INFO "No memory reg property [1] in devicetree\n");
116 return;
117 }
118 of_node_put(np);
119 bcsr = ioremap(r.start + 4, sizeof(u32));
120 io = &immap->im_ioport;
121
122 /* Enable the PHY */
123 clrbits32(bcsr, BCSR1_FETHIEN);
124 setbits32(bcsr, BCSR1_FETH_RST);
125
126 /* FCC1 pins are on port A/C. */
127 /* Configure port A and C pins for FCC1 Ethernet. */
128
129 tempval = in_be32(&io->iop_pdira);
130 tempval &= ~PA1_DIRA0;
131 tempval |= PA1_DIRA1;
132 out_be32(&io->iop_pdira, tempval);
133
134 tempval = in_be32(&io->iop_psora);
135 tempval &= ~PA1_PSORA0;
136 tempval |= PA1_PSORA1;
137 out_be32(&io->iop_psora, tempval);
138
139 setbits32(&io->iop_ppara, PA1_DIRA0 | PA1_DIRA1);
140
141 /* Alter clocks */
142 tempval = PC_CLK(fpi->clk_tx - 8) | PC_CLK(fpi->clk_rx - 8);
143
144 clrbits32(&io->iop_psorc, tempval);
145 clrbits32(&io->iop_pdirc, tempval);
146 setbits32(&io->iop_pparc, tempval);
147
148 cpm2_clk_setup(CPM_CLK_FCC1, fpi->clk_rx, CPM_CLK_RX);
149 cpm2_clk_setup(CPM_CLK_FCC1, fpi->clk_tx, CPM_CLK_TX);
150
151 iounmap(bcsr);
152 iounmap(immap);
153}
154
155static void init_fcc2_ioports(struct fs_platform_info *fpi)
156{
157 cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
158 struct device_node *np;
159 struct resource r;
160 u32 *bcsr;
161
162 struct io_port *io;
163 u32 tempval;
164
165 np = of_find_node_by_type(NULL, "memory");
166 if (!np) {
167 printk(KERN_INFO "No memory node in device tree\n");
168 return;
169 }
170 if (of_address_to_resource(np, 1, &r)) {
171 printk(KERN_INFO "No memory reg property [1] in devicetree\n");
172 return;
173 }
174 of_node_put(np);
175 io = &immap->im_ioport;
176 bcsr = ioremap(r.start + 12, sizeof(u32));
177
178 /* Enable the PHY */
179 clrbits32(bcsr, BCSR3_FETHIEN2);
180 setbits32(bcsr, BCSR3_FETH2_RST);
181
182 /* FCC2 are port B/C. */
183 /* Configure port A and C pins for FCC2 Ethernet. */
184
185 tempval = in_be32(&io->iop_pdirb);
186 tempval &= ~PB2_DIRB0;
187 tempval |= PB2_DIRB1;
188 out_be32(&io->iop_pdirb, tempval);
189
190 tempval = in_be32(&io->iop_psorb);
191 tempval &= ~PB2_PSORB0;
192 tempval |= PB2_PSORB1;
193 out_be32(&io->iop_psorb, tempval);
194
195 setbits32(&io->iop_pparb, PB2_DIRB0 | PB2_DIRB1);
196
197 tempval = PC_CLK(fpi->clk_tx - 8) | PC_CLK(fpi->clk_rx - 8);
198
199 /* Alter clocks */
200 clrbits32(&io->iop_psorc, tempval);
201 clrbits32(&io->iop_pdirc, tempval);
202 setbits32(&io->iop_pparc, tempval);
203
204 cpm2_clk_setup(CPM_CLK_FCC2, fpi->clk_rx, CPM_CLK_RX);
205 cpm2_clk_setup(CPM_CLK_FCC2, fpi->clk_tx, CPM_CLK_TX);
206
207 iounmap(bcsr);
208 iounmap(immap);
209}
210
211void init_fcc_ioports(struct fs_platform_info *fpi)
212{
213 int fcc_no = fs_get_fcc_index(fpi->fs_no);
214
215 switch (fcc_no) {
216 case 0:
217 init_fcc1_ioports(fpi);
218 break;
219 case 1:
220 init_fcc2_ioports(fpi);
221 break;
222 default:
223 printk(KERN_ERR "init_fcc_ioports: invalid FCC number\n");
224 return;
225 }
226}
227
228static void init_scc1_uart_ioports(struct fs_uart_platform_info *data)
229{
230 cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
231
232 /* SCC1 is only on port D */
233 setbits32(&immap->im_ioport.iop_ppard, 0x00000003);
234 clrbits32(&immap->im_ioport.iop_psord, 0x00000001);
235 setbits32(&immap->im_ioport.iop_psord, 0x00000002);
236 clrbits32(&immap->im_ioport.iop_pdird, 0x00000001);
237 setbits32(&immap->im_ioport.iop_pdird, 0x00000002);
238
239 clrbits32(&immap->im_cpmux.cmx_scr, (0x00000007 << (4 - data->clk_tx)));
240 clrbits32(&immap->im_cpmux.cmx_scr, (0x00000038 << (4 - data->clk_rx)));
241 setbits32(&immap->im_cpmux.cmx_scr,
242 ((data->clk_tx - 1) << (4 - data->clk_tx)));
243 setbits32(&immap->im_cpmux.cmx_scr,
244 ((data->clk_rx - 1) << (4 - data->clk_rx)));
245
246 iounmap(immap);
247}
248
249static void init_scc4_uart_ioports(struct fs_uart_platform_info *data)
250{
251 cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
252
253 setbits32(&immap->im_ioport.iop_ppard, 0x00000600);
254 clrbits32(&immap->im_ioport.iop_psord, 0x00000600);
255 clrbits32(&immap->im_ioport.iop_pdird, 0x00000200);
256 setbits32(&immap->im_ioport.iop_pdird, 0x00000400);
257
258 clrbits32(&immap->im_cpmux.cmx_scr, (0x00000007 << (4 - data->clk_tx)));
259 clrbits32(&immap->im_cpmux.cmx_scr, (0x00000038 << (4 - data->clk_rx)));
260 setbits32(&immap->im_cpmux.cmx_scr,
261 ((data->clk_tx - 1) << (4 - data->clk_tx)));
262 setbits32(&immap->im_cpmux.cmx_scr,
263 ((data->clk_rx - 1) << (4 - data->clk_rx)));
264
265 iounmap(immap);
266}
267
268void init_scc_ioports(struct fs_uart_platform_info *data)
269{
270 int scc_no = fs_get_scc_index(data->fs_no);
271
272 switch (scc_no) {
273 case 0:
274 init_scc1_uart_ioports(data);
275 data->brg = data->clk_rx;
276 break;
277 case 3:
278 init_scc4_uart_ioports(data);
279 data->brg = data->clk_rx;
280 break;
281 default:
282 printk(KERN_ERR "init_scc_ioports: invalid SCC number\n");
283 return;
284 }
285}
286
287void __init m82xx_board_setup(void)
288{
289 cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
290 struct device_node *np;
291 struct resource r;
292 u32 *bcsr;
293
294 np = of_find_node_by_type(NULL, "memory");
295 if (!np) {
296 printk(KERN_INFO "No memory node in device tree\n");
297 return;
298 }
299 if (of_address_to_resource(np, 1, &r)) {
300 printk(KERN_INFO "No memory reg property [1] in devicetree\n");
301 return;
302 }
303 of_node_put(np);
304 bcsr = ioremap(r.start + 4, sizeof(u32));
305 /* Enable the 2nd UART port */
306 clrbits32(bcsr, BCSR1_RS232_EN2);
307
308#ifdef CONFIG_SERIAL_CPM_SCC1
309 clrbits32((u32 *) & immap->im_scc[0].scc_sccm,
310 UART_SCCM_TX | UART_SCCM_RX);
311 clrbits32((u32 *) & immap->im_scc[0].scc_gsmrl,
312 SCC_GSMRL_ENR | SCC_GSMRL_ENT);
313#endif
314
315#ifdef CONFIG_SERIAL_CPM_SCC2
316 clrbits32((u32 *) & immap->im_scc[1].scc_sccm,
317 UART_SCCM_TX | UART_SCCM_RX);
318 clrbits32((u32 *) & immap->im_scc[1].scc_gsmrl,
319 SCC_GSMRL_ENR | SCC_GSMRL_ENT);
320#endif
321
322#ifdef CONFIG_SERIAL_CPM_SCC3
323 clrbits32((u32 *) & immap->im_scc[2].scc_sccm,
324 UART_SCCM_TX | UART_SCCM_RX);
325 clrbits32((u32 *) & immap->im_scc[2].scc_gsmrl,
326 SCC_GSMRL_ENR | SCC_GSMRL_ENT);
327#endif
328
329#ifdef CONFIG_SERIAL_CPM_SCC4
330 clrbits32((u32 *) & immap->im_scc[3].scc_sccm,
331 UART_SCCM_TX | UART_SCCM_RX);
332 clrbits32((u32 *) & immap->im_scc[3].scc_gsmrl,
333 SCC_GSMRL_ENR | SCC_GSMRL_ENT);
334#endif
335
336 iounmap(bcsr);
337 iounmap(immap);
338}
339
340#ifdef CONFIG_PCI
341static void m82xx_pci_mask_irq(unsigned int irq)
342{
343 int bit = irq - pci_int_base;
344
345 *pci_regs.pci_int_mask_reg |= (1 << (31 - bit));
346 return;
347}
348
349static void m82xx_pci_unmask_irq(unsigned int irq)
350{
351 int bit = irq - pci_int_base;
352
353 *pci_regs.pci_int_mask_reg &= ~(1 << (31 - bit));
354 return;
355}
356
357static void m82xx_pci_mask_and_ack(unsigned int irq)
358{
359 int bit = irq - pci_int_base;
360
361 *pci_regs.pci_int_mask_reg |= (1 << (31 - bit));
362 return;
363}
364
365static void m82xx_pci_end_irq(unsigned int irq)
366{
367 int bit = irq - pci_int_base;
368
369 *pci_regs.pci_int_mask_reg &= ~(1 << (31 - bit));
370 return;
371}
372
373struct hw_interrupt_type m82xx_pci_ic = {
374 .typename = "MPC82xx ADS PCI",
375 .name = "MPC82xx ADS PCI",
376 .enable = m82xx_pci_unmask_irq,
377 .disable = m82xx_pci_mask_irq,
378 .ack = m82xx_pci_mask_and_ack,
379 .end = m82xx_pci_end_irq,
380 .mask = m82xx_pci_mask_irq,
381 .mask_ack = m82xx_pci_mask_and_ack,
382 .unmask = m82xx_pci_unmask_irq,
383 .eoi = m82xx_pci_end_irq,
384};
385
386static void
387m82xx_pci_irq_demux(unsigned int irq, struct irq_desc *desc,
388 struct pt_regs *regs)
389{
390 unsigned long stat, mask, pend;
391 int bit;
392
393 for (;;) {
394 stat = *pci_regs.pci_int_stat_reg;
395 mask = *pci_regs.pci_int_mask_reg;
396 pend = stat & ~mask & 0xf0000000;
397 if (!pend)
398 break;
399 for (bit = 0; pend != 0; ++bit, pend <<= 1) {
400 if (pend & 0x80000000)
401 __do_IRQ(pci_int_base + bit, regs);
402 }
403 }
404}
405
406static int pci_pic_host_match(struct irq_host *h, struct device_node *node)
407{
408 return node == pci_pic_node;
409}
410
411static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
412 irq_hw_number_t hw)
413{
414 get_irq_desc(virq)->status |= IRQ_LEVEL;
415 set_irq_chip(virq, &m82xx_pci_ic);
416 return 0;
417}
418
419static void pci_host_unmap(struct irq_host *h, unsigned int virq)
420{
421 /* remove chip and handler */
422 set_irq_chip(virq, NULL);
423}
424
425static struct irq_host_ops pci_pic_host_ops = {
426 .match = pci_pic_host_match,
427 .map = pci_pic_host_map,
428 .unmap = pci_host_unmap,
429};
430
431void m82xx_pci_init_irq(void)
432{
433 int irq;
434 cpm2_map_t *immap;
435 struct device_node *np;
436 struct resource r;
437 const u32 *regs;
438 unsigned int size;
439 const u32 *irq_map;
440 int i;
441 unsigned int irq_max, irq_min;
442
443 if ((np = of_find_node_by_type(NULL, "soc")) == NULL) {
444 printk(KERN_INFO "No SOC node in device tree\n");
445 return;
446 }
447 memset(&r, 0, sizeof(r));
448 if (of_address_to_resource(np, 0, &r)) {
449 printk(KERN_INFO "No SOC reg property in device tree\n");
450 return;
451 }
452 immap = ioremap(r.start, sizeof(*immap));
453 of_node_put(np);
454
455 /* install the demultiplexer for the PCI cascade interrupt */
456 np = of_find_node_by_type(NULL, "pci");
457 if (!np) {
458 printk(KERN_INFO "No pci node on device tree\n");
459 iounmap(immap);
460 return;
461 }
462 irq_map = get_property(np, "interrupt-map", &size);
463 if ((!irq_map) || (size <= 7)) {
464 printk(KERN_INFO "No interrupt-map property of pci node\n");
465 iounmap(immap);
466 return;
467 }
468 size /= sizeof(irq_map[0]);
469 for (i = 0, irq_max = 0, irq_min = 512; i < size; i += 7, irq_map += 7) {
470 if (irq_map[5] < irq_min)
471 irq_min = irq_map[5];
472 if (irq_map[5] > irq_max)
473 irq_max = irq_map[5];
474 }
475 pci_int_base = irq_min;
476 irq = irq_of_parse_and_map(np, 0);
477 set_irq_chained_handler(irq, m82xx_pci_irq_demux);
478 of_node_put(np);
479 np = of_find_node_by_type(NULL, "pci-pic");
480 if (!np) {
481 printk(KERN_INFO "No pci pic node on device tree\n");
482 iounmap(immap);
483 return;
484 }
485 pci_pic_node = of_node_get(np);
486 /* PCI interrupt controller registers: status and mask */
487 regs = get_property(np, "reg", &size);
488 if ((!regs) || (size <= 2)) {
489 printk(KERN_INFO "No reg property in pci pic node\n");
490 iounmap(immap);
491 return;
492 }
493 pci_regs.pci_int_stat_reg =
494 ioremap(regs[0], sizeof(*pci_regs.pci_int_stat_reg));
495 pci_regs.pci_int_mask_reg =
496 ioremap(regs[1], sizeof(*pci_regs.pci_int_mask_reg));
497 of_node_put(np);
498 /* configure chip select for PCI interrupt controller */
499 immap->im_memctl.memc_br3 = regs[0] | 0x00001801;
500 immap->im_memctl.memc_or3 = 0xffff8010;
501 /* make PCI IRQ level sensitive */
502 immap->im_intctl.ic_siexr &= ~(1 << (14 - (irq - SIU_INT_IRQ1)));
503
504 /* mask all PCI interrupts */
505 *pci_regs.pci_int_mask_reg |= 0xfff00000;
506 iounmap(immap);
507 pci_pic_host =
508 irq_alloc_host(IRQ_HOST_MAP_LINEAR, irq_max - irq_min + 1,
509 &pci_pic_host_ops, irq_max + 1);
510 return;
511}
512
513static int m82xx_pci_exclude_device(u_char bus, u_char devfn)
514{
515 if (bus == 0 && PCI_SLOT(devfn) == 0)
516 return PCIBIOS_DEVICE_NOT_FOUND;
517 else
518 return PCIBIOS_SUCCESSFUL;
519}
520
521static void
522__init mpc82xx_pcibios_fixup(void)
523{
524 struct pci_dev *dev = NULL;
525
526 for_each_pci_dev(dev) {
527 pci_read_irq_line(dev);
528 }
529}
530
531void __init add_bridge(struct device_node *np)
532{
533 int len;
534 struct pci_controller *hose;
535 struct resource r;
536 const int *bus_range;
537 const void *ptr;
538
539 memset(&r, 0, sizeof(r));
540 if (of_address_to_resource(np, 0, &r)) {
541 printk(KERN_INFO "No PCI reg property in device tree\n");
542 return;
543 }
544 if (!(ptr = get_property(np, "clock-frequency", NULL))) {
545 printk(KERN_INFO "No clock-frequency property in PCI node");
546 return;
547 }
548 pci_clk_frq = *(uint *) ptr;
549 of_node_put(np);
550 bus_range = get_property(np, "bus-range", &len);
551 if (bus_range == NULL || len < 2 * sizeof(int)) {
552 printk(KERN_WARNING "Can't get bus-range for %s, assume"
553 " bus 0\n", np->full_name);
554 }
555
556 pci_assign_all_buses = 1;
557
558 hose = pcibios_alloc_controller();
559
560 if (!hose)
561 return;
562
563 hose->arch_data = np;
564 hose->set_cfg_type = 1;
565
566 hose->first_busno = bus_range ? bus_range[0] : 0;
567 hose->last_busno = bus_range ? bus_range[1] : 0xff;
568 hose->bus_offset = 0;
569
570 hose->set_cfg_type = 1;
571
572 setup_indirect_pci(hose,
573 r.start + offsetof(pci_cpm2_t, pci_cfg_addr),
574 r.start + offsetof(pci_cpm2_t, pci_cfg_data));
575
576 pci_process_bridge_OF_ranges(hose, np, 1);
577}
578#endif
579
580/*
581 * Setup the architecture
582 */
583static void __init mpc82xx_ads_setup_arch(void)
584{
585#ifdef CONFIG_PCI
586 struct device_node *np;
587#endif
588
589 if (ppc_md.progress)
590 ppc_md.progress("mpc82xx_ads_setup_arch()", 0);
591 cpm2_reset();
592
593 /* Map I/O region to a 256MB BAT */
594
595 m82xx_board_setup();
596
597#ifdef CONFIG_PCI
598 ppc_md.pci_exclude_device = m82xx_pci_exclude_device;
599 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
600 add_bridge(np);
601
602 of_node_put(np);
603 ppc_md.pci_map_irq = NULL;
604 ppc_md.pcibios_fixup = mpc82xx_pcibios_fixup;
605 ppc_md.pcibios_fixup_bus = NULL;
606#endif
607
608#ifdef CONFIG_ROOT_NFS
609 ROOT_DEV = Root_NFS;
610#else
611 ROOT_DEV = Root_HDA1;
612#endif
613
614 if (ppc_md.progress)
615 ppc_md.progress("mpc82xx_ads_setup_arch(), finish", 0);
616}
617
618/*
619 * Called very early, device-tree isn't unflattened
620 */
621static int __init mpc82xx_ads_probe(void)
622{
623 /* We always match for now, eventually we should look at
624 * the flat dev tree to ensure this is the board we are
625 * supposed to run on
626 */
627 return 1;
628}
629
630#define RMR_CSRE 0x00000001
631static void m82xx_restart(char *cmd)
632{
633 __volatile__ unsigned char dummy;
634
635 local_irq_disable();
636 ((cpm2_map_t *) cpm2_immr)->im_clkrst.car_rmr |= RMR_CSRE;
637
638 /* Clear the ME,EE,IR & DR bits in MSR to cause checkstop */
639 mtmsr(mfmsr() & ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR));
640 dummy = ((cpm2_map_t *) cpm2_immr)->im_clkrst.res[0];
641 printk("Restart failed\n");
642 while (1) ;
643}
644
645static void m82xx_halt(void)
646{
647 local_irq_disable();
648 while (1) ;
649}
650
651define_machine(mpc82xx_ads)
652{
653 .name = "MPC82xx ADS",
654 .probe = mpc82xx_ads_probe,
655 .setup_arch = mpc82xx_ads_setup_arch,
656 .init_IRQ = mpc82xx_ads_pic_init,
657 .show_cpuinfo = mpc82xx_ads_show_cpuinfo,
658 .get_irq = cpm2_get_irq,
659 .calibrate_decr = m82xx_calibrate_decr,
660 .restart = m82xx_restart,.halt = m82xx_halt,
661};
diff --git a/arch/powerpc/platforms/82xx/pq2ads.h b/arch/powerpc/platforms/82xx/pq2ads.h
new file mode 100644
index 000000000000..a7348213508f
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/pq2ads.h
@@ -0,0 +1,67 @@
1/*
2 * PQ2/mpc8260 board-specific stuff
3 *
4 * A collection of structures, addresses, and values associated with
5 * the Freescale MPC8260ADS/MPC8266ADS-PCI boards.
6 * Copied from the RPX-Classic and SBS8260 stuff.
7 *
8 * Author: Vitaly Bordug <vbordug@ru.mvista.com>
9 *
10 * Originally written by Dan Malek for Motorola MPC8260 family
11 *
12 * Copyright (c) 2001 Dan Malek <dan@embeddedalley.com>
13 * Copyright (c) 2006 MontaVista Software, Inc.
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 */
20
21#ifdef __KERNEL__
22#ifndef __MACH_ADS8260_DEFS
23#define __MACH_ADS8260_DEFS
24
25#include <linux/config.h>
26
27#include <asm/ppcboot.h>
28
29/* For our show_cpuinfo hooks. */
30#define CPUINFO_VENDOR "Freescale Semiconductor"
31#define CPUINFO_MACHINE "PQ2 ADS PowerPC"
32
33/* Backword-compatibility stuff for the drivers */
34#define CPM_MAP_ADDR ((uint)0xf0000000)
35#define CPM_IRQ_OFFSET 0
36
37/* The ADS8260 has 16, 32-bit wide control/status registers, accessed
38 * only on word boundaries.
39 * Not all are used (yet), or are interesting to us (yet).
40 */
41
42/* Things of interest in the CSR.
43 */
44#define BCSR0_LED0 ((uint)0x02000000) /* 0 == on */
45#define BCSR0_LED1 ((uint)0x01000000) /* 0 == on */
46#define BCSR1_FETHIEN ((uint)0x08000000) /* 0 == enable*/
47#define BCSR1_FETH_RST ((uint)0x04000000) /* 0 == reset */
48#define BCSR1_RS232_EN1 ((uint)0x02000000) /* 0 ==enable */
49#define BCSR1_RS232_EN2 ((uint)0x01000000) /* 0 ==enable */
50#define BCSR3_FETHIEN2 ((uint)0x10000000) /* 0 == enable*/
51#define BCSR3_FETH2_RS ((uint)0x80000000) /* 0 == reset */
52
53/* cpm serial driver works with constants below */
54
55#define SIU_INT_SMC1 ((uint)0x04+CPM_IRQ_OFFSET)
56#define SIU_INT_SMC2i ((uint)0x05+CPM_IRQ_OFFSET)
57#define SIU_INT_SCC1 ((uint)0x28+CPM_IRQ_OFFSET)
58#define SIU_INT_SCC2 ((uint)0x29+CPM_IRQ_OFFSET)
59#define SIU_INT_SCC3 ((uint)0x2a+CPM_IRQ_OFFSET)
60#define SIU_INT_SCC4 ((uint)0x2b+CPM_IRQ_OFFSET)
61
62void m82xx_pci_init_irq(void);
63void mpc82xx_ads_show_cpuinfo(struct seq_file*);
64void m82xx_calibrate_decr(void);
65
66#endif /* __MACH_ADS8260_DEFS */
67#endif /* __KERNEL__ */
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 5fe7b7faf45f..0975e94ac7c4 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -5,6 +5,13 @@ choice
5 prompt "Machine Type" 5 prompt "Machine Type"
6 default MPC834x_SYS 6 default MPC834x_SYS
7 7
8config MPC832x_MDS
9 bool "Freescale MPC832x MDS"
10 select DEFAULT_UIMAGE
11 select QUICC_ENGINE
12 help
13 This option enables support for the MPC832x MDS evaluation board.
14
8config MPC834x_SYS 15config MPC834x_SYS
9 bool "Freescale MPC834x SYS" 16 bool "Freescale MPC834x SYS"
10 select DEFAULT_UIMAGE 17 select DEFAULT_UIMAGE
@@ -27,6 +34,12 @@ config MPC834x_ITX
27 34
28endchoice 35endchoice
29 36
37config PPC_MPC832x
38 bool
39 select PPC_UDBG_16550
40 select PPC_INDIRECT_PCI
41 default y if MPC832x_MDS
42
30config MPC834x 43config MPC834x
31 bool 44 bool
32 select PPC_UDBG_16550 45 select PPC_UDBG_16550
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
new file mode 100644
index 000000000000..54dea9d42dc9
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -0,0 +1,215 @@
1/*
2 * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
3 *
4 * Description:
5 * MPC832xE MDS board specific routines.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/stddef.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/errno.h>
17#include <linux/reboot.h>
18#include <linux/pci.h>
19#include <linux/kdev_t.h>
20#include <linux/major.h>
21#include <linux/console.h>
22#include <linux/delay.h>
23#include <linux/seq_file.h>
24#include <linux/root_dev.h>
25#include <linux/initrd.h>
26
27#include <asm/system.h>
28#include <asm/atomic.h>
29#include <asm/time.h>
30#include <asm/io.h>
31#include <asm/machdep.h>
32#include <asm/ipic.h>
33#include <asm/bootinfo.h>
34#include <asm/irq.h>
35#include <asm/prom.h>
36#include <asm/udbg.h>
37#include <sysdev/fsl_soc.h>
38#include <asm/qe.h>
39#include <asm/qe_ic.h>
40
41#include "mpc83xx.h"
42#include "mpc832x_mds.h"
43
44#undef DEBUG
45#ifdef DEBUG
46#define DBG(fmt...) udbg_printf(fmt)
47#else
48#define DBG(fmt...)
49#endif
50
51#ifndef CONFIG_PCI
52unsigned long isa_io_base = 0;
53unsigned long isa_mem_base = 0;
54#endif
55
56static u8 *bcsr_regs = NULL;
57
58u8 *get_bcsr(void)
59{
60 return bcsr_regs;
61}
62
63/* ************************************************************************
64 *
65 * Setup the architecture
66 *
67 */
68static void __init mpc832x_sys_setup_arch(void)
69{
70 struct device_node *np;
71
72 if (ppc_md.progress)
73 ppc_md.progress("mpc832x_sys_setup_arch()", 0);
74
75 np = of_find_node_by_type(NULL, "cpu");
76 if (np != 0) {
77 unsigned int *fp =
78 (int *)get_property(np, "clock-frequency", NULL);
79 if (fp != 0)
80 loops_per_jiffy = *fp / HZ;
81 else
82 loops_per_jiffy = 50000000 / HZ;
83 of_node_put(np);
84 }
85
86 /* Map BCSR area */
87 np = of_find_node_by_name(NULL, "bcsr");
88 if (np != 0) {
89 struct resource res;
90
91 of_address_to_resource(np, 0, &res);
92 bcsr_regs = ioremap(res.start, res.end - res.start +1);
93 of_node_put(np);
94 }
95
96#ifdef CONFIG_PCI
97 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
98 add_bridge(np);
99
100 ppc_md.pci_swizzle = common_swizzle;
101 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
102#endif
103
104#ifdef CONFIG_QUICC_ENGINE
105 qe_reset();
106
107 if ((np = of_find_node_by_name(np, "par_io")) != NULL) {
108 par_io_init(np);
109 of_node_put(np);
110
111 for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;)
112 par_io_of_config(np);
113 }
114
115 if ((np = of_find_compatible_node(NULL, "network", "ucc_geth"))
116 != NULL){
117 /* Reset the Ethernet PHY */
118 bcsr_regs[9] &= ~0x20;
119 udelay(1000);
120 bcsr_regs[9] |= 0x20;
121 iounmap(bcsr_regs);
122 of_node_put(np);
123 }
124
125#endif /* CONFIG_QUICC_ENGINE */
126
127#ifdef CONFIG_BLK_DEV_INITRD
128 if (initrd_start)
129 ROOT_DEV = Root_RAM0;
130 else
131#endif
132#ifdef CONFIG_ROOT_NFS
133 ROOT_DEV = Root_NFS;
134#else
135 ROOT_DEV = Root_HDA1;
136#endif
137}
138
139void __init mpc832x_sys_init_IRQ(void)
140{
141
142 struct device_node *np;
143
144 np = of_find_node_by_type(NULL, "ipic");
145 if (!np)
146 return;
147
148 ipic_init(np, 0);
149
150 /* Initialize the default interrupt mapping priorities,
151 * in case the boot rom changed something on us.
152 */
153 ipic_set_default_priority();
154 of_node_put(np);
155
156#ifdef CONFIG_QUICC_ENGINE
157 np = of_find_node_by_type(NULL, "qeic");
158 if (!np)
159 return;
160
161 qe_ic_init(np, 0);
162 of_node_put(np);
163#endif /* CONFIG_QUICC_ENGINE */
164}
165
166#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
167extern ulong ds1374_get_rtc_time(void);
168extern int ds1374_set_rtc_time(ulong);
169
170static int __init mpc832x_rtc_hookup(void)
171{
172 struct timespec tv;
173
174 ppc_md.get_rtc_time = ds1374_get_rtc_time;
175 ppc_md.set_rtc_time = ds1374_set_rtc_time;
176
177 tv.tv_nsec = 0;
178 tv.tv_sec = (ppc_md.get_rtc_time) ();
179 do_settimeofday(&tv);
180
181 return 0;
182}
183
184late_initcall(mpc832x_rtc_hookup);
185#endif
186
187/*
188 * Called very early, MMU is off, device-tree isn't unflattened
189 */
190static int __init mpc832x_sys_probe(void)
191{
192 char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
193 "model", NULL);
194
195 if (model == NULL)
196 return 0;
197 if (strcmp(model, "MPC8323EMDS"))
198 return 0;
199
200 DBG("%s found\n", model);
201
202 return 1;
203}
204
205define_machine(mpc832x_mds) {
206 .name = "MPC832x MDS",
207 .probe = mpc832x_sys_probe,
208 .setup_arch = mpc832x_sys_setup_arch,
209 .init_IRQ = mpc832x_sys_init_IRQ,
210 .get_irq = ipic_get_irq,
211 .restart = mpc83xx_restart,
212 .time_init = mpc83xx_time_init,
213 .calibrate_decr = generic_calibrate_decr,
214 .progress = udbg_progress,
215};
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.h b/arch/powerpc/platforms/83xx/mpc832x_mds.h
new file mode 100644
index 000000000000..a49588904f8a
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.h
@@ -0,0 +1,19 @@
1/*
2 * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
3 *
4 * Description:
5 * MPC832x MDS board specific header.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#ifndef __MACH_MPC832x_MDS_H__
15#define __MACH_MPC832x_MDS_H__
16
17extern u8 *get_bcsr(void);
18
19#endif /* __MACH_MPC832x_MDS_H__ */
diff --git a/arch/powerpc/platforms/83xx/mpc8360e_pb.c b/arch/powerpc/platforms/83xx/mpc8360e_pb.c
new file mode 100644
index 000000000000..c0191900fc25
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/mpc8360e_pb.c
@@ -0,0 +1,219 @@
1/*
2 * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
3 *
4 * Author: Li Yang <LeoLi@freescale.com>
5 * Yin Olivia <Hong-hua.Yin@freescale.com>
6 *
7 * Description:
8 * MPC8360E MDS PB board specific routines.
9 *
10 * Changelog:
11 * Jun 21, 2006 Initial version
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 */
18
19#include <linux/stddef.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/errno.h>
23#include <linux/reboot.h>
24#include <linux/pci.h>
25#include <linux/kdev_t.h>
26#include <linux/major.h>
27#include <linux/console.h>
28#include <linux/delay.h>
29#include <linux/seq_file.h>
30#include <linux/root_dev.h>
31#include <linux/initrd.h>
32
33#include <asm/system.h>
34#include <asm/atomic.h>
35#include <asm/time.h>
36#include <asm/io.h>
37#include <asm/machdep.h>
38#include <asm/ipic.h>
39#include <asm/bootinfo.h>
40#include <asm/irq.h>
41#include <asm/prom.h>
42#include <asm/udbg.h>
43#include <sysdev/fsl_soc.h>
44#include <asm/qe.h>
45#include <asm/qe_ic.h>
46
47#include "mpc83xx.h"
48
49#undef DEBUG
50#ifdef DEBUG
51#define DBG(fmt...) udbg_printf(fmt)
52#else
53#define DBG(fmt...)
54#endif
55
56#ifndef CONFIG_PCI
57unsigned long isa_io_base = 0;
58unsigned long isa_mem_base = 0;
59#endif
60
61static u8 *bcsr_regs = NULL;
62
63u8 *get_bcsr(void)
64{
65 return bcsr_regs;
66}
67
68/* ************************************************************************
69 *
70 * Setup the architecture
71 *
72 */
73static void __init mpc8360_sys_setup_arch(void)
74{
75 struct device_node *np;
76
77 if (ppc_md.progress)
78 ppc_md.progress("mpc8360_sys_setup_arch()", 0);
79
80 np = of_find_node_by_type(NULL, "cpu");
81 if (np != 0) {
82 const unsigned int *fp =
83 get_property(np, "clock-frequency", NULL);
84 if (fp != 0)
85 loops_per_jiffy = *fp / HZ;
86 else
87 loops_per_jiffy = 50000000 / HZ;
88 of_node_put(np);
89 }
90
91 /* Map BCSR area */
92 np = of_find_node_by_name(NULL, "bcsr");
93 if (np != 0) {
94 struct resource res;
95
96 of_address_to_resource(np, 0, &res);
97 bcsr_regs = ioremap(res.start, res.end - res.start +1);
98 of_node_put(np);
99 }
100
101#ifdef CONFIG_PCI
102 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
103 add_bridge(np);
104
105 ppc_md.pci_swizzle = common_swizzle;
106 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
107#endif
108
109#ifdef CONFIG_QUICC_ENGINE
110 qe_reset();
111
112 if ((np = of_find_node_by_name(np, "par_io")) != NULL) {
113 par_io_init(np);
114 of_node_put(np);
115
116 for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;)
117 par_io_of_config(np);
118 }
119
120 if ((np = of_find_compatible_node(NULL, "network", "ucc_geth"))
121 != NULL){
122 /* Reset the Ethernet PHY */
123 bcsr_regs[9] &= ~0x20;
124 udelay(1000);
125 bcsr_regs[9] |= 0x20;
126 iounmap(bcsr_regs);
127 of_node_put(np);
128 }
129
130#endif /* CONFIG_QUICC_ENGINE */
131
132#ifdef CONFIG_BLK_DEV_INITRD
133 if (initrd_start)
134 ROOT_DEV = Root_RAM0;
135 else
136#endif
137#ifdef CONFIG_ROOT_NFS
138 ROOT_DEV = Root_NFS;
139#else
140 ROOT_DEV = Root_HDA1;
141#endif
142}
143
144void __init mpc8360_sys_init_IRQ(void)
145{
146
147 struct device_node *np;
148
149 np = of_find_node_by_type(NULL, "ipic");
150 if (!np)
151 return;
152
153 ipic_init(np, 0);
154
155 /* Initialize the default interrupt mapping priorities,
156 * in case the boot rom changed something on us.
157 */
158 ipic_set_default_priority();
159 of_node_put(np);
160
161#ifdef CONFIG_QUICC_ENGINE
162 np = of_find_node_by_type(NULL, "qeic");
163 if (!np)
164 return;
165
166 qe_ic_init(np, 0);
167 of_node_put(np);
168#endif /* CONFIG_QUICC_ENGINE */
169}
170
171#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
172extern ulong ds1374_get_rtc_time(void);
173extern int ds1374_set_rtc_time(ulong);
174
175static int __init mpc8360_rtc_hookup(void)
176{
177 struct timespec tv;
178
179 ppc_md.get_rtc_time = ds1374_get_rtc_time;
180 ppc_md.set_rtc_time = ds1374_set_rtc_time;
181
182 tv.tv_nsec = 0;
183 tv.tv_sec = (ppc_md.get_rtc_time) ();
184 do_settimeofday(&tv);
185
186 return 0;
187}
188
189late_initcall(mpc8360_rtc_hookup);
190#endif
191
192/*
193 * Called very early, MMU is off, device-tree isn't unflattened
194 */
195static int __init mpc8360_sys_probe(void)
196{
197 char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
198 "model", NULL);
199 if (model == NULL)
200 return 0;
201 if (strcmp(model, "MPC8360EPB"))
202 return 0;
203
204 DBG("MPC8360EMDS-PB found\n");
205
206 return 1;
207}
208
209define_machine(mpc8360_sys) {
210 .name = "MPC8360E PB",
211 .probe = mpc8360_sys_probe,
212 .setup_arch = mpc8360_sys_setup_arch,
213 .init_IRQ = mpc8360_sys_init_IRQ,
214 .get_irq = ipic_get_irq,
215 .restart = mpc83xx_restart,
216 .time_init = mpc83xx_time_init,
217 .calibrate_decr = generic_calibrate_decr,
218 .progress = udbg_progress,
219};
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 6b57a47c5d37..6cc59e0b4582 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -21,6 +21,12 @@
21 * You should have received a copy of the GNU General Public License 21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software 22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * TODO:
26 * - Fix various assumptions related to HW CPU numbers vs. linux CPU numbers
27 * vs node numbers in the setup code
28 * - Implement proper handling of maxcpus=1/2 (that is, routing of irqs from
29 * a non-active node to the active node)
24 */ 30 */
25 31
26#include <linux/interrupt.h> 32#include <linux/interrupt.h>
@@ -44,24 +50,25 @@ struct iic {
44 u8 target_id; 50 u8 target_id;
45 u8 eoi_stack[16]; 51 u8 eoi_stack[16];
46 int eoi_ptr; 52 int eoi_ptr;
47 struct irq_host *host; 53 struct device_node *node;
48}; 54};
49 55
50static DEFINE_PER_CPU(struct iic, iic); 56static DEFINE_PER_CPU(struct iic, iic);
51#define IIC_NODE_COUNT 2 57#define IIC_NODE_COUNT 2
52static struct irq_host *iic_hosts[IIC_NODE_COUNT]; 58static struct irq_host *iic_host;
53 59
54/* Convert between "pending" bits and hw irq number */ 60/* Convert between "pending" bits and hw irq number */
55static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits) 61static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits)
56{ 62{
57 unsigned char unit = bits.source & 0xf; 63 unsigned char unit = bits.source & 0xf;
64 unsigned char node = bits.source >> 4;
65 unsigned char class = bits.class & 3;
58 66
67 /* Decode IPIs */
59 if (bits.flags & CBE_IIC_IRQ_IPI) 68 if (bits.flags & CBE_IIC_IRQ_IPI)
60 return IIC_IRQ_IPI0 | (bits.prio >> 4); 69 return IIC_IRQ_TYPE_IPI | (bits.prio >> 4);
61 else if (bits.class <= 3)
62 return (bits.class << 4) | unit;
63 else 70 else
64 return IIC_IRQ_INVALID; 71 return (node << IIC_IRQ_NODE_SHIFT) | (class << 4) | unit;
65} 72}
66 73
67static void iic_mask(unsigned int irq) 74static void iic_mask(unsigned int irq)
@@ -86,21 +93,70 @@ static struct irq_chip iic_chip = {
86 .eoi = iic_eoi, 93 .eoi = iic_eoi,
87}; 94};
88 95
96
97static void iic_ioexc_eoi(unsigned int irq)
98{
99}
100
101static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc,
102 struct pt_regs *regs)
103{
104 struct cbe_iic_regs *node_iic = desc->handler_data;
105 unsigned int base = (irq & 0xffffff00) | IIC_IRQ_TYPE_IOEXC;
106 unsigned long bits, ack;
107 int cascade;
108
109 for (;;) {
110 bits = in_be64(&node_iic->iic_is);
111 if (bits == 0)
112 break;
113 /* pre-ack edge interrupts */
114 ack = bits & IIC_ISR_EDGE_MASK;
115 if (ack)
116 out_be64(&node_iic->iic_is, ack);
117 /* handle them */
118 for (cascade = 63; cascade >= 0; cascade--)
119 if (bits & (0x8000000000000000UL >> cascade)) {
120 unsigned int cirq =
121 irq_linear_revmap(iic_host,
122 base | cascade);
123 if (cirq != NO_IRQ)
124 generic_handle_irq(cirq, regs);
125 }
126 /* post-ack level interrupts */
127 ack = bits & ~IIC_ISR_EDGE_MASK;
128 if (ack)
129 out_be64(&node_iic->iic_is, ack);
130 }
131 desc->chip->eoi(irq);
132}
133
134
135static struct irq_chip iic_ioexc_chip = {
136 .typename = " CELL-IOEX",
137 .mask = iic_mask,
138 .unmask = iic_unmask,
139 .eoi = iic_ioexc_eoi,
140};
141
89/* Get an IRQ number from the pending state register of the IIC */ 142/* Get an IRQ number from the pending state register of the IIC */
90static unsigned int iic_get_irq(struct pt_regs *regs) 143static unsigned int iic_get_irq(struct pt_regs *regs)
91{ 144{
92 struct cbe_iic_pending_bits pending; 145 struct cbe_iic_pending_bits pending;
93 struct iic *iic; 146 struct iic *iic;
147 unsigned int virq;
94 148
95 iic = &__get_cpu_var(iic); 149 iic = &__get_cpu_var(iic);
96 *(unsigned long *) &pending = 150 *(unsigned long *) &pending =
97 in_be64((unsigned long __iomem *) &iic->regs->pending_destr); 151 in_be64((unsigned long __iomem *) &iic->regs->pending_destr);
152 if (!(pending.flags & CBE_IIC_IRQ_VALID))
153 return NO_IRQ;
154 virq = irq_linear_revmap(iic_host, iic_pending_to_hwnum(pending));
155 if (virq == NO_IRQ)
156 return NO_IRQ;
98 iic->eoi_stack[++iic->eoi_ptr] = pending.prio; 157 iic->eoi_stack[++iic->eoi_ptr] = pending.prio;
99 BUG_ON(iic->eoi_ptr > 15); 158 BUG_ON(iic->eoi_ptr > 15);
100 if (pending.flags & CBE_IIC_IRQ_VALID) 159 return virq;
101 return irq_linear_revmap(iic->host,
102 iic_pending_to_hwnum(pending));
103 return NO_IRQ;
104} 160}
105 161
106#ifdef CONFIG_SMP 162#ifdef CONFIG_SMP
@@ -108,12 +164,7 @@ static unsigned int iic_get_irq(struct pt_regs *regs)
108/* Use the highest interrupt priorities for IPI */ 164/* Use the highest interrupt priorities for IPI */
109static inline int iic_ipi_to_irq(int ipi) 165static inline int iic_ipi_to_irq(int ipi)
110{ 166{
111 return IIC_IRQ_IPI0 + IIC_NUM_IPIS - 1 - ipi; 167 return IIC_IRQ_TYPE_IPI + 0xf - ipi;
112}
113
114static inline int iic_irq_to_ipi(int irq)
115{
116 return IIC_NUM_IPIS - 1 - (irq - IIC_IRQ_IPI0);
117} 168}
118 169
119void iic_setup_cpu(void) 170void iic_setup_cpu(void)
@@ -123,7 +174,7 @@ void iic_setup_cpu(void)
123 174
124void iic_cause_IPI(int cpu, int mesg) 175void iic_cause_IPI(int cpu, int mesg)
125{ 176{
126 out_be64(&per_cpu(iic, cpu).regs->generate, (IIC_NUM_IPIS - 1 - mesg) << 4); 177 out_be64(&per_cpu(iic, cpu).regs->generate, (0xf - mesg) << 4);
127} 178}
128 179
129u8 iic_get_target_id(int cpu) 180u8 iic_get_target_id(int cpu)
@@ -134,9 +185,7 @@ EXPORT_SYMBOL_GPL(iic_get_target_id);
134 185
135struct irq_host *iic_get_irq_host(int node) 186struct irq_host *iic_get_irq_host(int node)
136{ 187{
137 if (node < 0 || node >= IIC_NODE_COUNT) 188 return iic_host;
138 return NULL;
139 return iic_hosts[node];
140} 189}
141EXPORT_SYMBOL_GPL(iic_get_irq_host); 190EXPORT_SYMBOL_GPL(iic_get_irq_host);
142 191
@@ -149,34 +198,20 @@ static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
149 198
150 return IRQ_HANDLED; 199 return IRQ_HANDLED;
151} 200}
152
153static void iic_request_ipi(int ipi, const char *name) 201static void iic_request_ipi(int ipi, const char *name)
154{ 202{
155 int node, virq; 203 int virq;
156 204
157 for (node = 0; node < IIC_NODE_COUNT; node++) { 205 virq = irq_create_mapping(iic_host, iic_ipi_to_irq(ipi));
158 char *rname; 206 if (virq == NO_IRQ) {
159 if (iic_hosts[node] == NULL) 207 printk(KERN_ERR
160 continue; 208 "iic: failed to map IPI %s\n", name);
161 virq = irq_create_mapping(iic_hosts[node], 209 return;
162 iic_ipi_to_irq(ipi));
163 if (virq == NO_IRQ) {
164 printk(KERN_ERR
165 "iic: failed to map IPI %s on node %d\n",
166 name, node);
167 continue;
168 }
169 rname = kzalloc(strlen(name) + 16, GFP_KERNEL);
170 if (rname)
171 sprintf(rname, "%s node %d", name, node);
172 else
173 rname = (char *)name;
174 if (request_irq(virq, iic_ipi_action, IRQF_DISABLED,
175 rname, (void *)(long)ipi))
176 printk(KERN_ERR
177 "iic: failed to request IPI %s on node %d\n",
178 name, node);
179 } 210 }
211 if (request_irq(virq, iic_ipi_action, IRQF_DISABLED, name,
212 (void *)(long)ipi))
213 printk(KERN_ERR
214 "iic: failed to request IPI %s\n", name);
180} 215}
181 216
182void iic_request_IPIs(void) 217void iic_request_IPIs(void)
@@ -193,16 +228,24 @@ void iic_request_IPIs(void)
193 228
194static int iic_host_match(struct irq_host *h, struct device_node *node) 229static int iic_host_match(struct irq_host *h, struct device_node *node)
195{ 230{
196 return h->host_data != NULL && node == h->host_data; 231 return device_is_compatible(node,
232 "IBM,CBEA-Internal-Interrupt-Controller");
197} 233}
198 234
199static int iic_host_map(struct irq_host *h, unsigned int virq, 235static int iic_host_map(struct irq_host *h, unsigned int virq,
200 irq_hw_number_t hw) 236 irq_hw_number_t hw)
201{ 237{
202 if (hw < IIC_IRQ_IPI0) 238 switch (hw & IIC_IRQ_TYPE_MASK) {
203 set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq); 239 case IIC_IRQ_TYPE_IPI:
204 else
205 set_irq_chip_and_handler(virq, &iic_chip, handle_percpu_irq); 240 set_irq_chip_and_handler(virq, &iic_chip, handle_percpu_irq);
241 break;
242 case IIC_IRQ_TYPE_IOEXC:
243 set_irq_chip_and_handler(virq, &iic_ioexc_chip,
244 handle_fasteoi_irq);
245 break;
246 default:
247 set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq);
248 }
206 return 0; 249 return 0;
207} 250}
208 251
@@ -211,11 +254,39 @@ static int iic_host_xlate(struct irq_host *h, struct device_node *ct,
211 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 254 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
212 255
213{ 256{
214 /* Currently, we don't translate anything. That needs to be fixed as 257 unsigned int node, ext, unit, class;
215 * we get better defined device-trees. iic interrupts have to be 258 const u32 *val;
216 * explicitely mapped by whoever needs them 259
217 */ 260 if (!device_is_compatible(ct,
218 return -ENODEV; 261 "IBM,CBEA-Internal-Interrupt-Controller"))
262 return -ENODEV;
263 if (intsize != 1)
264 return -ENODEV;
265 val = get_property(ct, "#interrupt-cells", NULL);
266 if (val == NULL || *val != 1)
267 return -ENODEV;
268
269 node = intspec[0] >> 24;
270 ext = (intspec[0] >> 16) & 0xff;
271 class = (intspec[0] >> 8) & 0xff;
272 unit = intspec[0] & 0xff;
273
274 /* Check if node is in supported range */
275 if (node > 1)
276 return -EINVAL;
277
278 /* Build up interrupt number, special case for IO exceptions */
279 *out_hwirq = (node << IIC_IRQ_NODE_SHIFT);
280 if (unit == IIC_UNIT_IIC && class == 1)
281 *out_hwirq |= IIC_IRQ_TYPE_IOEXC | ext;
282 else
283 *out_hwirq |= IIC_IRQ_TYPE_NORMAL |
284 (class << IIC_IRQ_CLASS_SHIFT) | unit;
285
286 /* Dummy flags, ignored by iic code */
287 *out_flags = IRQ_TYPE_EDGE_RISING;
288
289 return 0;
219} 290}
220 291
221static struct irq_host_ops iic_host_ops = { 292static struct irq_host_ops iic_host_ops = {
@@ -225,7 +296,7 @@ static struct irq_host_ops iic_host_ops = {
225}; 296};
226 297
227static void __init init_one_iic(unsigned int hw_cpu, unsigned long addr, 298static void __init init_one_iic(unsigned int hw_cpu, unsigned long addr,
228 struct irq_host *host) 299 struct device_node *node)
229{ 300{
230 /* XXX FIXME: should locate the linux CPU number from the HW cpu 301 /* XXX FIXME: should locate the linux CPU number from the HW cpu
231 * number properly. We are lucky for now 302 * number properly. We are lucky for now
@@ -237,19 +308,19 @@ static void __init init_one_iic(unsigned int hw_cpu, unsigned long addr,
237 308
238 iic->target_id = ((hw_cpu & 2) << 3) | ((hw_cpu & 1) ? 0xf : 0xe); 309 iic->target_id = ((hw_cpu & 2) << 3) | ((hw_cpu & 1) ? 0xf : 0xe);
239 iic->eoi_stack[0] = 0xff; 310 iic->eoi_stack[0] = 0xff;
240 iic->host = host; 311 iic->node = of_node_get(node);
241 out_be64(&iic->regs->prio, 0); 312 out_be64(&iic->regs->prio, 0);
242 313
243 printk(KERN_INFO "IIC for CPU %d at %lx mapped to %p, target id 0x%x\n", 314 printk(KERN_INFO "IIC for CPU %d target id 0x%x : %s\n",
244 hw_cpu, addr, iic->regs, iic->target_id); 315 hw_cpu, iic->target_id, node->full_name);
245} 316}
246 317
247static int __init setup_iic(void) 318static int __init setup_iic(void)
248{ 319{
249 struct device_node *dn; 320 struct device_node *dn;
250 struct resource r0, r1; 321 struct resource r0, r1;
251 struct irq_host *host; 322 unsigned int node, cascade, found = 0;
252 int found = 0; 323 struct cbe_iic_regs *node_iic;
253 const u32 *np; 324 const u32 *np;
254 325
255 for (dn = NULL; 326 for (dn = NULL;
@@ -269,19 +340,33 @@ static int __init setup_iic(void)
269 of_node_put(dn); 340 of_node_put(dn);
270 return -ENODEV; 341 return -ENODEV;
271 } 342 }
272 host = NULL; 343 found++;
273 if (found < IIC_NODE_COUNT) { 344 init_one_iic(np[0], r0.start, dn);
274 host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 345 init_one_iic(np[1], r1.start, dn);
275 IIC_SOURCE_COUNT, 346
276 &iic_host_ops, 347 /* Setup cascade for IO exceptions. XXX cleanup tricks to get
277 IIC_IRQ_INVALID); 348 * node vs CPU etc...
278 iic_hosts[found] = host; 349 * Note that we configure the IIC_IRR here with a hard coded
279 BUG_ON(iic_hosts[found] == NULL); 350 * priority of 1. We might want to improve that later.
280 iic_hosts[found]->host_data = of_node_get(dn); 351 */
281 found++; 352 node = np[0] >> 1;
282 } 353 node_iic = cbe_get_cpu_iic_regs(np[0]);
283 init_one_iic(np[0], r0.start, host); 354 cascade = node << IIC_IRQ_NODE_SHIFT;
284 init_one_iic(np[1], r1.start, host); 355 cascade |= 1 << IIC_IRQ_CLASS_SHIFT;
356 cascade |= IIC_UNIT_IIC;
357 cascade = irq_create_mapping(iic_host, cascade);
358 if (cascade == NO_IRQ)
359 continue;
360 set_irq_data(cascade, node_iic);
361 set_irq_chained_handler(cascade , iic_ioexc_cascade);
362 out_be64(&node_iic->iic_ir,
363 (1 << 12) /* priority */ |
364 (node << 4) /* dest node */ |
365 IIC_UNIT_THREAD_0 /* route them to thread 0 */);
366 /* Flush pending (make sure it triggers if there is
367 * anything pending
368 */
369 out_be64(&node_iic->iic_is, 0xfffffffffffffffful);
285 } 370 }
286 371
287 if (found) 372 if (found)
@@ -292,6 +377,12 @@ static int __init setup_iic(void)
292 377
293void __init iic_init_IRQ(void) 378void __init iic_init_IRQ(void)
294{ 379{
380 /* Setup an irq host data structure */
381 iic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, IIC_SOURCE_COUNT,
382 &iic_host_ops, IIC_IRQ_INVALID);
383 BUG_ON(iic_host == NULL);
384 irq_set_default_host(iic_host);
385
295 /* Discover and initialize iics */ 386 /* Discover and initialize iics */
296 if (setup_iic() < 0) 387 if (setup_iic() < 0)
297 panic("IIC: Failed to initialize !\n"); 388 panic("IIC: Failed to initialize !\n");
diff --git a/arch/powerpc/platforms/cell/interrupt.h b/arch/powerpc/platforms/cell/interrupt.h
index 5560a92ec3ab..9ba1d3c17b4b 100644
--- a/arch/powerpc/platforms/cell/interrupt.h
+++ b/arch/powerpc/platforms/cell/interrupt.h
@@ -2,48 +2,76 @@
2#define ASM_CELL_PIC_H 2#define ASM_CELL_PIC_H
3#ifdef __KERNEL__ 3#ifdef __KERNEL__
4/* 4/*
5 * Mapping of IIC pending bits into per-node 5 * Mapping of IIC pending bits into per-node interrupt numbers.
6 * interrupt numbers.
7 * 6 *
8 * IRQ FF CC SS PP FF CC SS PP Description 7 * Interrupt numbers are in the range 0...0x1ff where the top bit
8 * (0x100) represent the source node. Only 2 nodes are supported with
9 * the current code though it's trivial to extend that if necessary using
10 * higher level bits
9 * 11 *
10 * 00-3f 80 02 +0 00 - 80 02 +0 3f South Bridge 12 * The bottom 8 bits are split into 2 type bits and 6 data bits that
11 * 00-3f 80 02 +b 00 - 80 02 +b 3f South Bridge 13 * depend on the type:
12 * 41-4a 80 00 +1 ** - 80 00 +a ** SPU Class 0
13 * 51-5a 80 01 +1 ** - 80 01 +a ** SPU Class 1
14 * 61-6a 80 02 +1 ** - 80 02 +a ** SPU Class 2
15 * 70-7f C0 ** ** 00 - C0 ** ** 0f IPI
16 * 14 *
17 * F flags 15 * 00 (0x00 | data) : normal interrupt. data is (class << 4) | source
18 * C class 16 * 01 (0x40 | data) : IO exception. data is the exception number as
19 * S source 17 * defined by bit numbers in IIC_SR
20 * P Priority 18 * 10 (0x80 | data) : IPI. data is the IPI number (obtained from the priority)
21 * + node number 19 * and node is always 0 (IPIs are per-cpu, their source is
22 * * don't care 20 * not relevant)
21 * 11 (0xc0 | data) : reserved
23 * 22 *
24 * A node consists of a Cell Broadband Engine and an optional 23 * In addition, interrupt number 0x80000000 is defined as always invalid
25 * south bridge device providing a maximum of 64 IRQs. 24 * (that is the node field is expected to never extend to move than 23 bits)
26 * The south bridge may be connected to either IOIF0
27 * or IOIF1.
28 * Each SPE is represented as three IRQ lines, one per
29 * interrupt class.
30 * 16 IRQ numbers are reserved for inter processor
31 * interruptions, although these are only used in the
32 * range of the first node.
33 * 25 *
34 * This scheme needs 128 IRQ numbers per BIF node ID,
35 * which means that with the total of 512 lines
36 * available, we can have a maximum of four nodes.
37 */ 26 */
38 27
39enum { 28enum {
40 IIC_IRQ_INVALID = 0xff, 29 IIC_IRQ_INVALID = 0x80000000u,
41 IIC_IRQ_MAX = 0x3f, 30 IIC_IRQ_NODE_MASK = 0x100,
42 IIC_IRQ_EXT_IOIF0 = 0x20, 31 IIC_IRQ_NODE_SHIFT = 8,
43 IIC_IRQ_EXT_IOIF1 = 0x2b, 32 IIC_IRQ_MAX = 0x1ff,
44 IIC_IRQ_IPI0 = 0x40, 33 IIC_IRQ_TYPE_MASK = 0xc0,
45 IIC_NUM_IPIS = 0x10, /* IRQs reserved for IPI */ 34 IIC_IRQ_TYPE_NORMAL = 0x00,
46 IIC_SOURCE_COUNT = 0x50, 35 IIC_IRQ_TYPE_IOEXC = 0x40,
36 IIC_IRQ_TYPE_IPI = 0x80,
37 IIC_IRQ_CLASS_SHIFT = 4,
38 IIC_IRQ_CLASS_0 = 0x00,
39 IIC_IRQ_CLASS_1 = 0x10,
40 IIC_IRQ_CLASS_2 = 0x20,
41 IIC_SOURCE_COUNT = 0x200,
42
43 /* Here are defined the various source/dest units. Avoid using those
44 * definitions if you can, they are mostly here for reference
45 */
46 IIC_UNIT_SPU_0 = 0x4,
47 IIC_UNIT_SPU_1 = 0x7,
48 IIC_UNIT_SPU_2 = 0x3,
49 IIC_UNIT_SPU_3 = 0x8,
50 IIC_UNIT_SPU_4 = 0x2,
51 IIC_UNIT_SPU_5 = 0x9,
52 IIC_UNIT_SPU_6 = 0x1,
53 IIC_UNIT_SPU_7 = 0xa,
54 IIC_UNIT_IOC_0 = 0x0,
55 IIC_UNIT_IOC_1 = 0xb,
56 IIC_UNIT_THREAD_0 = 0xe, /* target only */
57 IIC_UNIT_THREAD_1 = 0xf, /* target only */
58 IIC_UNIT_IIC = 0xe, /* source only (IO exceptions) */
59
60 /* Base numbers for the external interrupts */
61 IIC_IRQ_EXT_IOIF0 =
62 IIC_IRQ_TYPE_NORMAL | IIC_IRQ_CLASS_2 | IIC_UNIT_IOC_0,
63 IIC_IRQ_EXT_IOIF1 =
64 IIC_IRQ_TYPE_NORMAL | IIC_IRQ_CLASS_2 | IIC_UNIT_IOC_1,
65
66 /* Base numbers for the IIC_ISR interrupts */
67 IIC_IRQ_IOEX_TMI = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 63,
68 IIC_IRQ_IOEX_PMI = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 62,
69 IIC_IRQ_IOEX_ATI = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 61,
70 IIC_IRQ_IOEX_MATBFI = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 60,
71 IIC_IRQ_IOEX_ELDI = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 59,
72
73 /* Which bits in IIC_ISR are edge sensitive */
74 IIC_ISR_EDGE_MASK = 0x4ul,
47}; 75};
48 76
49extern void iic_init_IRQ(void); 77extern void iic_init_IRQ(void);
@@ -52,7 +80,6 @@ extern void iic_request_IPIs(void);
52extern void iic_setup_cpu(void); 80extern void iic_setup_cpu(void);
53 81
54extern u8 iic_get_target_id(int cpu); 82extern u8 iic_get_target_id(int cpu);
55extern struct irq_host *iic_get_irq_host(int node);
56 83
57extern void spider_init_IRQ(void); 84extern void spider_init_IRQ(void);
58 85
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 742a03282b44..608b1ebc56b2 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -243,7 +243,6 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
243 const u32 *imap, *tmp; 243 const u32 *imap, *tmp;
244 int imaplen, intsize, unit; 244 int imaplen, intsize, unit;
245 struct device_node *iic; 245 struct device_node *iic;
246 struct irq_host *iic_host;
247 246
248#if 0 /* Enable that when we have a way to retreive the node as well */ 247#if 0 /* Enable that when we have a way to retreive the node as well */
249 /* First, we check wether we have a real "interrupts" in the device 248 /* First, we check wether we have a real "interrupts" in the device
@@ -289,11 +288,11 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
289 * the iic host from the iic OF node, but that way I'm still compatible 288 * the iic host from the iic OF node, but that way I'm still compatible
290 * with really really old old firmwares for which we don't have a node 289 * with really really old old firmwares for which we don't have a node
291 */ 290 */
292 iic_host = iic_get_irq_host(pic->node_id);
293 if (iic_host == NULL)
294 return NO_IRQ;
295 /* Manufacture an IIC interrupt number of class 2 */ 291 /* Manufacture an IIC interrupt number of class 2 */
296 virq = irq_create_mapping(iic_host, 0x20 | unit); 292 virq = irq_create_mapping(NULL,
293 (pic->node_id << IIC_IRQ_NODE_SHIFT) |
294 (2 << IIC_IRQ_CLASS_SHIFT) |
295 unit);
297 if (virq == NO_IRQ) 296 if (virq == NO_IRQ)
298 printk(KERN_ERR "spider_pic: failed to map cascade !"); 297 printk(KERN_ERR "spider_pic: failed to map cascade !");
299 return virq; 298 return virq;
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 0f5c8ebc7fc3..f78680346e5f 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -568,24 +568,23 @@ static void spu_unmap(struct spu *spu)
568/* This function shall be abstracted for HV platforms */ 568/* This function shall be abstracted for HV platforms */
569static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) 569static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
570{ 570{
571 struct irq_host *host;
572 unsigned int isrc; 571 unsigned int isrc;
573 const u32 *tmp; 572 const u32 *tmp;
574 573
575 host = iic_get_irq_host(spu->node); 574 /* Get the interrupt source unit from the device-tree */
576 if (host == NULL)
577 return -ENODEV;
578
579 /* Get the interrupt source from the device-tree */
580 tmp = get_property(np, "isrc", NULL); 575 tmp = get_property(np, "isrc", NULL);
581 if (!tmp) 576 if (!tmp)
582 return -ENODEV; 577 return -ENODEV;
583 spu->isrc = isrc = tmp[0]; 578 isrc = tmp[0];
579
580 /* Add the node number */
581 isrc |= spu->node << IIC_IRQ_NODE_SHIFT;
582 spu->isrc = isrc;
584 583
585 /* Now map interrupts of all 3 classes */ 584 /* Now map interrupts of all 3 classes */
586 spu->irqs[0] = irq_create_mapping(host, 0x00 | isrc); 585 spu->irqs[0] = irq_create_mapping(NULL, IIC_IRQ_CLASS_0 | isrc);
587 spu->irqs[1] = irq_create_mapping(host, 0x10 | isrc); 586 spu->irqs[1] = irq_create_mapping(NULL, IIC_IRQ_CLASS_1 | isrc);
588 spu->irqs[2] = irq_create_mapping(host, 0x20 | isrc); 587 spu->irqs[2] = irq_create_mapping(NULL, IIC_IRQ_CLASS_2 | isrc);
589 588
590 /* Right now, we only fail if class 2 failed */ 589 /* Right now, we only fail if class 2 failed */
591 return spu->irqs[2] == NO_IRQ ? -EINVAL : 0; 590 return spu->irqs[2] == NO_IRQ ? -EINVAL : 0;
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 3eb12065df23..4aa165e010d9 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -262,14 +262,6 @@ void __init iSeries_pci_final_fixup(void)
262 mf_display_src(0xC9000200); 262 mf_display_src(0xC9000200);
263} 263}
264 264
265void pcibios_fixup_bus(struct pci_bus *PciBus)
266{
267}
268
269void pcibios_fixup_resources(struct pci_dev *pdev)
270{
271}
272
273/* 265/*
274 * Look down the chain to find the matching Device Device 266 * Look down the chain to find the matching Device Device
275 */ 267 */
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 7f1953066ff8..a0ff7ba7d666 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -649,15 +649,21 @@ static void iseries_dedicated_idle(void)
649void __init iSeries_init_IRQ(void) { } 649void __init iSeries_init_IRQ(void) { }
650#endif 650#endif
651 651
652/*
653 * iSeries has no legacy IO, anything calling this function has to
654 * fail or bad things will happen
655 */
656static int iseries_check_legacy_ioport(unsigned int baseport)
657{
658 return -ENODEV;
659}
660
652static int __init iseries_probe(void) 661static int __init iseries_probe(void)
653{ 662{
654 unsigned long root = of_get_flat_dt_root(); 663 unsigned long root = of_get_flat_dt_root();
655 if (!of_flat_dt_is_compatible(root, "IBM,iSeries")) 664 if (!of_flat_dt_is_compatible(root, "IBM,iSeries"))
656 return 0; 665 return 0;
657 666
658 powerpc_firmware_features |= FW_FEATURE_ISERIES;
659 powerpc_firmware_features |= FW_FEATURE_LPAR;
660
661 hpte_init_iSeries(); 667 hpte_init_iSeries();
662 668
663 return 1; 669 return 1;
@@ -680,6 +686,7 @@ define_machine(iseries) {
680 .calibrate_decr = generic_calibrate_decr, 686 .calibrate_decr = generic_calibrate_decr,
681 .progress = iSeries_progress, 687 .progress = iSeries_progress,
682 .probe = iseries_probe, 688 .probe = iseries_probe,
689 .check_legacy_ioport = iseries_check_legacy_ioport,
683 /* XXX Implement enable_pmcs for iSeries */ 690 /* XXX Implement enable_pmcs for iSeries */
684}; 691};
685 692
@@ -687,6 +694,9 @@ void * __init iSeries_early_setup(void)
687{ 694{
688 unsigned long phys_mem_size; 695 unsigned long phys_mem_size;
689 696
697 powerpc_firmware_features |= FW_FEATURE_ISERIES;
698 powerpc_firmware_features |= FW_FEATURE_LPAR;
699
690 iSeries_fixup_klimit(); 700 iSeries_fixup_klimit();
691 701
692 /* 702 /*
diff --git a/arch/powerpc/platforms/powermac/udbg_scc.c b/arch/powerpc/platforms/powermac/udbg_scc.c
index ce1a235855f7..379db05b0082 100644
--- a/arch/powerpc/platforms/powermac/udbg_scc.c
+++ b/arch/powerpc/platforms/powermac/udbg_scc.c
@@ -111,8 +111,6 @@ void udbg_scc_init(int force_scc)
111 pmac_call_feature(PMAC_FTR_SCC_ENABLE, ch, 111 pmac_call_feature(PMAC_FTR_SCC_ENABLE, ch,
112 PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1); 112 PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
113 113
114
115 /* Setup for 57600 8N1 */
116 if (ch == ch_a) 114 if (ch == ch_a)
117 addr += 0x20; 115 addr += 0x20;
118 sccc = ioremap(addr & PAGE_MASK, PAGE_SIZE) ; 116 sccc = ioremap(addr & PAGE_MASK, PAGE_SIZE) ;
@@ -125,9 +123,21 @@ void udbg_scc_init(int force_scc)
125 x = in_8(sccc); 123 x = in_8(sccc);
126 out_8(sccc, 0x09); /* reset A or B side */ 124 out_8(sccc, 0x09); /* reset A or B side */
127 out_8(sccc, 0xc0); 125 out_8(sccc, 0xc0);
126
127 /* If SCC was the OF output port, read the BRG value, else
128 * Setup for 57600 8N1
129 */
130 if (ch_def != NULL) {
131 out_8(sccc, 13);
132 scc_inittab[1] = in_8(sccc);
133 out_8(sccc, 12);
134 scc_inittab[3] = in_8(sccc);
135 }
136
128 for (i = 0; i < sizeof(scc_inittab); ++i) 137 for (i = 0; i < sizeof(scc_inittab); ++i)
129 out_8(sccc, scc_inittab[i]); 138 out_8(sccc, scc_inittab[i]);
130 139
140
131 udbg_putc = udbg_scc_putc; 141 udbg_putc = udbg_scc_putc;
132 udbg_getc = udbg_scc_getc; 142 udbg_getc = udbg_scc_getc;
133 udbg_getc_poll = udbg_scc_getc_poll; 143 udbg_getc_poll = udbg_scc_getc_poll;
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 43dbf737698c..f82b13e531a3 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -180,7 +180,7 @@ static void __init pseries_mpic_init_IRQ(void)
180 180
181 cascade_irq = irq_of_parse_and_map(cascade, 0); 181 cascade_irq = irq_of_parse_and_map(cascade, 0);
182 if (cascade == NO_IRQ) { 182 if (cascade == NO_IRQ) {
183 printk(KERN_ERR "xics: failed to map cascade interrupt"); 183 printk(KERN_ERR "mpic: failed to map cascade interrupt");
184 return; 184 return;
185 } 185 }
186 186
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index f15f4d78aee9..91f052d8cce0 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
12obj-$(CONFIG_FSL_SOC) += fsl_soc.o 12obj-$(CONFIG_FSL_SOC) += fsl_soc.o
13obj-$(CONFIG_PPC_TODC) += todc.o 13obj-$(CONFIG_PPC_TODC) += todc.o
14obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o 14obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
15obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
15 16
16ifeq ($(CONFIG_PPC_MERGE),y) 17ifeq ($(CONFIG_PPC_MERGE),y)
17obj-$(CONFIG_PPC_I8259) += i8259.o 18obj-$(CONFIG_PPC_I8259) += i8259.o
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index 51752990f7b9..28b018994746 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -147,7 +147,7 @@ static struct irq_chip cpm2_pic = {
147 .end = cpm2_end_irq, 147 .end = cpm2_end_irq,
148}; 148};
149 149
150int cpm2_get_irq(struct pt_regs *regs) 150unsigned int cpm2_get_irq(struct pt_regs *regs)
151{ 151{
152 int irq; 152 int irq;
153 unsigned long bits; 153 unsigned long bits;
diff --git a/arch/powerpc/sysdev/cpm2_pic.h b/arch/powerpc/sysdev/cpm2_pic.h
index d63e45d4df58..3c513e5a688e 100644
--- a/arch/powerpc/sysdev/cpm2_pic.h
+++ b/arch/powerpc/sysdev/cpm2_pic.h
@@ -3,7 +3,7 @@
3 3
4extern intctl_cpm2_t *cpm2_intctl; 4extern intctl_cpm2_t *cpm2_intctl;
5 5
6extern int cpm2_get_irq(struct pt_regs *regs); 6extern unsigned int cpm2_get_irq(struct pt_regs *regs);
7 7
8extern void cpm2_pic_init(struct device_node*); 8extern void cpm2_pic_init(struct device_node*);
9 9
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 022ed275ea68..7d759f1c26b1 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -37,6 +37,7 @@
37#include <asm/cpm2.h> 37#include <asm/cpm2.h>
38 38
39extern void init_fcc_ioports(struct fs_platform_info*); 39extern void init_fcc_ioports(struct fs_platform_info*);
40extern void init_scc_ioports(struct fs_uart_platform_info*);
40static phys_addr_t immrbase = -1; 41static phys_addr_t immrbase = -1;
41 42
42phys_addr_t get_immrbase(void) 43phys_addr_t get_immrbase(void)
@@ -566,7 +567,7 @@ static int __init fs_enet_of_init(void)
566 struct resource r[4]; 567 struct resource r[4];
567 struct device_node *phy, *mdio; 568 struct device_node *phy, *mdio;
568 struct fs_platform_info fs_enet_data; 569 struct fs_platform_info fs_enet_data;
569 const unsigned int *id, *phy_addr; 570 const unsigned int *id, *phy_addr, phy_irq;
570 const void *mac_addr; 571 const void *mac_addr;
571 const phandle *ph; 572 const phandle *ph;
572 const char *model; 573 const char *model;
@@ -588,6 +589,7 @@ static int __init fs_enet_of_init(void)
588 if (ret) 589 if (ret)
589 goto err; 590 goto err;
590 r[2].name = fcc_regs_c; 591 r[2].name = fcc_regs_c;
592 fs_enet_data.fcc_regs_c = r[2].start;
591 593
592 r[3].start = r[3].end = irq_of_parse_and_map(np, 0); 594 r[3].start = r[3].end = irq_of_parse_and_map(np, 0);
593 r[3].flags = IORESOURCE_IRQ; 595 r[3].flags = IORESOURCE_IRQ;
@@ -620,6 +622,8 @@ static int __init fs_enet_of_init(void)
620 phy_addr = get_property(phy, "reg", NULL); 622 phy_addr = get_property(phy, "reg", NULL);
621 fs_enet_data.phy_addr = *phy_addr; 623 fs_enet_data.phy_addr = *phy_addr;
622 624
625 phy_irq = get_property(phy, "interrupts", NULL);
626
623 id = get_property(np, "device-id", NULL); 627 id = get_property(np, "device-id", NULL);
624 fs_enet_data.fs_no = *id; 628 fs_enet_data.fs_no = *id;
625 strcpy(fs_enet_data.fs_type, model); 629 strcpy(fs_enet_data.fs_type, model);
@@ -637,6 +641,7 @@ static int __init fs_enet_of_init(void)
637 641
638 if (strstr(model, "FCC")) { 642 if (strstr(model, "FCC")) {
639 int fcc_index = *id - 1; 643 int fcc_index = *id - 1;
644 unsigned char* mdio_bb_prop;
640 645
641 fs_enet_data.dpram_offset = (u32)cpm_dpram_addr(0); 646 fs_enet_data.dpram_offset = (u32)cpm_dpram_addr(0);
642 fs_enet_data.rx_ring = 32; 647 fs_enet_data.rx_ring = 32;
@@ -652,14 +657,57 @@ static int __init fs_enet_of_init(void)
652 (u32)res.start, fs_enet_data.phy_addr); 657 (u32)res.start, fs_enet_data.phy_addr);
653 fs_enet_data.bus_id = (char*)&bus_id[(*id)]; 658 fs_enet_data.bus_id = (char*)&bus_id[(*id)];
654 fs_enet_data.init_ioports = init_fcc_ioports; 659 fs_enet_data.init_ioports = init_fcc_ioports;
655 }
656 660
657 of_node_put(phy); 661 mdio_bb_prop = get_property(phy, "bitbang", NULL);
658 of_node_put(mdio); 662 if (mdio_bb_prop) {
663 struct platform_device *fs_enet_mdio_bb_dev;
664 struct fs_mii_bb_platform_info fs_enet_mdio_bb_data;
665
666 fs_enet_mdio_bb_dev =
667 platform_device_register_simple("fsl-bb-mdio",
668 i, NULL, 0);
669 memset(&fs_enet_mdio_bb_data, 0,
670 sizeof(struct fs_mii_bb_platform_info));
671 fs_enet_mdio_bb_data.mdio_dat.bit =
672 mdio_bb_prop[0];
673 fs_enet_mdio_bb_data.mdio_dir.bit =
674 mdio_bb_prop[1];
675 fs_enet_mdio_bb_data.mdc_dat.bit =
676 mdio_bb_prop[2];
677 fs_enet_mdio_bb_data.mdio_port =
678 mdio_bb_prop[3];
679 fs_enet_mdio_bb_data.mdc_port =
680 mdio_bb_prop[4];
681 fs_enet_mdio_bb_data.delay =
682 mdio_bb_prop[5];
683
684 fs_enet_mdio_bb_data.irq[0] = phy_irq[0];
685 fs_enet_mdio_bb_data.irq[1] = -1;
686 fs_enet_mdio_bb_data.irq[2] = -1;
687 fs_enet_mdio_bb_data.irq[3] = phy_irq[0];
688 fs_enet_mdio_bb_data.irq[31] = -1;
689
690 fs_enet_mdio_bb_data.mdio_dat.offset =
691 (u32)&cpm2_immr->im_ioport.iop_pdatc;
692 fs_enet_mdio_bb_data.mdio_dir.offset =
693 (u32)&cpm2_immr->im_ioport.iop_pdirc;
694 fs_enet_mdio_bb_data.mdc_dat.offset =
695 (u32)&cpm2_immr->im_ioport.iop_pdatc;
696
697 ret = platform_device_add_data(
698 fs_enet_mdio_bb_dev,
699 &fs_enet_mdio_bb_data,
700 sizeof(struct fs_mii_bb_platform_info));
701 if (ret)
702 goto unreg;
703 }
704
705 of_node_put(phy);
706 of_node_put(mdio);
659 707
660 ret = platform_device_add_data(fs_enet_dev, &fs_enet_data, 708 ret = platform_device_add_data(fs_enet_dev, &fs_enet_data,
661 sizeof(struct 709 sizeof(struct
662 fs_platform_info)); 710 fs_platform_info));
663 if (ret) 711 if (ret)
664 goto unreg; 712 goto unreg;
665 } 713 }
diff --git a/arch/powerpc/sysdev/qe_lib/Kconfig b/arch/powerpc/sysdev/qe_lib/Kconfig
new file mode 100644
index 000000000000..a725e80befa8
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/Kconfig
@@ -0,0 +1,30 @@
1#
2# QE Communication options
3#
4
5menu "QE Options"
6 depends on QUICC_ENGINE
7
8config UCC_SLOW
9 bool "UCC Slow Protocols Support"
10 default n
11 select UCC
12 help
13 This option provides qe_lib support to UCC slow
14 protocols: UART, BISYNC, QMC
15
16config UCC_FAST
17 bool "UCC Fast Protocols Support"
18 default n
19 select UCC
20 select UCC_SLOW
21 help
22 This option provides qe_lib support to UCC fast
23 protocols: HDLC, Ethernet, ATM, transparent
24
25config UCC
26 bool
27 default y if UCC_FAST || UCC_SLOW
28
29endmenu
30
diff --git a/arch/powerpc/sysdev/qe_lib/Makefile b/arch/powerpc/sysdev/qe_lib/Makefile
new file mode 100644
index 000000000000..874fe1a5b1cf
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for the linux ppc-specific parts of QE
3#
4obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_ic.o qe_io.o
5
6obj-$(CONFIG_UCC) += ucc.o
7obj-$(CONFIG_UCC_SLOW) += ucc_slow.o
8obj-$(CONFIG_UCC_FAST) += ucc_fast.o
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
new file mode 100644
index 000000000000..2bae632d3ad7
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -0,0 +1,353 @@
1/*
2 * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
3 *
4 * Authors: Shlomi Gridish <gridish@freescale.com>
5 * Li Yang <leoli@freescale.com>
6 * Based on cpm2_common.c from Dan Malek (dmalek@jlc.net)
7 *
8 * Description:
9 * General Purpose functions for the global management of the
10 * QUICC Engine (QE).
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17#include <linux/errno.h>
18#include <linux/sched.h>
19#include <linux/kernel.h>
20#include <linux/param.h>
21#include <linux/string.h>
22#include <linux/mm.h>
23#include <linux/interrupt.h>
24#include <linux/bootmem.h>
25#include <linux/module.h>
26#include <linux/delay.h>
27#include <linux/ioport.h>
28#include <asm/irq.h>
29#include <asm/page.h>
30#include <asm/pgtable.h>
31#include <asm/immap_qe.h>
32#include <asm/qe.h>
33#include <asm/prom.h>
34#include <asm/rheap.h>
35
36static void qe_snums_init(void);
37static void qe_muram_init(void);
38static int qe_sdma_init(void);
39
40static DEFINE_SPINLOCK(qe_lock);
41
42/* QE snum state */
43enum qe_snum_state {
44 QE_SNUM_STATE_USED,
45 QE_SNUM_STATE_FREE
46};
47
48/* QE snum */
49struct qe_snum {
50 u8 num;
51 enum qe_snum_state state;
52};
53
54/* We allocate this here because it is used almost exclusively for
55 * the communication processor devices.
56 */
57struct qe_immap *qe_immr = NULL;
58EXPORT_SYMBOL(qe_immr);
59
60static struct qe_snum snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */
61
62static phys_addr_t qebase = -1;
63
64phys_addr_t get_qe_base(void)
65{
66 struct device_node *qe;
67
68 if (qebase != -1)
69 return qebase;
70
71 qe = of_find_node_by_type(NULL, "qe");
72 if (qe) {
73 unsigned int size;
74 const void *prop = get_property(qe, "reg", &size);
75 qebase = of_translate_address(qe, prop);
76 of_node_put(qe);
77 };
78
79 return qebase;
80}
81
82EXPORT_SYMBOL(get_qe_base);
83
84void qe_reset(void)
85{
86 if (qe_immr == NULL)
87 qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
88
89 qe_snums_init();
90
91 qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
92 QE_CR_PROTOCOL_UNSPECIFIED, 0);
93
94 /* Reclaim the MURAM memory for our use. */
95 qe_muram_init();
96
97 if (qe_sdma_init())
98 panic("sdma init failed!");
99}
100
101int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
102{
103 unsigned long flags;
104 u8 mcn_shift = 0, dev_shift = 0;
105
106 spin_lock_irqsave(&qe_lock, flags);
107 if (cmd == QE_RESET) {
108 out_be32(&qe_immr->cp.cecr, (u32) (cmd | QE_CR_FLG));
109 } else {
110 if (cmd == QE_ASSIGN_PAGE) {
111 /* Here device is the SNUM, not sub-block */
112 dev_shift = QE_CR_SNUM_SHIFT;
113 } else if (cmd == QE_ASSIGN_RISC) {
114 /* Here device is the SNUM, and mcnProtocol is
115 * e_QeCmdRiscAssignment value */
116 dev_shift = QE_CR_SNUM_SHIFT;
117 mcn_shift = QE_CR_MCN_RISC_ASSIGN_SHIFT;
118 } else {
119 if (device == QE_CR_SUBBLOCK_USB)
120 mcn_shift = QE_CR_MCN_USB_SHIFT;
121 else
122 mcn_shift = QE_CR_MCN_NORMAL_SHIFT;
123 }
124
125 out_be32(&qe_immr->cp.cecdr,
126 immrbar_virt_to_phys((void *)cmd_input));
127 out_be32(&qe_immr->cp.cecr,
128 (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32)
129 mcn_protocol << mcn_shift));
130 }
131
132 /* wait for the QE_CR_FLG to clear */
133 while(in_be32(&qe_immr->cp.cecr) & QE_CR_FLG)
134 cpu_relax();
135 spin_unlock_irqrestore(&qe_lock, flags);
136
137 return 0;
138}
139EXPORT_SYMBOL(qe_issue_cmd);
140
141/* Set a baud rate generator. This needs lots of work. There are
142 * 16 BRGs, which can be connected to the QE channels or output
143 * as clocks. The BRGs are in two different block of internal
144 * memory mapped space.
145 * The baud rate clock is the system clock divided by something.
146 * It was set up long ago during the initial boot phase and is
147 * is given to us.
148 * Baud rate clocks are zero-based in the driver code (as that maps
149 * to port numbers). Documentation uses 1-based numbering.
150 */
151static unsigned int brg_clk = 0;
152
153unsigned int get_brg_clk(void)
154{
155 struct device_node *qe;
156 if (brg_clk)
157 return brg_clk;
158
159 qe = of_find_node_by_type(NULL, "qe");
160 if (qe) {
161 unsigned int size;
162 const u32 *prop = get_property(qe, "brg-frequency", &size);
163 brg_clk = *prop;
164 of_node_put(qe);
165 };
166 return brg_clk;
167}
168
169/* This function is used by UARTS, or anything else that uses a 16x
170 * oversampled clock.
171 */
172void qe_setbrg(u32 brg, u32 rate)
173{
174 volatile u32 *bp;
175 u32 divisor, tempval;
176 int div16 = 0;
177
178 bp = &qe_immr->brg.brgc1;
179 bp += brg;
180
181 divisor = (get_brg_clk() / rate);
182 if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
183 div16 = 1;
184 divisor /= 16;
185 }
186
187 tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE;
188 if (div16)
189 tempval |= QE_BRGC_DIV16;
190
191 out_be32(bp, tempval);
192}
193
194/* Initialize SNUMs (thread serial numbers) according to
195 * QE Module Control chapter, SNUM table
196 */
197static void qe_snums_init(void)
198{
199 int i;
200 static const u8 snum_init[] = {
201 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
202 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
203 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
204 0xD8, 0xD9, 0xE8, 0xE9,
205 };
206
207 for (i = 0; i < QE_NUM_OF_SNUM; i++) {
208 snums[i].num = snum_init[i];
209 snums[i].state = QE_SNUM_STATE_FREE;
210 }
211}
212
213int qe_get_snum(void)
214{
215 unsigned long flags;
216 int snum = -EBUSY;
217 int i;
218
219 spin_lock_irqsave(&qe_lock, flags);
220 for (i = 0; i < QE_NUM_OF_SNUM; i++) {
221 if (snums[i].state == QE_SNUM_STATE_FREE) {
222 snums[i].state = QE_SNUM_STATE_USED;
223 snum = snums[i].num;
224 break;
225 }
226 }
227 spin_unlock_irqrestore(&qe_lock, flags);
228
229 return snum;
230}
231EXPORT_SYMBOL(qe_get_snum);
232
233void qe_put_snum(u8 snum)
234{
235 int i;
236
237 for (i = 0; i < QE_NUM_OF_SNUM; i++) {
238 if (snums[i].num == snum) {
239 snums[i].state = QE_SNUM_STATE_FREE;
240 break;
241 }
242 }
243}
244EXPORT_SYMBOL(qe_put_snum);
245
246static int qe_sdma_init(void)
247{
248 struct sdma *sdma = &qe_immr->sdma;
249 u32 sdma_buf_offset;
250
251 if (!sdma)
252 return -ENODEV;
253
254 /* allocate 2 internal temporary buffers (512 bytes size each) for
255 * the SDMA */
256 sdma_buf_offset = qe_muram_alloc(512 * 2, 64);
257 if (IS_MURAM_ERR(sdma_buf_offset))
258 return -ENOMEM;
259
260 out_be32(&sdma->sdebcr, sdma_buf_offset & QE_SDEBCR_BA_MASK);
261 out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK | (0x1 >>
262 QE_SDMR_CEN_SHIFT)));
263
264 return 0;
265}
266
267/*
268 * muram_alloc / muram_free bits.
269 */
270static DEFINE_SPINLOCK(qe_muram_lock);
271
272/* 16 blocks should be enough to satisfy all requests
273 * until the memory subsystem goes up... */
274static rh_block_t qe_boot_muram_rh_block[16];
275static rh_info_t qe_muram_info;
276
277static void qe_muram_init(void)
278{
279 struct device_node *np;
280 u32 address;
281 u64 size;
282 unsigned int flags;
283
284 /* initialize the info header */
285 rh_init(&qe_muram_info, 1,
286 sizeof(qe_boot_muram_rh_block) /
287 sizeof(qe_boot_muram_rh_block[0]), qe_boot_muram_rh_block);
288
289 /* Attach the usable muram area */
290 /* XXX: This is a subset of the available muram. It
291 * varies with the processor and the microcode patches activated.
292 */
293 if ((np = of_find_node_by_name(NULL, "data-only")) != NULL) {
294 address = *of_get_address(np, 0, &size, &flags);
295 of_node_put(np);
296 rh_attach_region(&qe_muram_info,
297 (void *)address, (int)size);
298 }
299}
300
301/* This function returns an index into the MURAM area.
302 */
303u32 qe_muram_alloc(u32 size, u32 align)
304{
305 void *start;
306 unsigned long flags;
307
308 spin_lock_irqsave(&qe_muram_lock, flags);
309 start = rh_alloc_align(&qe_muram_info, size, align, "QE");
310 spin_unlock_irqrestore(&qe_muram_lock, flags);
311
312 return (u32) start;
313}
314EXPORT_SYMBOL(qe_muram_alloc);
315
316int qe_muram_free(u32 offset)
317{
318 int ret;
319 unsigned long flags;
320
321 spin_lock_irqsave(&qe_muram_lock, flags);
322 ret = rh_free(&qe_muram_info, (void *)offset);
323 spin_unlock_irqrestore(&qe_muram_lock, flags);
324
325 return ret;
326}
327EXPORT_SYMBOL(qe_muram_free);
328
329/* not sure if this is ever needed */
330u32 qe_muram_alloc_fixed(u32 offset, u32 size)
331{
332 void *start;
333 unsigned long flags;
334
335 spin_lock_irqsave(&qe_muram_lock, flags);
336 start = rh_alloc_fixed(&qe_muram_info, (void *)offset, size, "commproc");
337 spin_unlock_irqrestore(&qe_muram_lock, flags);
338
339 return (u32) start;
340}
341EXPORT_SYMBOL(qe_muram_alloc_fixed);
342
343void qe_muram_dump(void)
344{
345 rh_dump(&qe_muram_info);
346}
347EXPORT_SYMBOL(qe_muram_dump);
348
349void *qe_muram_addr(u32 offset)
350{
351 return (void *)&qe_immr->muram[offset];
352}
353EXPORT_SYMBOL(qe_muram_addr);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
new file mode 100644
index 000000000000..c229d07d4957
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -0,0 +1,555 @@
1/*
2 * arch/powerpc/sysdev/qe_lib/qe_ic.c
3 *
4 * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
5 *
6 * Author: Li Yang <leoli@freescale.com>
7 * Based on code from Shlomi Gridish <gridish@freescale.com>
8 *
9 * QUICC ENGINE Interrupt Controller
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/errno.h>
20#include <linux/reboot.h>
21#include <linux/slab.h>
22#include <linux/stddef.h>
23#include <linux/sched.h>
24#include <linux/signal.h>
25#include <linux/sysdev.h>
26#include <linux/device.h>
27#include <linux/bootmem.h>
28#include <linux/spinlock.h>
29#include <asm/irq.h>
30#include <asm/io.h>
31#include <asm/prom.h>
32#include <asm/qe_ic.h>
33
34#include "qe_ic.h"
35
36static DEFINE_SPINLOCK(qe_ic_lock);
37
38static struct qe_ic_info qe_ic_info[] = {
39 [1] = {
40 .mask = 0x00008000,
41 .mask_reg = QEIC_CIMR,
42 .pri_code = 0,
43 .pri_reg = QEIC_CIPWCC,
44 },
45 [2] = {
46 .mask = 0x00004000,
47 .mask_reg = QEIC_CIMR,
48 .pri_code = 1,
49 .pri_reg = QEIC_CIPWCC,
50 },
51 [3] = {
52 .mask = 0x00002000,
53 .mask_reg = QEIC_CIMR,
54 .pri_code = 2,
55 .pri_reg = QEIC_CIPWCC,
56 },
57 [10] = {
58 .mask = 0x00000040,
59 .mask_reg = QEIC_CIMR,
60 .pri_code = 1,
61 .pri_reg = QEIC_CIPZCC,
62 },
63 [11] = {
64 .mask = 0x00000020,
65 .mask_reg = QEIC_CIMR,
66 .pri_code = 2,
67 .pri_reg = QEIC_CIPZCC,
68 },
69 [12] = {
70 .mask = 0x00000010,
71 .mask_reg = QEIC_CIMR,
72 .pri_code = 3,
73 .pri_reg = QEIC_CIPZCC,
74 },
75 [13] = {
76 .mask = 0x00000008,
77 .mask_reg = QEIC_CIMR,
78 .pri_code = 4,
79 .pri_reg = QEIC_CIPZCC,
80 },
81 [14] = {
82 .mask = 0x00000004,
83 .mask_reg = QEIC_CIMR,
84 .pri_code = 5,
85 .pri_reg = QEIC_CIPZCC,
86 },
87 [15] = {
88 .mask = 0x00000002,
89 .mask_reg = QEIC_CIMR,
90 .pri_code = 6,
91 .pri_reg = QEIC_CIPZCC,
92 },
93 [20] = {
94 .mask = 0x10000000,
95 .mask_reg = QEIC_CRIMR,
96 .pri_code = 3,
97 .pri_reg = QEIC_CIPRTA,
98 },
99 [25] = {
100 .mask = 0x00800000,
101 .mask_reg = QEIC_CRIMR,
102 .pri_code = 0,
103 .pri_reg = QEIC_CIPRTB,
104 },
105 [26] = {
106 .mask = 0x00400000,
107 .mask_reg = QEIC_CRIMR,
108 .pri_code = 1,
109 .pri_reg = QEIC_CIPRTB,
110 },
111 [27] = {
112 .mask = 0x00200000,
113 .mask_reg = QEIC_CRIMR,
114 .pri_code = 2,
115 .pri_reg = QEIC_CIPRTB,
116 },
117 [28] = {
118 .mask = 0x00100000,
119 .mask_reg = QEIC_CRIMR,
120 .pri_code = 3,
121 .pri_reg = QEIC_CIPRTB,
122 },
123 [32] = {
124 .mask = 0x80000000,
125 .mask_reg = QEIC_CIMR,
126 .pri_code = 0,
127 .pri_reg = QEIC_CIPXCC,
128 },
129 [33] = {
130 .mask = 0x40000000,
131 .mask_reg = QEIC_CIMR,
132 .pri_code = 1,
133 .pri_reg = QEIC_CIPXCC,
134 },
135 [34] = {
136 .mask = 0x20000000,
137 .mask_reg = QEIC_CIMR,
138 .pri_code = 2,
139 .pri_reg = QEIC_CIPXCC,
140 },
141 [35] = {
142 .mask = 0x10000000,
143 .mask_reg = QEIC_CIMR,
144 .pri_code = 3,
145 .pri_reg = QEIC_CIPXCC,
146 },
147 [36] = {
148 .mask = 0x08000000,
149 .mask_reg = QEIC_CIMR,
150 .pri_code = 4,
151 .pri_reg = QEIC_CIPXCC,
152 },
153 [40] = {
154 .mask = 0x00800000,
155 .mask_reg = QEIC_CIMR,
156 .pri_code = 0,
157 .pri_reg = QEIC_CIPYCC,
158 },
159 [41] = {
160 .mask = 0x00400000,
161 .mask_reg = QEIC_CIMR,
162 .pri_code = 1,
163 .pri_reg = QEIC_CIPYCC,
164 },
165 [42] = {
166 .mask = 0x00200000,
167 .mask_reg = QEIC_CIMR,
168 .pri_code = 2,
169 .pri_reg = QEIC_CIPYCC,
170 },
171 [43] = {
172 .mask = 0x00100000,
173 .mask_reg = QEIC_CIMR,
174 .pri_code = 3,
175 .pri_reg = QEIC_CIPYCC,
176 },
177};
178
179static inline u32 qe_ic_read(volatile __be32 __iomem * base, unsigned int reg)
180{
181 return in_be32(base + (reg >> 2));
182}
183
184static inline void qe_ic_write(volatile __be32 __iomem * base, unsigned int reg,
185 u32 value)
186{
187 out_be32(base + (reg >> 2), value);
188}
189
190static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
191{
192 return irq_desc[virq].chip_data;
193}
194
195#define virq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
196
197static void qe_ic_unmask_irq(unsigned int virq)
198{
199 struct qe_ic *qe_ic = qe_ic_from_irq(virq);
200 unsigned int src = virq_to_hw(virq);
201 unsigned long flags;
202 u32 temp;
203
204 spin_lock_irqsave(&qe_ic_lock, flags);
205
206 temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
207 qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
208 temp | qe_ic_info[src].mask);
209
210 spin_unlock_irqrestore(&qe_ic_lock, flags);
211}
212
213static void qe_ic_mask_irq(unsigned int virq)
214{
215 struct qe_ic *qe_ic = qe_ic_from_irq(virq);
216 unsigned int src = virq_to_hw(virq);
217 unsigned long flags;
218 u32 temp;
219
220 spin_lock_irqsave(&qe_ic_lock, flags);
221
222 temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
223 qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
224 temp & ~qe_ic_info[src].mask);
225
226 spin_unlock_irqrestore(&qe_ic_lock, flags);
227}
228
229static void qe_ic_mask_irq_and_ack(unsigned int virq)
230{
231 struct qe_ic *qe_ic = qe_ic_from_irq(virq);
232 unsigned int src = virq_to_hw(virq);
233 unsigned long flags;
234 u32 temp;
235
236 spin_lock_irqsave(&qe_ic_lock, flags);
237
238 temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
239 qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
240 temp & ~qe_ic_info[src].mask);
241
242 /* There is nothing to do for ack here, ack is handled in ISR */
243
244 spin_unlock_irqrestore(&qe_ic_lock, flags);
245}
246
247static struct irq_chip qe_ic_irq_chip = {
248 .typename = " QEIC ",
249 .unmask = qe_ic_unmask_irq,
250 .mask = qe_ic_mask_irq,
251 .mask_ack = qe_ic_mask_irq_and_ack,
252};
253
254static int qe_ic_host_match(struct irq_host *h, struct device_node *node)
255{
256 struct qe_ic *qe_ic = h->host_data;
257
258 /* Exact match, unless qe_ic node is NULL */
259 return qe_ic->of_node == NULL || qe_ic->of_node == node;
260}
261
262static int qe_ic_host_map(struct irq_host *h, unsigned int virq,
263 irq_hw_number_t hw)
264{
265 struct qe_ic *qe_ic = h->host_data;
266 struct irq_chip *chip;
267
268 if (qe_ic_info[hw].mask == 0) {
269 printk(KERN_ERR "Can't map reserved IRQ \n");
270 return -EINVAL;
271 }
272 /* Default chip */
273 chip = &qe_ic->hc_irq;
274
275 set_irq_chip_data(virq, qe_ic);
276 get_irq_desc(virq)->status |= IRQ_LEVEL;
277
278 set_irq_chip_and_handler(virq, chip, handle_level_irq);
279
280 return 0;
281}
282
283static int qe_ic_host_xlate(struct irq_host *h, struct device_node *ct,
284 u32 * intspec, unsigned int intsize,
285 irq_hw_number_t * out_hwirq,
286 unsigned int *out_flags)
287{
288 *out_hwirq = intspec[0];
289 if (intsize > 1)
290 *out_flags = intspec[1];
291 else
292 *out_flags = IRQ_TYPE_NONE;
293 return 0;
294}
295
296static struct irq_host_ops qe_ic_host_ops = {
297 .match = qe_ic_host_match,
298 .map = qe_ic_host_map,
299 .xlate = qe_ic_host_xlate,
300};
301
302/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
303unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic, struct pt_regs *regs)
304{
305 int irq;
306
307 BUG_ON(qe_ic == NULL);
308
309 /* get the interrupt source vector. */
310 irq = qe_ic_read(qe_ic->regs, QEIC_CIVEC) >> 26;
311
312 if (irq == 0)
313 return NO_IRQ;
314
315 return irq_linear_revmap(qe_ic->irqhost, irq);
316}
317
318/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
319unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic, struct pt_regs *regs)
320{
321 int irq;
322
323 BUG_ON(qe_ic == NULL);
324
325 /* get the interrupt source vector. */
326 irq = qe_ic_read(qe_ic->regs, QEIC_CHIVEC) >> 26;
327
328 if (irq == 0)
329 return NO_IRQ;
330
331 return irq_linear_revmap(qe_ic->irqhost, irq);
332}
333
334/* FIXME: We mask all the QE Low interrupts while handling. We should
335 * let other interrupt come in, but BAD interrupts are generated */
336void fastcall qe_ic_cascade_low(unsigned int irq, struct irq_desc *desc,
337 struct pt_regs *regs)
338{
339 struct qe_ic *qe_ic = desc->handler_data;
340 struct irq_chip *chip = irq_desc[irq].chip;
341
342 unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic, regs);
343
344 chip->mask_ack(irq);
345 if (cascade_irq != NO_IRQ)
346 generic_handle_irq(cascade_irq, regs);
347 chip->unmask(irq);
348}
349
350/* FIXME: We mask all the QE High interrupts while handling. We should
351 * let other interrupt come in, but BAD interrupts are generated */
352void fastcall qe_ic_cascade_high(unsigned int irq, struct irq_desc *desc,
353 struct pt_regs *regs)
354{
355 struct qe_ic *qe_ic = desc->handler_data;
356 struct irq_chip *chip = irq_desc[irq].chip;
357
358 unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic, regs);
359
360 chip->mask_ack(irq);
361 if (cascade_irq != NO_IRQ)
362 generic_handle_irq(cascade_irq, regs);
363 chip->unmask(irq);
364}
365
366void __init qe_ic_init(struct device_node *node, unsigned int flags)
367{
368 struct qe_ic *qe_ic;
369 struct resource res;
370 u32 temp = 0, ret, high_active = 0;
371
372 qe_ic = alloc_bootmem(sizeof(struct qe_ic));
373 if (qe_ic == NULL)
374 return;
375
376 memset(qe_ic, 0, sizeof(struct qe_ic));
377 qe_ic->of_node = node ? of_node_get(node) : NULL;
378
379 qe_ic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
380 NR_QE_IC_INTS, &qe_ic_host_ops, 0);
381 if (qe_ic->irqhost == NULL) {
382 of_node_put(node);
383 return;
384 }
385
386 ret = of_address_to_resource(node, 0, &res);
387 if (ret)
388 return;
389
390 qe_ic->regs = ioremap(res.start, res.end - res.start + 1);
391
392 qe_ic->irqhost->host_data = qe_ic;
393 qe_ic->hc_irq = qe_ic_irq_chip;
394
395 qe_ic->virq_high = irq_of_parse_and_map(node, 0);
396 qe_ic->virq_low = irq_of_parse_and_map(node, 1);
397
398 if (qe_ic->virq_low == NO_IRQ) {
399 printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
400 return;
401 }
402
403 /* default priority scheme is grouped. If spread mode is */
404 /* required, configure cicr accordingly. */
405 if (flags & QE_IC_SPREADMODE_GRP_W)
406 temp |= CICR_GWCC;
407 if (flags & QE_IC_SPREADMODE_GRP_X)
408 temp |= CICR_GXCC;
409 if (flags & QE_IC_SPREADMODE_GRP_Y)
410 temp |= CICR_GYCC;
411 if (flags & QE_IC_SPREADMODE_GRP_Z)
412 temp |= CICR_GZCC;
413 if (flags & QE_IC_SPREADMODE_GRP_RISCA)
414 temp |= CICR_GRTA;
415 if (flags & QE_IC_SPREADMODE_GRP_RISCB)
416 temp |= CICR_GRTB;
417
418 /* choose destination signal for highest priority interrupt */
419 if (flags & QE_IC_HIGH_SIGNAL) {
420 temp |= (SIGNAL_HIGH << CICR_HPIT_SHIFT);
421 high_active = 1;
422 }
423
424 qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
425
426 set_irq_data(qe_ic->virq_low, qe_ic);
427 set_irq_chained_handler(qe_ic->virq_low, qe_ic_cascade_low);
428
429 if (qe_ic->virq_high != NO_IRQ) {
430 set_irq_data(qe_ic->virq_high, qe_ic);
431 set_irq_chained_handler(qe_ic->virq_high, qe_ic_cascade_high);
432 }
433
434 printk("QEIC (%d IRQ sources) at %p\n", NR_QE_IC_INTS, qe_ic->regs);
435}
436
437void qe_ic_set_highest_priority(unsigned int virq, int high)
438{
439 struct qe_ic *qe_ic = qe_ic_from_irq(virq);
440 unsigned int src = virq_to_hw(virq);
441 u32 temp = 0;
442
443 temp = qe_ic_read(qe_ic->regs, QEIC_CICR);
444
445 temp &= ~CICR_HP_MASK;
446 temp |= src << CICR_HP_SHIFT;
447
448 temp &= ~CICR_HPIT_MASK;
449 temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << CICR_HPIT_SHIFT;
450
451 qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
452}
453
454/* Set Priority level within its group, from 1 to 8 */
455int qe_ic_set_priority(unsigned int virq, unsigned int priority)
456{
457 struct qe_ic *qe_ic = qe_ic_from_irq(virq);
458 unsigned int src = virq_to_hw(virq);
459 u32 temp;
460
461 if (priority > 8 || priority == 0)
462 return -EINVAL;
463 if (src > 127)
464 return -EINVAL;
465 if (qe_ic_info[src].pri_reg == 0)
466 return -EINVAL;
467
468 temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].pri_reg);
469
470 if (priority < 4) {
471 temp &= ~(0x7 << (32 - priority * 3));
472 temp |= qe_ic_info[src].pri_code << (32 - priority * 3);
473 } else {
474 temp &= ~(0x7 << (24 - priority * 3));
475 temp |= qe_ic_info[src].pri_code << (24 - priority * 3);
476 }
477
478 qe_ic_write(qe_ic->regs, qe_ic_info[src].pri_reg, temp);
479
480 return 0;
481}
482
483/* Set a QE priority to use high irq, only priority 1~2 can use high irq */
484int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high)
485{
486 struct qe_ic *qe_ic = qe_ic_from_irq(virq);
487 unsigned int src = virq_to_hw(virq);
488 u32 temp, control_reg = QEIC_CICNR, shift = 0;
489
490 if (priority > 2 || priority == 0)
491 return -EINVAL;
492
493 switch (qe_ic_info[src].pri_reg) {
494 case QEIC_CIPZCC:
495 shift = CICNR_ZCC1T_SHIFT;
496 break;
497 case QEIC_CIPWCC:
498 shift = CICNR_WCC1T_SHIFT;
499 break;
500 case QEIC_CIPYCC:
501 shift = CICNR_YCC1T_SHIFT;
502 break;
503 case QEIC_CIPXCC:
504 shift = CICNR_XCC1T_SHIFT;
505 break;
506 case QEIC_CIPRTA:
507 shift = CRICR_RTA1T_SHIFT;
508 control_reg = QEIC_CRICR;
509 break;
510 case QEIC_CIPRTB:
511 shift = CRICR_RTB1T_SHIFT;
512 control_reg = QEIC_CRICR;
513 break;
514 default:
515 return -EINVAL;
516 }
517
518 shift += (2 - priority) * 2;
519 temp = qe_ic_read(qe_ic->regs, control_reg);
520 temp &= ~(SIGNAL_MASK << shift);
521 temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << shift;
522 qe_ic_write(qe_ic->regs, control_reg, temp);
523
524 return 0;
525}
526
527static struct sysdev_class qe_ic_sysclass = {
528 set_kset_name("qe_ic"),
529};
530
531static struct sys_device device_qe_ic = {
532 .id = 0,
533 .cls = &qe_ic_sysclass,
534};
535
536static int __init init_qe_ic_sysfs(void)
537{
538 int rc;
539
540 printk(KERN_DEBUG "Registering qe_ic with sysfs...\n");
541
542 rc = sysdev_class_register(&qe_ic_sysclass);
543 if (rc) {
544 printk(KERN_ERR "Failed registering qe_ic sys class\n");
545 return -ENODEV;
546 }
547 rc = sysdev_register(&device_qe_ic);
548 if (rc) {
549 printk(KERN_ERR "Failed registering qe_ic sys device\n");
550 return -ENODEV;
551 }
552 return 0;
553}
554
555subsys_initcall(init_qe_ic_sysfs);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.h b/arch/powerpc/sysdev/qe_lib/qe_ic.h
new file mode 100644
index 000000000000..9a631adb189d
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.h
@@ -0,0 +1,106 @@
1/*
2 * arch/powerpc/sysdev/qe_lib/qe_ic.h
3 *
4 * QUICC ENGINE Interrupt Controller Header
5 *
6 * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
7 *
8 * Author: Li Yang <leoli@freescale.com>
9 * Based on code from Shlomi Gridish <gridish@freescale.com>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16#ifndef _POWERPC_SYSDEV_QE_IC_H
17#define _POWERPC_SYSDEV_QE_IC_H
18
19#include <asm/qe_ic.h>
20
21#define NR_QE_IC_INTS 64
22
23/* QE IC registers offset */
24#define QEIC_CICR 0x00
25#define QEIC_CIVEC 0x04
26#define QEIC_CRIPNR 0x08
27#define QEIC_CIPNR 0x0c
28#define QEIC_CIPXCC 0x10
29#define QEIC_CIPYCC 0x14
30#define QEIC_CIPWCC 0x18
31#define QEIC_CIPZCC 0x1c
32#define QEIC_CIMR 0x20
33#define QEIC_CRIMR 0x24
34#define QEIC_CICNR 0x28
35#define QEIC_CIPRTA 0x30
36#define QEIC_CIPRTB 0x34
37#define QEIC_CRICR 0x3c
38#define QEIC_CHIVEC 0x60
39
40/* Interrupt priority registers */
41#define CIPCC_SHIFT_PRI0 29
42#define CIPCC_SHIFT_PRI1 26
43#define CIPCC_SHIFT_PRI2 23
44#define CIPCC_SHIFT_PRI3 20
45#define CIPCC_SHIFT_PRI4 13
46#define CIPCC_SHIFT_PRI5 10
47#define CIPCC_SHIFT_PRI6 7
48#define CIPCC_SHIFT_PRI7 4
49
50/* CICR priority modes */
51#define CICR_GWCC 0x00040000
52#define CICR_GXCC 0x00020000
53#define CICR_GYCC 0x00010000
54#define CICR_GZCC 0x00080000
55#define CICR_GRTA 0x00200000
56#define CICR_GRTB 0x00400000
57#define CICR_HPIT_SHIFT 8
58#define CICR_HPIT_MASK 0x00000300
59#define CICR_HP_SHIFT 24
60#define CICR_HP_MASK 0x3f000000
61
62/* CICNR */
63#define CICNR_WCC1T_SHIFT 20
64#define CICNR_ZCC1T_SHIFT 28
65#define CICNR_YCC1T_SHIFT 12
66#define CICNR_XCC1T_SHIFT 4
67
68/* CRICR */
69#define CRICR_RTA1T_SHIFT 20
70#define CRICR_RTB1T_SHIFT 28
71
72/* Signal indicator */
73#define SIGNAL_MASK 3
74#define SIGNAL_HIGH 2
75#define SIGNAL_LOW 0
76
77struct qe_ic {
78 /* Control registers offset */
79 volatile u32 __iomem *regs;
80
81 /* The remapper for this QEIC */
82 struct irq_host *irqhost;
83
84 /* The "linux" controller struct */
85 struct irq_chip hc_irq;
86
87 /* The device node of the interrupt controller */
88 struct device_node *of_node;
89
90 /* VIRQ numbers of QE high/low irqs */
91 unsigned int virq_high;
92 unsigned int virq_low;
93};
94
95/*
96 * QE interrupt controller internal structure
97 */
98struct qe_ic_info {
99 u32 mask; /* location of this source at the QIMR register. */
100 u32 mask_reg; /* Mask register offset */
101 u8 pri_code; /* for grouped interrupts sources - the interrupt
102 code as appears at the group priority register */
103 u32 pri_reg; /* Group priority register offset */
104};
105
106#endif /* _POWERPC_SYSDEV_QE_IC_H */
diff --git a/arch/powerpc/sysdev/qe_lib/qe_io.c b/arch/powerpc/sysdev/qe_lib/qe_io.c
new file mode 100644
index 000000000000..aea435970389
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/qe_io.c
@@ -0,0 +1,226 @@
1/*
2 * arch/powerpc/sysdev/qe_lib/qe_io.c
3 *
4 * QE Parallel I/O ports configuration routines
5 *
6 * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
7 *
8 * Author: Li Yang <LeoLi@freescale.com>
9 * Based on code from Shlomi Gridish <gridish@freescale.com>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16
17#include <linux/config.h>
18#include <linux/stddef.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/errno.h>
22#include <linux/module.h>
23#include <linux/ioport.h>
24
25#include <asm/io.h>
26#include <asm/prom.h>
27#include <sysdev/fsl_soc.h>
28
29#undef DEBUG
30
31#define NUM_OF_PINS 32
32
33struct port_regs {
34 __be32 cpodr; /* Open drain register */
35 __be32 cpdata; /* Data register */
36 __be32 cpdir1; /* Direction register */
37 __be32 cpdir2; /* Direction register */
38 __be32 cppar1; /* Pin assignment register */
39 __be32 cppar2; /* Pin assignment register */
40};
41
42static struct port_regs *par_io = NULL;
43static int num_par_io_ports = 0;
44
45int par_io_init(struct device_node *np)
46{
47 struct resource res;
48 int ret;
49 const u32 *num_ports;
50
51 /* Map Parallel I/O ports registers */
52 ret = of_address_to_resource(np, 0, &res);
53 if (ret)
54 return ret;
55 par_io = ioremap(res.start, res.end - res.start + 1);
56
57 num_ports = get_property(np, "num-ports", NULL);
58 if (num_ports)
59 num_par_io_ports = *num_ports;
60
61 return 0;
62}
63
64int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain,
65 int assignment, int has_irq)
66{
67 u32 pin_mask1bit, pin_mask2bits, new_mask2bits, tmp_val;
68
69 if (!par_io)
70 return -1;
71
72 /* calculate pin location for single and 2 bits information */
73 pin_mask1bit = (u32) (1 << (NUM_OF_PINS - (pin + 1)));
74
75 /* Set open drain, if required */
76 tmp_val = in_be32(&par_io[port].cpodr);
77 if (open_drain)
78 out_be32(&par_io[port].cpodr, pin_mask1bit | tmp_val);
79 else
80 out_be32(&par_io[port].cpodr, ~pin_mask1bit & tmp_val);
81
82 /* define direction */
83 tmp_val = (pin > (NUM_OF_PINS / 2) - 1) ?
84 in_be32(&par_io[port].cpdir2) :
85 in_be32(&par_io[port].cpdir1);
86
87 /* get all bits mask for 2 bit per port */
88 pin_mask2bits = (u32) (0x3 << (NUM_OF_PINS -
89 (pin % (NUM_OF_PINS / 2) + 1) * 2));
90
91 /* Get the final mask we need for the right definition */
92 new_mask2bits = (u32) (dir << (NUM_OF_PINS -
93 (pin % (NUM_OF_PINS / 2) + 1) * 2));
94
95 /* clear and set 2 bits mask */
96 if (pin > (NUM_OF_PINS / 2) - 1) {
97 out_be32(&par_io[port].cpdir2,
98 ~pin_mask2bits & tmp_val);
99 tmp_val &= ~pin_mask2bits;
100 out_be32(&par_io[port].cpdir2, new_mask2bits | tmp_val);
101 } else {
102 out_be32(&par_io[port].cpdir1,
103 ~pin_mask2bits & tmp_val);
104 tmp_val &= ~pin_mask2bits;
105 out_be32(&par_io[port].cpdir1, new_mask2bits | tmp_val);
106 }
107 /* define pin assignment */
108 tmp_val = (pin > (NUM_OF_PINS / 2) - 1) ?
109 in_be32(&par_io[port].cppar2) :
110 in_be32(&par_io[port].cppar1);
111
112 new_mask2bits = (u32) (assignment << (NUM_OF_PINS -
113 (pin % (NUM_OF_PINS / 2) + 1) * 2));
114 /* clear and set 2 bits mask */
115 if (pin > (NUM_OF_PINS / 2) - 1) {
116 out_be32(&par_io[port].cppar2,
117 ~pin_mask2bits & tmp_val);
118 tmp_val &= ~pin_mask2bits;
119 out_be32(&par_io[port].cppar2, new_mask2bits | tmp_val);
120 } else {
121 out_be32(&par_io[port].cppar1,
122 ~pin_mask2bits & tmp_val);
123 tmp_val &= ~pin_mask2bits;
124 out_be32(&par_io[port].cppar1, new_mask2bits | tmp_val);
125 }
126
127 return 0;
128}
129EXPORT_SYMBOL(par_io_config_pin);
130
131int par_io_data_set(u8 port, u8 pin, u8 val)
132{
133 u32 pin_mask, tmp_val;
134
135 if (port >= num_par_io_ports)
136 return -EINVAL;
137 if (pin >= NUM_OF_PINS)
138 return -EINVAL;
139 /* calculate pin location */
140 pin_mask = (u32) (1 << (NUM_OF_PINS - 1 - pin));
141
142 tmp_val = in_be32(&par_io[port].cpdata);
143
144 if (val == 0) /* clear */
145 out_be32(&par_io[port].cpdata, ~pin_mask & tmp_val);
146 else /* set */
147 out_be32(&par_io[port].cpdata, pin_mask | tmp_val);
148
149 return 0;
150}
151EXPORT_SYMBOL(par_io_data_set);
152
153int par_io_of_config(struct device_node *np)
154{
155 struct device_node *pio;
156 const phandle *ph;
157 int pio_map_len;
158 const unsigned int *pio_map;
159
160 if (par_io == NULL) {
161 printk(KERN_ERR "par_io not initialized \n");
162 return -1;
163 }
164
165 ph = get_property(np, "pio-handle", NULL);
166 if (ph == 0) {
167 printk(KERN_ERR "pio-handle not available \n");
168 return -1;
169 }
170
171 pio = of_find_node_by_phandle(*ph);
172
173 pio_map = get_property(pio, "pio-map", &pio_map_len);
174 if (pio_map == NULL) {
175 printk(KERN_ERR "pio-map is not set! \n");
176 return -1;
177 }
178 pio_map_len /= sizeof(unsigned int);
179 if ((pio_map_len % 6) != 0) {
180 printk(KERN_ERR "pio-map format wrong! \n");
181 return -1;
182 }
183
184 while (pio_map_len > 0) {
185 par_io_config_pin((u8) pio_map[0], (u8) pio_map[1],
186 (int) pio_map[2], (int) pio_map[3],
187 (int) pio_map[4], (int) pio_map[5]);
188 pio_map += 6;
189 pio_map_len -= 6;
190 }
191 of_node_put(pio);
192 return 0;
193}
194EXPORT_SYMBOL(par_io_of_config);
195
196#ifdef DEBUG
197static void dump_par_io(void)
198{
199 int i;
200
201 printk(KERN_INFO "PAR IO registars:\n");
202 printk(KERN_INFO "Base address: 0x%08x\n", (u32) par_io);
203 for (i = 0; i < num_par_io_ports; i++) {
204 printk(KERN_INFO "cpodr[%d] : addr - 0x%08x, val - 0x%08x\n",
205 i, (u32) & par_io[i].cpodr,
206 in_be32(&par_io[i].cpodr));
207 printk(KERN_INFO "cpdata[%d]: addr - 0x%08x, val - 0x%08x\n",
208 i, (u32) & par_io[i].cpdata,
209 in_be32(&par_io[i].cpdata));
210 printk(KERN_INFO "cpdir1[%d]: addr - 0x%08x, val - 0x%08x\n",
211 i, (u32) & par_io[i].cpdir1,
212 in_be32(&par_io[i].cpdir1));
213 printk(KERN_INFO "cpdir2[%d]: addr - 0x%08x, val - 0x%08x\n",
214 i, (u32) & par_io[i].cpdir2,
215 in_be32(&par_io[i].cpdir2));
216 printk(KERN_INFO "cppar1[%d]: addr - 0x%08x, val - 0x%08x\n",
217 i, (u32) & par_io[i].cppar1,
218 in_be32(&par_io[i].cppar1));
219 printk(KERN_INFO "cppar2[%d]: addr - 0x%08x, val - 0x%08x\n",
220 i, (u32) & par_io[i].cppar2,
221 in_be32(&par_io[i].cppar2));
222 }
223
224}
225EXPORT_SYMBOL(dump_par_io);
226#endif /* DEBUG */
diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c
new file mode 100644
index 000000000000..916c9e5df57f
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/ucc.c
@@ -0,0 +1,251 @@
1/*
2 * arch/powerpc/sysdev/qe_lib/ucc.c
3 *
4 * QE UCC API Set - UCC specific routines implementations.
5 *
6 * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
7 *
8 * Authors: Shlomi Gridish <gridish@freescale.com>
9 * Li Yang <leoli@freescale.com>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/errno.h>
19#include <linux/slab.h>
20#include <linux/stddef.h>
21
22#include <asm/irq.h>
23#include <asm/io.h>
24#include <asm/immap_qe.h>
25#include <asm/qe.h>
26#include <asm/ucc.h>
27
28static DEFINE_SPINLOCK(ucc_lock);
29
30int ucc_set_qe_mux_mii_mng(int ucc_num)
31{
32 unsigned long flags;
33
34 spin_lock_irqsave(&ucc_lock, flags);
35 out_be32(&qe_immr->qmx.cmxgcr,
36 ((in_be32(&qe_immr->qmx.cmxgcr) &
37 ~QE_CMXGCR_MII_ENET_MNG) |
38 (ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT)));
39 spin_unlock_irqrestore(&ucc_lock, flags);
40
41 return 0;
42}
43
44int ucc_set_type(int ucc_num, struct ucc_common *regs,
45 enum ucc_speed_type speed)
46{
47 u8 guemr = 0;
48
49 /* check if the UCC number is in range. */
50 if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0))
51 return -EINVAL;
52
53 guemr = regs->guemr;
54 guemr &= ~(UCC_GUEMR_MODE_MASK_RX | UCC_GUEMR_MODE_MASK_TX);
55 switch (speed) {
56 case UCC_SPEED_TYPE_SLOW:
57 guemr |= (UCC_GUEMR_MODE_SLOW_RX | UCC_GUEMR_MODE_SLOW_TX);
58 break;
59 case UCC_SPEED_TYPE_FAST:
60 guemr |= (UCC_GUEMR_MODE_FAST_RX | UCC_GUEMR_MODE_FAST_TX);
61 break;
62 default:
63 return -EINVAL;
64 }
65 regs->guemr = guemr;
66
67 return 0;
68}
69
70int ucc_init_guemr(struct ucc_common *regs)
71{
72 u8 guemr = 0;
73
74 if (!regs)
75 return -EINVAL;
76
77 /* Set bit 3 (which is reserved in the GUEMR register) to 1 */
78 guemr = UCC_GUEMR_SET_RESERVED3;
79
80 regs->guemr = guemr;
81
82 return 0;
83}
84
85static void get_cmxucr_reg(int ucc_num, volatile u32 ** p_cmxucr, u8 * reg_num,
86 u8 * shift)
87{
88 switch (ucc_num) {
89 case 0: *p_cmxucr = &(qe_immr->qmx.cmxucr1);
90 *reg_num = 1;
91 *shift = 16;
92 break;
93 case 2: *p_cmxucr = &(qe_immr->qmx.cmxucr1);
94 *reg_num = 1;
95 *shift = 0;
96 break;
97 case 4: *p_cmxucr = &(qe_immr->qmx.cmxucr2);
98 *reg_num = 2;
99 *shift = 16;
100 break;
101 case 6: *p_cmxucr = &(qe_immr->qmx.cmxucr2);
102 *reg_num = 2;
103 *shift = 0;
104 break;
105 case 1: *p_cmxucr = &(qe_immr->qmx.cmxucr3);
106 *reg_num = 3;
107 *shift = 16;
108 break;
109 case 3: *p_cmxucr = &(qe_immr->qmx.cmxucr3);
110 *reg_num = 3;
111 *shift = 0;
112 break;
113 case 5: *p_cmxucr = &(qe_immr->qmx.cmxucr4);
114 *reg_num = 4;
115 *shift = 16;
116 break;
117 case 7: *p_cmxucr = &(qe_immr->qmx.cmxucr4);
118 *reg_num = 4;
119 *shift = 0;
120 break;
121 default:
122 break;
123 }
124}
125
126int ucc_mux_set_grant_tsa_bkpt(int ucc_num, int set, u32 mask)
127{
128 volatile u32 *p_cmxucr;
129 u8 reg_num;
130 u8 shift;
131
132 /* check if the UCC number is in range. */
133 if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0))
134 return -EINVAL;
135
136 get_cmxucr_reg(ucc_num, &p_cmxucr, &reg_num, &shift);
137
138 if (set)
139 out_be32(p_cmxucr, in_be32(p_cmxucr) | (mask << shift));
140 else
141 out_be32(p_cmxucr, in_be32(p_cmxucr) & ~(mask << shift));
142
143 return 0;
144}
145
146int ucc_set_qe_mux_rxtx(int ucc_num, enum qe_clock clock, enum comm_dir mode)
147{
148 volatile u32 *p_cmxucr;
149 u8 reg_num;
150 u8 shift;
151 u32 clock_bits;
152 u32 clock_mask;
153 int source = -1;
154
155 /* check if the UCC number is in range. */
156 if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0))
157 return -EINVAL;
158
159 if (!((mode == COMM_DIR_RX) || (mode == COMM_DIR_TX))) {
160 printk(KERN_ERR
161 "ucc_set_qe_mux_rxtx: bad comm mode type passed.");
162 return -EINVAL;
163 }
164
165 get_cmxucr_reg(ucc_num, &p_cmxucr, &reg_num, &shift);
166
167 switch (reg_num) {
168 case 1:
169 switch (clock) {
170 case QE_BRG1: source = 1; break;
171 case QE_BRG2: source = 2; break;
172 case QE_BRG7: source = 3; break;
173 case QE_BRG8: source = 4; break;
174 case QE_CLK9: source = 5; break;
175 case QE_CLK10: source = 6; break;
176 case QE_CLK11: source = 7; break;
177 case QE_CLK12: source = 8; break;
178 case QE_CLK15: source = 9; break;
179 case QE_CLK16: source = 10; break;
180 default: source = -1; break;
181 }
182 break;
183 case 2:
184 switch (clock) {
185 case QE_BRG5: source = 1; break;
186 case QE_BRG6: source = 2; break;
187 case QE_BRG7: source = 3; break;
188 case QE_BRG8: source = 4; break;
189 case QE_CLK13: source = 5; break;
190 case QE_CLK14: source = 6; break;
191 case QE_CLK19: source = 7; break;
192 case QE_CLK20: source = 8; break;
193 case QE_CLK15: source = 9; break;
194 case QE_CLK16: source = 10; break;
195 default: source = -1; break;
196 }
197 break;
198 case 3:
199 switch (clock) {
200 case QE_BRG9: source = 1; break;
201 case QE_BRG10: source = 2; break;
202 case QE_BRG15: source = 3; break;
203 case QE_BRG16: source = 4; break;
204 case QE_CLK3: source = 5; break;
205 case QE_CLK4: source = 6; break;
206 case QE_CLK17: source = 7; break;
207 case QE_CLK18: source = 8; break;
208 case QE_CLK7: source = 9; break;
209 case QE_CLK8: source = 10; break;
210 default: source = -1; break;
211 }
212 break;
213 case 4:
214 switch (clock) {
215 case QE_BRG13: source = 1; break;
216 case QE_BRG14: source = 2; break;
217 case QE_BRG15: source = 3; break;
218 case QE_BRG16: source = 4; break;
219 case QE_CLK5: source = 5; break;
220 case QE_CLK6: source = 6; break;
221 case QE_CLK21: source = 7; break;
222 case QE_CLK22: source = 8; break;
223 case QE_CLK7: source = 9; break;
224 case QE_CLK8: source = 10; break;
225 default: source = -1; break;
226 }
227 break;
228 default:
229 source = -1;
230 break;
231 }
232
233 if (source == -1) {
234 printk(KERN_ERR
235 "ucc_set_qe_mux_rxtx: Bad combination of clock and UCC.");
236 return -ENOENT;
237 }
238
239 clock_bits = (u32) source;
240 clock_mask = QE_CMXUCR_TX_CLK_SRC_MASK;
241 if (mode == COMM_DIR_RX) {
242 clock_bits <<= 4; /* Rx field is 4 bits to left of Tx field */
243 clock_mask <<= 4; /* Rx field is 4 bits to left of Tx field */
244 }
245 clock_bits <<= shift;
246 clock_mask <<= shift;
247
248 out_be32(p_cmxucr, (in_be32(p_cmxucr) & ~clock_mask) | clock_bits);
249
250 return 0;
251}
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
new file mode 100644
index 000000000000..c2be7348fcbd
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
@@ -0,0 +1,396 @@
1/*
2 * arch/powerpc/sysdev/qe_lib/ucc_fast.c
3 *
4 * QE UCC Fast API Set - UCC Fast specific routines implementations.
5 *
6 * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
7 *
8 * Authors: Shlomi Gridish <gridish@freescale.com>
9 * Li Yang <leoli@freescale.com>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/errno.h>
19#include <linux/slab.h>
20#include <linux/stddef.h>
21#include <linux/interrupt.h>
22
23#include <asm/io.h>
24#include <asm/immap_qe.h>
25#include <asm/qe.h>
26
27#include <asm/ucc.h>
28#include <asm/ucc_fast.h>
29
30#define uccf_printk(level, format, arg...) \
31 printk(level format "\n", ## arg)
32
33#define uccf_dbg(format, arg...) \
34 uccf_printk(KERN_DEBUG , format , ## arg)
35#define uccf_err(format, arg...) \
36 uccf_printk(KERN_ERR , format , ## arg)
37#define uccf_info(format, arg...) \
38 uccf_printk(KERN_INFO , format , ## arg)
39#define uccf_warn(format, arg...) \
40 uccf_printk(KERN_WARNING , format , ## arg)
41
42#ifdef UCCF_VERBOSE_DEBUG
43#define uccf_vdbg uccf_dbg
44#else
45#define uccf_vdbg(fmt, args...) do { } while (0)
46#endif /* UCCF_VERBOSE_DEBUG */
47
48void ucc_fast_dump_regs(struct ucc_fast_private * uccf)
49{
50 uccf_info("UCC%d Fast registers:", uccf->uf_info->ucc_num);
51 uccf_info("Base address: 0x%08x", (u32) uccf->uf_regs);
52
53 uccf_info("gumr : addr - 0x%08x, val - 0x%08x",
54 (u32) & uccf->uf_regs->gumr, in_be32(&uccf->uf_regs->gumr));
55 uccf_info("upsmr : addr - 0x%08x, val - 0x%08x",
56 (u32) & uccf->uf_regs->upsmr, in_be32(&uccf->uf_regs->upsmr));
57 uccf_info("utodr : addr - 0x%08x, val - 0x%04x",
58 (u32) & uccf->uf_regs->utodr, in_be16(&uccf->uf_regs->utodr));
59 uccf_info("udsr : addr - 0x%08x, val - 0x%04x",
60 (u32) & uccf->uf_regs->udsr, in_be16(&uccf->uf_regs->udsr));
61 uccf_info("ucce : addr - 0x%08x, val - 0x%08x",
62 (u32) & uccf->uf_regs->ucce, in_be32(&uccf->uf_regs->ucce));
63 uccf_info("uccm : addr - 0x%08x, val - 0x%08x",
64 (u32) & uccf->uf_regs->uccm, in_be32(&uccf->uf_regs->uccm));
65 uccf_info("uccs : addr - 0x%08x, val - 0x%02x",
66 (u32) & uccf->uf_regs->uccs, uccf->uf_regs->uccs);
67 uccf_info("urfb : addr - 0x%08x, val - 0x%08x",
68 (u32) & uccf->uf_regs->urfb, in_be32(&uccf->uf_regs->urfb));
69 uccf_info("urfs : addr - 0x%08x, val - 0x%04x",
70 (u32) & uccf->uf_regs->urfs, in_be16(&uccf->uf_regs->urfs));
71 uccf_info("urfet : addr - 0x%08x, val - 0x%04x",
72 (u32) & uccf->uf_regs->urfet, in_be16(&uccf->uf_regs->urfet));
73 uccf_info("urfset: addr - 0x%08x, val - 0x%04x",
74 (u32) & uccf->uf_regs->urfset,
75 in_be16(&uccf->uf_regs->urfset));
76 uccf_info("utfb : addr - 0x%08x, val - 0x%08x",
77 (u32) & uccf->uf_regs->utfb, in_be32(&uccf->uf_regs->utfb));
78 uccf_info("utfs : addr - 0x%08x, val - 0x%04x",
79 (u32) & uccf->uf_regs->utfs, in_be16(&uccf->uf_regs->utfs));
80 uccf_info("utfet : addr - 0x%08x, val - 0x%04x",
81 (u32) & uccf->uf_regs->utfet, in_be16(&uccf->uf_regs->utfet));
82 uccf_info("utftt : addr - 0x%08x, val - 0x%04x",
83 (u32) & uccf->uf_regs->utftt, in_be16(&uccf->uf_regs->utftt));
84 uccf_info("utpt : addr - 0x%08x, val - 0x%04x",
85 (u32) & uccf->uf_regs->utpt, in_be16(&uccf->uf_regs->utpt));
86 uccf_info("urtry : addr - 0x%08x, val - 0x%08x",
87 (u32) & uccf->uf_regs->urtry, in_be32(&uccf->uf_regs->urtry));
88 uccf_info("guemr : addr - 0x%08x, val - 0x%02x",
89 (u32) & uccf->uf_regs->guemr, uccf->uf_regs->guemr);
90}
91
92u32 ucc_fast_get_qe_cr_subblock(int uccf_num)
93{
94 switch (uccf_num) {
95 case 0: return QE_CR_SUBBLOCK_UCCFAST1;
96 case 1: return QE_CR_SUBBLOCK_UCCFAST2;
97 case 2: return QE_CR_SUBBLOCK_UCCFAST3;
98 case 3: return QE_CR_SUBBLOCK_UCCFAST4;
99 case 4: return QE_CR_SUBBLOCK_UCCFAST5;
100 case 5: return QE_CR_SUBBLOCK_UCCFAST6;
101 case 6: return QE_CR_SUBBLOCK_UCCFAST7;
102 case 7: return QE_CR_SUBBLOCK_UCCFAST8;
103 default: return QE_CR_SUBBLOCK_INVALID;
104 }
105}
106
107void ucc_fast_transmit_on_demand(struct ucc_fast_private * uccf)
108{
109 out_be16(&uccf->uf_regs->utodr, UCC_FAST_TOD);
110}
111
112void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode)
113{
114 struct ucc_fast *uf_regs;
115 u32 gumr;
116
117 uf_regs = uccf->uf_regs;
118
119 /* Enable reception and/or transmission on this UCC. */
120 gumr = in_be32(&uf_regs->gumr);
121 if (mode & COMM_DIR_TX) {
122 gumr |= UCC_FAST_GUMR_ENT;
123 uccf->enabled_tx = 1;
124 }
125 if (mode & COMM_DIR_RX) {
126 gumr |= UCC_FAST_GUMR_ENR;
127 uccf->enabled_rx = 1;
128 }
129 out_be32(&uf_regs->gumr, gumr);
130}
131
132void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode)
133{
134 struct ucc_fast *uf_regs;
135 u32 gumr;
136
137 uf_regs = uccf->uf_regs;
138
139 /* Disable reception and/or transmission on this UCC. */
140 gumr = in_be32(&uf_regs->gumr);
141 if (mode & COMM_DIR_TX) {
142 gumr &= ~UCC_FAST_GUMR_ENT;
143 uccf->enabled_tx = 0;
144 }
145 if (mode & COMM_DIR_RX) {
146 gumr &= ~UCC_FAST_GUMR_ENR;
147 uccf->enabled_rx = 0;
148 }
149 out_be32(&uf_regs->gumr, gumr);
150}
151
152int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** uccf_ret)
153{
154 struct ucc_fast_private *uccf;
155 struct ucc_fast *uf_regs;
156 u32 gumr = 0;
157 int ret;
158
159 uccf_vdbg("%s: IN", __FUNCTION__);
160
161 if (!uf_info)
162 return -EINVAL;
163
164 /* check if the UCC port number is in range. */
165 if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) {
166 uccf_err("ucc_fast_init: Illagal UCC number!");
167 return -EINVAL;
168 }
169
170 /* Check that 'max_rx_buf_length' is properly aligned (4). */
171 if (uf_info->max_rx_buf_length & (UCC_FAST_MRBLR_ALIGNMENT - 1)) {
172 uccf_err("ucc_fast_init: max_rx_buf_length not aligned.");
173 return -EINVAL;
174 }
175
176 /* Validate Virtual Fifo register values */
177 if (uf_info->urfs < UCC_FAST_URFS_MIN_VAL) {
178 uccf_err
179 ("ucc_fast_init: Virtual Fifo register urfs too small.");
180 return -EINVAL;
181 }
182
183 if (uf_info->urfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
184 uccf_err
185 ("ucc_fast_init: Virtual Fifo register urfs not aligned.");
186 return -EINVAL;
187 }
188
189 if (uf_info->urfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
190 uccf_err
191 ("ucc_fast_init: Virtual Fifo register urfet not aligned.");
192 return -EINVAL;
193 }
194
195 if (uf_info->urfset & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
196 uccf_err
197 ("ucc_fast_init: Virtual Fifo register urfset not aligned.");
198 return -EINVAL;
199 }
200
201 if (uf_info->utfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
202 uccf_err
203 ("ucc_fast_init: Virtual Fifo register utfs not aligned.");
204 return -EINVAL;
205 }
206
207 if (uf_info->utfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
208 uccf_err
209 ("ucc_fast_init: Virtual Fifo register utfet not aligned.");
210 return -EINVAL;
211 }
212
213 if (uf_info->utftt & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
214 uccf_err
215 ("ucc_fast_init: Virtual Fifo register utftt not aligned.");
216 return -EINVAL;
217 }
218
219 uccf = (struct ucc_fast_private *)
220 kmalloc(sizeof(struct ucc_fast_private), GFP_KERNEL);
221 if (!uccf) {
222 uccf_err
223 ("ucc_fast_init: No memory for UCC slow data structure!");
224 return -ENOMEM;
225 }
226 memset(uccf, 0, sizeof(struct ucc_fast_private));
227
228 /* Fill fast UCC structure */
229 uccf->uf_info = uf_info;
230 /* Set the PHY base address */
231 uccf->uf_regs =
232 (struct ucc_fast *) ioremap(uf_info->regs, sizeof(struct ucc_fast));
233 if (uccf->uf_regs == NULL) {
234 uccf_err
235 ("ucc_fast_init: No memory map for UCC slow controller!");
236 return -ENOMEM;
237 }
238
239 uccf->enabled_tx = 0;
240 uccf->enabled_rx = 0;
241 uccf->stopped_tx = 0;
242 uccf->stopped_rx = 0;
243 uf_regs = uccf->uf_regs;
244 uccf->p_ucce = (u32 *) & (uf_regs->ucce);
245 uccf->p_uccm = (u32 *) & (uf_regs->uccm);
246#ifdef STATISTICS
247 uccf->tx_frames = 0;
248 uccf->rx_frames = 0;
249 uccf->rx_discarded = 0;
250#endif /* STATISTICS */
251
252 /* Init Guemr register */
253 if ((ret = ucc_init_guemr((struct ucc_common *) (uf_regs)))) {
254 uccf_err("ucc_fast_init: Could not init the guemr register.");
255 ucc_fast_free(uccf);
256 return ret;
257 }
258
259 /* Set UCC to fast type */
260 if ((ret = ucc_set_type(uf_info->ucc_num,
261 (struct ucc_common *) (uf_regs),
262 UCC_SPEED_TYPE_FAST))) {
263 uccf_err("ucc_fast_init: Could not set type to fast.");
264 ucc_fast_free(uccf);
265 return ret;
266 }
267
268 uccf->mrblr = uf_info->max_rx_buf_length;
269
270 /* Set GUMR */
271 /* For more details see the hardware spec. */
272 /* gumr starts as zero. */
273 if (uf_info->tci)
274 gumr |= UCC_FAST_GUMR_TCI;
275 gumr |= uf_info->ttx_trx;
276 if (uf_info->cdp)
277 gumr |= UCC_FAST_GUMR_CDP;
278 if (uf_info->ctsp)
279 gumr |= UCC_FAST_GUMR_CTSP;
280 if (uf_info->cds)
281 gumr |= UCC_FAST_GUMR_CDS;
282 if (uf_info->ctss)
283 gumr |= UCC_FAST_GUMR_CTSS;
284 if (uf_info->txsy)
285 gumr |= UCC_FAST_GUMR_TXSY;
286 if (uf_info->rsyn)
287 gumr |= UCC_FAST_GUMR_RSYN;
288 gumr |= uf_info->synl;
289 if (uf_info->rtsm)
290 gumr |= UCC_FAST_GUMR_RTSM;
291 gumr |= uf_info->renc;
292 if (uf_info->revd)
293 gumr |= UCC_FAST_GUMR_REVD;
294 gumr |= uf_info->tenc;
295 gumr |= uf_info->tcrc;
296 gumr |= uf_info->mode;
297 out_be32(&uf_regs->gumr, gumr);
298
299 /* Allocate memory for Tx Virtual Fifo */
300 uccf->ucc_fast_tx_virtual_fifo_base_offset =
301 qe_muram_alloc(uf_info->utfs, UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
302 if (IS_MURAM_ERR(uccf->ucc_fast_tx_virtual_fifo_base_offset)) {
303 uccf_err
304 ("ucc_fast_init: Can not allocate MURAM memory for "
305 "struct ucc_fastx_virtual_fifo_base_offset.");
306 uccf->ucc_fast_tx_virtual_fifo_base_offset = 0;
307 ucc_fast_free(uccf);
308 return -ENOMEM;
309 }
310
311 /* Allocate memory for Rx Virtual Fifo */
312 uccf->ucc_fast_rx_virtual_fifo_base_offset =
313 qe_muram_alloc(uf_info->urfs +
314 (u32)
315 UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR,
316 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
317 if (IS_MURAM_ERR(uccf->ucc_fast_rx_virtual_fifo_base_offset)) {
318 uccf_err
319 ("ucc_fast_init: Can not allocate MURAM memory for "
320 "ucc_fast_rx_virtual_fifo_base_offset.");
321 uccf->ucc_fast_rx_virtual_fifo_base_offset = 0;
322 ucc_fast_free(uccf);
323 return -ENOMEM;
324 }
325
326 /* Set Virtual Fifo registers */
327 out_be16(&uf_regs->urfs, uf_info->urfs);
328 out_be16(&uf_regs->urfet, uf_info->urfet);
329 out_be16(&uf_regs->urfset, uf_info->urfset);
330 out_be16(&uf_regs->utfs, uf_info->utfs);
331 out_be16(&uf_regs->utfet, uf_info->utfet);
332 out_be16(&uf_regs->utftt, uf_info->utftt);
333 /* utfb, urfb are offsets from MURAM base */
334 out_be32(&uf_regs->utfb, uccf->ucc_fast_tx_virtual_fifo_base_offset);
335 out_be32(&uf_regs->urfb, uccf->ucc_fast_rx_virtual_fifo_base_offset);
336
337 /* Mux clocking */
338 /* Grant Support */
339 ucc_set_qe_mux_grant(uf_info->ucc_num, uf_info->grant_support);
340 /* Breakpoint Support */
341 ucc_set_qe_mux_bkpt(uf_info->ucc_num, uf_info->brkpt_support);
342 /* Set Tsa or NMSI mode. */
343 ucc_set_qe_mux_tsa(uf_info->ucc_num, uf_info->tsa);
344 /* If NMSI (not Tsa), set Tx and Rx clock. */
345 if (!uf_info->tsa) {
346 /* Rx clock routing */
347 if (uf_info->rx_clock != QE_CLK_NONE) {
348 if (ucc_set_qe_mux_rxtx
349 (uf_info->ucc_num, uf_info->rx_clock,
350 COMM_DIR_RX)) {
351 uccf_err
352 ("ucc_fast_init: Illegal value for parameter 'RxClock'.");
353 ucc_fast_free(uccf);
354 return -EINVAL;
355 }
356 }
357 /* Tx clock routing */
358 if (uf_info->tx_clock != QE_CLK_NONE) {
359 if (ucc_set_qe_mux_rxtx
360 (uf_info->ucc_num, uf_info->tx_clock,
361 COMM_DIR_TX)) {
362 uccf_err
363 ("ucc_fast_init: Illegal value for parameter 'TxClock'.");
364 ucc_fast_free(uccf);
365 return -EINVAL;
366 }
367 }
368 }
369
370 /* Set interrupt mask register at UCC level. */
371 out_be32(&uf_regs->uccm, uf_info->uccm_mask);
372
373 /* First, clear anything pending at UCC level,
374 * otherwise, old garbage may come through
375 * as soon as the dam is opened
376 * Writing '1' clears
377 */
378 out_be32(&uf_regs->ucce, 0xffffffff);
379
380 *uccf_ret = uccf;
381 return 0;
382}
383
384void ucc_fast_free(struct ucc_fast_private * uccf)
385{
386 if (!uccf)
387 return;
388
389 if (uccf->ucc_fast_tx_virtual_fifo_base_offset)
390 qe_muram_free(uccf->ucc_fast_tx_virtual_fifo_base_offset);
391
392 if (uccf->ucc_fast_rx_virtual_fifo_base_offset)
393 qe_muram_free(uccf->ucc_fast_rx_virtual_fifo_base_offset);
394
395 kfree(uccf);
396}
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
new file mode 100644
index 000000000000..1fb88ef7cf06
--- /dev/null
+++ b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
@@ -0,0 +1,404 @@
1/*
2 * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
3 *
4 * Authors: Shlomi Gridish <gridish@freescale.com>
5 * Li Yang <leoli@freescale.com>
6 *
7 * Description:
8 * QE UCC Slow API Set - UCC Slow specific routines implementations.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/errno.h>
18#include <linux/slab.h>
19#include <linux/stddef.h>
20#include <linux/interrupt.h>
21
22#include <asm/irq.h>
23#include <asm/io.h>
24#include <asm/immap_qe.h>
25#include <asm/qe.h>
26
27#include <asm/ucc.h>
28#include <asm/ucc_slow.h>
29
30#define uccs_printk(level, format, arg...) \
31 printk(level format "\n", ## arg)
32
33#define uccs_dbg(format, arg...) \
34 uccs_printk(KERN_DEBUG , format , ## arg)
35#define uccs_err(format, arg...) \
36 uccs_printk(KERN_ERR , format , ## arg)
37#define uccs_info(format, arg...) \
38 uccs_printk(KERN_INFO , format , ## arg)
39#define uccs_warn(format, arg...) \
40 uccs_printk(KERN_WARNING , format , ## arg)
41
42#ifdef UCCS_VERBOSE_DEBUG
43#define uccs_vdbg uccs_dbg
44#else
45#define uccs_vdbg(fmt, args...) do { } while (0)
46#endif /* UCCS_VERBOSE_DEBUG */
47
48u32 ucc_slow_get_qe_cr_subblock(int uccs_num)
49{
50 switch (uccs_num) {
51 case 0: return QE_CR_SUBBLOCK_UCCSLOW1;
52 case 1: return QE_CR_SUBBLOCK_UCCSLOW2;
53 case 2: return QE_CR_SUBBLOCK_UCCSLOW3;
54 case 3: return QE_CR_SUBBLOCK_UCCSLOW4;
55 case 4: return QE_CR_SUBBLOCK_UCCSLOW5;
56 case 5: return QE_CR_SUBBLOCK_UCCSLOW6;
57 case 6: return QE_CR_SUBBLOCK_UCCSLOW7;
58 case 7: return QE_CR_SUBBLOCK_UCCSLOW8;
59 default: return QE_CR_SUBBLOCK_INVALID;
60 }
61}
62
63void ucc_slow_poll_transmitter_now(struct ucc_slow_private * uccs)
64{
65 out_be16(&uccs->us_regs->utodr, UCC_SLOW_TOD);
66}
67
68void ucc_slow_graceful_stop_tx(struct ucc_slow_private * uccs)
69{
70 struct ucc_slow_info *us_info = uccs->us_info;
71 u32 id;
72
73 id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
74 qe_issue_cmd(QE_GRACEFUL_STOP_TX, id,
75 QE_CR_PROTOCOL_UNSPECIFIED, 0);
76}
77
78void ucc_slow_stop_tx(struct ucc_slow_private * uccs)
79{
80 struct ucc_slow_info *us_info = uccs->us_info;
81 u32 id;
82
83 id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
84 qe_issue_cmd(QE_STOP_TX, id, QE_CR_PROTOCOL_UNSPECIFIED, 0);
85}
86
87void ucc_slow_restart_tx(struct ucc_slow_private * uccs)
88{
89 struct ucc_slow_info *us_info = uccs->us_info;
90 u32 id;
91
92 id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
93 qe_issue_cmd(QE_RESTART_TX, id, QE_CR_PROTOCOL_UNSPECIFIED, 0);
94}
95
96void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode)
97{
98 struct ucc_slow *us_regs;
99 u32 gumr_l;
100
101 us_regs = uccs->us_regs;
102
103 /* Enable reception and/or transmission on this UCC. */
104 gumr_l = in_be32(&us_regs->gumr_l);
105 if (mode & COMM_DIR_TX) {
106 gumr_l |= UCC_SLOW_GUMR_L_ENT;
107 uccs->enabled_tx = 1;
108 }
109 if (mode & COMM_DIR_RX) {
110 gumr_l |= UCC_SLOW_GUMR_L_ENR;
111 uccs->enabled_rx = 1;
112 }
113 out_be32(&us_regs->gumr_l, gumr_l);
114}
115
116void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode)
117{
118 struct ucc_slow *us_regs;
119 u32 gumr_l;
120
121 us_regs = uccs->us_regs;
122
123 /* Disable reception and/or transmission on this UCC. */
124 gumr_l = in_be32(&us_regs->gumr_l);
125 if (mode & COMM_DIR_TX) {
126 gumr_l &= ~UCC_SLOW_GUMR_L_ENT;
127 uccs->enabled_tx = 0;
128 }
129 if (mode & COMM_DIR_RX) {
130 gumr_l &= ~UCC_SLOW_GUMR_L_ENR;
131 uccs->enabled_rx = 0;
132 }
133 out_be32(&us_regs->gumr_l, gumr_l);
134}
135
136int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** uccs_ret)
137{
138 u32 i;
139 struct ucc_slow *us_regs;
140 u32 gumr;
141 u8 function_code = 0;
142 u8 *bd;
143 struct ucc_slow_private *uccs;
144 u32 id;
145 u32 command;
146 int ret;
147
148 uccs_vdbg("%s: IN", __FUNCTION__);
149
150 if (!us_info)
151 return -EINVAL;
152
153 /* check if the UCC port number is in range. */
154 if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM - 1)) {
155 uccs_err("ucc_slow_init: Illagal UCC number!");
156 return -EINVAL;
157 }
158
159 /*
160 * Set mrblr
161 * Check that 'max_rx_buf_length' is properly aligned (4), unless
162 * rfw is 1, meaning that QE accepts one byte at a time, unlike normal
163 * case when QE accepts 32 bits at a time.
164 */
165 if ((!us_info->rfw) &&
166 (us_info->max_rx_buf_length & (UCC_SLOW_MRBLR_ALIGNMENT - 1))) {
167 uccs_err("max_rx_buf_length not aligned.");
168 return -EINVAL;
169 }
170
171 uccs = (struct ucc_slow_private *)
172 kmalloc(sizeof(struct ucc_slow_private), GFP_KERNEL);
173 if (!uccs) {
174 uccs_err
175 ("ucc_slow_init: No memory for UCC slow data structure!");
176 return -ENOMEM;
177 }
178 memset(uccs, 0, sizeof(struct ucc_slow_private));
179
180 /* Fill slow UCC structure */
181 uccs->us_info = us_info;
182 uccs->saved_uccm = 0;
183 uccs->p_rx_frame = 0;
184 uccs->us_regs = us_info->us_regs;
185 us_regs = uccs->us_regs;
186 uccs->p_ucce = (u16 *) & (us_regs->ucce);
187 uccs->p_uccm = (u16 *) & (us_regs->uccm);
188#ifdef STATISTICS
189 uccs->rx_frames = 0;
190 uccs->tx_frames = 0;
191 uccs->rx_discarded = 0;
192#endif /* STATISTICS */
193
194 /* Get PRAM base */
195 uccs->us_pram_offset = qe_muram_alloc(UCC_SLOW_PRAM_SIZE,
196 ALIGNMENT_OF_UCC_SLOW_PRAM);
197 if (IS_MURAM_ERR(uccs->us_pram_offset)) {
198 uccs_err
199 ("ucc_slow_init: Can not allocate MURAM memory "
200 "for Slow UCC.");
201 ucc_slow_free(uccs);
202 return -ENOMEM;
203 }
204 id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
205 qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, id, QE_CR_PROTOCOL_UNSPECIFIED,
206 (u32) uccs->us_pram_offset);
207
208 uccs->us_pram = qe_muram_addr(uccs->us_pram_offset);
209
210 /* Init Guemr register */
211 if ((ret = ucc_init_guemr((struct ucc_common *) (us_info->us_regs)))) {
212 uccs_err("ucc_slow_init: Could not init the guemr register.");
213 ucc_slow_free(uccs);
214 return ret;
215 }
216
217 /* Set UCC to slow type */
218 if ((ret = ucc_set_type(us_info->ucc_num,
219 (struct ucc_common *) (us_info->us_regs),
220 UCC_SPEED_TYPE_SLOW))) {
221 uccs_err("ucc_slow_init: Could not init the guemr register.");
222 ucc_slow_free(uccs);
223 return ret;
224 }
225
226 out_be16(&uccs->us_pram->mrblr, us_info->max_rx_buf_length);
227
228 INIT_LIST_HEAD(&uccs->confQ);
229
230 /* Allocate BDs. */
231 uccs->rx_base_offset =
232 qe_muram_alloc(us_info->rx_bd_ring_len * sizeof(struct qe_bd),
233 QE_ALIGNMENT_OF_BD);
234 if (IS_MURAM_ERR(uccs->rx_base_offset)) {
235 uccs_err("ucc_slow_init: No memory for Rx BD's.");
236 uccs->rx_base_offset = 0;
237 ucc_slow_free(uccs);
238 return -ENOMEM;
239 }
240
241 uccs->tx_base_offset =
242 qe_muram_alloc(us_info->tx_bd_ring_len * sizeof(struct qe_bd),
243 QE_ALIGNMENT_OF_BD);
244 if (IS_MURAM_ERR(uccs->tx_base_offset)) {
245 uccs_err("ucc_slow_init: No memory for Tx BD's.");
246 uccs->tx_base_offset = 0;
247 ucc_slow_free(uccs);
248 return -ENOMEM;
249 }
250
251 /* Init Tx bds */
252 bd = uccs->confBd = uccs->tx_bd = qe_muram_addr(uccs->tx_base_offset);
253 for (i = 0; i < us_info->tx_bd_ring_len; i++) {
254 /* clear bd buffer */
255 out_be32(&(((struct qe_bd *)bd)->buf), 0);
256 /* set bd status and length */
257 out_be32((u32*)bd, 0);
258 bd += sizeof(struct qe_bd);
259 }
260 bd -= sizeof(struct qe_bd);
261 /* set bd status and length */
262 out_be32((u32*)bd, T_W); /* for last BD set Wrap bit */
263
264 /* Init Rx bds */
265 bd = uccs->rx_bd = qe_muram_addr(uccs->rx_base_offset);
266 for (i = 0; i < us_info->rx_bd_ring_len; i++) {
267 /* set bd status and length */
268 out_be32((u32*)bd, 0);
269 /* clear bd buffer */
270 out_be32(&(((struct qe_bd *)bd)->buf), 0);
271 bd += sizeof(struct qe_bd);
272 }
273 bd -= sizeof(struct qe_bd);
274 /* set bd status and length */
275 out_be32((u32*)bd, R_W); /* for last BD set Wrap bit */
276
277 /* Set GUMR (For more details see the hardware spec.). */
278 /* gumr_h */
279 gumr = 0;
280 gumr |= us_info->tcrc;
281 if (us_info->cdp)
282 gumr |= UCC_SLOW_GUMR_H_CDP;
283 if (us_info->ctsp)
284 gumr |= UCC_SLOW_GUMR_H_CTSP;
285 if (us_info->cds)
286 gumr |= UCC_SLOW_GUMR_H_CDS;
287 if (us_info->ctss)
288 gumr |= UCC_SLOW_GUMR_H_CTSS;
289 if (us_info->tfl)
290 gumr |= UCC_SLOW_GUMR_H_TFL;
291 if (us_info->rfw)
292 gumr |= UCC_SLOW_GUMR_H_RFW;
293 if (us_info->txsy)
294 gumr |= UCC_SLOW_GUMR_H_TXSY;
295 if (us_info->rtsm)
296 gumr |= UCC_SLOW_GUMR_H_RTSM;
297 out_be32(&us_regs->gumr_h, gumr);
298
299 /* gumr_l */
300 gumr = 0;
301 if (us_info->tci)
302 gumr |= UCC_SLOW_GUMR_L_TCI;
303 if (us_info->rinv)
304 gumr |= UCC_SLOW_GUMR_L_RINV;
305 if (us_info->tinv)
306 gumr |= UCC_SLOW_GUMR_L_TINV;
307 if (us_info->tend)
308 gumr |= UCC_SLOW_GUMR_L_TEND;
309 gumr |= us_info->tdcr;
310 gumr |= us_info->rdcr;
311 gumr |= us_info->tenc;
312 gumr |= us_info->renc;
313 gumr |= us_info->diag;
314 gumr |= us_info->mode;
315 out_be32(&us_regs->gumr_l, gumr);
316
317 /* Function code registers */
318 /* function_code has initial value 0 */
319
320 /* if the data is in cachable memory, the 'global' */
321 /* in the function code should be set. */
322 function_code |= us_info->data_mem_part;
323 function_code |= QE_BMR_BYTE_ORDER_BO_MOT; /* Required for QE */
324 uccs->us_pram->tfcr = function_code;
325 uccs->us_pram->rfcr = function_code;
326
327 /* rbase, tbase are offsets from MURAM base */
328 out_be16(&uccs->us_pram->rbase, uccs->us_pram_offset);
329 out_be16(&uccs->us_pram->tbase, uccs->us_pram_offset);
330
331 /* Mux clocking */
332 /* Grant Support */
333 ucc_set_qe_mux_grant(us_info->ucc_num, us_info->grant_support);
334 /* Breakpoint Support */
335 ucc_set_qe_mux_bkpt(us_info->ucc_num, us_info->brkpt_support);
336 /* Set Tsa or NMSI mode. */
337 ucc_set_qe_mux_tsa(us_info->ucc_num, us_info->tsa);
338 /* If NMSI (not Tsa), set Tx and Rx clock. */
339 if (!us_info->tsa) {
340 /* Rx clock routing */
341 if (ucc_set_qe_mux_rxtx
342 (us_info->ucc_num, us_info->rx_clock, COMM_DIR_RX)) {
343 uccs_err
344 ("ucc_slow_init: Illegal value for parameter"
345 " 'RxClock'.");
346 ucc_slow_free(uccs);
347 return -EINVAL;
348 }
349 /* Tx clock routing */
350 if (ucc_set_qe_mux_rxtx(us_info->ucc_num,
351 us_info->tx_clock, COMM_DIR_TX)) {
352 uccs_err
353 ("ucc_slow_init: Illegal value for parameter "
354 "'TxClock'.");
355 ucc_slow_free(uccs);
356 return -EINVAL;
357 }
358 }
359
360 /*
361 * INTERRUPTS
362 */
363 /* Set interrupt mask register at UCC level. */
364 out_be16(&us_regs->uccm, us_info->uccm_mask);
365
366 /* First, clear anything pending at UCC level, */
367 /* otherwise, old garbage may come through */
368 /* as soon as the dam is opened. */
369
370 /* Writing '1' clears */
371 out_be16(&us_regs->ucce, 0xffff);
372
373 /* Issue QE Init command */
374 if (us_info->init_tx && us_info->init_rx)
375 command = QE_INIT_TX_RX;
376 else if (us_info->init_tx)
377 command = QE_INIT_TX;
378 else
379 command = QE_INIT_RX; /* We know at least one is TRUE */
380 id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
381 qe_issue_cmd(command, id, QE_CR_PROTOCOL_UNSPECIFIED, 0);
382
383 *uccs_ret = uccs;
384 return 0;
385}
386
387void ucc_slow_free(struct ucc_slow_private * uccs)
388{
389 if (!uccs)
390 return;
391
392 if (uccs->rx_base_offset)
393 qe_muram_free(uccs->rx_base_offset);
394
395 if (uccs->tx_base_offset)
396 qe_muram_free(uccs->tx_base_offset);
397
398 if (uccs->us_pram) {
399 qe_muram_free(uccs->us_pram_offset);
400 uccs->us_pram = NULL;
401 }
402
403 kfree(uccs);
404}
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 8adad1444a51..708236f34746 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -2,6 +2,8 @@
2 * Routines providing a simple monitor for use on the PowerMac. 2 * Routines providing a simple monitor for use on the PowerMac.
3 * 3 *
4 * Copyright (C) 1996-2005 Paul Mackerras. 4 * Copyright (C) 1996-2005 Paul Mackerras.
5 * Copyright (C) 2001 PPC64 Team, IBM Corp
6 * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
5 * 7 *
6 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
@@ -503,7 +505,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
503 505
504 mtmsr(msr); /* restore interrupt enable */ 506 mtmsr(msr); /* restore interrupt enable */
505 507
506 return cmd != 'X'; 508 return cmd != 'X' && cmd != EOF;
507} 509}
508 510
509int xmon(struct pt_regs *excp) 511int xmon(struct pt_regs *excp)
@@ -2597,3 +2599,34 @@ static int __init setup_xmon_sysrq(void)
2597} 2599}
2598__initcall(setup_xmon_sysrq); 2600__initcall(setup_xmon_sysrq);
2599#endif /* CONFIG_MAGIC_SYSRQ */ 2601#endif /* CONFIG_MAGIC_SYSRQ */
2602
2603int __initdata xmon_early, xmon_off;
2604
2605static int __init early_parse_xmon(char *p)
2606{
2607 if (!p || strncmp(p, "early", 5) == 0) {
2608 /* just "xmon" is equivalent to "xmon=early" */
2609 xmon_init(1);
2610 xmon_early = 1;
2611 } else if (strncmp(p, "on", 2) == 0)
2612 xmon_init(1);
2613 else if (strncmp(p, "off", 3) == 0)
2614 xmon_off = 1;
2615 else if (strncmp(p, "nobt", 4) == 0)
2616 xmon_no_auto_backtrace = 1;
2617 else
2618 return 1;
2619
2620 return 0;
2621}
2622early_param("xmon", early_parse_xmon);
2623
2624void __init xmon_setup(void)
2625{
2626#ifdef CONFIG_XMON_DEFAULT
2627 if (!xmon_off)
2628 xmon_init(1);
2629#endif
2630 if (xmon_early)
2631 debugger(NULL);
2632}