diff options
137 files changed, 8141 insertions, 1065 deletions
diff --git a/Documentation/powerpc/dts-bindings/fsl/diu.txt b/Documentation/powerpc/dts-bindings/fsl/diu.txt index deb35de70988..b66cb6d31d69 100644 --- a/Documentation/powerpc/dts-bindings/fsl/diu.txt +++ b/Documentation/powerpc/dts-bindings/fsl/diu.txt | |||
@@ -4,10 +4,17 @@ The Freescale DIU is a LCD controller, with proper hardware, it can also | |||
4 | drive DVI monitors. | 4 | drive DVI monitors. |
5 | 5 | ||
6 | Required properties: | 6 | Required properties: |
7 | - compatible : should be "fsl-diu". | 7 | - compatible : should be "fsl,diu" or "fsl,mpc5121-diu". |
8 | - reg : should contain at least address and length of the DIU register | 8 | - reg : should contain at least address and length of the DIU register |
9 | set. | 9 | set. |
10 | - Interrupts : one DIU interrupt should be describe here. | 10 | - interrupts : one DIU interrupt should be described here. |
11 | - interrupt-parent : the phandle for the interrupt controller that | ||
12 | services interrupts for this device. | ||
13 | |||
14 | Optional properties: | ||
15 | - edid : verbatim EDID data block describing attached display. | ||
16 | Data from the detailed timing descriptor will be used to | ||
17 | program the display controller. | ||
11 | 18 | ||
12 | Example (MPC8610HPCD): | 19 | Example (MPC8610HPCD): |
13 | display@2c000 { | 20 | display@2c000 { |
@@ -16,3 +23,12 @@ Example (MPC8610HPCD): | |||
16 | interrupts = <72 2>; | 23 | interrupts = <72 2>; |
17 | interrupt-parent = <&mpic>; | 24 | interrupt-parent = <&mpic>; |
18 | }; | 25 | }; |
26 | |||
27 | Example for MPC5121: | ||
28 | display@2100 { | ||
29 | compatible = "fsl,mpc5121-diu"; | ||
30 | reg = <0x2100 0x100>; | ||
31 | interrupts = <64 0x8>; | ||
32 | interrupt-parent = <&ipic>; | ||
33 | edid = [edid-data]; | ||
34 | }; | ||
diff --git a/Documentation/powerpc/dts-bindings/fsl/i2c.txt b/Documentation/powerpc/dts-bindings/fsl/i2c.txt index 50da20310585..1eacd6b20ed5 100644 --- a/Documentation/powerpc/dts-bindings/fsl/i2c.txt +++ b/Documentation/powerpc/dts-bindings/fsl/i2c.txt | |||
@@ -20,6 +20,7 @@ Recommended properties : | |||
20 | - fsl,preserve-clocking : boolean; if defined, the clock settings | 20 | - fsl,preserve-clocking : boolean; if defined, the clock settings |
21 | from the bootloader are preserved (not touched). | 21 | from the bootloader are preserved (not touched). |
22 | - clock-frequency : desired I2C bus clock frequency in Hz. | 22 | - clock-frequency : desired I2C bus clock frequency in Hz. |
23 | - fsl,timeout : I2C bus timeout in microseconds. | ||
23 | 24 | ||
24 | Examples : | 25 | Examples : |
25 | 26 | ||
@@ -59,4 +60,5 @@ Examples : | |||
59 | interrupts = <43 2>; | 60 | interrupts = <43 2>; |
60 | interrupt-parent = <&mpic>; | 61 | interrupt-parent = <&mpic>; |
61 | clock-frequency = <400000>; | 62 | clock-frequency = <400000>; |
63 | fsl,timeout = <10000>; | ||
62 | }; | 64 | }; |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 2031a2846865..e4545f85ee9f 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -141,6 +141,7 @@ config PPC | |||
141 | select GENERIC_ATOMIC64 if PPC32 | 141 | select GENERIC_ATOMIC64 if PPC32 |
142 | select HAVE_PERF_EVENTS | 142 | select HAVE_PERF_EVENTS |
143 | select HAVE_REGS_AND_STACK_ACCESS_API | 143 | select HAVE_REGS_AND_STACK_ACCESS_API |
144 | select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64 | ||
144 | 145 | ||
145 | config EARLY_PRINTK | 146 | config EARLY_PRINTK |
146 | bool | 147 | bool |
@@ -218,7 +219,7 @@ config ARCH_HIBERNATION_POSSIBLE | |||
218 | config ARCH_SUSPEND_POSSIBLE | 219 | config ARCH_SUSPEND_POSSIBLE |
219 | def_bool y | 220 | def_bool y |
220 | depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ | 221 | depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ |
221 | PPC_85xx || PPC_86xx | 222 | PPC_85xx || PPC_86xx || PPC_PSERIES |
222 | 223 | ||
223 | config PPC_DCR_NATIVE | 224 | config PPC_DCR_NATIVE |
224 | bool | 225 | bool |
@@ -351,7 +352,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE | |||
351 | 352 | ||
352 | config KEXEC | 353 | config KEXEC |
353 | bool "kexec system call (EXPERIMENTAL)" | 354 | bool "kexec system call (EXPERIMENTAL)" |
354 | depends on (PPC_BOOK3S || (FSL_BOOKE && !SMP)) && EXPERIMENTAL | 355 | depends on (PPC_BOOK3S || FSL_BOOKE) && EXPERIMENTAL |
355 | help | 356 | help |
356 | kexec is a system call that implements the ability to shutdown your | 357 | kexec is a system call that implements the ability to shutdown your |
357 | current kernel, and to start another kernel. It is like a reboot | 358 | current kernel, and to start another kernel. It is like a reboot |
@@ -368,8 +369,8 @@ config KEXEC | |||
368 | 369 | ||
369 | config CRASH_DUMP | 370 | config CRASH_DUMP |
370 | bool "Build a kdump crash kernel" | 371 | bool "Build a kdump crash kernel" |
371 | depends on PPC64 || 6xx | 372 | depends on PPC64 || 6xx || FSL_BOOKE |
372 | select RELOCATABLE if PPC64 | 373 | select RELOCATABLE if PPC64 || FSL_BOOKE |
373 | help | 374 | help |
374 | Build a kernel suitable for use as a kdump capture kernel. | 375 | Build a kernel suitable for use as a kdump capture kernel. |
375 | The same kernel binary can be used as production kernel and dump | 376 | The same kernel binary can be used as production kernel and dump |
@@ -668,7 +669,7 @@ config NEED_SG_DMA_LENGTH | |||
668 | 669 | ||
669 | config GENERIC_ISA_DMA | 670 | config GENERIC_ISA_DMA |
670 | bool | 671 | bool |
671 | depends on PPC64 || POWER4 || 6xx && !CPM2 | 672 | depends on ISA_DMA_API |
672 | default y | 673 | default y |
673 | 674 | ||
674 | config PPC_INDIRECT_PCI | 675 | config PPC_INDIRECT_PCI |
@@ -897,7 +898,7 @@ config KERNEL_START_BOOL | |||
897 | config KERNEL_START | 898 | config KERNEL_START |
898 | hex "Virtual address of kernel base" if KERNEL_START_BOOL | 899 | hex "Virtual address of kernel base" if KERNEL_START_BOOL |
899 | default PAGE_OFFSET if PAGE_OFFSET_BOOL | 900 | default PAGE_OFFSET if PAGE_OFFSET_BOOL |
900 | default "0xc2000000" if CRASH_DUMP | 901 | default "0xc2000000" if CRASH_DUMP && !RELOCATABLE |
901 | default "0xc0000000" | 902 | default "0xc0000000" |
902 | 903 | ||
903 | config PHYSICAL_START_BOOL | 904 | config PHYSICAL_START_BOOL |
@@ -910,7 +911,7 @@ config PHYSICAL_START_BOOL | |||
910 | 911 | ||
911 | config PHYSICAL_START | 912 | config PHYSICAL_START |
912 | hex "Physical address where the kernel is loaded" if PHYSICAL_START_BOOL | 913 | hex "Physical address where the kernel is loaded" if PHYSICAL_START_BOOL |
913 | default "0x02000000" if PPC_STD_MMU && CRASH_DUMP | 914 | default "0x02000000" if PPC_STD_MMU && CRASH_DUMP && !RELOCATABLE |
914 | default "0x00000000" | 915 | default "0x00000000" |
915 | 916 | ||
916 | config PHYSICAL_ALIGN | 917 | config PHYSICAL_ALIGN |
diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts index cd56bb5b347b..5806ef0b860b 100644 --- a/arch/powerpc/boot/dts/canyonlands.dts +++ b/arch/powerpc/boot/dts/canyonlands.dts | |||
@@ -270,7 +270,7 @@ | |||
270 | clock-frequency = <0>; /* Filled in by U-Boot */ | 270 | clock-frequency = <0>; /* Filled in by U-Boot */ |
271 | current-speed = <0>; /* Filled in by U-Boot */ | 271 | current-speed = <0>; /* Filled in by U-Boot */ |
272 | interrupt-parent = <&UIC1>; | 272 | interrupt-parent = <&UIC1>; |
273 | interrupts = <0x1d 0x4>; | 273 | interrupts = <28 0x4>; |
274 | }; | 274 | }; |
275 | 275 | ||
276 | UART3: serial@ef600600 { | 276 | UART3: serial@ef600600 { |
@@ -281,7 +281,7 @@ | |||
281 | clock-frequency = <0>; /* Filled in by U-Boot */ | 281 | clock-frequency = <0>; /* Filled in by U-Boot */ |
282 | current-speed = <0>; /* Filled in by U-Boot */ | 282 | current-speed = <0>; /* Filled in by U-Boot */ |
283 | interrupt-parent = <&UIC1>; | 283 | interrupt-parent = <&UIC1>; |
284 | interrupts = <0x1e 0x4>; | 284 | interrupts = <29 0x4>; |
285 | }; | 285 | }; |
286 | 286 | ||
287 | IIC0: i2c@ef600700 { | 287 | IIC0: i2c@ef600700 { |
diff --git a/arch/powerpc/boot/dts/glacier.dts b/arch/powerpc/boot/dts/glacier.dts index d62a4fb6f93c..e618fc4cbc9e 100644 --- a/arch/powerpc/boot/dts/glacier.dts +++ b/arch/powerpc/boot/dts/glacier.dts | |||
@@ -259,7 +259,7 @@ | |||
259 | clock-frequency = <0>; /* Filled in by U-Boot */ | 259 | clock-frequency = <0>; /* Filled in by U-Boot */ |
260 | current-speed = <0>; /* Filled in by U-Boot */ | 260 | current-speed = <0>; /* Filled in by U-Boot */ |
261 | interrupt-parent = <&UIC1>; | 261 | interrupt-parent = <&UIC1>; |
262 | interrupts = <0x1d 0x4>; | 262 | interrupts = <28 0x4>; |
263 | }; | 263 | }; |
264 | 264 | ||
265 | UART3: serial@ef600600 { | 265 | UART3: serial@ef600600 { |
@@ -270,7 +270,7 @@ | |||
270 | clock-frequency = <0>; /* Filled in by U-Boot */ | 270 | clock-frequency = <0>; /* Filled in by U-Boot */ |
271 | current-speed = <0>; /* Filled in by U-Boot */ | 271 | current-speed = <0>; /* Filled in by U-Boot */ |
272 | interrupt-parent = <&UIC1>; | 272 | interrupt-parent = <&UIC1>; |
273 | interrupts = <0x1e 0x4>; | 273 | interrupts = <29 0x4>; |
274 | }; | 274 | }; |
275 | 275 | ||
276 | IIC0: i2c@ef600700 { | 276 | IIC0: i2c@ef600700 { |
diff --git a/arch/powerpc/boot/dts/mpc8308rdb.dts b/arch/powerpc/boot/dts/mpc8308rdb.dts new file mode 100644 index 000000000000..a97eb2db5a18 --- /dev/null +++ b/arch/powerpc/boot/dts/mpc8308rdb.dts | |||
@@ -0,0 +1,303 @@ | |||
1 | /* | ||
2 | * MPC8308RDB Device Tree Source | ||
3 | * | ||
4 | * Copyright 2009 Freescale Semiconductor Inc. | ||
5 | * Copyright 2010 Ilya Yanok, Emcraft Systems, yanok@emcraft.com | ||
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 | /dts-v1/; | ||
14 | |||
15 | / { | ||
16 | compatible = "fsl,mpc8308rdb"; | ||
17 | #address-cells = <1>; | ||
18 | #size-cells = <1>; | ||
19 | |||
20 | aliases { | ||
21 | ethernet0 = &enet0; | ||
22 | ethernet1 = &enet1; | ||
23 | serial0 = &serial0; | ||
24 | serial1 = &serial1; | ||
25 | pci0 = &pci0; | ||
26 | }; | ||
27 | |||
28 | cpus { | ||
29 | #address-cells = <1>; | ||
30 | #size-cells = <0>; | ||
31 | |||
32 | PowerPC,8308@0 { | ||
33 | device_type = "cpu"; | ||
34 | reg = <0x0>; | ||
35 | d-cache-line-size = <32>; | ||
36 | i-cache-line-size = <32>; | ||
37 | d-cache-size = <16384>; | ||
38 | i-cache-size = <16384>; | ||
39 | timebase-frequency = <0>; // from bootloader | ||
40 | bus-frequency = <0>; // from bootloader | ||
41 | clock-frequency = <0>; // from bootloader | ||
42 | }; | ||
43 | }; | ||
44 | |||
45 | memory { | ||
46 | device_type = "memory"; | ||
47 | reg = <0x00000000 0x08000000>; // 128MB at 0 | ||
48 | }; | ||
49 | |||
50 | localbus@e0005000 { | ||
51 | #address-cells = <2>; | ||
52 | #size-cells = <1>; | ||
53 | compatible = "fsl,mpc8315-elbc", "fsl,elbc", "simple-bus"; | ||
54 | reg = <0xe0005000 0x1000>; | ||
55 | interrupts = <77 0x8>; | ||
56 | interrupt-parent = <&ipic>; | ||
57 | |||
58 | // CS0 and CS1 are swapped when | ||
59 | // booting from nand, but the | ||
60 | // addresses are the same. | ||
61 | ranges = <0x0 0x0 0xfe000000 0x00800000 | ||
62 | 0x1 0x0 0xe0600000 0x00002000 | ||
63 | 0x2 0x0 0xf0000000 0x00020000 | ||
64 | 0x3 0x0 0xfa000000 0x00008000>; | ||
65 | |||
66 | flash@0,0 { | ||
67 | #address-cells = <1>; | ||
68 | #size-cells = <1>; | ||
69 | compatible = "cfi-flash"; | ||
70 | reg = <0x0 0x0 0x800000>; | ||
71 | bank-width = <2>; | ||
72 | device-width = <1>; | ||
73 | |||
74 | u-boot@0 { | ||
75 | reg = <0x0 0x60000>; | ||
76 | read-only; | ||
77 | }; | ||
78 | env@60000 { | ||
79 | reg = <0x60000 0x10000>; | ||
80 | }; | ||
81 | env1@70000 { | ||
82 | reg = <0x70000 0x10000>; | ||
83 | }; | ||
84 | kernel@80000 { | ||
85 | reg = <0x80000 0x200000>; | ||
86 | }; | ||
87 | dtb@280000 { | ||
88 | reg = <0x280000 0x10000>; | ||
89 | }; | ||
90 | ramdisk@290000 { | ||
91 | reg = <0x290000 0x570000>; | ||
92 | }; | ||
93 | }; | ||
94 | |||
95 | nand@1,0 { | ||
96 | #address-cells = <1>; | ||
97 | #size-cells = <1>; | ||
98 | compatible = "fsl,mpc8315-fcm-nand", | ||
99 | "fsl,elbc-fcm-nand"; | ||
100 | reg = <0x1 0x0 0x2000>; | ||
101 | |||
102 | jffs2@0 { | ||
103 | reg = <0x0 0x2000000>; | ||
104 | }; | ||
105 | }; | ||
106 | }; | ||
107 | |||
108 | immr@e0000000 { | ||
109 | #address-cells = <1>; | ||
110 | #size-cells = <1>; | ||
111 | device_type = "soc"; | ||
112 | compatible = "fsl,mpc8315-immr", "simple-bus"; | ||
113 | ranges = <0 0xe0000000 0x00100000>; | ||
114 | reg = <0xe0000000 0x00000200>; | ||
115 | bus-frequency = <0>; | ||
116 | |||
117 | i2c@3000 { | ||
118 | #address-cells = <1>; | ||
119 | #size-cells = <0>; | ||
120 | cell-index = <0>; | ||
121 | compatible = "fsl-i2c"; | ||
122 | reg = <0x3000 0x100>; | ||
123 | interrupts = <14 0x8>; | ||
124 | interrupt-parent = <&ipic>; | ||
125 | dfsrr; | ||
126 | rtc@68 { | ||
127 | compatible = "dallas,ds1339"; | ||
128 | reg = <0x68>; | ||
129 | }; | ||
130 | }; | ||
131 | |||
132 | usb@23000 { | ||
133 | compatible = "fsl-usb2-dr"; | ||
134 | reg = <0x23000 0x1000>; | ||
135 | #address-cells = <1>; | ||
136 | #size-cells = <0>; | ||
137 | interrupt-parent = <&ipic>; | ||
138 | interrupts = <38 0x8>; | ||
139 | dr_mode = "peripheral"; | ||
140 | phy_type = "ulpi"; | ||
141 | }; | ||
142 | |||
143 | enet0: ethernet@24000 { | ||
144 | #address-cells = <1>; | ||
145 | #size-cells = <1>; | ||
146 | ranges = <0x0 0x24000 0x1000>; | ||
147 | |||
148 | cell-index = <0>; | ||
149 | device_type = "network"; | ||
150 | model = "eTSEC"; | ||
151 | compatible = "gianfar"; | ||
152 | reg = <0x24000 0x1000>; | ||
153 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
154 | interrupts = <32 0x8 33 0x8 34 0x8>; | ||
155 | interrupt-parent = <&ipic>; | ||
156 | tbi-handle = < &tbi0 >; | ||
157 | phy-handle = < &phy2 >; | ||
158 | fsl,magic-packet; | ||
159 | |||
160 | mdio@520 { | ||
161 | #address-cells = <1>; | ||
162 | #size-cells = <0>; | ||
163 | compatible = "fsl,gianfar-mdio"; | ||
164 | reg = <0x520 0x20>; | ||
165 | phy2: ethernet-phy@2 { | ||
166 | interrupt-parent = <&ipic>; | ||
167 | interrupts = <17 0x8>; | ||
168 | reg = <0x2>; | ||
169 | device_type = "ethernet-phy"; | ||
170 | }; | ||
171 | tbi0: tbi-phy@11 { | ||
172 | reg = <0x11>; | ||
173 | device_type = "tbi-phy"; | ||
174 | }; | ||
175 | }; | ||
176 | }; | ||
177 | |||
178 | enet1: ethernet@25000 { | ||
179 | #address-cells = <1>; | ||
180 | #size-cells = <1>; | ||
181 | cell-index = <1>; | ||
182 | device_type = "network"; | ||
183 | model = "eTSEC"; | ||
184 | compatible = "gianfar"; | ||
185 | reg = <0x25000 0x1000>; | ||
186 | ranges = <0x0 0x25000 0x1000>; | ||
187 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
188 | interrupts = <35 0x8 36 0x8 37 0x8>; | ||
189 | interrupt-parent = <&ipic>; | ||
190 | tbi-handle = < &tbi1 >; | ||
191 | /* Vitesse 7385 isn't on the MDIO bus */ | ||
192 | fixed-link = <1 1 1000 0 0>; | ||
193 | fsl,magic-packet; | ||
194 | |||
195 | mdio@520 { | ||
196 | #address-cells = <1>; | ||
197 | #size-cells = <0>; | ||
198 | compatible = "fsl,gianfar-tbi"; | ||
199 | reg = <0x520 0x20>; | ||
200 | |||
201 | tbi1: tbi-phy@11 { | ||
202 | reg = <0x11>; | ||
203 | device_type = "tbi-phy"; | ||
204 | }; | ||
205 | }; | ||
206 | }; | ||
207 | |||
208 | serial0: serial@4500 { | ||
209 | cell-index = <0>; | ||
210 | device_type = "serial"; | ||
211 | compatible = "ns16550"; | ||
212 | reg = <0x4500 0x100>; | ||
213 | clock-frequency = <133333333>; | ||
214 | interrupts = <9 0x8>; | ||
215 | interrupt-parent = <&ipic>; | ||
216 | }; | ||
217 | |||
218 | serial1: serial@4600 { | ||
219 | cell-index = <1>; | ||
220 | device_type = "serial"; | ||
221 | compatible = "ns16550"; | ||
222 | reg = <0x4600 0x100>; | ||
223 | clock-frequency = <133333333>; | ||
224 | interrupts = <10 0x8>; | ||
225 | interrupt-parent = <&ipic>; | ||
226 | }; | ||
227 | |||
228 | gpio@c00 { | ||
229 | #gpio-cells = <2>; | ||
230 | device_type = "gpio"; | ||
231 | compatible = "fsl,mpc8308-gpio", "fsl,mpc8349-gpio"; | ||
232 | reg = <0xc00 0x18>; | ||
233 | interrupts = <74 0x8>; | ||
234 | interrupt-parent = <&ipic>; | ||
235 | gpio-controller; | ||
236 | }; | ||
237 | |||
238 | /* IPIC | ||
239 | * interrupts cell = <intr #, sense> | ||
240 | * sense values match linux IORESOURCE_IRQ_* defines: | ||
241 | * sense == 8: Level, low assertion | ||
242 | * sense == 2: Edge, high-to-low change | ||
243 | */ | ||
244 | ipic: interrupt-controller@700 { | ||
245 | compatible = "fsl,ipic"; | ||
246 | interrupt-controller; | ||
247 | #address-cells = <0>; | ||
248 | #interrupt-cells = <2>; | ||
249 | reg = <0x700 0x100>; | ||
250 | device_type = "ipic"; | ||
251 | }; | ||
252 | |||
253 | ipic-msi@7c0 { | ||
254 | compatible = "fsl,ipic-msi"; | ||
255 | reg = <0x7c0 0x40>; | ||
256 | msi-available-ranges = <0x0 0x100>; | ||
257 | interrupts = < 0x43 0x8 | ||
258 | 0x4 0x8 | ||
259 | 0x51 0x8 | ||
260 | 0x52 0x8 | ||
261 | 0x56 0x8 | ||
262 | 0x57 0x8 | ||
263 | 0x58 0x8 | ||
264 | 0x59 0x8 >; | ||
265 | interrupt-parent = < &ipic >; | ||
266 | }; | ||
267 | |||
268 | }; | ||
269 | |||
270 | pci0: pcie@e0009000 { | ||
271 | #address-cells = <3>; | ||
272 | #size-cells = <2>; | ||
273 | #interrupt-cells = <1>; | ||
274 | device_type = "pci"; | ||
275 | compatible = "fsl,mpc8308-pcie", "fsl,mpc8314-pcie"; | ||
276 | reg = <0xe0009000 0x00001000 | ||
277 | 0xb0000000 0x01000000>; | ||
278 | ranges = <0x02000000 0 0xa0000000 0xa0000000 0 0x10000000 | ||
279 | 0x01000000 0 0x00000000 0xb1000000 0 0x00800000>; | ||
280 | bus-range = <0 0>; | ||
281 | interrupt-map-mask = <0xf800 0 0 7>; | ||
282 | interrupt-map = <0 0 0 1 &ipic 1 8 | ||
283 | 0 0 0 2 &ipic 1 8 | ||
284 | 0 0 0 3 &ipic 1 8 | ||
285 | 0 0 0 4 &ipic 1 8>; | ||
286 | interrupts = <0x1 0x8>; | ||
287 | interrupt-parent = <&ipic>; | ||
288 | clock-frequency = <0>; | ||
289 | |||
290 | pcie@0 { | ||
291 | #address-cells = <3>; | ||
292 | #size-cells = <2>; | ||
293 | device_type = "pci"; | ||
294 | reg = <0 0 0 0 0>; | ||
295 | ranges = <0x02000000 0 0xa0000000 | ||
296 | 0x02000000 0 0xa0000000 | ||
297 | 0 0x10000000 | ||
298 | 0x01000000 0 0x00000000 | ||
299 | 0x01000000 0 0x00000000 | ||
300 | 0 0x00800000>; | ||
301 | }; | ||
302 | }; | ||
303 | }; | ||
diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/boot/dts/mpc8540ads.dts index 9dc292962a9a..8d1bf0fd9268 100644 --- a/arch/powerpc/boot/dts/mpc8540ads.dts +++ b/arch/powerpc/boot/dts/mpc8540ads.dts | |||
@@ -71,14 +71,14 @@ | |||
71 | }; | 71 | }; |
72 | 72 | ||
73 | memory-controller@2000 { | 73 | memory-controller@2000 { |
74 | compatible = "fsl,8540-memory-controller"; | 74 | compatible = "fsl,mpc8540-memory-controller"; |
75 | reg = <0x2000 0x1000>; | 75 | reg = <0x2000 0x1000>; |
76 | interrupt-parent = <&mpic>; | 76 | interrupt-parent = <&mpic>; |
77 | interrupts = <18 2>; | 77 | interrupts = <18 2>; |
78 | }; | 78 | }; |
79 | 79 | ||
80 | L2: l2-cache-controller@20000 { | 80 | L2: l2-cache-controller@20000 { |
81 | compatible = "fsl,8540-l2-cache-controller"; | 81 | compatible = "fsl,mpc8540-l2-cache-controller"; |
82 | reg = <0x20000 0x1000>; | 82 | reg = <0x20000 0x1000>; |
83 | cache-line-size = <32>; // 32 bytes | 83 | cache-line-size = <32>; // 32 bytes |
84 | cache-size = <0x40000>; // L2, 256K | 84 | cache-size = <0x40000>; // L2, 256K |
diff --git a/arch/powerpc/boot/dts/mpc8541cds.dts b/arch/powerpc/boot/dts/mpc8541cds.dts index 9a3ad311aedf..87ff96549fac 100644 --- a/arch/powerpc/boot/dts/mpc8541cds.dts +++ b/arch/powerpc/boot/dts/mpc8541cds.dts | |||
@@ -71,14 +71,14 @@ | |||
71 | }; | 71 | }; |
72 | 72 | ||
73 | memory-controller@2000 { | 73 | memory-controller@2000 { |
74 | compatible = "fsl,8541-memory-controller"; | 74 | compatible = "fsl,mpc8541-memory-controller"; |
75 | reg = <0x2000 0x1000>; | 75 | reg = <0x2000 0x1000>; |
76 | interrupt-parent = <&mpic>; | 76 | interrupt-parent = <&mpic>; |
77 | interrupts = <18 2>; | 77 | interrupts = <18 2>; |
78 | }; | 78 | }; |
79 | 79 | ||
80 | L2: l2-cache-controller@20000 { | 80 | L2: l2-cache-controller@20000 { |
81 | compatible = "fsl,8541-l2-cache-controller"; | 81 | compatible = "fsl,mpc8541-l2-cache-controller"; |
82 | reg = <0x20000 0x1000>; | 82 | reg = <0x20000 0x1000>; |
83 | cache-line-size = <32>; // 32 bytes | 83 | cache-line-size = <32>; // 32 bytes |
84 | cache-size = <0x40000>; // L2, 256K | 84 | cache-size = <0x40000>; // L2, 256K |
diff --git a/arch/powerpc/boot/dts/mpc8544ds.dts b/arch/powerpc/boot/dts/mpc8544ds.dts index 98e94b465662..d793968743c9 100644 --- a/arch/powerpc/boot/dts/mpc8544ds.dts +++ b/arch/powerpc/boot/dts/mpc8544ds.dts | |||
@@ -73,14 +73,14 @@ | |||
73 | }; | 73 | }; |
74 | 74 | ||
75 | memory-controller@2000 { | 75 | memory-controller@2000 { |
76 | compatible = "fsl,8544-memory-controller"; | 76 | compatible = "fsl,mpc8544-memory-controller"; |
77 | reg = <0x2000 0x1000>; | 77 | reg = <0x2000 0x1000>; |
78 | interrupt-parent = <&mpic>; | 78 | interrupt-parent = <&mpic>; |
79 | interrupts = <18 2>; | 79 | interrupts = <18 2>; |
80 | }; | 80 | }; |
81 | 81 | ||
82 | L2: l2-cache-controller@20000 { | 82 | L2: l2-cache-controller@20000 { |
83 | compatible = "fsl,8544-l2-cache-controller"; | 83 | compatible = "fsl,mpc8544-l2-cache-controller"; |
84 | reg = <0x20000 0x1000>; | 84 | reg = <0x20000 0x1000>; |
85 | cache-line-size = <32>; // 32 bytes | 85 | cache-line-size = <32>; // 32 bytes |
86 | cache-size = <0x40000>; // L2, 256K | 86 | cache-size = <0x40000>; // L2, 256K |
diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts index 0f5262452682..a17a5572fb73 100644 --- a/arch/powerpc/boot/dts/mpc8548cds.dts +++ b/arch/powerpc/boot/dts/mpc8548cds.dts | |||
@@ -74,14 +74,14 @@ | |||
74 | }; | 74 | }; |
75 | 75 | ||
76 | memory-controller@2000 { | 76 | memory-controller@2000 { |
77 | compatible = "fsl,8548-memory-controller"; | 77 | compatible = "fsl,mpc8548-memory-controller"; |
78 | reg = <0x2000 0x1000>; | 78 | reg = <0x2000 0x1000>; |
79 | interrupt-parent = <&mpic>; | 79 | interrupt-parent = <&mpic>; |
80 | interrupts = <18 2>; | 80 | interrupts = <18 2>; |
81 | }; | 81 | }; |
82 | 82 | ||
83 | L2: l2-cache-controller@20000 { | 83 | L2: l2-cache-controller@20000 { |
84 | compatible = "fsl,8548-l2-cache-controller"; | 84 | compatible = "fsl,mpc8548-l2-cache-controller"; |
85 | reg = <0x20000 0x1000>; | 85 | reg = <0x20000 0x1000>; |
86 | cache-line-size = <32>; // 32 bytes | 86 | cache-line-size = <32>; // 32 bytes |
87 | cache-size = <0x80000>; // L2, 512K | 87 | cache-size = <0x80000>; // L2, 512K |
diff --git a/arch/powerpc/boot/dts/mpc8555cds.dts b/arch/powerpc/boot/dts/mpc8555cds.dts index 065b2f093de2..5c5614f9eb17 100644 --- a/arch/powerpc/boot/dts/mpc8555cds.dts +++ b/arch/powerpc/boot/dts/mpc8555cds.dts | |||
@@ -71,14 +71,14 @@ | |||
71 | }; | 71 | }; |
72 | 72 | ||
73 | memory-controller@2000 { | 73 | memory-controller@2000 { |
74 | compatible = "fsl,8555-memory-controller"; | 74 | compatible = "fsl,mpc8555-memory-controller"; |
75 | reg = <0x2000 0x1000>; | 75 | reg = <0x2000 0x1000>; |
76 | interrupt-parent = <&mpic>; | 76 | interrupt-parent = <&mpic>; |
77 | interrupts = <18 2>; | 77 | interrupts = <18 2>; |
78 | }; | 78 | }; |
79 | 79 | ||
80 | L2: l2-cache-controller@20000 { | 80 | L2: l2-cache-controller@20000 { |
81 | compatible = "fsl,8555-l2-cache-controller"; | 81 | compatible = "fsl,mpc8555-l2-cache-controller"; |
82 | reg = <0x20000 0x1000>; | 82 | reg = <0x20000 0x1000>; |
83 | cache-line-size = <32>; // 32 bytes | 83 | cache-line-size = <32>; // 32 bytes |
84 | cache-size = <0x40000>; // L2, 256K | 84 | cache-size = <0x40000>; // L2, 256K |
diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/boot/dts/mpc8560ads.dts index a5bb1ec70a5a..6e85e1ba0851 100644 --- a/arch/powerpc/boot/dts/mpc8560ads.dts +++ b/arch/powerpc/boot/dts/mpc8560ads.dts | |||
@@ -71,14 +71,14 @@ | |||
71 | }; | 71 | }; |
72 | 72 | ||
73 | memory-controller@2000 { | 73 | memory-controller@2000 { |
74 | compatible = "fsl,8540-memory-controller"; | 74 | compatible = "fsl,mpc8540-memory-controller"; |
75 | reg = <0x2000 0x1000>; | 75 | reg = <0x2000 0x1000>; |
76 | interrupt-parent = <&mpic>; | 76 | interrupt-parent = <&mpic>; |
77 | interrupts = <18 2>; | 77 | interrupts = <18 2>; |
78 | }; | 78 | }; |
79 | 79 | ||
80 | L2: l2-cache-controller@20000 { | 80 | L2: l2-cache-controller@20000 { |
81 | compatible = "fsl,8540-l2-cache-controller"; | 81 | compatible = "fsl,mpc8540-l2-cache-controller"; |
82 | reg = <0x20000 0x1000>; | 82 | reg = <0x20000 0x1000>; |
83 | cache-line-size = <32>; // 32 bytes | 83 | cache-line-size = <32>; // 32 bytes |
84 | cache-size = <0x40000>; // L2, 256K | 84 | cache-size = <0x40000>; // L2, 256K |
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts index 92fb17876e7d..30cf0e098bb9 100644 --- a/arch/powerpc/boot/dts/mpc8568mds.dts +++ b/arch/powerpc/boot/dts/mpc8568mds.dts | |||
@@ -124,14 +124,14 @@ | |||
124 | }; | 124 | }; |
125 | 125 | ||
126 | memory-controller@2000 { | 126 | memory-controller@2000 { |
127 | compatible = "fsl,8568-memory-controller"; | 127 | compatible = "fsl,mpc8568-memory-controller"; |
128 | reg = <0x2000 0x1000>; | 128 | reg = <0x2000 0x1000>; |
129 | interrupt-parent = <&mpic>; | 129 | interrupt-parent = <&mpic>; |
130 | interrupts = <18 2>; | 130 | interrupts = <18 2>; |
131 | }; | 131 | }; |
132 | 132 | ||
133 | L2: l2-cache-controller@20000 { | 133 | L2: l2-cache-controller@20000 { |
134 | compatible = "fsl,8568-l2-cache-controller"; | 134 | compatible = "fsl,mpc8568-l2-cache-controller"; |
135 | reg = <0x20000 0x1000>; | 135 | reg = <0x20000 0x1000>; |
136 | cache-line-size = <32>; // 32 bytes | 136 | cache-line-size = <32>; // 32 bytes |
137 | cache-size = <0x80000>; // L2, 512K | 137 | cache-size = <0x80000>; // L2, 512K |
diff --git a/arch/powerpc/boot/dts/p1021mds.dts b/arch/powerpc/boot/dts/p1021mds.dts index 7fad2df25981..ad5b85269004 100644 --- a/arch/powerpc/boot/dts/p1021mds.dts +++ b/arch/powerpc/boot/dts/p1021mds.dts | |||
@@ -617,6 +617,7 @@ | |||
617 | bus-frequency = <0>; | 617 | bus-frequency = <0>; |
618 | fsl,qe-num-riscs = <1>; | 618 | fsl,qe-num-riscs = <1>; |
619 | fsl,qe-num-snums = <28>; | 619 | fsl,qe-num-snums = <28>; |
620 | status = "disabled"; /* no firmware loaded */ | ||
620 | 621 | ||
621 | qeic: interrupt-controller@80 { | 622 | qeic: interrupt-controller@80 { |
622 | interrupt-controller; | 623 | interrupt-controller; |
diff --git a/arch/powerpc/boot/dts/p1022ds.dts b/arch/powerpc/boot/dts/p1022ds.dts new file mode 100644 index 000000000000..8bcb10b92677 --- /dev/null +++ b/arch/powerpc/boot/dts/p1022ds.dts | |||
@@ -0,0 +1,633 @@ | |||
1 | /* | ||
2 | * P1022 DS 36Bit Physical Address Map Device Tree Source | ||
3 | * | ||
4 | * Copyright 2010 Freescale Semiconductor, Inc. | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public License | ||
7 | * version 2. This program is licensed "as is" without any warranty of any | ||
8 | * kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | /dts-v1/; | ||
12 | / { | ||
13 | model = "fsl,P1022"; | ||
14 | compatible = "fsl,P1022DS"; | ||
15 | #address-cells = <2>; | ||
16 | #size-cells = <2>; | ||
17 | interrupt-parent = <&mpic>; | ||
18 | |||
19 | aliases { | ||
20 | ethernet0 = &enet0; | ||
21 | ethernet1 = &enet1; | ||
22 | serial0 = &serial0; | ||
23 | serial1 = &serial1; | ||
24 | pci0 = &pci0; | ||
25 | pci1 = &pci1; | ||
26 | pci2 = &pci2; | ||
27 | }; | ||
28 | |||
29 | cpus { | ||
30 | #address-cells = <1>; | ||
31 | #size-cells = <0>; | ||
32 | |||
33 | PowerPC,P1022@0 { | ||
34 | device_type = "cpu"; | ||
35 | reg = <0x0>; | ||
36 | next-level-cache = <&L2>; | ||
37 | }; | ||
38 | |||
39 | PowerPC,P1022@1 { | ||
40 | device_type = "cpu"; | ||
41 | reg = <0x1>; | ||
42 | next-level-cache = <&L2>; | ||
43 | }; | ||
44 | }; | ||
45 | |||
46 | memory { | ||
47 | device_type = "memory"; | ||
48 | }; | ||
49 | |||
50 | localbus@fffe05000 { | ||
51 | #address-cells = <2>; | ||
52 | #size-cells = <1>; | ||
53 | compatible = "fsl,p1022-elbc", "fsl,elbc", "simple-bus"; | ||
54 | reg = <0 0xffe05000 0 0x1000>; | ||
55 | interrupts = <19 2>; | ||
56 | |||
57 | ranges = <0x0 0x0 0xf 0xe8000000 0x08000000 | ||
58 | 0x1 0x0 0xf 0xe0000000 0x08000000 | ||
59 | 0x2 0x0 0x0 0xffa00000 0x00040000 | ||
60 | 0x3 0x0 0xf 0xffdf0000 0x00008000>; | ||
61 | |||
62 | nor@0,0 { | ||
63 | #address-cells = <1>; | ||
64 | #size-cells = <1>; | ||
65 | compatible = "cfi-flash"; | ||
66 | reg = <0x0 0x0 0x8000000>; | ||
67 | bank-width = <2>; | ||
68 | device-width = <1>; | ||
69 | |||
70 | partition@0 { | ||
71 | reg = <0x0 0x03000000>; | ||
72 | label = "ramdisk-nor"; | ||
73 | read-only; | ||
74 | }; | ||
75 | |||
76 | partition@3000000 { | ||
77 | reg = <0x03000000 0x00e00000>; | ||
78 | label = "diagnostic-nor"; | ||
79 | read-only; | ||
80 | }; | ||
81 | |||
82 | partition@3e00000 { | ||
83 | reg = <0x03e00000 0x00200000>; | ||
84 | label = "dink-nor"; | ||
85 | read-only; | ||
86 | }; | ||
87 | |||
88 | partition@4000000 { | ||
89 | reg = <0x04000000 0x00400000>; | ||
90 | label = "kernel-nor"; | ||
91 | read-only; | ||
92 | }; | ||
93 | |||
94 | partition@4400000 { | ||
95 | reg = <0x04400000 0x03b00000>; | ||
96 | label = "jffs2-nor"; | ||
97 | }; | ||
98 | |||
99 | partition@7f00000 { | ||
100 | reg = <0x07f00000 0x00080000>; | ||
101 | label = "dtb-nor"; | ||
102 | read-only; | ||
103 | }; | ||
104 | |||
105 | partition@7f80000 { | ||
106 | reg = <0x07f80000 0x00080000>; | ||
107 | label = "u-boot-nor"; | ||
108 | read-only; | ||
109 | }; | ||
110 | }; | ||
111 | |||
112 | nand@2,0 { | ||
113 | #address-cells = <1>; | ||
114 | #size-cells = <1>; | ||
115 | compatible = "fsl,elbc-fcm-nand"; | ||
116 | reg = <0x2 0x0 0x40000>; | ||
117 | |||
118 | partition@0 { | ||
119 | reg = <0x0 0x02000000>; | ||
120 | label = "u-boot-nand"; | ||
121 | read-only; | ||
122 | }; | ||
123 | |||
124 | partition@2000000 { | ||
125 | reg = <0x02000000 0x10000000>; | ||
126 | label = "jffs2-nand"; | ||
127 | }; | ||
128 | |||
129 | partition@12000000 { | ||
130 | reg = <0x12000000 0x10000000>; | ||
131 | label = "ramdisk-nand"; | ||
132 | read-only; | ||
133 | }; | ||
134 | |||
135 | partition@22000000 { | ||
136 | reg = <0x22000000 0x04000000>; | ||
137 | label = "kernel-nand"; | ||
138 | }; | ||
139 | |||
140 | partition@26000000 { | ||
141 | reg = <0x26000000 0x01000000>; | ||
142 | label = "dtb-nand"; | ||
143 | read-only; | ||
144 | }; | ||
145 | |||
146 | partition@27000000 { | ||
147 | reg = <0x27000000 0x19000000>; | ||
148 | label = "reserved-nand"; | ||
149 | }; | ||
150 | }; | ||
151 | }; | ||
152 | |||
153 | soc@fffe00000 { | ||
154 | #address-cells = <1>; | ||
155 | #size-cells = <1>; | ||
156 | device_type = "soc"; | ||
157 | compatible = "fsl,p1022-immr", "simple-bus"; | ||
158 | ranges = <0x0 0xf 0xffe00000 0x100000>; | ||
159 | bus-frequency = <0>; // Filled out by uboot. | ||
160 | |||
161 | ecm-law@0 { | ||
162 | compatible = "fsl,ecm-law"; | ||
163 | reg = <0x0 0x1000>; | ||
164 | fsl,num-laws = <12>; | ||
165 | }; | ||
166 | |||
167 | ecm@1000 { | ||
168 | compatible = "fsl,p1022-ecm", "fsl,ecm"; | ||
169 | reg = <0x1000 0x1000>; | ||
170 | interrupts = <16 2>; | ||
171 | }; | ||
172 | |||
173 | memory-controller@2000 { | ||
174 | compatible = "fsl,p1022-memory-controller"; | ||
175 | reg = <0x2000 0x1000>; | ||
176 | interrupts = <16 2>; | ||
177 | }; | ||
178 | |||
179 | i2c@3000 { | ||
180 | #address-cells = <1>; | ||
181 | #size-cells = <0>; | ||
182 | cell-index = <0>; | ||
183 | compatible = "fsl-i2c"; | ||
184 | reg = <0x3000 0x100>; | ||
185 | interrupts = <43 2>; | ||
186 | dfsrr; | ||
187 | }; | ||
188 | |||
189 | i2c@3100 { | ||
190 | #address-cells = <1>; | ||
191 | #size-cells = <0>; | ||
192 | cell-index = <1>; | ||
193 | compatible = "fsl-i2c"; | ||
194 | reg = <0x3100 0x100>; | ||
195 | interrupts = <43 2>; | ||
196 | dfsrr; | ||
197 | |||
198 | wm8776:codec@1a { | ||
199 | compatible = "wlf,wm8776"; | ||
200 | reg = <0x1a>; | ||
201 | /* MCLK source is a stand-alone oscillator */ | ||
202 | clock-frequency = <12288000>; | ||
203 | }; | ||
204 | }; | ||
205 | |||
206 | serial0: serial@4500 { | ||
207 | cell-index = <0>; | ||
208 | device_type = "serial"; | ||
209 | compatible = "ns16550"; | ||
210 | reg = <0x4500 0x100>; | ||
211 | clock-frequency = <0>; | ||
212 | interrupts = <42 2>; | ||
213 | }; | ||
214 | |||
215 | serial1: serial@4600 { | ||
216 | cell-index = <1>; | ||
217 | device_type = "serial"; | ||
218 | compatible = "ns16550"; | ||
219 | reg = <0x4600 0x100>; | ||
220 | clock-frequency = <0>; | ||
221 | interrupts = <42 2>; | ||
222 | }; | ||
223 | |||
224 | spi@7000 { | ||
225 | cell-index = <0>; | ||
226 | #address-cells = <1>; | ||
227 | #size-cells = <0>; | ||
228 | compatible = "fsl,espi"; | ||
229 | reg = <0x7000 0x1000>; | ||
230 | interrupts = <59 0x2>; | ||
231 | espi,num-ss-bits = <4>; | ||
232 | mode = "cpu"; | ||
233 | |||
234 | fsl_m25p80@0 { | ||
235 | #address-cells = <1>; | ||
236 | #size-cells = <1>; | ||
237 | compatible = "fsl,espi-flash"; | ||
238 | reg = <0>; | ||
239 | linux,modalias = "fsl_m25p80"; | ||
240 | spi-max-frequency = <40000000>; /* input clock */ | ||
241 | partition@0 { | ||
242 | label = "u-boot-spi"; | ||
243 | reg = <0x00000000 0x00100000>; | ||
244 | read-only; | ||
245 | }; | ||
246 | partition@100000 { | ||
247 | label = "kernel-spi"; | ||
248 | reg = <0x00100000 0x00500000>; | ||
249 | read-only; | ||
250 | }; | ||
251 | partition@600000 { | ||
252 | label = "dtb-spi"; | ||
253 | reg = <0x00600000 0x00100000>; | ||
254 | read-only; | ||
255 | }; | ||
256 | partition@700000 { | ||
257 | label = "file system-spi"; | ||
258 | reg = <0x00700000 0x00900000>; | ||
259 | }; | ||
260 | }; | ||
261 | }; | ||
262 | |||
263 | ssi@15000 { | ||
264 | compatible = "fsl,mpc8610-ssi"; | ||
265 | cell-index = <0>; | ||
266 | reg = <0x15000 0x100>; | ||
267 | interrupts = <75 2>; | ||
268 | fsl,mode = "i2s-slave"; | ||
269 | codec-handle = <&wm8776>; | ||
270 | fsl,playback-dma = <&dma00>; | ||
271 | fsl,capture-dma = <&dma01>; | ||
272 | fsl,fifo-depth = <16>; | ||
273 | }; | ||
274 | |||
275 | dma@c300 { | ||
276 | #address-cells = <1>; | ||
277 | #size-cells = <1>; | ||
278 | compatible = "fsl,eloplus-dma"; | ||
279 | reg = <0xc300 0x4>; | ||
280 | ranges = <0x0 0xc100 0x200>; | ||
281 | cell-index = <1>; | ||
282 | dma00: dma-channel@0 { | ||
283 | compatible = "fsl,eloplus-dma-channel"; | ||
284 | reg = <0x0 0x80>; | ||
285 | cell-index = <0>; | ||
286 | interrupts = <76 2>; | ||
287 | }; | ||
288 | dma01: dma-channel@80 { | ||
289 | compatible = "fsl,eloplus-dma-channel"; | ||
290 | reg = <0x80 0x80>; | ||
291 | cell-index = <1>; | ||
292 | interrupts = <77 2>; | ||
293 | }; | ||
294 | dma-channel@100 { | ||
295 | compatible = "fsl,eloplus-dma-channel"; | ||
296 | reg = <0x100 0x80>; | ||
297 | cell-index = <2>; | ||
298 | interrupts = <78 2>; | ||
299 | }; | ||
300 | dma-channel@180 { | ||
301 | compatible = "fsl,eloplus-dma-channel"; | ||
302 | reg = <0x180 0x80>; | ||
303 | cell-index = <3>; | ||
304 | interrupts = <79 2>; | ||
305 | }; | ||
306 | }; | ||
307 | |||
308 | gpio: gpio-controller@f000 { | ||
309 | #gpio-cells = <2>; | ||
310 | compatible = "fsl,mpc8572-gpio"; | ||
311 | reg = <0xf000 0x100>; | ||
312 | interrupts = <47 0x2>; | ||
313 | gpio-controller; | ||
314 | }; | ||
315 | |||
316 | L2: l2-cache-controller@20000 { | ||
317 | compatible = "fsl,p1022-l2-cache-controller"; | ||
318 | reg = <0x20000 0x1000>; | ||
319 | cache-line-size = <32>; // 32 bytes | ||
320 | cache-size = <0x40000>; // L2, 256K | ||
321 | interrupts = <16 2>; | ||
322 | }; | ||
323 | |||
324 | dma@21300 { | ||
325 | #address-cells = <1>; | ||
326 | #size-cells = <1>; | ||
327 | compatible = "fsl,eloplus-dma"; | ||
328 | reg = <0x21300 0x4>; | ||
329 | ranges = <0x0 0x21100 0x200>; | ||
330 | cell-index = <0>; | ||
331 | dma-channel@0 { | ||
332 | compatible = "fsl,eloplus-dma-channel"; | ||
333 | reg = <0x0 0x80>; | ||
334 | cell-index = <0>; | ||
335 | interrupts = <20 2>; | ||
336 | }; | ||
337 | dma-channel@80 { | ||
338 | compatible = "fsl,eloplus-dma-channel"; | ||
339 | reg = <0x80 0x80>; | ||
340 | cell-index = <1>; | ||
341 | interrupts = <21 2>; | ||
342 | }; | ||
343 | dma-channel@100 { | ||
344 | compatible = "fsl,eloplus-dma-channel"; | ||
345 | reg = <0x100 0x80>; | ||
346 | cell-index = <2>; | ||
347 | interrupts = <22 2>; | ||
348 | }; | ||
349 | dma-channel@180 { | ||
350 | compatible = "fsl,eloplus-dma-channel"; | ||
351 | reg = <0x180 0x80>; | ||
352 | cell-index = <3>; | ||
353 | interrupts = <23 2>; | ||
354 | }; | ||
355 | }; | ||
356 | |||
357 | usb@22000 { | ||
358 | #address-cells = <1>; | ||
359 | #size-cells = <0>; | ||
360 | compatible = "fsl-usb2-dr"; | ||
361 | reg = <0x22000 0x1000>; | ||
362 | interrupts = <28 0x2>; | ||
363 | phy_type = "ulpi"; | ||
364 | }; | ||
365 | |||
366 | mdio@24000 { | ||
367 | #address-cells = <1>; | ||
368 | #size-cells = <0>; | ||
369 | compatible = "fsl,etsec2-mdio"; | ||
370 | reg = <0x24000 0x1000 0xb0030 0x4>; | ||
371 | |||
372 | phy0: ethernet-phy@0 { | ||
373 | interrupts = <3 1>; | ||
374 | reg = <0x1>; | ||
375 | }; | ||
376 | phy1: ethernet-phy@1 { | ||
377 | interrupts = <9 1>; | ||
378 | reg = <0x2>; | ||
379 | }; | ||
380 | }; | ||
381 | |||
382 | mdio@25000 { | ||
383 | #address-cells = <1>; | ||
384 | #size-cells = <0>; | ||
385 | compatible = "fsl,etsec2-mdio"; | ||
386 | reg = <0x25000 0x1000 0xb1030 0x4>; | ||
387 | }; | ||
388 | |||
389 | enet0: ethernet@B0000 { | ||
390 | #address-cells = <1>; | ||
391 | #size-cells = <1>; | ||
392 | cell-index = <0>; | ||
393 | device_type = "network"; | ||
394 | model = "eTSEC"; | ||
395 | compatible = "fsl,etsec2"; | ||
396 | fsl,num_rx_queues = <0x8>; | ||
397 | fsl,num_tx_queues = <0x8>; | ||
398 | fsl,magic-packet; | ||
399 | fsl,wake-on-filer; | ||
400 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
401 | fixed-link = <1 1 1000 0 0>; | ||
402 | phy-handle = <&phy0>; | ||
403 | phy-connection-type = "rgmii-id"; | ||
404 | queue-group@0{ | ||
405 | #address-cells = <1>; | ||
406 | #size-cells = <1>; | ||
407 | reg = <0xB0000 0x1000>; | ||
408 | interrupts = <29 2 30 2 34 2>; | ||
409 | }; | ||
410 | queue-group@1{ | ||
411 | #address-cells = <1>; | ||
412 | #size-cells = <1>; | ||
413 | reg = <0xB4000 0x1000>; | ||
414 | interrupts = <17 2 18 2 24 2>; | ||
415 | }; | ||
416 | }; | ||
417 | |||
418 | enet1: ethernet@B1000 { | ||
419 | #address-cells = <1>; | ||
420 | #size-cells = <1>; | ||
421 | cell-index = <0>; | ||
422 | device_type = "network"; | ||
423 | model = "eTSEC"; | ||
424 | compatible = "fsl,etsec2"; | ||
425 | fsl,num_rx_queues = <0x8>; | ||
426 | fsl,num_tx_queues = <0x8>; | ||
427 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
428 | fixed-link = <1 1 1000 0 0>; | ||
429 | phy-handle = <&phy1>; | ||
430 | phy-connection-type = "rgmii-id"; | ||
431 | queue-group@0{ | ||
432 | #address-cells = <1>; | ||
433 | #size-cells = <1>; | ||
434 | reg = <0xB1000 0x1000>; | ||
435 | interrupts = <35 2 36 2 40 2>; | ||
436 | }; | ||
437 | queue-group@1{ | ||
438 | #address-cells = <1>; | ||
439 | #size-cells = <1>; | ||
440 | reg = <0xB5000 0x1000>; | ||
441 | interrupts = <51 2 52 2 67 2>; | ||
442 | }; | ||
443 | }; | ||
444 | |||
445 | sdhci@2e000 { | ||
446 | compatible = "fsl,p1022-esdhc", "fsl,esdhc"; | ||
447 | reg = <0x2e000 0x1000>; | ||
448 | interrupts = <72 0x2>; | ||
449 | fsl,sdhci-auto-cmd12; | ||
450 | /* Filled in by U-Boot */ | ||
451 | clock-frequency = <0>; | ||
452 | }; | ||
453 | |||
454 | crypto@30000 { | ||
455 | compatible = "fsl,sec3.3", "fsl,sec3.1", "fsl,sec3.0", | ||
456 | "fsl,sec2.4", "fsl,sec2.2", "fsl,sec2.1", | ||
457 | "fsl,sec2.0"; | ||
458 | reg = <0x30000 0x10000>; | ||
459 | interrupts = <45 2 58 2>; | ||
460 | fsl,num-channels = <4>; | ||
461 | fsl,channel-fifo-len = <24>; | ||
462 | fsl,exec-units-mask = <0x97c>; | ||
463 | fsl,descriptor-types-mask = <0x3a30abf>; | ||
464 | }; | ||
465 | |||
466 | sata@18000 { | ||
467 | compatible = "fsl,mpc8536-sata", "fsl,pq-sata"; | ||
468 | reg = <0x18000 0x1000>; | ||
469 | cell-index = <1>; | ||
470 | interrupts = <74 0x2>; | ||
471 | }; | ||
472 | |||
473 | sata@19000 { | ||
474 | compatible = "fsl,mpc8536-sata", "fsl,pq-sata"; | ||
475 | reg = <0x19000 0x1000>; | ||
476 | cell-index = <2>; | ||
477 | interrupts = <41 0x2>; | ||
478 | }; | ||
479 | |||
480 | power@e0070{ | ||
481 | compatible = "fsl,mpc8536-pmc", "fsl,mpc8548-pmc"; | ||
482 | reg = <0xe0070 0x20>; | ||
483 | }; | ||
484 | |||
485 | display@10000 { | ||
486 | compatible = "fsl,diu", "fsl,p1022-diu"; | ||
487 | reg = <0x10000 1000>; | ||
488 | interrupts = <64 2>; | ||
489 | }; | ||
490 | |||
491 | timer@41100 { | ||
492 | compatible = "fsl,mpic-global-timer"; | ||
493 | reg = <0x41100 0x204>; | ||
494 | interrupts = <0xf7 0x2>; | ||
495 | }; | ||
496 | |||
497 | mpic: pic@40000 { | ||
498 | interrupt-controller; | ||
499 | #address-cells = <0>; | ||
500 | #interrupt-cells = <2>; | ||
501 | reg = <0x40000 0x40000>; | ||
502 | compatible = "chrp,open-pic"; | ||
503 | device_type = "open-pic"; | ||
504 | }; | ||
505 | |||
506 | msi@41600 { | ||
507 | compatible = "fsl,p1022-msi", "fsl,mpic-msi"; | ||
508 | reg = <0x41600 0x80>; | ||
509 | msi-available-ranges = <0 0x100>; | ||
510 | interrupts = < | ||
511 | 0xe0 0 | ||
512 | 0xe1 0 | ||
513 | 0xe2 0 | ||
514 | 0xe3 0 | ||
515 | 0xe4 0 | ||
516 | 0xe5 0 | ||
517 | 0xe6 0 | ||
518 | 0xe7 0>; | ||
519 | }; | ||
520 | |||
521 | global-utilities@e0000 { //global utilities block | ||
522 | compatible = "fsl,p1022-guts"; | ||
523 | reg = <0xe0000 0x1000>; | ||
524 | fsl,has-rstcr; | ||
525 | }; | ||
526 | }; | ||
527 | |||
528 | pci0: pcie@fffe09000 { | ||
529 | compatible = "fsl,p1022-pcie"; | ||
530 | device_type = "pci"; | ||
531 | #interrupt-cells = <1>; | ||
532 | #size-cells = <2>; | ||
533 | #address-cells = <3>; | ||
534 | reg = <0xf 0xffe09000 0 0x1000>; | ||
535 | bus-range = <0 255>; | ||
536 | ranges = <0x2000000 0x0 0xa0000000 0xc 0x20000000 0x0 0x20000000 | ||
537 | 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>; | ||
538 | clock-frequency = <33333333>; | ||
539 | interrupts = <16 2>; | ||
540 | interrupt-map-mask = <0xf800 0 0 7>; | ||
541 | interrupt-map = < | ||
542 | /* IDSEL 0x0 */ | ||
543 | 0000 0 0 1 &mpic 4 1 | ||
544 | 0000 0 0 2 &mpic 5 1 | ||
545 | 0000 0 0 3 &mpic 6 1 | ||
546 | 0000 0 0 4 &mpic 7 1 | ||
547 | >; | ||
548 | pcie@0 { | ||
549 | reg = <0x0 0x0 0x0 0x0 0x0>; | ||
550 | #size-cells = <2>; | ||
551 | #address-cells = <3>; | ||
552 | device_type = "pci"; | ||
553 | ranges = <0x2000000 0x0 0xe0000000 | ||
554 | 0x2000000 0x0 0xe0000000 | ||
555 | 0x0 0x20000000 | ||
556 | |||
557 | 0x1000000 0x0 0x0 | ||
558 | 0x1000000 0x0 0x0 | ||
559 | 0x0 0x100000>; | ||
560 | }; | ||
561 | }; | ||
562 | |||
563 | pci1: pcie@fffe0a000 { | ||
564 | compatible = "fsl,p1022-pcie"; | ||
565 | device_type = "pci"; | ||
566 | #interrupt-cells = <1>; | ||
567 | #size-cells = <2>; | ||
568 | #address-cells = <3>; | ||
569 | reg = <0xf 0xffe0a000 0 0x1000>; | ||
570 | bus-range = <0 255>; | ||
571 | ranges = <0x2000000 0x0 0xc0000000 0xc 0x40000000 0x0 0x20000000 | ||
572 | 0x1000000 0x0 0x00000000 0xf 0xffc20000 0x0 0x10000>; | ||
573 | clock-frequency = <33333333>; | ||
574 | interrupts = <16 2>; | ||
575 | interrupt-map-mask = <0xf800 0 0 7>; | ||
576 | interrupt-map = < | ||
577 | /* IDSEL 0x0 */ | ||
578 | 0000 0 0 1 &mpic 0 1 | ||
579 | 0000 0 0 2 &mpic 1 1 | ||
580 | 0000 0 0 3 &mpic 2 1 | ||
581 | 0000 0 0 4 &mpic 3 1 | ||
582 | >; | ||
583 | pcie@0 { | ||
584 | reg = <0x0 0x0 0x0 0x0 0x0>; | ||
585 | #size-cells = <2>; | ||
586 | #address-cells = <3>; | ||
587 | device_type = "pci"; | ||
588 | ranges = <0x2000000 0x0 0xe0000000 | ||
589 | 0x2000000 0x0 0xe0000000 | ||
590 | 0x0 0x20000000 | ||
591 | |||
592 | 0x1000000 0x0 0x0 | ||
593 | 0x1000000 0x0 0x0 | ||
594 | 0x0 0x100000>; | ||
595 | }; | ||
596 | }; | ||
597 | |||
598 | |||
599 | pci2: pcie@fffe0b000 { | ||
600 | compatible = "fsl,p1022-pcie"; | ||
601 | device_type = "pci"; | ||
602 | #interrupt-cells = <1>; | ||
603 | #size-cells = <2>; | ||
604 | #address-cells = <3>; | ||
605 | reg = <0xf 0xffe0b000 0 0x1000>; | ||
606 | bus-range = <0 255>; | ||
607 | ranges = <0x2000000 0x0 0x80000000 0xc 0x00000000 0x0 0x20000000 | ||
608 | 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>; | ||
609 | clock-frequency = <33333333>; | ||
610 | interrupts = <16 2>; | ||
611 | interrupt-map-mask = <0xf800 0 0 7>; | ||
612 | interrupt-map = < | ||
613 | /* IDSEL 0x0 */ | ||
614 | 0000 0 0 1 &mpic 8 1 | ||
615 | 0000 0 0 2 &mpic 9 1 | ||
616 | 0000 0 0 3 &mpic 10 1 | ||
617 | 0000 0 0 4 &mpic 11 1 | ||
618 | >; | ||
619 | pcie@0 { | ||
620 | reg = <0x0 0x0 0x0 0x0 0x0>; | ||
621 | #size-cells = <2>; | ||
622 | #address-cells = <3>; | ||
623 | device_type = "pci"; | ||
624 | ranges = <0x2000000 0x0 0xe0000000 | ||
625 | 0x2000000 0x0 0xe0000000 | ||
626 | 0x0 0x20000000 | ||
627 | |||
628 | 0x1000000 0x0 0x0 | ||
629 | 0x1000000 0x0 0x0 | ||
630 | 0x0 0x100000>; | ||
631 | }; | ||
632 | }; | ||
633 | }; | ||
diff --git a/arch/powerpc/boot/dts/pdm360ng.dts b/arch/powerpc/boot/dts/pdm360ng.dts new file mode 100644 index 000000000000..94dfa5c9a7f9 --- /dev/null +++ b/arch/powerpc/boot/dts/pdm360ng.dts | |||
@@ -0,0 +1,410 @@ | |||
1 | /* | ||
2 | * Device Tree Source for IFM PDM360NG. | ||
3 | * | ||
4 | * Copyright 2009 - 2010 DENX Software Engineering. | ||
5 | * Anatolij Gustschin <agust@denx.de> | ||
6 | * | ||
7 | * Based on MPC5121E ADS dts. | ||
8 | * Copyright 2008 Freescale Semiconductor Inc. | ||
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 | |||
16 | /dts-v1/; | ||
17 | |||
18 | / { | ||
19 | model = "pdm360ng"; | ||
20 | compatible = "ifm,pdm360ng"; | ||
21 | #address-cells = <1>; | ||
22 | #size-cells = <1>; | ||
23 | interrupt-parent = <&ipic>; | ||
24 | |||
25 | aliases { | ||
26 | ethernet0 = ð0; | ||
27 | }; | ||
28 | |||
29 | cpus { | ||
30 | #address-cells = <1>; | ||
31 | #size-cells = <0>; | ||
32 | |||
33 | PowerPC,5121@0 { | ||
34 | device_type = "cpu"; | ||
35 | reg = <0>; | ||
36 | d-cache-line-size = <0x20>; // 32 bytes | ||
37 | i-cache-line-size = <0x20>; // 32 bytes | ||
38 | d-cache-size = <0x8000>; // L1, 32K | ||
39 | i-cache-size = <0x8000>; // L1, 32K | ||
40 | timebase-frequency = <49500000>;// 49.5 MHz (csb/4) | ||
41 | bus-frequency = <198000000>; // 198 MHz csb bus | ||
42 | clock-frequency = <396000000>; // 396 MHz ppc core | ||
43 | }; | ||
44 | }; | ||
45 | |||
46 | memory { | ||
47 | device_type = "memory"; | ||
48 | reg = <0x00000000 0x20000000>; // 512MB at 0 | ||
49 | }; | ||
50 | |||
51 | nfc@40000000 { | ||
52 | compatible = "fsl,mpc5121-nfc"; | ||
53 | reg = <0x40000000 0x100000>; | ||
54 | interrupts = <0x6 0x8>; | ||
55 | #address-cells = <0x1>; | ||
56 | #size-cells = <0x1>; | ||
57 | bank-width = <0x1>; | ||
58 | chips = <0x1>; | ||
59 | |||
60 | partition@0 { | ||
61 | label = "nand0"; | ||
62 | reg = <0x0 0x40000000>; | ||
63 | }; | ||
64 | }; | ||
65 | |||
66 | sram@50000000 { | ||
67 | compatible = "fsl,mpc5121-sram"; | ||
68 | reg = <0x50000000 0x20000>; // 128K at 0x50000000 | ||
69 | }; | ||
70 | |||
71 | localbus@80000020 { | ||
72 | compatible = "fsl,mpc5121-localbus"; | ||
73 | #address-cells = <2>; | ||
74 | #size-cells = <1>; | ||
75 | reg = <0x80000020 0x40>; | ||
76 | |||
77 | ranges = <0x0 0x0 0xf0000000 0x10000000 /* Flash */ | ||
78 | 0x2 0x0 0x50040000 0x00020000>; /* CS2: MRAM */ | ||
79 | |||
80 | flash@0,0 { | ||
81 | compatible = "amd,s29gl01gp", "cfi-flash"; | ||
82 | reg = <0 0x00000000 0x08000000 | ||
83 | 0 0x08000000 0x08000000>; | ||
84 | #address-cells = <1>; | ||
85 | #size-cells = <1>; | ||
86 | bank-width = <4>; | ||
87 | device-width = <2>; | ||
88 | |||
89 | partition@0 { | ||
90 | label = "u-boot"; | ||
91 | reg = <0x00000000 0x00080000>; | ||
92 | read-only; | ||
93 | }; | ||
94 | partition@80000 { | ||
95 | label = "environment"; | ||
96 | reg = <0x00080000 0x00080000>; | ||
97 | read-only; | ||
98 | }; | ||
99 | partition@100000 { | ||
100 | label = "splash-image"; | ||
101 | reg = <0x00100000 0x00080000>; | ||
102 | read-only; | ||
103 | }; | ||
104 | partition@180000 { | ||
105 | label = "device-tree"; | ||
106 | reg = <0x00180000 0x00040000>; | ||
107 | }; | ||
108 | partition@1c0000 { | ||
109 | label = "kernel"; | ||
110 | reg = <0x001c0000 0x00500000>; | ||
111 | }; | ||
112 | partition@6c0000 { | ||
113 | label = "filesystem"; | ||
114 | reg = <0x006c0000 0x07940000>; | ||
115 | }; | ||
116 | }; | ||
117 | |||
118 | mram0@2,0 { | ||
119 | compatible = "mtd-ram"; | ||
120 | reg = <2 0x00000 0x10000>; | ||
121 | bank-width = <2>; | ||
122 | }; | ||
123 | |||
124 | mram1@2,10000 { | ||
125 | compatible = "mtd-ram"; | ||
126 | reg = <2 0x010000 0x10000>; | ||
127 | bank-width = <2>; | ||
128 | }; | ||
129 | }; | ||
130 | |||
131 | soc@80000000 { | ||
132 | compatible = "fsl,mpc5121-immr"; | ||
133 | #address-cells = <1>; | ||
134 | #size-cells = <1>; | ||
135 | #interrupt-cells = <2>; | ||
136 | ranges = <0x0 0x80000000 0x400000>; | ||
137 | reg = <0x80000000 0x400000>; | ||
138 | bus-frequency = <66000000>; // 66 MHz ips bus | ||
139 | |||
140 | // IPIC | ||
141 | // interrupts cell = <intr #, sense> | ||
142 | // sense values match linux IORESOURCE_IRQ_* defines: | ||
143 | // sense == 8: Level, low assertion | ||
144 | // sense == 2: Edge, high-to-low change | ||
145 | // | ||
146 | ipic: interrupt-controller@c00 { | ||
147 | compatible = "fsl,mpc5121-ipic", "fsl,ipic"; | ||
148 | interrupt-controller; | ||
149 | #address-cells = <0>; | ||
150 | #interrupt-cells = <2>; | ||
151 | reg = <0xc00 0x100>; | ||
152 | }; | ||
153 | |||
154 | rtc@a00 { // Real time clock | ||
155 | compatible = "fsl,mpc5121-rtc"; | ||
156 | reg = <0xa00 0x100>; | ||
157 | interrupts = <79 0x8 80 0x8>; | ||
158 | }; | ||
159 | |||
160 | reset@e00 { // Reset module | ||
161 | compatible = "fsl,mpc5121-reset"; | ||
162 | reg = <0xe00 0x100>; | ||
163 | }; | ||
164 | |||
165 | clock@f00 { // Clock control | ||
166 | compatible = "fsl,mpc5121-clock"; | ||
167 | reg = <0xf00 0x100>; | ||
168 | }; | ||
169 | |||
170 | pmc@1000{ //Power Management Controller | ||
171 | compatible = "fsl,mpc5121-pmc"; | ||
172 | reg = <0x1000 0x100>; | ||
173 | interrupts = <83 0x2>; | ||
174 | }; | ||
175 | |||
176 | gpio@1100 { | ||
177 | compatible = "fsl,mpc5121-gpio"; | ||
178 | reg = <0x1100 0x100>; | ||
179 | interrupts = <78 0x8>; | ||
180 | }; | ||
181 | |||
182 | can@1300 { | ||
183 | compatible = "fsl,mpc5121-mscan"; | ||
184 | interrupts = <12 0x8>; | ||
185 | reg = <0x1300 0x80>; | ||
186 | }; | ||
187 | |||
188 | can@1380 { | ||
189 | compatible = "fsl,mpc5121-mscan"; | ||
190 | interrupts = <13 0x8>; | ||
191 | reg = <0x1380 0x80>; | ||
192 | }; | ||
193 | |||
194 | i2c@1700 { | ||
195 | #address-cells = <1>; | ||
196 | #size-cells = <0>; | ||
197 | compatible = "fsl,mpc5121-i2c"; | ||
198 | reg = <0x1700 0x20>; | ||
199 | interrupts = <0x9 0x8>; | ||
200 | fsl,preserve-clocking; | ||
201 | |||
202 | eeprom@50 { | ||
203 | compatible = "at,24c01"; | ||
204 | reg = <0x50>; | ||
205 | }; | ||
206 | |||
207 | rtc@68 { | ||
208 | compatible = "stm,m41t00"; | ||
209 | reg = <0x68>; | ||
210 | }; | ||
211 | }; | ||
212 | |||
213 | i2c@1740 { | ||
214 | #address-cells = <1>; | ||
215 | #size-cells = <0>; | ||
216 | compatible = "fsl,mpc5121-i2c"; | ||
217 | reg = <0x1740 0x20>; | ||
218 | interrupts = <0xb 0x8>; | ||
219 | fsl,preserve-clocking; | ||
220 | }; | ||
221 | |||
222 | i2ccontrol@1760 { | ||
223 | compatible = "fsl,mpc5121-i2c-ctrl"; | ||
224 | reg = <0x1760 0x8>; | ||
225 | }; | ||
226 | |||
227 | axe@2000 { | ||
228 | compatible = "fsl,mpc5121-axe"; | ||
229 | reg = <0x2000 0x100>; | ||
230 | interrupts = <42 0x8>; | ||
231 | }; | ||
232 | |||
233 | display@2100 { | ||
234 | compatible = "fsl,mpc5121-diu"; | ||
235 | reg = <0x2100 0x100>; | ||
236 | interrupts = <64 0x8>; | ||
237 | }; | ||
238 | |||
239 | can@2300 { | ||
240 | compatible = "fsl,mpc5121-mscan"; | ||
241 | interrupts = <90 0x8>; | ||
242 | reg = <0x2300 0x80>; | ||
243 | }; | ||
244 | |||
245 | can@2380 { | ||
246 | compatible = "fsl,mpc5121-mscan"; | ||
247 | interrupts = <91 0x8>; | ||
248 | reg = <0x2380 0x80>; | ||
249 | }; | ||
250 | |||
251 | viu@2400 { | ||
252 | compatible = "fsl,mpc5121-viu"; | ||
253 | reg = <0x2400 0x400>; | ||
254 | interrupts = <67 0x8>; | ||
255 | }; | ||
256 | |||
257 | mdio@2800 { | ||
258 | compatible = "fsl,mpc5121-fec-mdio"; | ||
259 | reg = <0x2800 0x200>; | ||
260 | #address-cells = <1>; | ||
261 | #size-cells = <0>; | ||
262 | phy: ethernet-phy@0 { | ||
263 | compatible = "smsc,lan8700"; | ||
264 | reg = <0x1f>; | ||
265 | }; | ||
266 | }; | ||
267 | |||
268 | eth0: ethernet@2800 { | ||
269 | compatible = "fsl,mpc5121-fec"; | ||
270 | reg = <0x2800 0x200>; | ||
271 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
272 | interrupts = <4 0x8>; | ||
273 | phy-handle = < &phy >; | ||
274 | }; | ||
275 | |||
276 | // USB1 using external ULPI PHY | ||
277 | usb@3000 { | ||
278 | compatible = "fsl,mpc5121-usb2-dr"; | ||
279 | reg = <0x3000 0x600>; | ||
280 | #address-cells = <1>; | ||
281 | #size-cells = <0>; | ||
282 | interrupts = <43 0x8>; | ||
283 | dr_mode = "host"; | ||
284 | phy_type = "ulpi"; | ||
285 | }; | ||
286 | |||
287 | // USB0 using internal UTMI PHY | ||
288 | usb@4000 { | ||
289 | compatible = "fsl,mpc5121-usb2-dr"; | ||
290 | reg = <0x4000 0x600>; | ||
291 | #address-cells = <1>; | ||
292 | #size-cells = <0>; | ||
293 | interrupts = <44 0x8>; | ||
294 | dr_mode = "otg"; | ||
295 | phy_type = "utmi_wide"; | ||
296 | fsl,invert-pwr-fault; | ||
297 | }; | ||
298 | |||
299 | // IO control | ||
300 | ioctl@a000 { | ||
301 | compatible = "fsl,mpc5121-ioctl"; | ||
302 | reg = <0xA000 0x1000>; | ||
303 | }; | ||
304 | |||
305 | // 512x PSCs are not 52xx PSCs compatible | ||
306 | serial@11000 { | ||
307 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
308 | cell-index = <0>; | ||
309 | reg = <0x11000 0x100>; | ||
310 | interrupts = <40 0x8>; | ||
311 | fsl,rx-fifo-size = <16>; | ||
312 | fsl,tx-fifo-size = <16>; | ||
313 | }; | ||
314 | |||
315 | serial@11100 { | ||
316 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
317 | cell-index = <1>; | ||
318 | reg = <0x11100 0x100>; | ||
319 | interrupts = <40 0x8>; | ||
320 | fsl,rx-fifo-size = <16>; | ||
321 | fsl,tx-fifo-size = <16>; | ||
322 | }; | ||
323 | |||
324 | serial@11200 { | ||
325 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
326 | cell-index = <2>; | ||
327 | reg = <0x11200 0x100>; | ||
328 | interrupts = <40 0x8>; | ||
329 | fsl,rx-fifo-size = <16>; | ||
330 | fsl,tx-fifo-size = <16>; | ||
331 | }; | ||
332 | |||
333 | serial@11300 { | ||
334 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
335 | cell-index = <3>; | ||
336 | reg = <0x11300 0x100>; | ||
337 | interrupts = <40 0x8>; | ||
338 | fsl,rx-fifo-size = <16>; | ||
339 | fsl,tx-fifo-size = <16>; | ||
340 | }; | ||
341 | |||
342 | serial@11400 { | ||
343 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
344 | cell-index = <4>; | ||
345 | reg = <0x11400 0x100>; | ||
346 | interrupts = <40 0x8>; | ||
347 | fsl,rx-fifo-size = <16>; | ||
348 | fsl,tx-fifo-size = <16>; | ||
349 | }; | ||
350 | |||
351 | serial@11600 { | ||
352 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
353 | cell-index = <6>; | ||
354 | reg = <0x11600 0x100>; | ||
355 | interrupts = <40 0x8>; | ||
356 | fsl,rx-fifo-size = <16>; | ||
357 | fsl,tx-fifo-size = <16>; | ||
358 | }; | ||
359 | |||
360 | serial@11800 { | ||
361 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
362 | cell-index = <8>; | ||
363 | reg = <0x11800 0x100>; | ||
364 | interrupts = <40 0x8>; | ||
365 | fsl,rx-fifo-size = <16>; | ||
366 | fsl,tx-fifo-size = <16>; | ||
367 | }; | ||
368 | |||
369 | serial@11B00 { | ||
370 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
371 | cell-index = <11>; | ||
372 | reg = <0x11B00 0x100>; | ||
373 | interrupts = <40 0x8>; | ||
374 | fsl,rx-fifo-size = <16>; | ||
375 | fsl,tx-fifo-size = <16>; | ||
376 | }; | ||
377 | |||
378 | pscfifo@11f00 { | ||
379 | compatible = "fsl,mpc5121-psc-fifo"; | ||
380 | reg = <0x11f00 0x100>; | ||
381 | interrupts = <40 0x8>; | ||
382 | }; | ||
383 | |||
384 | spi@11900 { | ||
385 | compatible = "fsl,mpc5121-psc-spi", "fsl,mpc5121-psc"; | ||
386 | cell-index = <9>; | ||
387 | #address-cells = <1>; | ||
388 | #size-cells = <0>; | ||
389 | reg = <0x11900 0x100>; | ||
390 | interrupts = <40 0x8>; | ||
391 | fsl,rx-fifo-size = <16>; | ||
392 | fsl,tx-fifo-size = <16>; | ||
393 | |||
394 | // 7845 touch screen controller | ||
395 | ts@0 { | ||
396 | compatible = "ti,ads7846"; | ||
397 | reg = <0x0>; | ||
398 | spi-max-frequency = <3000000>; | ||
399 | // pen irq is GPIO25 | ||
400 | interrupts = <78 0x8>; | ||
401 | }; | ||
402 | }; | ||
403 | |||
404 | dma@14000 { | ||
405 | compatible = "fsl,mpc5121-dma"; | ||
406 | reg = <0x14000 0x1800>; | ||
407 | interrupts = <65 0x8>; | ||
408 | }; | ||
409 | }; | ||
410 | }; | ||
diff --git a/arch/powerpc/boot/dts/stxssa8555.dts b/arch/powerpc/boot/dts/stxssa8555.dts new file mode 100644 index 000000000000..49efd44057d7 --- /dev/null +++ b/arch/powerpc/boot/dts/stxssa8555.dts | |||
@@ -0,0 +1,380 @@ | |||
1 | /* | ||
2 | * MPC8555-based STx GP3 Device Tree Source | ||
3 | * | ||
4 | * Copyright 2006, 2008 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * Copyright 2010 Silicon Turnkey Express LLC. | ||
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 | /dts-v1/; | ||
15 | |||
16 | / { | ||
17 | model = "stx,gp3"; | ||
18 | compatible = "stx,gp3-8560", "stx,gp3"; | ||
19 | #address-cells = <1>; | ||
20 | #size-cells = <1>; | ||
21 | |||
22 | aliases { | ||
23 | ethernet0 = &enet0; | ||
24 | ethernet1 = &enet1; | ||
25 | serial0 = &serial0; | ||
26 | serial1 = &serial1; | ||
27 | pci0 = &pci0; | ||
28 | }; | ||
29 | |||
30 | cpus { | ||
31 | #address-cells = <1>; | ||
32 | #size-cells = <0>; | ||
33 | |||
34 | PowerPC,8555@0 { | ||
35 | device_type = "cpu"; | ||
36 | reg = <0x0>; | ||
37 | d-cache-line-size = <32>; // 32 bytes | ||
38 | i-cache-line-size = <32>; // 32 bytes | ||
39 | d-cache-size = <0x8000>; // L1, 32K | ||
40 | i-cache-size = <0x8000>; // L1, 32K | ||
41 | timebase-frequency = <0>; // 33 MHz, from uboot | ||
42 | bus-frequency = <0>; // 166 MHz | ||
43 | clock-frequency = <0>; // 825 MHz, from uboot | ||
44 | next-level-cache = <&L2>; | ||
45 | }; | ||
46 | }; | ||
47 | |||
48 | memory { | ||
49 | device_type = "memory"; | ||
50 | reg = <0x00000000 0x10000000>; | ||
51 | }; | ||
52 | |||
53 | soc8555@e0000000 { | ||
54 | #address-cells = <1>; | ||
55 | #size-cells = <1>; | ||
56 | device_type = "soc"; | ||
57 | compatible = "simple-bus"; | ||
58 | ranges = <0x0 0xe0000000 0x100000>; | ||
59 | bus-frequency = <0>; | ||
60 | |||
61 | ecm-law@0 { | ||
62 | compatible = "fsl,ecm-law"; | ||
63 | reg = <0x0 0x1000>; | ||
64 | fsl,num-laws = <8>; | ||
65 | }; | ||
66 | |||
67 | ecm@1000 { | ||
68 | compatible = "fsl,mpc8555-ecm", "fsl,ecm"; | ||
69 | reg = <0x1000 0x1000>; | ||
70 | interrupts = <17 2>; | ||
71 | interrupt-parent = <&mpic>; | ||
72 | }; | ||
73 | |||
74 | memory-controller@2000 { | ||
75 | compatible = "fsl,mpc8555-memory-controller"; | ||
76 | reg = <0x2000 0x1000>; | ||
77 | interrupt-parent = <&mpic>; | ||
78 | interrupts = <18 2>; | ||
79 | }; | ||
80 | |||
81 | L2: l2-cache-controller@20000 { | ||
82 | compatible = "fsl,mpc8555-l2-cache-controller"; | ||
83 | reg = <0x20000 0x1000>; | ||
84 | cache-line-size = <32>; // 32 bytes | ||
85 | cache-size = <0x40000>; // L2, 256K | ||
86 | interrupt-parent = <&mpic>; | ||
87 | interrupts = <16 2>; | ||
88 | }; | ||
89 | |||
90 | i2c@3000 { | ||
91 | #address-cells = <1>; | ||
92 | #size-cells = <0>; | ||
93 | cell-index = <0>; | ||
94 | compatible = "fsl-i2c"; | ||
95 | reg = <0x3000 0x100>; | ||
96 | interrupts = <43 2>; | ||
97 | interrupt-parent = <&mpic>; | ||
98 | dfsrr; | ||
99 | }; | ||
100 | |||
101 | dma@21300 { | ||
102 | #address-cells = <1>; | ||
103 | #size-cells = <1>; | ||
104 | compatible = "fsl,mpc8555-dma", "fsl,eloplus-dma"; | ||
105 | reg = <0x21300 0x4>; | ||
106 | ranges = <0x0 0x21100 0x200>; | ||
107 | cell-index = <0>; | ||
108 | dma-channel@0 { | ||
109 | compatible = "fsl,mpc8555-dma-channel", | ||
110 | "fsl,eloplus-dma-channel"; | ||
111 | reg = <0x0 0x80>; | ||
112 | cell-index = <0>; | ||
113 | interrupt-parent = <&mpic>; | ||
114 | interrupts = <20 2>; | ||
115 | }; | ||
116 | dma-channel@80 { | ||
117 | compatible = "fsl,mpc8555-dma-channel", | ||
118 | "fsl,eloplus-dma-channel"; | ||
119 | reg = <0x80 0x80>; | ||
120 | cell-index = <1>; | ||
121 | interrupt-parent = <&mpic>; | ||
122 | interrupts = <21 2>; | ||
123 | }; | ||
124 | dma-channel@100 { | ||
125 | compatible = "fsl,mpc8555-dma-channel", | ||
126 | "fsl,eloplus-dma-channel"; | ||
127 | reg = <0x100 0x80>; | ||
128 | cell-index = <2>; | ||
129 | interrupt-parent = <&mpic>; | ||
130 | interrupts = <22 2>; | ||
131 | }; | ||
132 | dma-channel@180 { | ||
133 | compatible = "fsl,mpc8555-dma-channel", | ||
134 | "fsl,eloplus-dma-channel"; | ||
135 | reg = <0x180 0x80>; | ||
136 | cell-index = <3>; | ||
137 | interrupt-parent = <&mpic>; | ||
138 | interrupts = <23 2>; | ||
139 | }; | ||
140 | }; | ||
141 | |||
142 | enet0: ethernet@24000 { | ||
143 | #address-cells = <1>; | ||
144 | #size-cells = <1>; | ||
145 | cell-index = <0>; | ||
146 | device_type = "network"; | ||
147 | model = "TSEC"; | ||
148 | compatible = "gianfar"; | ||
149 | reg = <0x24000 0x1000>; | ||
150 | ranges = <0x0 0x24000 0x1000>; | ||
151 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
152 | interrupts = <29 2 30 2 34 2>; | ||
153 | interrupt-parent = <&mpic>; | ||
154 | tbi-handle = <&tbi0>; | ||
155 | phy-handle = <&phy0>; | ||
156 | |||
157 | mdio@520 { | ||
158 | #address-cells = <1>; | ||
159 | #size-cells = <0>; | ||
160 | compatible = "fsl,gianfar-mdio"; | ||
161 | reg = <0x520 0x20>; | ||
162 | |||
163 | phy0: ethernet-phy@2 { | ||
164 | interrupt-parent = <&mpic>; | ||
165 | interrupts = <5 1>; | ||
166 | reg = <0x2>; | ||
167 | device_type = "ethernet-phy"; | ||
168 | }; | ||
169 | phy1: ethernet-phy@4 { | ||
170 | interrupt-parent = <&mpic>; | ||
171 | interrupts = <5 1>; | ||
172 | reg = <0x4>; | ||
173 | device_type = "ethernet-phy"; | ||
174 | }; | ||
175 | tbi0: tbi-phy@11 { | ||
176 | reg = <0x11>; | ||
177 | device_type = "tbi-phy"; | ||
178 | }; | ||
179 | }; | ||
180 | }; | ||
181 | |||
182 | enet1: ethernet@25000 { | ||
183 | #address-cells = <1>; | ||
184 | #size-cells = <1>; | ||
185 | cell-index = <1>; | ||
186 | device_type = "network"; | ||
187 | model = "TSEC"; | ||
188 | compatible = "gianfar"; | ||
189 | reg = <0x25000 0x1000>; | ||
190 | ranges = <0x0 0x25000 0x1000>; | ||
191 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
192 | interrupts = <35 2 36 2 40 2>; | ||
193 | interrupt-parent = <&mpic>; | ||
194 | tbi-handle = <&tbi1>; | ||
195 | phy-handle = <&phy1>; | ||
196 | |||
197 | mdio@520 { | ||
198 | #address-cells = <1>; | ||
199 | #size-cells = <0>; | ||
200 | compatible = "fsl,gianfar-tbi"; | ||
201 | reg = <0x520 0x20>; | ||
202 | |||
203 | tbi1: tbi-phy@11 { | ||
204 | reg = <0x11>; | ||
205 | device_type = "tbi-phy"; | ||
206 | }; | ||
207 | }; | ||
208 | }; | ||
209 | |||
210 | serial0: serial@4500 { | ||
211 | cell-index = <0>; | ||
212 | device_type = "serial"; | ||
213 | compatible = "ns16550"; | ||
214 | reg = <0x4500 0x100>; // reg base, size | ||
215 | clock-frequency = <0>; // should we fill in in uboot? | ||
216 | interrupts = <42 2>; | ||
217 | interrupt-parent = <&mpic>; | ||
218 | }; | ||
219 | |||
220 | serial1: serial@4600 { | ||
221 | cell-index = <1>; | ||
222 | device_type = "serial"; | ||
223 | compatible = "ns16550"; | ||
224 | reg = <0x4600 0x100>; // reg base, size | ||
225 | clock-frequency = <0>; // should we fill in in uboot? | ||
226 | interrupts = <42 2>; | ||
227 | interrupt-parent = <&mpic>; | ||
228 | }; | ||
229 | |||
230 | crypto@30000 { | ||
231 | compatible = "fsl,sec2.0"; | ||
232 | reg = <0x30000 0x10000>; | ||
233 | interrupts = <45 2>; | ||
234 | interrupt-parent = <&mpic>; | ||
235 | fsl,num-channels = <4>; | ||
236 | fsl,channel-fifo-len = <24>; | ||
237 | fsl,exec-units-mask = <0x7e>; | ||
238 | fsl,descriptor-types-mask = <0x01010ebf>; | ||
239 | }; | ||
240 | |||
241 | mpic: pic@40000 { | ||
242 | interrupt-controller; | ||
243 | #address-cells = <0>; | ||
244 | #interrupt-cells = <2>; | ||
245 | reg = <0x40000 0x40000>; | ||
246 | compatible = "chrp,open-pic"; | ||
247 | device_type = "open-pic"; | ||
248 | }; | ||
249 | |||
250 | cpm@919c0 { | ||
251 | #address-cells = <1>; | ||
252 | #size-cells = <1>; | ||
253 | compatible = "fsl,mpc8555-cpm", "fsl,cpm2"; | ||
254 | reg = <0x919c0 0x30>; | ||
255 | ranges; | ||
256 | |||
257 | muram@80000 { | ||
258 | #address-cells = <1>; | ||
259 | #size-cells = <1>; | ||
260 | ranges = <0x0 0x80000 0x10000>; | ||
261 | |||
262 | data@0 { | ||
263 | compatible = "fsl,cpm-muram-data"; | ||
264 | reg = <0x0 0x2000 0x9000 0x1000>; | ||
265 | }; | ||
266 | }; | ||
267 | |||
268 | brg@919f0 { | ||
269 | compatible = "fsl,mpc8555-brg", | ||
270 | "fsl,cpm2-brg", | ||
271 | "fsl,cpm-brg"; | ||
272 | reg = <0x919f0 0x10 0x915f0 0x10>; | ||
273 | }; | ||
274 | |||
275 | cpmpic: pic@90c00 { | ||
276 | interrupt-controller; | ||
277 | #address-cells = <0>; | ||
278 | #interrupt-cells = <2>; | ||
279 | interrupts = <46 2>; | ||
280 | interrupt-parent = <&mpic>; | ||
281 | reg = <0x90c00 0x80>; | ||
282 | compatible = "fsl,mpc8555-cpm-pic", "fsl,cpm2-pic"; | ||
283 | }; | ||
284 | }; | ||
285 | }; | ||
286 | |||
287 | pci0: pci@e0008000 { | ||
288 | interrupt-map-mask = <0x1f800 0x0 0x0 0x7>; | ||
289 | interrupt-map = < | ||
290 | |||
291 | /* IDSEL 0x10 */ | ||
292 | 0x8000 0x0 0x0 0x1 &mpic 0x0 0x1 | ||
293 | 0x8000 0x0 0x0 0x2 &mpic 0x1 0x1 | ||
294 | 0x8000 0x0 0x0 0x3 &mpic 0x2 0x1 | ||
295 | 0x8000 0x0 0x0 0x4 &mpic 0x3 0x1 | ||
296 | |||
297 | /* IDSEL 0x11 */ | ||
298 | 0x8800 0x0 0x0 0x1 &mpic 0x0 0x1 | ||
299 | 0x8800 0x0 0x0 0x2 &mpic 0x1 0x1 | ||
300 | 0x8800 0x0 0x0 0x3 &mpic 0x2 0x1 | ||
301 | 0x8800 0x0 0x0 0x4 &mpic 0x3 0x1 | ||
302 | |||
303 | /* IDSEL 0x12 (Slot 1) */ | ||
304 | 0x9000 0x0 0x0 0x1 &mpic 0x0 0x1 | ||
305 | 0x9000 0x0 0x0 0x2 &mpic 0x1 0x1 | ||
306 | 0x9000 0x0 0x0 0x3 &mpic 0x2 0x1 | ||
307 | 0x9000 0x0 0x0 0x4 &mpic 0x3 0x1 | ||
308 | |||
309 | /* IDSEL 0x13 (Slot 2) */ | ||
310 | 0x9800 0x0 0x0 0x1 &mpic 0x1 0x1 | ||
311 | 0x9800 0x0 0x0 0x2 &mpic 0x2 0x1 | ||
312 | 0x9800 0x0 0x0 0x3 &mpic 0x3 0x1 | ||
313 | 0x9800 0x0 0x0 0x4 &mpic 0x0 0x1 | ||
314 | |||
315 | /* IDSEL 0x14 (Slot 3) */ | ||
316 | 0xa000 0x0 0x0 0x1 &mpic 0x2 0x1 | ||
317 | 0xa000 0x0 0x0 0x2 &mpic 0x3 0x1 | ||
318 | 0xa000 0x0 0x0 0x3 &mpic 0x0 0x1 | ||
319 | 0xa000 0x0 0x0 0x4 &mpic 0x1 0x1 | ||
320 | |||
321 | /* IDSEL 0x15 (Slot 4) */ | ||
322 | 0xa800 0x0 0x0 0x1 &mpic 0x3 0x1 | ||
323 | 0xa800 0x0 0x0 0x2 &mpic 0x0 0x1 | ||
324 | 0xa800 0x0 0x0 0x3 &mpic 0x1 0x1 | ||
325 | 0xa800 0x0 0x0 0x4 &mpic 0x2 0x1 | ||
326 | |||
327 | /* Bus 1 (Tundra Bridge) */ | ||
328 | /* IDSEL 0x12 (ISA bridge) */ | ||
329 | 0x19000 0x0 0x0 0x1 &mpic 0x0 0x1 | ||
330 | 0x19000 0x0 0x0 0x2 &mpic 0x1 0x1 | ||
331 | 0x19000 0x0 0x0 0x3 &mpic 0x2 0x1 | ||
332 | 0x19000 0x0 0x0 0x4 &mpic 0x3 0x1>; | ||
333 | interrupt-parent = <&mpic>; | ||
334 | interrupts = <24 2>; | ||
335 | bus-range = <0 0>; | ||
336 | ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000 | ||
337 | 0x1000000 0x0 0x0 0xe2000000 0x0 0x100000>; | ||
338 | clock-frequency = <66666666>; | ||
339 | #interrupt-cells = <1>; | ||
340 | #size-cells = <2>; | ||
341 | #address-cells = <3>; | ||
342 | reg = <0xe0008000 0x1000>; | ||
343 | compatible = "fsl,mpc8540-pci"; | ||
344 | device_type = "pci"; | ||
345 | |||
346 | i8259@19000 { | ||
347 | interrupt-controller; | ||
348 | device_type = "interrupt-controller"; | ||
349 | reg = <0x19000 0x0 0x0 0x0 0x1>; | ||
350 | #address-cells = <0>; | ||
351 | #interrupt-cells = <2>; | ||
352 | compatible = "chrp,iic"; | ||
353 | interrupts = <1>; | ||
354 | interrupt-parent = <&pci0>; | ||
355 | }; | ||
356 | }; | ||
357 | |||
358 | pci1: pci@e0009000 { | ||
359 | interrupt-map-mask = <0xf800 0x0 0x0 0x7>; | ||
360 | interrupt-map = < | ||
361 | |||
362 | /* IDSEL 0x15 */ | ||
363 | 0xa800 0x0 0x0 0x1 &mpic 0xb 0x1 | ||
364 | 0xa800 0x0 0x0 0x2 &mpic 0xb 0x1 | ||
365 | 0xa800 0x0 0x0 0x3 &mpic 0xb 0x1 | ||
366 | 0xa800 0x0 0x0 0x4 &mpic 0xb 0x1>; | ||
367 | interrupt-parent = <&mpic>; | ||
368 | interrupts = <25 2>; | ||
369 | bus-range = <0 0>; | ||
370 | ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000 | ||
371 | 0x1000000 0x0 0x0 0xe3000000 0x0 0x100000>; | ||
372 | clock-frequency = <66666666>; | ||
373 | #interrupt-cells = <1>; | ||
374 | #size-cells = <2>; | ||
375 | #address-cells = <3>; | ||
376 | reg = <0xe0009000 0x1000>; | ||
377 | compatible = "fsl,mpc8540-pci"; | ||
378 | device_type = "pci"; | ||
379 | }; | ||
380 | }; | ||
diff --git a/arch/powerpc/boot/dts/tqm8540.dts b/arch/powerpc/boot/dts/tqm8540.dts index 71347537b83e..15ca731bc24e 100644 --- a/arch/powerpc/boot/dts/tqm8540.dts +++ b/arch/powerpc/boot/dts/tqm8540.dts | |||
@@ -289,7 +289,14 @@ | |||
289 | interrupt-map = < | 289 | interrupt-map = < |
290 | /* IDSEL 28 */ | 290 | /* IDSEL 28 */ |
291 | 0xe000 0 0 1 &mpic 2 1 | 291 | 0xe000 0 0 1 &mpic 2 1 |
292 | 0xe000 0 0 2 &mpic 3 1>; | 292 | 0xe000 0 0 2 &mpic 3 1 |
293 | 0xe000 0 0 3 &mpic 6 1 | ||
294 | 0xe000 0 0 4 &mpic 5 1 | ||
295 | |||
296 | /* IDSEL 11 */ | ||
297 | 0x5800 0 0 1 &mpic 6 1 | ||
298 | 0x5800 0 0 2 &mpic 5 1 | ||
299 | >; | ||
293 | 300 | ||
294 | interrupt-parent = <&mpic>; | 301 | interrupt-parent = <&mpic>; |
295 | interrupts = <24 2>; | 302 | interrupts = <24 2>; |
diff --git a/arch/powerpc/boot/dts/tqm8541.dts b/arch/powerpc/boot/dts/tqm8541.dts index b30f63753d41..f49d09181312 100644 --- a/arch/powerpc/boot/dts/tqm8541.dts +++ b/arch/powerpc/boot/dts/tqm8541.dts | |||
@@ -311,7 +311,14 @@ | |||
311 | interrupt-map = < | 311 | interrupt-map = < |
312 | /* IDSEL 28 */ | 312 | /* IDSEL 28 */ |
313 | 0xe000 0 0 1 &mpic 2 1 | 313 | 0xe000 0 0 1 &mpic 2 1 |
314 | 0xe000 0 0 2 &mpic 3 1>; | 314 | 0xe000 0 0 2 &mpic 3 1 |
315 | 0xe000 0 0 3 &mpic 6 1 | ||
316 | 0xe000 0 0 4 &mpic 5 1 | ||
317 | |||
318 | /* IDSEL 11 */ | ||
319 | 0x5800 0 0 1 &mpic 6 1 | ||
320 | 0x5800 0 0 2 &mpic 5 1 | ||
321 | >; | ||
315 | 322 | ||
316 | interrupt-parent = <&mpic>; | 323 | interrupt-parent = <&mpic>; |
317 | interrupts = <24 2>; | 324 | interrupts = <24 2>; |
diff --git a/arch/powerpc/boot/dts/tqm8548-bigflash.dts b/arch/powerpc/boot/dts/tqm8548-bigflash.dts index 61f25e15fd66..5dbb36edb038 100644 --- a/arch/powerpc/boot/dts/tqm8548-bigflash.dts +++ b/arch/powerpc/boot/dts/tqm8548-bigflash.dts | |||
@@ -442,7 +442,14 @@ | |||
442 | interrupt-map = < | 442 | interrupt-map = < |
443 | /* IDSEL 28 */ | 443 | /* IDSEL 28 */ |
444 | 0xe000 0 0 1 &mpic 2 1 | 444 | 0xe000 0 0 1 &mpic 2 1 |
445 | 0xe000 0 0 2 &mpic 3 1>; | 445 | 0xe000 0 0 2 &mpic 3 1 |
446 | 0xe000 0 0 3 &mpic 6 1 | ||
447 | 0xe000 0 0 4 &mpic 5 1 | ||
448 | |||
449 | /* IDSEL 11 */ | ||
450 | 0x5800 0 0 1 &mpic 6 1 | ||
451 | 0x5800 0 0 2 &mpic 5 1 | ||
452 | >; | ||
446 | 453 | ||
447 | interrupt-parent = <&mpic>; | 454 | interrupt-parent = <&mpic>; |
448 | interrupts = <24 2>; | 455 | interrupts = <24 2>; |
diff --git a/arch/powerpc/boot/dts/tqm8548.dts b/arch/powerpc/boot/dts/tqm8548.dts index 025759c7c955..a050ae427108 100644 --- a/arch/powerpc/boot/dts/tqm8548.dts +++ b/arch/powerpc/boot/dts/tqm8548.dts | |||
@@ -442,7 +442,14 @@ | |||
442 | interrupt-map = < | 442 | interrupt-map = < |
443 | /* IDSEL 28 */ | 443 | /* IDSEL 28 */ |
444 | 0xe000 0 0 1 &mpic 2 1 | 444 | 0xe000 0 0 1 &mpic 2 1 |
445 | 0xe000 0 0 2 &mpic 3 1>; | 445 | 0xe000 0 0 2 &mpic 3 1 |
446 | 0xe000 0 0 3 &mpic 6 1 | ||
447 | 0xe000 0 0 4 &mpic 5 1 | ||
448 | |||
449 | /* IDSEL 11 */ | ||
450 | 0x5800 0 0 1 &mpic 6 1 | ||
451 | 0x5800 0 0 2 &mpic 5 1 | ||
452 | >; | ||
446 | 453 | ||
447 | interrupt-parent = <&mpic>; | 454 | interrupt-parent = <&mpic>; |
448 | interrupts = <24 2>; | 455 | interrupts = <24 2>; |
diff --git a/arch/powerpc/boot/dts/tqm8555.dts b/arch/powerpc/boot/dts/tqm8555.dts index 95e287381836..81bad8cd3756 100644 --- a/arch/powerpc/boot/dts/tqm8555.dts +++ b/arch/powerpc/boot/dts/tqm8555.dts | |||
@@ -311,7 +311,14 @@ | |||
311 | interrupt-map = < | 311 | interrupt-map = < |
312 | /* IDSEL 28 */ | 312 | /* IDSEL 28 */ |
313 | 0xe000 0 0 1 &mpic 2 1 | 313 | 0xe000 0 0 1 &mpic 2 1 |
314 | 0xe000 0 0 2 &mpic 3 1>; | 314 | 0xe000 0 0 2 &mpic 3 1 |
315 | 0xe000 0 0 3 &mpic 6 1 | ||
316 | 0xe000 0 0 4 &mpic 5 1 | ||
317 | |||
318 | /* IDSEL 11 */ | ||
319 | 0x5800 0 0 1 &mpic 6 1 | ||
320 | 0x5800 0 0 2 &mpic 5 1 | ||
321 | >; | ||
315 | 322 | ||
316 | interrupt-parent = <&mpic>; | 323 | interrupt-parent = <&mpic>; |
317 | interrupts = <24 2>; | 324 | interrupts = <24 2>; |
diff --git a/arch/powerpc/boot/dts/tqm8560.dts b/arch/powerpc/boot/dts/tqm8560.dts index ff70580a8f4c..22ec39b5beeb 100644 --- a/arch/powerpc/boot/dts/tqm8560.dts +++ b/arch/powerpc/boot/dts/tqm8560.dts | |||
@@ -382,7 +382,14 @@ | |||
382 | interrupt-map = < | 382 | interrupt-map = < |
383 | /* IDSEL 28 */ | 383 | /* IDSEL 28 */ |
384 | 0xe000 0 0 1 &mpic 2 1 | 384 | 0xe000 0 0 1 &mpic 2 1 |
385 | 0xe000 0 0 2 &mpic 3 1>; | 385 | 0xe000 0 0 2 &mpic 3 1 |
386 | 0xe000 0 0 3 &mpic 6 1 | ||
387 | 0xe000 0 0 4 &mpic 5 1 | ||
388 | |||
389 | /* IDSEL 11 */ | ||
390 | 0x5800 0 0 1 &mpic 6 1 | ||
391 | 0x5800 0 0 2 &mpic 5 1 | ||
392 | >; | ||
386 | 393 | ||
387 | interrupt-parent = <&mpic>; | 394 | interrupt-parent = <&mpic>; |
388 | interrupts = <24 2>; | 395 | interrupts = <24 2>; |
diff --git a/arch/powerpc/boot/dts/tqm8xx.dts b/arch/powerpc/boot/dts/tqm8xx.dts new file mode 100644 index 000000000000..f6da7ec49a8e --- /dev/null +++ b/arch/powerpc/boot/dts/tqm8xx.dts | |||
@@ -0,0 +1,172 @@ | |||
1 | /* | ||
2 | * TQM8XX Device Tree Source | ||
3 | * | ||
4 | * Heiko Schocher <hs@denx.de> | ||
5 | * 2010 DENX Software Engineering GmbH | ||
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 | /dts-v1/; | ||
14 | |||
15 | / { | ||
16 | model = "TQM8xx"; | ||
17 | compatible = "tqc,tqm8xx"; | ||
18 | #address-cells = <1>; | ||
19 | #size-cells = <1>; | ||
20 | |||
21 | aliases { | ||
22 | ethernet0 = ð0; | ||
23 | ethernet1 = ð1; | ||
24 | mdio1 = &phy1; | ||
25 | serial0 = &smc1; | ||
26 | }; | ||
27 | |||
28 | cpus { | ||
29 | #address-cells = <1>; | ||
30 | #size-cells = <0>; | ||
31 | |||
32 | PowerPC,860@0 { | ||
33 | device_type = "cpu"; | ||
34 | reg = <0x0>; | ||
35 | d-cache-line-size = <16>; // 16 bytes | ||
36 | i-cache-line-size = <16>; // 16 bytes | ||
37 | d-cache-size = <0x1000>; // L1, 4K | ||
38 | i-cache-size = <0x1000>; // L1, 4K | ||
39 | timebase-frequency = <0>; | ||
40 | bus-frequency = <0>; | ||
41 | clock-frequency = <0>; | ||
42 | interrupts = <15 2>; // decrementer interrupt | ||
43 | interrupt-parent = <&PIC>; | ||
44 | }; | ||
45 | }; | ||
46 | |||
47 | memory { | ||
48 | device_type = "memory"; | ||
49 | reg = <0x0 0x2000000>; | ||
50 | }; | ||
51 | |||
52 | localbus@fff00100 { | ||
53 | compatible = "fsl,mpc860-localbus", "fsl,pq1-localbus"; | ||
54 | #address-cells = <2>; | ||
55 | #size-cells = <1>; | ||
56 | reg = <0xfff00100 0x40>; | ||
57 | |||
58 | ranges = < | ||
59 | 0x0 0x0 0x40000000 0x800000 | ||
60 | >; | ||
61 | |||
62 | flash@0,0 { | ||
63 | compatible = "cfi-flash"; | ||
64 | reg = <0 0 0x800000>; | ||
65 | #address-cells = <1>; | ||
66 | #size-cells = <1>; | ||
67 | bank-width = <4>; | ||
68 | device-width = <2>; | ||
69 | }; | ||
70 | }; | ||
71 | |||
72 | soc@fff00000 { | ||
73 | #address-cells = <1>; | ||
74 | #size-cells = <1>; | ||
75 | device_type = "soc"; | ||
76 | ranges = <0x0 0xfff00000 0x00004000>; | ||
77 | |||
78 | phy1: mdio@e00 { | ||
79 | compatible = "fsl,mpc866-fec-mdio", "fsl,pq1-fec-mdio"; | ||
80 | reg = <0xe00 0x188>; | ||
81 | #address-cells = <1>; | ||
82 | #size-cells = <0>; | ||
83 | PHY: ethernet-phy@f { | ||
84 | reg = <0xf>; | ||
85 | device_type = "ethernet-phy"; | ||
86 | }; | ||
87 | }; | ||
88 | |||
89 | eth1: ethernet@e00 { | ||
90 | device_type = "network"; | ||
91 | compatible = "fsl,mpc866-fec-enet", | ||
92 | "fsl,pq1-fec-enet"; | ||
93 | reg = <0xe00 0x188>; | ||
94 | interrupts = <3 1>; | ||
95 | interrupt-parent = <&PIC>; | ||
96 | phy-handle = <&PHY>; | ||
97 | linux,network-index = <1>; | ||
98 | }; | ||
99 | |||
100 | PIC: pic@0 { | ||
101 | interrupt-controller; | ||
102 | #interrupt-cells = <2>; | ||
103 | reg = <0x0 0x24>; | ||
104 | compatible = "fsl,mpc860-pic", "fsl,pq1-pic"; | ||
105 | }; | ||
106 | |||
107 | cpm@9c0 { | ||
108 | #address-cells = <1>; | ||
109 | #size-cells = <1>; | ||
110 | compatible = "fsl,mpc860-cpm", "fsl,cpm1"; | ||
111 | ranges; | ||
112 | reg = <0x9c0 0x40>; | ||
113 | brg-frequency = <0>; | ||
114 | interrupts = <0 2>; // cpm error interrupt | ||
115 | interrupt-parent = <&CPM_PIC>; | ||
116 | |||
117 | muram@2000 { | ||
118 | #address-cells = <1>; | ||
119 | #size-cells = <1>; | ||
120 | ranges = <0x0 0x2000 0x2000>; | ||
121 | |||
122 | data@0 { | ||
123 | compatible = "fsl,cpm-muram-data"; | ||
124 | reg = <0x0 0x2000>; | ||
125 | }; | ||
126 | }; | ||
127 | |||
128 | brg@9f0 { | ||
129 | compatible = "fsl,mpc860-brg", | ||
130 | "fsl,cpm1-brg", | ||
131 | "fsl,cpm-brg"; | ||
132 | reg = <0x9f0 0x10>; | ||
133 | clock-frequency = <0>; | ||
134 | }; | ||
135 | |||
136 | CPM_PIC: pic@930 { | ||
137 | interrupt-controller; | ||
138 | #address-cells = <0>; | ||
139 | #interrupt-cells = <1>; | ||
140 | interrupts = <5 2 0 2>; | ||
141 | interrupt-parent = <&PIC>; | ||
142 | reg = <0x930 0x20>; | ||
143 | compatible = "fsl,mpc860-cpm-pic", | ||
144 | "fsl,cpm1-pic"; | ||
145 | }; | ||
146 | |||
147 | |||
148 | smc1: serial@a80 { | ||
149 | device_type = "serial"; | ||
150 | compatible = "fsl,mpc860-smc-uart", | ||
151 | "fsl,cpm1-smc-uart"; | ||
152 | reg = <0xa80 0x10 0x3e80 0x40>; | ||
153 | interrupts = <4>; | ||
154 | interrupt-parent = <&CPM_PIC>; | ||
155 | fsl,cpm-brg = <1>; | ||
156 | fsl,cpm-command = <0x90>; | ||
157 | }; | ||
158 | |||
159 | eth0: ethernet@a00 { | ||
160 | device_type = "network"; | ||
161 | compatible = "fsl,mpc860-scc-enet", | ||
162 | "fsl,cpm1-scc-enet"; | ||
163 | reg = <0xa00 0x18 0x3c00 0x100>; | ||
164 | interrupts = <30>; | ||
165 | interrupt-parent = <&CPM_PIC>; | ||
166 | fsl,cpm-command = <0000>; | ||
167 | linux,network-index = <0>; | ||
168 | fixed-link = <0 0 10 0 0>; | ||
169 | }; | ||
170 | }; | ||
171 | }; | ||
172 | }; | ||
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index cfebef9f9123..d32f31a03f58 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig | |||
@@ -19,7 +19,8 @@ CONFIG_E500=y | |||
19 | CONFIG_FSL_EMB_PERFMON=y | 19 | CONFIG_FSL_EMB_PERFMON=y |
20 | CONFIG_BOOKE=y | 20 | CONFIG_BOOKE=y |
21 | CONFIG_FSL_BOOKE=y | 21 | CONFIG_FSL_BOOKE=y |
22 | # CONFIG_PHYS_64BIT is not set | 22 | CONFIG_PTE_64BIT=y |
23 | CONFIG_PHYS_64BIT=y | ||
23 | CONFIG_SPE=y | 24 | CONFIG_SPE=y |
24 | CONFIG_PPC_MMU_NOHASH=y | 25 | CONFIG_PPC_MMU_NOHASH=y |
25 | CONFIG_PPC_MMU_NOHASH_32=y | 26 | CONFIG_PPC_MMU_NOHASH_32=y |
@@ -28,7 +29,7 @@ CONFIG_PPC_BOOK3E_MMU=y | |||
28 | # CONFIG_SMP is not set | 29 | # CONFIG_SMP is not set |
29 | CONFIG_PPC32=y | 30 | CONFIG_PPC32=y |
30 | CONFIG_WORD_SIZE=32 | 31 | CONFIG_WORD_SIZE=32 |
31 | # CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set | 32 | CONFIG_ARCH_PHYS_ADDR_T_64BIT=y |
32 | CONFIG_MMU=y | 33 | CONFIG_MMU=y |
33 | CONFIG_GENERIC_CMOS_UPDATE=y | 34 | CONFIG_GENERIC_CMOS_UPDATE=y |
34 | CONFIG_GENERIC_TIME=y | 35 | CONFIG_GENERIC_TIME=y |
@@ -239,6 +240,7 @@ CONFIG_MPC85xx_MDS=y | |||
239 | CONFIG_MPC8536_DS=y | 240 | CONFIG_MPC8536_DS=y |
240 | CONFIG_MPC85xx_DS=y | 241 | CONFIG_MPC85xx_DS=y |
241 | CONFIG_MPC85xx_RDB=y | 242 | CONFIG_MPC85xx_RDB=y |
243 | CONFIG_P1022_DS=y | ||
242 | CONFIG_SOCRATES=y | 244 | CONFIG_SOCRATES=y |
243 | CONFIG_KSI8560=y | 245 | CONFIG_KSI8560=y |
244 | CONFIG_XES_MPC85xx=y | 246 | CONFIG_XES_MPC85xx=y |
@@ -311,7 +313,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y | |||
311 | CONFIG_PAGEFLAGS_EXTENDED=y | 313 | CONFIG_PAGEFLAGS_EXTENDED=y |
312 | CONFIG_SPLIT_PTLOCK_CPUS=4 | 314 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
313 | CONFIG_MIGRATION=y | 315 | CONFIG_MIGRATION=y |
314 | # CONFIG_PHYS_ADDR_T_64BIT is not set | 316 | CONFIG_PHYS_ADDR_T_64BIT=y |
315 | CONFIG_ZONE_DMA_FLAG=1 | 317 | CONFIG_ZONE_DMA_FLAG=1 |
316 | CONFIG_BOUNCE=y | 318 | CONFIG_BOUNCE=y |
317 | CONFIG_VIRT_TO_BUS=y | 319 | CONFIG_VIRT_TO_BUS=y |
@@ -321,7 +323,7 @@ CONFIG_PPC_4K_PAGES=y | |||
321 | # CONFIG_PPC_16K_PAGES is not set | 323 | # CONFIG_PPC_16K_PAGES is not set |
322 | # CONFIG_PPC_64K_PAGES is not set | 324 | # CONFIG_PPC_64K_PAGES is not set |
323 | # CONFIG_PPC_256K_PAGES is not set | 325 | # CONFIG_PPC_256K_PAGES is not set |
324 | CONFIG_FORCE_MAX_ZONEORDER=11 | 326 | CONFIG_FORCE_MAX_ZONEORDER=12 |
325 | CONFIG_PROC_DEVICETREE=y | 327 | CONFIG_PROC_DEVICETREE=y |
326 | # CONFIG_CMDLINE_BOOL is not set | 328 | # CONFIG_CMDLINE_BOOL is not set |
327 | CONFIG_EXTRA_TARGETS="" | 329 | CONFIG_EXTRA_TARGETS="" |
@@ -1122,16 +1124,13 @@ CONFIG_VGA_CONSOLE=y | |||
1122 | # CONFIG_VGACON_SOFT_SCROLLBACK is not set | 1124 | # CONFIG_VGACON_SOFT_SCROLLBACK is not set |
1123 | CONFIG_DUMMY_CONSOLE=y | 1125 | CONFIG_DUMMY_CONSOLE=y |
1124 | CONFIG_SOUND=y | 1126 | CONFIG_SOUND=y |
1125 | CONFIG_SOUND_OSS_CORE=y | 1127 | # CONFIG_SOUND_OSS_CORE is not set |
1126 | CONFIG_SOUND_OSS_CORE_PRECLAIM=y | ||
1127 | CONFIG_SND=y | 1128 | CONFIG_SND=y |
1128 | CONFIG_SND_TIMER=y | 1129 | CONFIG_SND_TIMER=y |
1129 | CONFIG_SND_PCM=y | 1130 | CONFIG_SND_PCM=y |
1130 | # CONFIG_SND_SEQUENCER is not set | 1131 | # CONFIG_SND_SEQUENCER is not set |
1131 | CONFIG_SND_OSSEMUL=y | 1132 | # CONFIG_SND_MIXER_OSS is not set |
1132 | CONFIG_SND_MIXER_OSS=y | 1133 | # CONFIG_SND_PCM_OSS is not set |
1133 | CONFIG_SND_PCM_OSS=y | ||
1134 | CONFIG_SND_PCM_OSS_PLUGINS=y | ||
1135 | # CONFIG_SND_HRTIMER is not set | 1134 | # CONFIG_SND_HRTIMER is not set |
1136 | # CONFIG_SND_DYNAMIC_MINORS is not set | 1135 | # CONFIG_SND_DYNAMIC_MINORS is not set |
1137 | # CONFIG_SND_SUPPORT_OLD_API is not set | 1136 | # CONFIG_SND_SUPPORT_OLD_API is not set |
@@ -1145,12 +1144,7 @@ CONFIG_SND_VMASTER=y | |||
1145 | # CONFIG_SND_SBAWE_SEQ is not set | 1144 | # CONFIG_SND_SBAWE_SEQ is not set |
1146 | # CONFIG_SND_EMU10K1_SEQ is not set | 1145 | # CONFIG_SND_EMU10K1_SEQ is not set |
1147 | CONFIG_SND_AC97_CODEC=y | 1146 | CONFIG_SND_AC97_CODEC=y |
1148 | CONFIG_SND_DRIVERS=y | 1147 | # CONFIG_SND_DRIVERS is not set |
1149 | # CONFIG_SND_DUMMY is not set | ||
1150 | # CONFIG_SND_MTPAV is not set | ||
1151 | # CONFIG_SND_SERIAL_U16550 is not set | ||
1152 | # CONFIG_SND_MPU401 is not set | ||
1153 | # CONFIG_SND_AC97_POWER_SAVE is not set | ||
1154 | CONFIG_SND_PCI=y | 1148 | CONFIG_SND_PCI=y |
1155 | # CONFIG_SND_AD1889 is not set | 1149 | # CONFIG_SND_AD1889 is not set |
1156 | # CONFIG_SND_ALS300 is not set | 1150 | # CONFIG_SND_ALS300 is not set |
@@ -1218,12 +1212,8 @@ CONFIG_SND_INTEL8X0=y | |||
1218 | # CONFIG_SND_VIRTUOSO is not set | 1212 | # CONFIG_SND_VIRTUOSO is not set |
1219 | # CONFIG_SND_VX222 is not set | 1213 | # CONFIG_SND_VX222 is not set |
1220 | # CONFIG_SND_YMFPCI is not set | 1214 | # CONFIG_SND_YMFPCI is not set |
1221 | CONFIG_SND_PPC=y | 1215 | # CONFIG_SND_PPC is not set |
1222 | CONFIG_SND_USB=y | 1216 | # CONFIG_SND_USB is not set |
1223 | # CONFIG_SND_USB_AUDIO is not set | ||
1224 | # CONFIG_SND_USB_UA101 is not set | ||
1225 | # CONFIG_SND_USB_USX2Y is not set | ||
1226 | # CONFIG_SND_USB_CAIAQ is not set | ||
1227 | # CONFIG_SND_SOC is not set | 1217 | # CONFIG_SND_SOC is not set |
1228 | # CONFIG_SOUND_PRIME is not set | 1218 | # CONFIG_SOUND_PRIME is not set |
1229 | CONFIG_AC97_BUS=y | 1219 | CONFIG_AC97_BUS=y |
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig index f5451d80f19b..f93de10adcda 100644 --- a/arch/powerpc/configs/mpc85xx_smp_defconfig +++ b/arch/powerpc/configs/mpc85xx_smp_defconfig | |||
@@ -19,7 +19,8 @@ CONFIG_E500=y | |||
19 | CONFIG_FSL_EMB_PERFMON=y | 19 | CONFIG_FSL_EMB_PERFMON=y |
20 | CONFIG_BOOKE=y | 20 | CONFIG_BOOKE=y |
21 | CONFIG_FSL_BOOKE=y | 21 | CONFIG_FSL_BOOKE=y |
22 | # CONFIG_PHYS_64BIT is not set | 22 | CONFIG_PTE_64BIT=y |
23 | CONFIG_PHYS_64BIT=y | ||
23 | CONFIG_SPE=y | 24 | CONFIG_SPE=y |
24 | CONFIG_PPC_MMU_NOHASH=y | 25 | CONFIG_PPC_MMU_NOHASH=y |
25 | CONFIG_PPC_MMU_NOHASH_32=y | 26 | CONFIG_PPC_MMU_NOHASH_32=y |
@@ -29,7 +30,7 @@ CONFIG_SMP=y | |||
29 | CONFIG_NR_CPUS=8 | 30 | CONFIG_NR_CPUS=8 |
30 | CONFIG_PPC32=y | 31 | CONFIG_PPC32=y |
31 | CONFIG_WORD_SIZE=32 | 32 | CONFIG_WORD_SIZE=32 |
32 | # CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set | 33 | CONFIG_ARCH_PHYS_ADDR_T_64BIT=y |
33 | CONFIG_MMU=y | 34 | CONFIG_MMU=y |
34 | CONFIG_GENERIC_CMOS_UPDATE=y | 35 | CONFIG_GENERIC_CMOS_UPDATE=y |
35 | CONFIG_GENERIC_TIME=y | 36 | CONFIG_GENERIC_TIME=y |
@@ -243,6 +244,7 @@ CONFIG_MPC85xx_MDS=y | |||
243 | CONFIG_MPC8536_DS=y | 244 | CONFIG_MPC8536_DS=y |
244 | CONFIG_MPC85xx_DS=y | 245 | CONFIG_MPC85xx_DS=y |
245 | CONFIG_MPC85xx_RDB=y | 246 | CONFIG_MPC85xx_RDB=y |
247 | CONFIG_P1022_DS=y | ||
246 | CONFIG_SOCRATES=y | 248 | CONFIG_SOCRATES=y |
247 | CONFIG_KSI8560=y | 249 | CONFIG_KSI8560=y |
248 | CONFIG_XES_MPC85xx=y | 250 | CONFIG_XES_MPC85xx=y |
@@ -316,7 +318,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y | |||
316 | CONFIG_PAGEFLAGS_EXTENDED=y | 318 | CONFIG_PAGEFLAGS_EXTENDED=y |
317 | CONFIG_SPLIT_PTLOCK_CPUS=4 | 319 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
318 | CONFIG_MIGRATION=y | 320 | CONFIG_MIGRATION=y |
319 | # CONFIG_PHYS_ADDR_T_64BIT is not set | 321 | CONFIG_PHYS_ADDR_T_64BIT=y |
320 | CONFIG_ZONE_DMA_FLAG=1 | 322 | CONFIG_ZONE_DMA_FLAG=1 |
321 | CONFIG_BOUNCE=y | 323 | CONFIG_BOUNCE=y |
322 | CONFIG_VIRT_TO_BUS=y | 324 | CONFIG_VIRT_TO_BUS=y |
@@ -326,7 +328,7 @@ CONFIG_PPC_4K_PAGES=y | |||
326 | # CONFIG_PPC_16K_PAGES is not set | 328 | # CONFIG_PPC_16K_PAGES is not set |
327 | # CONFIG_PPC_64K_PAGES is not set | 329 | # CONFIG_PPC_64K_PAGES is not set |
328 | # CONFIG_PPC_256K_PAGES is not set | 330 | # CONFIG_PPC_256K_PAGES is not set |
329 | CONFIG_FORCE_MAX_ZONEORDER=11 | 331 | CONFIG_FORCE_MAX_ZONEORDER=12 |
330 | CONFIG_PROC_DEVICETREE=y | 332 | CONFIG_PROC_DEVICETREE=y |
331 | # CONFIG_CMDLINE_BOOL is not set | 333 | # CONFIG_CMDLINE_BOOL is not set |
332 | CONFIG_EXTRA_TARGETS="" | 334 | CONFIG_EXTRA_TARGETS="" |
@@ -1127,16 +1129,13 @@ CONFIG_VGA_CONSOLE=y | |||
1127 | # CONFIG_VGACON_SOFT_SCROLLBACK is not set | 1129 | # CONFIG_VGACON_SOFT_SCROLLBACK is not set |
1128 | CONFIG_DUMMY_CONSOLE=y | 1130 | CONFIG_DUMMY_CONSOLE=y |
1129 | CONFIG_SOUND=y | 1131 | CONFIG_SOUND=y |
1130 | CONFIG_SOUND_OSS_CORE=y | 1132 | # CONFIG_SOUND_OSS_CORE is not set |
1131 | CONFIG_SOUND_OSS_CORE_PRECLAIM=y | ||
1132 | CONFIG_SND=y | 1133 | CONFIG_SND=y |
1133 | CONFIG_SND_TIMER=y | 1134 | CONFIG_SND_TIMER=y |
1134 | CONFIG_SND_PCM=y | 1135 | CONFIG_SND_PCM=y |
1135 | # CONFIG_SND_SEQUENCER is not set | 1136 | # CONFIG_SND_SEQUENCER is not set |
1136 | CONFIG_SND_OSSEMUL=y | 1137 | # CONFIG_SND_MIXER_OSS is not set |
1137 | CONFIG_SND_MIXER_OSS=y | 1138 | # CONFIG_SND_PCM_OSS is not set |
1138 | CONFIG_SND_PCM_OSS=y | ||
1139 | CONFIG_SND_PCM_OSS_PLUGINS=y | ||
1140 | # CONFIG_SND_HRTIMER is not set | 1139 | # CONFIG_SND_HRTIMER is not set |
1141 | # CONFIG_SND_DYNAMIC_MINORS is not set | 1140 | # CONFIG_SND_DYNAMIC_MINORS is not set |
1142 | # CONFIG_SND_SUPPORT_OLD_API is not set | 1141 | # CONFIG_SND_SUPPORT_OLD_API is not set |
@@ -1150,12 +1149,7 @@ CONFIG_SND_VMASTER=y | |||
1150 | # CONFIG_SND_SBAWE_SEQ is not set | 1149 | # CONFIG_SND_SBAWE_SEQ is not set |
1151 | # CONFIG_SND_EMU10K1_SEQ is not set | 1150 | # CONFIG_SND_EMU10K1_SEQ is not set |
1152 | CONFIG_SND_AC97_CODEC=y | 1151 | CONFIG_SND_AC97_CODEC=y |
1153 | CONFIG_SND_DRIVERS=y | 1152 | # CONFIG_SND_DRIVERS is not set |
1154 | # CONFIG_SND_DUMMY is not set | ||
1155 | # CONFIG_SND_MTPAV is not set | ||
1156 | # CONFIG_SND_SERIAL_U16550 is not set | ||
1157 | # CONFIG_SND_MPU401 is not set | ||
1158 | # CONFIG_SND_AC97_POWER_SAVE is not set | ||
1159 | CONFIG_SND_PCI=y | 1153 | CONFIG_SND_PCI=y |
1160 | # CONFIG_SND_AD1889 is not set | 1154 | # CONFIG_SND_AD1889 is not set |
1161 | # CONFIG_SND_ALS300 is not set | 1155 | # CONFIG_SND_ALS300 is not set |
@@ -1223,12 +1217,8 @@ CONFIG_SND_INTEL8X0=y | |||
1223 | # CONFIG_SND_VIRTUOSO is not set | 1217 | # CONFIG_SND_VIRTUOSO is not set |
1224 | # CONFIG_SND_VX222 is not set | 1218 | # CONFIG_SND_VX222 is not set |
1225 | # CONFIG_SND_YMFPCI is not set | 1219 | # CONFIG_SND_YMFPCI is not set |
1226 | CONFIG_SND_PPC=y | 1220 | # CONFIG_SND_PPC is not set |
1227 | CONFIG_SND_USB=y | 1221 | # CONFIG_SND_USB is not set |
1228 | # CONFIG_SND_USB_AUDIO is not set | ||
1229 | # CONFIG_SND_USB_UA101 is not set | ||
1230 | # CONFIG_SND_USB_USX2Y is not set | ||
1231 | # CONFIG_SND_USB_CAIAQ is not set | ||
1232 | # CONFIG_SND_SOC is not set | 1222 | # CONFIG_SND_SOC is not set |
1233 | # CONFIG_SOUND_PRIME is not set | 1223 | # CONFIG_SOUND_PRIME is not set |
1234 | CONFIG_AC97_BUS=y | 1224 | CONFIG_AC97_BUS=y |
diff --git a/arch/powerpc/configs/tqm8xx_defconfig b/arch/powerpc/configs/tqm8xx_defconfig new file mode 100644 index 000000000000..85e654b64874 --- /dev/null +++ b/arch/powerpc/configs/tqm8xx_defconfig | |||
@@ -0,0 +1,934 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.34-rc1 | ||
4 | # Tue Mar 23 08:22:15 2010 | ||
5 | # | ||
6 | # CONFIG_PPC64 is not set | ||
7 | |||
8 | # | ||
9 | # Processor support | ||
10 | # | ||
11 | # CONFIG_PPC_BOOK3S_32 is not set | ||
12 | # CONFIG_PPC_85xx is not set | ||
13 | CONFIG_PPC_8xx=y | ||
14 | # CONFIG_40x is not set | ||
15 | # CONFIG_44x is not set | ||
16 | # CONFIG_E200 is not set | ||
17 | CONFIG_8xx=y | ||
18 | CONFIG_PPC_MMU_NOHASH=y | ||
19 | CONFIG_PPC_MMU_NOHASH_32=y | ||
20 | # CONFIG_PPC_MM_SLICES is not set | ||
21 | CONFIG_NOT_COHERENT_CACHE=y | ||
22 | CONFIG_PPC32=y | ||
23 | CONFIG_WORD_SIZE=32 | ||
24 | # CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set | ||
25 | CONFIG_MMU=y | ||
26 | CONFIG_GENERIC_CMOS_UPDATE=y | ||
27 | CONFIG_GENERIC_TIME=y | ||
28 | CONFIG_GENERIC_TIME_VSYSCALL=y | ||
29 | CONFIG_GENERIC_CLOCKEVENTS=y | ||
30 | CONFIG_GENERIC_HARDIRQS=y | ||
31 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y | ||
32 | # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set | ||
33 | # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set | ||
34 | CONFIG_IRQ_PER_CPU=y | ||
35 | CONFIG_NR_IRQS=512 | ||
36 | CONFIG_STACKTRACE_SUPPORT=y | ||
37 | CONFIG_HAVE_LATENCYTOP_SUPPORT=y | ||
38 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y | ||
39 | CONFIG_LOCKDEP_SUPPORT=y | ||
40 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | ||
41 | CONFIG_ARCH_HAS_ILOG2_U32=y | ||
42 | CONFIG_GENERIC_HWEIGHT=y | ||
43 | CONFIG_GENERIC_FIND_NEXT_BIT=y | ||
44 | # CONFIG_ARCH_NO_VIRT_TO_BUS is not set | ||
45 | CONFIG_PPC=y | ||
46 | CONFIG_EARLY_PRINTK=y | ||
47 | CONFIG_GENERIC_NVRAM=y | ||
48 | CONFIG_SCHED_OMIT_FRAME_POINTER=y | ||
49 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y | ||
50 | CONFIG_PPC_OF=y | ||
51 | CONFIG_OF=y | ||
52 | # CONFIG_PPC_UDBG_16550 is not set | ||
53 | # CONFIG_GENERIC_TBSYNC is not set | ||
54 | CONFIG_AUDIT_ARCH=y | ||
55 | CONFIG_GENERIC_BUG=y | ||
56 | CONFIG_DTC=y | ||
57 | # CONFIG_DEFAULT_UIMAGE is not set | ||
58 | CONFIG_ARCH_HIBERNATION_POSSIBLE=y | ||
59 | # CONFIG_PPC_DCR_NATIVE is not set | ||
60 | # CONFIG_PPC_DCR_MMIO is not set | ||
61 | CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y | ||
62 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
63 | CONFIG_CONSTRUCTORS=y | ||
64 | |||
65 | # | ||
66 | # General setup | ||
67 | # | ||
68 | CONFIG_EXPERIMENTAL=y | ||
69 | CONFIG_BROKEN_ON_SMP=y | ||
70 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
71 | CONFIG_LOCALVERSION="" | ||
72 | CONFIG_LOCALVERSION_AUTO=y | ||
73 | # CONFIG_SWAP is not set | ||
74 | CONFIG_SYSVIPC=y | ||
75 | CONFIG_SYSVIPC_SYSCTL=y | ||
76 | # CONFIG_POSIX_MQUEUE is not set | ||
77 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
78 | # CONFIG_TASKSTATS is not set | ||
79 | # CONFIG_AUDIT is not set | ||
80 | |||
81 | # | ||
82 | # RCU Subsystem | ||
83 | # | ||
84 | CONFIG_TREE_RCU=y | ||
85 | # CONFIG_TREE_PREEMPT_RCU is not set | ||
86 | # CONFIG_TINY_RCU is not set | ||
87 | # CONFIG_RCU_TRACE is not set | ||
88 | CONFIG_RCU_FANOUT=32 | ||
89 | # CONFIG_RCU_FANOUT_EXACT is not set | ||
90 | # CONFIG_TREE_RCU_TRACE is not set | ||
91 | # CONFIG_IKCONFIG is not set | ||
92 | CONFIG_LOG_BUF_SHIFT=14 | ||
93 | # CONFIG_CGROUPS is not set | ||
94 | CONFIG_SYSFS_DEPRECATED=y | ||
95 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
96 | # CONFIG_RELAY is not set | ||
97 | # CONFIG_NAMESPACES is not set | ||
98 | # CONFIG_BLK_DEV_INITRD is not set | ||
99 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
100 | CONFIG_SYSCTL=y | ||
101 | CONFIG_ANON_INODES=y | ||
102 | CONFIG_EMBEDDED=y | ||
103 | # CONFIG_SYSCTL_SYSCALL is not set | ||
104 | CONFIG_KALLSYMS=y | ||
105 | # CONFIG_KALLSYMS_ALL is not set | ||
106 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
107 | CONFIG_HOTPLUG=y | ||
108 | CONFIG_PRINTK=y | ||
109 | CONFIG_BUG=y | ||
110 | # CONFIG_ELF_CORE is not set | ||
111 | # CONFIG_BASE_FULL is not set | ||
112 | # CONFIG_FUTEX is not set | ||
113 | CONFIG_EPOLL=y | ||
114 | CONFIG_SIGNALFD=y | ||
115 | CONFIG_TIMERFD=y | ||
116 | CONFIG_EVENTFD=y | ||
117 | CONFIG_SHMEM=y | ||
118 | CONFIG_AIO=y | ||
119 | CONFIG_HAVE_PERF_EVENTS=y | ||
120 | |||
121 | # | ||
122 | # Kernel Performance Events And Counters | ||
123 | # | ||
124 | # CONFIG_PERF_EVENTS is not set | ||
125 | # CONFIG_PERF_COUNTERS is not set | ||
126 | # CONFIG_VM_EVENT_COUNTERS is not set | ||
127 | CONFIG_SLUB_DEBUG=y | ||
128 | CONFIG_COMPAT_BRK=y | ||
129 | # CONFIG_SLAB is not set | ||
130 | CONFIG_SLUB=y | ||
131 | # CONFIG_SLOB is not set | ||
132 | # CONFIG_PROFILING is not set | ||
133 | CONFIG_HAVE_OPROFILE=y | ||
134 | # CONFIG_KPROBES is not set | ||
135 | CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y | ||
136 | CONFIG_HAVE_IOREMAP_PROT=y | ||
137 | CONFIG_HAVE_KPROBES=y | ||
138 | CONFIG_HAVE_KRETPROBES=y | ||
139 | CONFIG_HAVE_ARCH_TRACEHOOK=y | ||
140 | CONFIG_HAVE_DMA_ATTRS=y | ||
141 | CONFIG_HAVE_CLK=y | ||
142 | CONFIG_HAVE_DMA_API_DEBUG=y | ||
143 | |||
144 | # | ||
145 | # GCOV-based kernel profiling | ||
146 | # | ||
147 | # CONFIG_SLOW_WORK is not set | ||
148 | # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set | ||
149 | CONFIG_SLABINFO=y | ||
150 | CONFIG_BASE_SMALL=1 | ||
151 | CONFIG_MODULES=y | ||
152 | # CONFIG_MODULE_FORCE_LOAD is not set | ||
153 | CONFIG_MODULE_UNLOAD=y | ||
154 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
155 | # CONFIG_MODVERSIONS is not set | ||
156 | CONFIG_MODULE_SRCVERSION_ALL=y | ||
157 | CONFIG_BLOCK=y | ||
158 | CONFIG_LBDAF=y | ||
159 | # CONFIG_BLK_DEV_BSG is not set | ||
160 | # CONFIG_BLK_DEV_INTEGRITY is not set | ||
161 | |||
162 | # | ||
163 | # IO Schedulers | ||
164 | # | ||
165 | CONFIG_IOSCHED_NOOP=y | ||
166 | CONFIG_IOSCHED_DEADLINE=y | ||
167 | # CONFIG_IOSCHED_CFQ is not set | ||
168 | CONFIG_DEFAULT_DEADLINE=y | ||
169 | # CONFIG_DEFAULT_CFQ is not set | ||
170 | # CONFIG_DEFAULT_NOOP is not set | ||
171 | CONFIG_DEFAULT_IOSCHED="deadline" | ||
172 | # CONFIG_INLINE_SPIN_TRYLOCK is not set | ||
173 | # CONFIG_INLINE_SPIN_TRYLOCK_BH is not set | ||
174 | # CONFIG_INLINE_SPIN_LOCK is not set | ||
175 | # CONFIG_INLINE_SPIN_LOCK_BH is not set | ||
176 | # CONFIG_INLINE_SPIN_LOCK_IRQ is not set | ||
177 | # CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set | ||
178 | CONFIG_INLINE_SPIN_UNLOCK=y | ||
179 | # CONFIG_INLINE_SPIN_UNLOCK_BH is not set | ||
180 | CONFIG_INLINE_SPIN_UNLOCK_IRQ=y | ||
181 | # CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set | ||
182 | # CONFIG_INLINE_READ_TRYLOCK is not set | ||
183 | # CONFIG_INLINE_READ_LOCK is not set | ||
184 | # CONFIG_INLINE_READ_LOCK_BH is not set | ||
185 | # CONFIG_INLINE_READ_LOCK_IRQ is not set | ||
186 | # CONFIG_INLINE_READ_LOCK_IRQSAVE is not set | ||
187 | CONFIG_INLINE_READ_UNLOCK=y | ||
188 | # CONFIG_INLINE_READ_UNLOCK_BH is not set | ||
189 | CONFIG_INLINE_READ_UNLOCK_IRQ=y | ||
190 | # CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set | ||
191 | # CONFIG_INLINE_WRITE_TRYLOCK is not set | ||
192 | # CONFIG_INLINE_WRITE_LOCK is not set | ||
193 | # CONFIG_INLINE_WRITE_LOCK_BH is not set | ||
194 | # CONFIG_INLINE_WRITE_LOCK_IRQ is not set | ||
195 | # CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set | ||
196 | CONFIG_INLINE_WRITE_UNLOCK=y | ||
197 | # CONFIG_INLINE_WRITE_UNLOCK_BH is not set | ||
198 | CONFIG_INLINE_WRITE_UNLOCK_IRQ=y | ||
199 | # CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set | ||
200 | # CONFIG_MUTEX_SPIN_ON_OWNER is not set | ||
201 | # CONFIG_FREEZER is not set | ||
202 | |||
203 | # | ||
204 | # Platform support | ||
205 | # | ||
206 | # CONFIG_PPC_CELL is not set | ||
207 | # CONFIG_PPC_CELL_NATIVE is not set | ||
208 | CONFIG_CPM1=y | ||
209 | # CONFIG_MPC8XXFADS is not set | ||
210 | # CONFIG_MPC86XADS is not set | ||
211 | # CONFIG_MPC885ADS is not set | ||
212 | # CONFIG_PPC_EP88XC is not set | ||
213 | # CONFIG_PPC_ADDER875 is not set | ||
214 | # CONFIG_PPC_MGSUVD is not set | ||
215 | CONFIG_TQM8XX=y | ||
216 | |||
217 | # | ||
218 | # MPC8xx CPM Options | ||
219 | # | ||
220 | |||
221 | # | ||
222 | # Generic MPC8xx Options | ||
223 | # | ||
224 | CONFIG_8xx_COPYBACK=y | ||
225 | # CONFIG_8xx_GPIO is not set | ||
226 | # CONFIG_8xx_CPU6 is not set | ||
227 | # CONFIG_8xx_CPU15 is not set | ||
228 | CONFIG_NO_UCODE_PATCH=y | ||
229 | # CONFIG_USB_SOF_UCODE_PATCH is not set | ||
230 | # CONFIG_I2C_SPI_UCODE_PATCH is not set | ||
231 | # CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set | ||
232 | # CONFIG_PQ2ADS is not set | ||
233 | # CONFIG_IPIC is not set | ||
234 | # CONFIG_MPIC is not set | ||
235 | # CONFIG_MPIC_WEIRD is not set | ||
236 | # CONFIG_PPC_I8259 is not set | ||
237 | # CONFIG_PPC_RTAS is not set | ||
238 | # CONFIG_MMIO_NVRAM is not set | ||
239 | # CONFIG_PPC_MPC106 is not set | ||
240 | # CONFIG_PPC_970_NAP is not set | ||
241 | # CONFIG_PPC_INDIRECT_IO is not set | ||
242 | # CONFIG_GENERIC_IOMAP is not set | ||
243 | # CONFIG_CPU_FREQ is not set | ||
244 | # CONFIG_QUICC_ENGINE is not set | ||
245 | # CONFIG_FSL_ULI1575 is not set | ||
246 | CONFIG_CPM=y | ||
247 | # CONFIG_SIMPLE_GPIO is not set | ||
248 | |||
249 | # | ||
250 | # Kernel options | ||
251 | # | ||
252 | # CONFIG_HIGHMEM is not set | ||
253 | CONFIG_TICK_ONESHOT=y | ||
254 | CONFIG_NO_HZ=y | ||
255 | CONFIG_HIGH_RES_TIMERS=y | ||
256 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | ||
257 | CONFIG_HZ_100=y | ||
258 | # CONFIG_HZ_250 is not set | ||
259 | # CONFIG_HZ_300 is not set | ||
260 | # CONFIG_HZ_1000 is not set | ||
261 | CONFIG_HZ=100 | ||
262 | CONFIG_SCHED_HRTICK=y | ||
263 | CONFIG_PREEMPT_NONE=y | ||
264 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
265 | # CONFIG_PREEMPT is not set | ||
266 | CONFIG_BINFMT_ELF=y | ||
267 | # CONFIG_HAVE_AOUT is not set | ||
268 | # CONFIG_BINFMT_MISC is not set | ||
269 | # CONFIG_MATH_EMULATION is not set | ||
270 | CONFIG_8XX_MINIMAL_FPEMU=y | ||
271 | # CONFIG_IOMMU_HELPER is not set | ||
272 | # CONFIG_SWIOTLB is not set | ||
273 | CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y | ||
274 | CONFIG_ARCH_HAS_WALK_MEMORY=y | ||
275 | CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y | ||
276 | CONFIG_SPARSE_IRQ=y | ||
277 | CONFIG_MAX_ACTIVE_REGIONS=32 | ||
278 | CONFIG_ARCH_FLATMEM_ENABLE=y | ||
279 | CONFIG_ARCH_POPULATES_NODE_MAP=y | ||
280 | CONFIG_SELECT_MEMORY_MODEL=y | ||
281 | CONFIG_FLATMEM_MANUAL=y | ||
282 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
283 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
284 | CONFIG_FLATMEM=y | ||
285 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
286 | CONFIG_PAGEFLAGS_EXTENDED=y | ||
287 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
288 | CONFIG_MIGRATION=y | ||
289 | # CONFIG_PHYS_ADDR_T_64BIT is not set | ||
290 | CONFIG_ZONE_DMA_FLAG=1 | ||
291 | CONFIG_BOUNCE=y | ||
292 | CONFIG_VIRT_TO_BUS=y | ||
293 | # CONFIG_KSM is not set | ||
294 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | ||
295 | CONFIG_PPC_4K_PAGES=y | ||
296 | # CONFIG_PPC_16K_PAGES is not set | ||
297 | # CONFIG_PPC_64K_PAGES is not set | ||
298 | # CONFIG_PPC_256K_PAGES is not set | ||
299 | CONFIG_FORCE_MAX_ZONEORDER=11 | ||
300 | CONFIG_PROC_DEVICETREE=y | ||
301 | # CONFIG_CMDLINE_BOOL is not set | ||
302 | CONFIG_EXTRA_TARGETS="" | ||
303 | # CONFIG_PM is not set | ||
304 | # CONFIG_SECCOMP is not set | ||
305 | CONFIG_ISA_DMA_API=y | ||
306 | |||
307 | # | ||
308 | # Bus options | ||
309 | # | ||
310 | CONFIG_ZONE_DMA=y | ||
311 | CONFIG_NEED_DMA_MAP_STATE=y | ||
312 | CONFIG_FSL_SOC=y | ||
313 | # CONFIG_PCI is not set | ||
314 | # CONFIG_PCI_DOMAINS is not set | ||
315 | # CONFIG_PCI_SYSCALL is not set | ||
316 | # CONFIG_PCI_QSPAN is not set | ||
317 | # CONFIG_ARCH_SUPPORTS_MSI is not set | ||
318 | # CONFIG_PCCARD is not set | ||
319 | # CONFIG_HAS_RAPIDIO is not set | ||
320 | |||
321 | # | ||
322 | # Advanced setup | ||
323 | # | ||
324 | # CONFIG_ADVANCED_OPTIONS is not set | ||
325 | |||
326 | # | ||
327 | # Default settings for advanced configuration options are used | ||
328 | # | ||
329 | CONFIG_LOWMEM_SIZE=0x30000000 | ||
330 | CONFIG_PAGE_OFFSET=0xc0000000 | ||
331 | CONFIG_KERNEL_START=0xc0000000 | ||
332 | CONFIG_PHYSICAL_START=0x00000000 | ||
333 | CONFIG_TASK_SIZE=0x80000000 | ||
334 | CONFIG_CONSISTENT_SIZE=0x00200000 | ||
335 | CONFIG_NET=y | ||
336 | |||
337 | # | ||
338 | # Networking options | ||
339 | # | ||
340 | CONFIG_PACKET=y | ||
341 | CONFIG_UNIX=y | ||
342 | # CONFIG_NET_KEY is not set | ||
343 | CONFIG_INET=y | ||
344 | # CONFIG_IP_MULTICAST is not set | ||
345 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
346 | CONFIG_IP_FIB_HASH=y | ||
347 | CONFIG_IP_PNP=y | ||
348 | # CONFIG_IP_PNP_DHCP is not set | ||
349 | # CONFIG_IP_PNP_BOOTP is not set | ||
350 | # CONFIG_IP_PNP_RARP is not set | ||
351 | # CONFIG_NET_IPIP is not set | ||
352 | # CONFIG_NET_IPGRE is not set | ||
353 | # CONFIG_ARPD is not set | ||
354 | CONFIG_SYN_COOKIES=y | ||
355 | # CONFIG_INET_AH is not set | ||
356 | # CONFIG_INET_ESP is not set | ||
357 | # CONFIG_INET_IPCOMP is not set | ||
358 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
359 | # CONFIG_INET_TUNNEL is not set | ||
360 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
361 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
362 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
363 | # CONFIG_INET_LRO is not set | ||
364 | CONFIG_INET_DIAG=y | ||
365 | CONFIG_INET_TCP_DIAG=y | ||
366 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
367 | CONFIG_TCP_CONG_CUBIC=y | ||
368 | CONFIG_DEFAULT_TCP_CONG="cubic" | ||
369 | # CONFIG_TCP_MD5SIG is not set | ||
370 | # CONFIG_IPV6 is not set | ||
371 | # CONFIG_NETWORK_SECMARK is not set | ||
372 | # CONFIG_NETFILTER is not set | ||
373 | # CONFIG_IP_DCCP is not set | ||
374 | # CONFIG_IP_SCTP is not set | ||
375 | # CONFIG_RDS is not set | ||
376 | # CONFIG_TIPC is not set | ||
377 | # CONFIG_ATM is not set | ||
378 | # CONFIG_BRIDGE is not set | ||
379 | # CONFIG_NET_DSA is not set | ||
380 | # CONFIG_VLAN_8021Q is not set | ||
381 | # CONFIG_DECNET is not set | ||
382 | # CONFIG_LLC2 is not set | ||
383 | # CONFIG_IPX is not set | ||
384 | # CONFIG_ATALK is not set | ||
385 | # CONFIG_X25 is not set | ||
386 | # CONFIG_LAPB is not set | ||
387 | # CONFIG_ECONET is not set | ||
388 | # CONFIG_WAN_ROUTER is not set | ||
389 | # CONFIG_PHONET is not set | ||
390 | # CONFIG_IEEE802154 is not set | ||
391 | # CONFIG_NET_SCHED is not set | ||
392 | # CONFIG_DCB is not set | ||
393 | |||
394 | # | ||
395 | # Network testing | ||
396 | # | ||
397 | # CONFIG_NET_PKTGEN is not set | ||
398 | # CONFIG_HAMRADIO is not set | ||
399 | # CONFIG_CAN is not set | ||
400 | # CONFIG_IRDA is not set | ||
401 | # CONFIG_BT is not set | ||
402 | # CONFIG_AF_RXRPC is not set | ||
403 | # CONFIG_WIRELESS is not set | ||
404 | # CONFIG_WIMAX is not set | ||
405 | # CONFIG_RFKILL is not set | ||
406 | # CONFIG_NET_9P is not set | ||
407 | |||
408 | # | ||
409 | # Device Drivers | ||
410 | # | ||
411 | |||
412 | # | ||
413 | # Generic Driver Options | ||
414 | # | ||
415 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
416 | # CONFIG_DEVTMPFS is not set | ||
417 | CONFIG_STANDALONE=y | ||
418 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
419 | # CONFIG_FW_LOADER is not set | ||
420 | # CONFIG_DEBUG_DRIVER is not set | ||
421 | # CONFIG_DEBUG_DEVRES is not set | ||
422 | # CONFIG_SYS_HYPERVISOR is not set | ||
423 | # CONFIG_CONNECTOR is not set | ||
424 | CONFIG_MTD=y | ||
425 | # CONFIG_MTD_DEBUG is not set | ||
426 | # CONFIG_MTD_TESTS is not set | ||
427 | CONFIG_MTD_CONCAT=y | ||
428 | CONFIG_MTD_PARTITIONS=y | ||
429 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
430 | CONFIG_MTD_CMDLINE_PARTS=y | ||
431 | CONFIG_MTD_OF_PARTS=y | ||
432 | # CONFIG_MTD_AR7_PARTS is not set | ||
433 | |||
434 | # | ||
435 | # User Modules And Translation Layers | ||
436 | # | ||
437 | CONFIG_MTD_CHAR=y | ||
438 | CONFIG_MTD_BLKDEVS=y | ||
439 | CONFIG_MTD_BLOCK=y | ||
440 | # CONFIG_FTL is not set | ||
441 | # CONFIG_NFTL is not set | ||
442 | # CONFIG_INFTL is not set | ||
443 | # CONFIG_RFD_FTL is not set | ||
444 | # CONFIG_SSFDC is not set | ||
445 | # CONFIG_MTD_OOPS is not set | ||
446 | |||
447 | # | ||
448 | # RAM/ROM/Flash chip drivers | ||
449 | # | ||
450 | CONFIG_MTD_CFI=y | ||
451 | # CONFIG_MTD_JEDECPROBE is not set | ||
452 | CONFIG_MTD_GEN_PROBE=y | ||
453 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | ||
454 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
455 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
456 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
457 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
458 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
459 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
460 | CONFIG_MTD_CFI_I1=y | ||
461 | CONFIG_MTD_CFI_I2=y | ||
462 | # CONFIG_MTD_CFI_I4 is not set | ||
463 | # CONFIG_MTD_CFI_I8 is not set | ||
464 | CONFIG_MTD_CFI_INTELEXT=y | ||
465 | CONFIG_MTD_CFI_AMDSTD=y | ||
466 | # CONFIG_MTD_CFI_STAA is not set | ||
467 | CONFIG_MTD_CFI_UTIL=y | ||
468 | # CONFIG_MTD_RAM is not set | ||
469 | # CONFIG_MTD_ROM is not set | ||
470 | # CONFIG_MTD_ABSENT is not set | ||
471 | |||
472 | # | ||
473 | # Mapping drivers for chip access | ||
474 | # | ||
475 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | ||
476 | # CONFIG_MTD_PHYSMAP is not set | ||
477 | CONFIG_MTD_PHYSMAP_OF=y | ||
478 | # CONFIG_MTD_CFI_FLAGADM is not set | ||
479 | # CONFIG_MTD_PLATRAM is not set | ||
480 | |||
481 | # | ||
482 | # Self-contained MTD device drivers | ||
483 | # | ||
484 | # CONFIG_MTD_SLRAM is not set | ||
485 | # CONFIG_MTD_PHRAM is not set | ||
486 | # CONFIG_MTD_MTDRAM is not set | ||
487 | # CONFIG_MTD_BLOCK2MTD is not set | ||
488 | |||
489 | # | ||
490 | # Disk-On-Chip Device Drivers | ||
491 | # | ||
492 | # CONFIG_MTD_DOC2000 is not set | ||
493 | # CONFIG_MTD_DOC2001 is not set | ||
494 | # CONFIG_MTD_DOC2001PLUS is not set | ||
495 | # CONFIG_MTD_NAND is not set | ||
496 | # CONFIG_MTD_ONENAND is not set | ||
497 | |||
498 | # | ||
499 | # LPDDR flash memory drivers | ||
500 | # | ||
501 | # CONFIG_MTD_LPDDR is not set | ||
502 | |||
503 | # | ||
504 | # UBI - Unsorted block images | ||
505 | # | ||
506 | # CONFIG_MTD_UBI is not set | ||
507 | CONFIG_OF_FLATTREE=y | ||
508 | CONFIG_OF_DYNAMIC=y | ||
509 | CONFIG_OF_DEVICE=y | ||
510 | CONFIG_OF_MDIO=y | ||
511 | # CONFIG_PARPORT is not set | ||
512 | # CONFIG_BLK_DEV is not set | ||
513 | # CONFIG_MISC_DEVICES is not set | ||
514 | CONFIG_HAVE_IDE=y | ||
515 | # CONFIG_IDE is not set | ||
516 | |||
517 | # | ||
518 | # SCSI device support | ||
519 | # | ||
520 | # CONFIG_RAID_ATTRS is not set | ||
521 | # CONFIG_SCSI is not set | ||
522 | # CONFIG_SCSI_DMA is not set | ||
523 | # CONFIG_SCSI_NETLINK is not set | ||
524 | # CONFIG_ATA is not set | ||
525 | # CONFIG_MD is not set | ||
526 | # CONFIG_MACINTOSH_DRIVERS is not set | ||
527 | CONFIG_NETDEVICES=y | ||
528 | # CONFIG_DUMMY is not set | ||
529 | # CONFIG_BONDING is not set | ||
530 | # CONFIG_MACVLAN is not set | ||
531 | # CONFIG_EQUALIZER is not set | ||
532 | # CONFIG_TUN is not set | ||
533 | # CONFIG_VETH is not set | ||
534 | CONFIG_PHYLIB=y | ||
535 | |||
536 | # | ||
537 | # MII PHY device drivers | ||
538 | # | ||
539 | # CONFIG_MARVELL_PHY is not set | ||
540 | CONFIG_DAVICOM_PHY=y | ||
541 | # CONFIG_QSEMI_PHY is not set | ||
542 | # CONFIG_LXT_PHY is not set | ||
543 | # CONFIG_CICADA_PHY is not set | ||
544 | # CONFIG_VITESSE_PHY is not set | ||
545 | # CONFIG_SMSC_PHY is not set | ||
546 | # CONFIG_BROADCOM_PHY is not set | ||
547 | # CONFIG_ICPLUS_PHY is not set | ||
548 | # CONFIG_REALTEK_PHY is not set | ||
549 | # CONFIG_NATIONAL_PHY is not set | ||
550 | # CONFIG_STE10XP is not set | ||
551 | # CONFIG_LSI_ET1011C_PHY is not set | ||
552 | CONFIG_FIXED_PHY=y | ||
553 | # CONFIG_MDIO_BITBANG is not set | ||
554 | CONFIG_NET_ETHERNET=y | ||
555 | CONFIG_MII=y | ||
556 | # CONFIG_ETHOC is not set | ||
557 | # CONFIG_DNET is not set | ||
558 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | ||
559 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | ||
560 | # CONFIG_IBM_NEW_EMAC_TAH is not set | ||
561 | # CONFIG_IBM_NEW_EMAC_EMAC4 is not set | ||
562 | # CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set | ||
563 | # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set | ||
564 | # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set | ||
565 | # CONFIG_B44 is not set | ||
566 | # CONFIG_KS8842 is not set | ||
567 | # CONFIG_KS8851_MLL is not set | ||
568 | # CONFIG_XILINX_EMACLITE is not set | ||
569 | CONFIG_FS_ENET=y | ||
570 | CONFIG_FS_ENET_HAS_SCC=y | ||
571 | CONFIG_FS_ENET_HAS_FEC=y | ||
572 | CONFIG_FS_ENET_MDIO_FEC=y | ||
573 | # CONFIG_NETDEV_1000 is not set | ||
574 | # CONFIG_NETDEV_10000 is not set | ||
575 | # CONFIG_WLAN is not set | ||
576 | |||
577 | # | ||
578 | # Enable WiMAX (Networking options) to see the WiMAX drivers | ||
579 | # | ||
580 | # CONFIG_WAN is not set | ||
581 | # CONFIG_PPP is not set | ||
582 | # CONFIG_SLIP is not set | ||
583 | # CONFIG_NETCONSOLE is not set | ||
584 | # CONFIG_NETPOLL is not set | ||
585 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
586 | # CONFIG_ISDN is not set | ||
587 | # CONFIG_PHONE is not set | ||
588 | |||
589 | # | ||
590 | # Input device support | ||
591 | # | ||
592 | # CONFIG_INPUT is not set | ||
593 | |||
594 | # | ||
595 | # Hardware I/O ports | ||
596 | # | ||
597 | # CONFIG_SERIO is not set | ||
598 | # CONFIG_GAMEPORT is not set | ||
599 | |||
600 | # | ||
601 | # Character devices | ||
602 | # | ||
603 | # CONFIG_VT is not set | ||
604 | CONFIG_DEVKMEM=y | ||
605 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
606 | |||
607 | # | ||
608 | # Serial drivers | ||
609 | # | ||
610 | # CONFIG_SERIAL_8250 is not set | ||
611 | |||
612 | # | ||
613 | # Non-8250 serial port support | ||
614 | # | ||
615 | # CONFIG_SERIAL_UARTLITE is not set | ||
616 | CONFIG_SERIAL_CORE=y | ||
617 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
618 | CONFIG_SERIAL_CPM=y | ||
619 | CONFIG_SERIAL_CPM_CONSOLE=y | ||
620 | # CONFIG_SERIAL_TIMBERDALE is not set | ||
621 | # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set | ||
622 | CONFIG_UNIX98_PTYS=y | ||
623 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | ||
624 | # CONFIG_LEGACY_PTYS is not set | ||
625 | # CONFIG_HVC_UDBG is not set | ||
626 | # CONFIG_IPMI_HANDLER is not set | ||
627 | CONFIG_HW_RANDOM=y | ||
628 | # CONFIG_HW_RANDOM_TIMERIOMEM is not set | ||
629 | # CONFIG_NVRAM is not set | ||
630 | CONFIG_GEN_RTC=y | ||
631 | # CONFIG_GEN_RTC_X is not set | ||
632 | # CONFIG_R3964 is not set | ||
633 | # CONFIG_RAW_DRIVER is not set | ||
634 | # CONFIG_TCG_TPM is not set | ||
635 | # CONFIG_I2C is not set | ||
636 | # CONFIG_SPI is not set | ||
637 | |||
638 | # | ||
639 | # PPS support | ||
640 | # | ||
641 | # CONFIG_PPS is not set | ||
642 | CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y | ||
643 | # CONFIG_GPIOLIB is not set | ||
644 | # CONFIG_W1 is not set | ||
645 | # CONFIG_POWER_SUPPLY is not set | ||
646 | # CONFIG_HWMON is not set | ||
647 | # CONFIG_THERMAL is not set | ||
648 | # CONFIG_WATCHDOG is not set | ||
649 | CONFIG_SSB_POSSIBLE=y | ||
650 | |||
651 | # | ||
652 | # Sonics Silicon Backplane | ||
653 | # | ||
654 | # CONFIG_SSB is not set | ||
655 | |||
656 | # | ||
657 | # Multifunction device drivers | ||
658 | # | ||
659 | # CONFIG_MFD_CORE is not set | ||
660 | # CONFIG_MFD_SM501 is not set | ||
661 | # CONFIG_HTC_PASIC3 is not set | ||
662 | # CONFIG_MFD_TMIO is not set | ||
663 | # CONFIG_REGULATOR is not set | ||
664 | # CONFIG_MEDIA_SUPPORT is not set | ||
665 | |||
666 | # | ||
667 | # Graphics support | ||
668 | # | ||
669 | # CONFIG_VGASTATE is not set | ||
670 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
671 | # CONFIG_FB is not set | ||
672 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
673 | |||
674 | # | ||
675 | # Display device support | ||
676 | # | ||
677 | # CONFIG_DISPLAY_SUPPORT is not set | ||
678 | # CONFIG_SOUND is not set | ||
679 | # CONFIG_USB_SUPPORT is not set | ||
680 | # CONFIG_MMC is not set | ||
681 | # CONFIG_MEMSTICK is not set | ||
682 | # CONFIG_NEW_LEDS is not set | ||
683 | # CONFIG_ACCESSIBILITY is not set | ||
684 | # CONFIG_EDAC is not set | ||
685 | # CONFIG_RTC_CLASS is not set | ||
686 | # CONFIG_DMADEVICES is not set | ||
687 | # CONFIG_AUXDISPLAY is not set | ||
688 | # CONFIG_UIO is not set | ||
689 | |||
690 | # | ||
691 | # TI VLYNQ | ||
692 | # | ||
693 | # CONFIG_STAGING is not set | ||
694 | |||
695 | # | ||
696 | # File systems | ||
697 | # | ||
698 | # CONFIG_EXT2_FS is not set | ||
699 | # CONFIG_EXT3_FS is not set | ||
700 | # CONFIG_EXT4_FS is not set | ||
701 | # CONFIG_REISERFS_FS is not set | ||
702 | # CONFIG_JFS_FS is not set | ||
703 | # CONFIG_FS_POSIX_ACL is not set | ||
704 | # CONFIG_XFS_FS is not set | ||
705 | # CONFIG_GFS2_FS is not set | ||
706 | # CONFIG_OCFS2_FS is not set | ||
707 | # CONFIG_BTRFS_FS is not set | ||
708 | # CONFIG_NILFS2_FS is not set | ||
709 | CONFIG_FILE_LOCKING=y | ||
710 | CONFIG_FSNOTIFY=y | ||
711 | # CONFIG_DNOTIFY is not set | ||
712 | # CONFIG_INOTIFY is not set | ||
713 | CONFIG_INOTIFY_USER=y | ||
714 | # CONFIG_QUOTA is not set | ||
715 | # CONFIG_AUTOFS_FS is not set | ||
716 | # CONFIG_AUTOFS4_FS is not set | ||
717 | # CONFIG_FUSE_FS is not set | ||
718 | |||
719 | # | ||
720 | # Caches | ||
721 | # | ||
722 | # CONFIG_FSCACHE is not set | ||
723 | |||
724 | # | ||
725 | # CD-ROM/DVD Filesystems | ||
726 | # | ||
727 | # CONFIG_ISO9660_FS is not set | ||
728 | # CONFIG_UDF_FS is not set | ||
729 | |||
730 | # | ||
731 | # DOS/FAT/NT Filesystems | ||
732 | # | ||
733 | # CONFIG_MSDOS_FS is not set | ||
734 | # CONFIG_VFAT_FS is not set | ||
735 | # CONFIG_NTFS_FS is not set | ||
736 | |||
737 | # | ||
738 | # Pseudo filesystems | ||
739 | # | ||
740 | CONFIG_PROC_FS=y | ||
741 | # CONFIG_PROC_KCORE is not set | ||
742 | CONFIG_PROC_SYSCTL=y | ||
743 | CONFIG_PROC_PAGE_MONITOR=y | ||
744 | CONFIG_SYSFS=y | ||
745 | CONFIG_TMPFS=y | ||
746 | # CONFIG_TMPFS_POSIX_ACL is not set | ||
747 | # CONFIG_HUGETLB_PAGE is not set | ||
748 | # CONFIG_CONFIGFS_FS is not set | ||
749 | CONFIG_MISC_FILESYSTEMS=y | ||
750 | # CONFIG_ADFS_FS is not set | ||
751 | # CONFIG_AFFS_FS is not set | ||
752 | # CONFIG_HFS_FS is not set | ||
753 | # CONFIG_HFSPLUS_FS is not set | ||
754 | # CONFIG_BEFS_FS is not set | ||
755 | # CONFIG_BFS_FS is not set | ||
756 | # CONFIG_EFS_FS is not set | ||
757 | # CONFIG_JFFS2_FS is not set | ||
758 | # CONFIG_LOGFS is not set | ||
759 | CONFIG_CRAMFS=y | ||
760 | # CONFIG_SQUASHFS is not set | ||
761 | # CONFIG_VXFS_FS is not set | ||
762 | # CONFIG_MINIX_FS is not set | ||
763 | # CONFIG_OMFS_FS is not set | ||
764 | # CONFIG_HPFS_FS is not set | ||
765 | # CONFIG_QNX4FS_FS is not set | ||
766 | # CONFIG_ROMFS_FS is not set | ||
767 | # CONFIG_SYSV_FS is not set | ||
768 | # CONFIG_UFS_FS is not set | ||
769 | CONFIG_NETWORK_FILESYSTEMS=y | ||
770 | CONFIG_NFS_FS=y | ||
771 | CONFIG_NFS_V3=y | ||
772 | # CONFIG_NFS_V3_ACL is not set | ||
773 | # CONFIG_NFS_V4 is not set | ||
774 | CONFIG_ROOT_NFS=y | ||
775 | # CONFIG_NFSD is not set | ||
776 | CONFIG_LOCKD=y | ||
777 | CONFIG_LOCKD_V4=y | ||
778 | CONFIG_NFS_COMMON=y | ||
779 | CONFIG_SUNRPC=y | ||
780 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
781 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
782 | # CONFIG_SMB_FS is not set | ||
783 | # CONFIG_CIFS is not set | ||
784 | # CONFIG_NCP_FS is not set | ||
785 | # CONFIG_CODA_FS is not set | ||
786 | # CONFIG_AFS_FS is not set | ||
787 | |||
788 | # | ||
789 | # Partition Types | ||
790 | # | ||
791 | CONFIG_PARTITION_ADVANCED=y | ||
792 | # CONFIG_ACORN_PARTITION is not set | ||
793 | # CONFIG_OSF_PARTITION is not set | ||
794 | # CONFIG_AMIGA_PARTITION is not set | ||
795 | # CONFIG_ATARI_PARTITION is not set | ||
796 | # CONFIG_MAC_PARTITION is not set | ||
797 | CONFIG_MSDOS_PARTITION=y | ||
798 | # CONFIG_BSD_DISKLABEL is not set | ||
799 | # CONFIG_MINIX_SUBPARTITION is not set | ||
800 | # CONFIG_SOLARIS_X86_PARTITION is not set | ||
801 | # CONFIG_UNIXWARE_DISKLABEL is not set | ||
802 | # CONFIG_LDM_PARTITION is not set | ||
803 | # CONFIG_SGI_PARTITION is not set | ||
804 | # CONFIG_ULTRIX_PARTITION is not set | ||
805 | # CONFIG_SUN_PARTITION is not set | ||
806 | # CONFIG_KARMA_PARTITION is not set | ||
807 | # CONFIG_EFI_PARTITION is not set | ||
808 | # CONFIG_SYSV68_PARTITION is not set | ||
809 | # CONFIG_NLS is not set | ||
810 | # CONFIG_DLM is not set | ||
811 | # CONFIG_BINARY_PRINTF is not set | ||
812 | |||
813 | # | ||
814 | # Library routines | ||
815 | # | ||
816 | CONFIG_GENERIC_FIND_LAST_BIT=y | ||
817 | # CONFIG_CRC_CCITT is not set | ||
818 | # CONFIG_CRC16 is not set | ||
819 | # CONFIG_CRC_T10DIF is not set | ||
820 | # CONFIG_CRC_ITU_T is not set | ||
821 | # CONFIG_CRC32 is not set | ||
822 | # CONFIG_CRC7 is not set | ||
823 | # CONFIG_LIBCRC32C is not set | ||
824 | CONFIG_ZLIB_INFLATE=y | ||
825 | CONFIG_HAS_IOMEM=y | ||
826 | CONFIG_HAS_IOPORT=y | ||
827 | CONFIG_HAS_DMA=y | ||
828 | CONFIG_HAVE_LMB=y | ||
829 | CONFIG_NLATTR=y | ||
830 | CONFIG_GENERIC_ATOMIC64=y | ||
831 | |||
832 | # | ||
833 | # Kernel hacking | ||
834 | # | ||
835 | # CONFIG_PRINTK_TIME is not set | ||
836 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
837 | CONFIG_ENABLE_MUST_CHECK=y | ||
838 | CONFIG_FRAME_WARN=1024 | ||
839 | CONFIG_MAGIC_SYSRQ=y | ||
840 | # CONFIG_STRIP_ASM_SYMS is not set | ||
841 | # CONFIG_UNUSED_SYMBOLS is not set | ||
842 | # CONFIG_DEBUG_FS is not set | ||
843 | # CONFIG_HEADERS_CHECK is not set | ||
844 | CONFIG_DEBUG_KERNEL=y | ||
845 | # CONFIG_DEBUG_SHIRQ is not set | ||
846 | CONFIG_DETECT_SOFTLOCKUP=y | ||
847 | # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set | ||
848 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 | ||
849 | CONFIG_DETECT_HUNG_TASK=y | ||
850 | # CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set | ||
851 | CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 | ||
852 | CONFIG_SCHED_DEBUG=y | ||
853 | # CONFIG_SCHEDSTATS is not set | ||
854 | # CONFIG_TIMER_STATS is not set | ||
855 | # CONFIG_DEBUG_OBJECTS is not set | ||
856 | # CONFIG_SLUB_DEBUG_ON is not set | ||
857 | # CONFIG_SLUB_STATS is not set | ||
858 | # CONFIG_DEBUG_KMEMLEAK is not set | ||
859 | # CONFIG_DEBUG_SPINLOCK is not set | ||
860 | # CONFIG_DEBUG_MUTEXES is not set | ||
861 | # CONFIG_DEBUG_LOCK_ALLOC is not set | ||
862 | # CONFIG_PROVE_LOCKING is not set | ||
863 | # CONFIG_LOCK_STAT is not set | ||
864 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | ||
865 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | ||
866 | # CONFIG_DEBUG_KOBJECT is not set | ||
867 | CONFIG_DEBUG_BUGVERBOSE=y | ||
868 | CONFIG_DEBUG_INFO=y | ||
869 | # CONFIG_DEBUG_VM is not set | ||
870 | # CONFIG_DEBUG_WRITECOUNT is not set | ||
871 | # CONFIG_DEBUG_MEMORY_INIT is not set | ||
872 | # CONFIG_DEBUG_LIST is not set | ||
873 | # CONFIG_DEBUG_SG is not set | ||
874 | # CONFIG_DEBUG_NOTIFIERS is not set | ||
875 | # CONFIG_DEBUG_CREDENTIALS is not set | ||
876 | # CONFIG_RCU_TORTURE_TEST is not set | ||
877 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
878 | # CONFIG_BACKTRACE_SELF_TEST is not set | ||
879 | # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set | ||
880 | # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set | ||
881 | # CONFIG_FAULT_INJECTION is not set | ||
882 | # CONFIG_LATENCYTOP is not set | ||
883 | # CONFIG_SYSCTL_SYSCALL_CHECK is not set | ||
884 | # CONFIG_DEBUG_PAGEALLOC is not set | ||
885 | CONFIG_HAVE_FUNCTION_TRACER=y | ||
886 | CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y | ||
887 | CONFIG_HAVE_DYNAMIC_FTRACE=y | ||
888 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y | ||
889 | CONFIG_TRACING_SUPPORT=y | ||
890 | CONFIG_FTRACE=y | ||
891 | # CONFIG_FUNCTION_TRACER is not set | ||
892 | # CONFIG_IRQSOFF_TRACER is not set | ||
893 | # CONFIG_SCHED_TRACER is not set | ||
894 | # CONFIG_ENABLE_DEFAULT_TRACERS is not set | ||
895 | # CONFIG_BOOT_TRACER is not set | ||
896 | CONFIG_BRANCH_PROFILE_NONE=y | ||
897 | # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set | ||
898 | # CONFIG_PROFILE_ALL_BRANCHES is not set | ||
899 | # CONFIG_STACK_TRACER is not set | ||
900 | # CONFIG_KMEMTRACE is not set | ||
901 | # CONFIG_WORKQUEUE_TRACER is not set | ||
902 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
903 | # CONFIG_DMA_API_DEBUG is not set | ||
904 | # CONFIG_SAMPLES is not set | ||
905 | CONFIG_HAVE_ARCH_KGDB=y | ||
906 | # CONFIG_KGDB is not set | ||
907 | # CONFIG_PPC_DISABLE_WERROR is not set | ||
908 | CONFIG_PPC_WERROR=y | ||
909 | CONFIG_PRINT_STACK_DEPTH=64 | ||
910 | # CONFIG_DEBUG_STACKOVERFLOW is not set | ||
911 | # CONFIG_DEBUG_STACK_USAGE is not set | ||
912 | # CONFIG_CODE_PATCHING_SELFTEST is not set | ||
913 | # CONFIG_FTR_FIXUP_SELFTEST is not set | ||
914 | # CONFIG_MSI_BITMAP_SELFTEST is not set | ||
915 | # CONFIG_XMON is not set | ||
916 | # CONFIG_IRQSTACKS is not set | ||
917 | # CONFIG_BDI_SWITCH is not set | ||
918 | # CONFIG_PPC_EARLY_DEBUG is not set | ||
919 | |||
920 | # | ||
921 | # Security options | ||
922 | # | ||
923 | # CONFIG_KEYS is not set | ||
924 | # CONFIG_SECURITY is not set | ||
925 | # CONFIG_SECURITYFS is not set | ||
926 | # CONFIG_DEFAULT_SECURITY_SELINUX is not set | ||
927 | # CONFIG_DEFAULT_SECURITY_SMACK is not set | ||
928 | # CONFIG_DEFAULT_SECURITY_TOMOYO is not set | ||
929 | CONFIG_DEFAULT_SECURITY_DAC=y | ||
930 | CONFIG_DEFAULT_SECURITY="" | ||
931 | # CONFIG_CRYPTO is not set | ||
932 | CONFIG_PPC_CLOCK=y | ||
933 | CONFIG_PPC_LIB_RHEAP=y | ||
934 | # CONFIG_VIRTUALIZATION is not set | ||
diff --git a/arch/powerpc/include/asm/abs_addr.h b/arch/powerpc/include/asm/abs_addr.h index 9a846efe6382..5ab0b71531be 100644 --- a/arch/powerpc/include/asm/abs_addr.h +++ b/arch/powerpc/include/asm/abs_addr.h | |||
@@ -69,7 +69,7 @@ static inline unsigned long phys_to_abs(unsigned long pa) | |||
69 | * Legacy iSeries Hypervisor calls | 69 | * Legacy iSeries Hypervisor calls |
70 | */ | 70 | */ |
71 | #define iseries_hv_addr(virtaddr) \ | 71 | #define iseries_hv_addr(virtaddr) \ |
72 | (0x8000000000000000 | virt_to_abs(virtaddr)) | 72 | (0x8000000000000000UL | virt_to_abs(virtaddr)) |
73 | 73 | ||
74 | #endif /* __KERNEL__ */ | 74 | #endif /* __KERNEL__ */ |
75 | #endif /* _ASM_POWERPC_ABS_ADDR_H */ | 75 | #endif /* _ASM_POWERPC_ABS_ADDR_H */ |
diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h index 2048a6aeea91..decad950f11a 100644 --- a/arch/powerpc/include/asm/asm-compat.h +++ b/arch/powerpc/include/asm/asm-compat.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #define PPC_STLCX stringify_in_c(stdcx.) | 30 | #define PPC_STLCX stringify_in_c(stdcx.) |
31 | #define PPC_CNTLZL stringify_in_c(cntlzd) | 31 | #define PPC_CNTLZL stringify_in_c(cntlzd) |
32 | #define PPC_LR_STKOFF 16 | 32 | #define PPC_LR_STKOFF 16 |
33 | #define PPC_MIN_STKFRM 112 | ||
33 | 34 | ||
34 | /* Move to CR, single-entry optimized version. Only available | 35 | /* Move to CR, single-entry optimized version. Only available |
35 | * on POWER4 and later. | 36 | * on POWER4 and later. |
@@ -55,6 +56,7 @@ | |||
55 | #define PPC_CNTLZL stringify_in_c(cntlzw) | 56 | #define PPC_CNTLZL stringify_in_c(cntlzw) |
56 | #define PPC_MTOCRF stringify_in_c(mtcrf) | 57 | #define PPC_MTOCRF stringify_in_c(mtcrf) |
57 | #define PPC_LR_STKOFF 4 | 58 | #define PPC_LR_STKOFF 4 |
59 | #define PPC_MIN_STKFRM 16 | ||
58 | 60 | ||
59 | #endif | 61 | #endif |
60 | 62 | ||
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index b0b21134f61a..5e2e2cfcc81b 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h | |||
@@ -517,6 +517,10 @@ static inline int cpu_has_feature(unsigned long feature) | |||
517 | & feature); | 517 | & feature); |
518 | } | 518 | } |
519 | 519 | ||
520 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
521 | #define HBP_NUM 1 | ||
522 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
523 | |||
520 | #endif /* !__ASSEMBLY__ */ | 524 | #endif /* !__ASSEMBLY__ */ |
521 | 525 | ||
522 | #endif /* __KERNEL__ */ | 526 | #endif /* __KERNEL__ */ |
diff --git a/arch/powerpc/include/asm/dbell.h b/arch/powerpc/include/asm/dbell.h index 501189a543d1..0893ab9343a6 100644 --- a/arch/powerpc/include/asm/dbell.h +++ b/arch/powerpc/include/asm/dbell.h | |||
@@ -27,10 +27,10 @@ enum ppc_dbell { | |||
27 | PPC_G_DBELL_MC = 4, /* guest mcheck doorbell */ | 27 | PPC_G_DBELL_MC = 4, /* guest mcheck doorbell */ |
28 | }; | 28 | }; |
29 | 29 | ||
30 | #ifdef CONFIG_SMP | 30 | extern void doorbell_message_pass(int target, int msg); |
31 | extern unsigned long dbell_smp_message[NR_CPUS]; | 31 | extern void doorbell_exception(struct pt_regs *regs); |
32 | extern void smp_dbell_message_pass(int target, int msg); | 32 | extern void doorbell_check_self(void); |
33 | #endif | 33 | extern void doorbell_setup_this_cpu(void); |
34 | 34 | ||
35 | static inline void ppc_msgsnd(enum ppc_dbell type, u32 flags, u32 tag) | 35 | static inline void ppc_msgsnd(enum ppc_dbell type, u32 flags, u32 tag) |
36 | { | 36 | { |
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index 5119b7db3142..de03ca58db5d 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h | |||
@@ -74,6 +74,7 @@ | |||
74 | #define H_NOT_ENOUGH_RESOURCES -44 | 74 | #define H_NOT_ENOUGH_RESOURCES -44 |
75 | #define H_R_STATE -45 | 75 | #define H_R_STATE -45 |
76 | #define H_RESCINDEND -46 | 76 | #define H_RESCINDEND -46 |
77 | #define H_MULTI_THREADS_ACTIVE -9005 | ||
77 | 78 | ||
78 | 79 | ||
79 | /* Long Busy is a condition that can be returned by the firmware | 80 | /* Long Busy is a condition that can be returned by the firmware |
diff --git a/arch/powerpc/include/asm/hw_breakpoint.h b/arch/powerpc/include/asm/hw_breakpoint.h new file mode 100644 index 000000000000..1c33ec17ca36 --- /dev/null +++ b/arch/powerpc/include/asm/hw_breakpoint.h | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * PowerPC BookIII S hardware breakpoint definitions | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | * | ||
18 | * Copyright 2010, IBM Corporation. | ||
19 | * Author: K.Prasad <prasad@linux.vnet.ibm.com> | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H | ||
24 | #define _PPC_BOOK3S_64_HW_BREAKPOINT_H | ||
25 | |||
26 | #ifdef __KERNEL__ | ||
27 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
28 | |||
29 | struct arch_hw_breakpoint { | ||
30 | bool extraneous_interrupt; | ||
31 | u8 len; /* length of the target data symbol */ | ||
32 | int type; | ||
33 | unsigned long address; | ||
34 | }; | ||
35 | |||
36 | #include <linux/kdebug.h> | ||
37 | #include <asm/reg.h> | ||
38 | #include <asm/system.h> | ||
39 | |||
40 | struct perf_event; | ||
41 | struct pmu; | ||
42 | struct perf_sample_data; | ||
43 | |||
44 | #define HW_BREAKPOINT_ALIGN 0x7 | ||
45 | /* Maximum permissible length of any HW Breakpoint */ | ||
46 | #define HW_BREAKPOINT_LEN 0x8 | ||
47 | |||
48 | extern int hw_breakpoint_slots(int type); | ||
49 | extern int arch_bp_generic_fields(int type, int *gen_bp_type); | ||
50 | extern int arch_check_bp_in_kernelspace(struct perf_event *bp); | ||
51 | extern int arch_validate_hwbkpt_settings(struct perf_event *bp); | ||
52 | extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused, | ||
53 | unsigned long val, void *data); | ||
54 | int arch_install_hw_breakpoint(struct perf_event *bp); | ||
55 | void arch_uninstall_hw_breakpoint(struct perf_event *bp); | ||
56 | void hw_breakpoint_pmu_read(struct perf_event *bp); | ||
57 | extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk); | ||
58 | |||
59 | extern struct pmu perf_ops_bp; | ||
60 | extern void ptrace_triggered(struct perf_event *bp, int nmi, | ||
61 | struct perf_sample_data *data, struct pt_regs *regs); | ||
62 | static inline void hw_breakpoint_disable(void) | ||
63 | { | ||
64 | set_dabr(0); | ||
65 | } | ||
66 | extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs); | ||
67 | |||
68 | #else /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
69 | static inline void hw_breakpoint_disable(void) { } | ||
70 | static inline void thread_change_pc(struct task_struct *tsk, | ||
71 | struct pt_regs *regs) { } | ||
72 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
73 | #endif /* __KERNEL__ */ | ||
74 | #endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */ | ||
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 9f0fc9e6ce0d..adc8e6cdf339 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h | |||
@@ -266,6 +266,7 @@ struct machdep_calls { | |||
266 | void (*suspend_disable_irqs)(void); | 266 | void (*suspend_disable_irqs)(void); |
267 | void (*suspend_enable_irqs)(void); | 267 | void (*suspend_enable_irqs)(void); |
268 | #endif | 268 | #endif |
269 | int (*suspend_disable_cpu)(void); | ||
269 | 270 | ||
270 | #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE | 271 | #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE |
271 | ssize_t (*cpu_probe)(const char *, size_t); | 272 | ssize_t (*cpu_probe)(const char *, size_t); |
@@ -277,6 +278,7 @@ extern void e500_idle(void); | |||
277 | extern void power4_idle(void); | 278 | extern void power4_idle(void); |
278 | extern void power4_cpu_offline_powersave(void); | 279 | extern void power4_cpu_offline_powersave(void); |
279 | extern void ppc6xx_idle(void); | 280 | extern void ppc6xx_idle(void); |
281 | extern void book3e_idle(void); | ||
280 | 282 | ||
281 | /* | 283 | /* |
282 | * ppc_md contains a copy of the machine description structure for the | 284 | * ppc_md contains a copy of the machine description structure for the |
@@ -366,8 +368,5 @@ static inline void log_error(char *buf, unsigned int err_type, int fatal) | |||
366 | #define machine_late_initcall(mach,fn) __define_machine_initcall(mach,"7",fn,7) | 368 | #define machine_late_initcall(mach,fn) __define_machine_initcall(mach,"7",fn,7) |
367 | #define machine_late_initcall_sync(mach,fn) __define_machine_initcall(mach,"7s",fn,7s) | 369 | #define machine_late_initcall_sync(mach,fn) __define_machine_initcall(mach,"7s",fn,7s) |
368 | 370 | ||
369 | void generic_suspend_disable_irqs(void); | ||
370 | void generic_suspend_enable_irqs(void); | ||
371 | |||
372 | #endif /* __KERNEL__ */ | 371 | #endif /* __KERNEL__ */ |
373 | #endif /* _ASM_POWERPC_MACHDEP_H */ | 372 | #endif /* _ASM_POWERPC_MACHDEP_H */ |
diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/mmu-book3e.h index 74695816205c..87a1d787c5b6 100644 --- a/arch/powerpc/include/asm/mmu-book3e.h +++ b/arch/powerpc/include/asm/mmu-book3e.h | |||
@@ -193,6 +193,10 @@ struct mmu_psize_def | |||
193 | { | 193 | { |
194 | unsigned int shift; /* number of bits */ | 194 | unsigned int shift; /* number of bits */ |
195 | unsigned int enc; /* PTE encoding */ | 195 | unsigned int enc; /* PTE encoding */ |
196 | unsigned int ind; /* Corresponding indirect page size shift */ | ||
197 | unsigned int flags; | ||
198 | #define MMU_PAGE_SIZE_DIRECT 0x1 /* Supported as a direct size */ | ||
199 | #define MMU_PAGE_SIZE_INDIRECT 0x2 /* Supported as an indirect size */ | ||
196 | }; | 200 | }; |
197 | extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; | 201 | extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; |
198 | 202 | ||
diff --git a/arch/powerpc/include/asm/mpc5121.h b/arch/powerpc/include/asm/mpc5121.h index e6a30bb1d16a..8c0ab2ca689c 100644 --- a/arch/powerpc/include/asm/mpc5121.h +++ b/arch/powerpc/include/asm/mpc5121.h | |||
@@ -21,4 +21,36 @@ struct mpc512x_reset_module { | |||
21 | u32 rcer; /* Reset Control Enable Register */ | 21 | u32 rcer; /* Reset Control Enable Register */ |
22 | }; | 22 | }; |
23 | 23 | ||
24 | /* | ||
25 | * Clock Control Module | ||
26 | */ | ||
27 | struct mpc512x_ccm { | ||
28 | u32 spmr; /* System PLL Mode Register */ | ||
29 | u32 sccr1; /* System Clock Control Register 1 */ | ||
30 | u32 sccr2; /* System Clock Control Register 2 */ | ||
31 | u32 scfr1; /* System Clock Frequency Register 1 */ | ||
32 | u32 scfr2; /* System Clock Frequency Register 2 */ | ||
33 | u32 scfr2s; /* System Clock Frequency Shadow Register 2 */ | ||
34 | u32 bcr; /* Bread Crumb Register */ | ||
35 | u32 p0ccr; /* PSC0 Clock Control Register */ | ||
36 | u32 p1ccr; /* PSC1 CCR */ | ||
37 | u32 p2ccr; /* PSC2 CCR */ | ||
38 | u32 p3ccr; /* PSC3 CCR */ | ||
39 | u32 p4ccr; /* PSC4 CCR */ | ||
40 | u32 p5ccr; /* PSC5 CCR */ | ||
41 | u32 p6ccr; /* PSC6 CCR */ | ||
42 | u32 p7ccr; /* PSC7 CCR */ | ||
43 | u32 p8ccr; /* PSC8 CCR */ | ||
44 | u32 p9ccr; /* PSC9 CCR */ | ||
45 | u32 p10ccr; /* PSC10 CCR */ | ||
46 | u32 p11ccr; /* PSC11 CCR */ | ||
47 | u32 spccr; /* SPDIF Clock Control Register */ | ||
48 | u32 cccr; /* CFM Clock Control Register */ | ||
49 | u32 dccr; /* DIU Clock Control Register */ | ||
50 | u32 m1ccr; /* MSCAN1 CCR */ | ||
51 | u32 m2ccr; /* MSCAN2 CCR */ | ||
52 | u32 m3ccr; /* MSCAN3 CCR */ | ||
53 | u32 m4ccr; /* MSCAN4 CCR */ | ||
54 | u8 res[0x98]; /* Reserved */ | ||
55 | }; | ||
24 | #endif /* __ASM_POWERPC_MPC5121_H__ */ | 56 | #endif /* __ASM_POWERPC_MPC5121_H__ */ |
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 8ce7963ad41d..1ff6662f7faf 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h | |||
@@ -146,7 +146,7 @@ struct paca_struct { | |||
146 | extern struct paca_struct *paca; | 146 | extern struct paca_struct *paca; |
147 | extern __initdata struct paca_struct boot_paca; | 147 | extern __initdata struct paca_struct boot_paca; |
148 | extern void initialise_paca(struct paca_struct *new_paca, int cpu); | 148 | extern void initialise_paca(struct paca_struct *new_paca, int cpu); |
149 | 149 | extern void setup_paca(struct paca_struct *new_paca); | |
150 | extern void allocate_pacas(void); | 150 | extern void allocate_pacas(void); |
151 | extern void free_unused_pacas(void); | 151 | extern void free_unused_pacas(void); |
152 | 152 | ||
diff --git a/arch/powerpc/include/asm/percpu.h b/arch/powerpc/include/asm/percpu.h index f879252b7ea6..2cedefddba37 100644 --- a/arch/powerpc/include/asm/percpu.h +++ b/arch/powerpc/include/asm/percpu.h | |||
@@ -1,7 +1,6 @@ | |||
1 | #ifndef _ASM_POWERPC_PERCPU_H_ | 1 | #ifndef _ASM_POWERPC_PERCPU_H_ |
2 | #define _ASM_POWERPC_PERCPU_H_ | 2 | #define _ASM_POWERPC_PERCPU_H_ |
3 | #ifdef __powerpc64__ | 3 | #ifdef __powerpc64__ |
4 | #include <linux/compiler.h> | ||
5 | 4 | ||
6 | /* | 5 | /* |
7 | * Same as asm-generic/percpu.h, except that we store the per cpu offset | 6 | * Same as asm-generic/percpu.h, except that we store the per cpu offset |
@@ -12,9 +11,7 @@ | |||
12 | 11 | ||
13 | #include <asm/paca.h> | 12 | #include <asm/paca.h> |
14 | 13 | ||
15 | #define __per_cpu_offset(cpu) (paca[cpu].data_offset) | ||
16 | #define __my_cpu_offset local_paca->data_offset | 14 | #define __my_cpu_offset local_paca->data_offset |
17 | #define per_cpu_offset(x) (__per_cpu_offset(x)) | ||
18 | 15 | ||
19 | #endif /* CONFIG_SMP */ | 16 | #endif /* CONFIG_SMP */ |
20 | #endif /* __powerpc64__ */ | 17 | #endif /* __powerpc64__ */ |
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index d553bbeb726c..43adc8b819ed 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h | |||
@@ -52,13 +52,17 @@ | |||
52 | #define PPC_INST_WAIT 0x7c00007c | 52 | #define PPC_INST_WAIT 0x7c00007c |
53 | #define PPC_INST_TLBIVAX 0x7c000624 | 53 | #define PPC_INST_TLBIVAX 0x7c000624 |
54 | #define PPC_INST_TLBSRX_DOT 0x7c0006a5 | 54 | #define PPC_INST_TLBSRX_DOT 0x7c0006a5 |
55 | #define PPC_INST_XXLOR 0xf0000510 | ||
55 | 56 | ||
56 | /* macros to insert fields into opcodes */ | 57 | /* macros to insert fields into opcodes */ |
57 | #define __PPC_RA(a) (((a) & 0x1f) << 16) | 58 | #define __PPC_RA(a) (((a) & 0x1f) << 16) |
58 | #define __PPC_RB(b) (((b) & 0x1f) << 11) | 59 | #define __PPC_RB(b) (((b) & 0x1f) << 11) |
59 | #define __PPC_RS(s) (((s) & 0x1f) << 21) | 60 | #define __PPC_RS(s) (((s) & 0x1f) << 21) |
60 | #define __PPC_RT(s) __PPC_RS(s) | 61 | #define __PPC_RT(s) __PPC_RS(s) |
62 | #define __PPC_XA(a) ((((a) & 0x1f) << 16) | (((a) & 0x20) >> 3)) | ||
63 | #define __PPC_XB(b) ((((b) & 0x1f) << 11) | (((b) & 0x20) >> 4)) | ||
61 | #define __PPC_XS(s) ((((s) & 0x1f) << 21) | (((s) & 0x20) >> 5)) | 64 | #define __PPC_XS(s) ((((s) & 0x1f) << 21) | (((s) & 0x20) >> 5)) |
65 | #define __PPC_XT(s) __PPC_XS(s) | ||
62 | #define __PPC_T_TLB(t) (((t) & 0x3) << 21) | 66 | #define __PPC_T_TLB(t) (((t) & 0x3) << 21) |
63 | #define __PPC_WC(w) (((w) & 0x3) << 21) | 67 | #define __PPC_WC(w) (((w) & 0x3) << 21) |
64 | /* | 68 | /* |
@@ -106,9 +110,12 @@ | |||
106 | * the 128 bit load store instructions based on that. | 110 | * the 128 bit load store instructions based on that. |
107 | */ | 111 | */ |
108 | #define VSX_XX1(s, a, b) (__PPC_XS(s) | __PPC_RA(a) | __PPC_RB(b)) | 112 | #define VSX_XX1(s, a, b) (__PPC_XS(s) | __PPC_RA(a) | __PPC_RB(b)) |
113 | #define VSX_XX3(t, a, b) (__PPC_XT(t) | __PPC_XA(a) | __PPC_XB(b)) | ||
109 | #define STXVD2X(s, a, b) stringify_in_c(.long PPC_INST_STXVD2X | \ | 114 | #define STXVD2X(s, a, b) stringify_in_c(.long PPC_INST_STXVD2X | \ |
110 | VSX_XX1((s), (a), (b))) | 115 | VSX_XX1((s), (a), (b))) |
111 | #define LXVD2X(s, a, b) stringify_in_c(.long PPC_INST_LXVD2X | \ | 116 | #define LXVD2X(s, a, b) stringify_in_c(.long PPC_INST_LXVD2X | \ |
112 | VSX_XX1((s), (a), (b))) | 117 | VSX_XX1((s), (a), (b))) |
118 | #define XXLOR(t, a, b) stringify_in_c(.long PPC_INST_XXLOR | \ | ||
119 | VSX_XX3((t), (a), (b))) | ||
113 | 120 | ||
114 | #endif /* _ASM_POWERPC_PPC_OPCODE_H */ | 121 | #endif /* _ASM_POWERPC_PPC_OPCODE_H */ |
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 7492fe8ad6e4..19c05b0f74be 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h | |||
@@ -209,6 +209,14 @@ struct thread_struct { | |||
209 | #ifdef CONFIG_PPC64 | 209 | #ifdef CONFIG_PPC64 |
210 | unsigned long start_tb; /* Start purr when proc switched in */ | 210 | unsigned long start_tb; /* Start purr when proc switched in */ |
211 | unsigned long accum_tb; /* Total accumilated purr for process */ | 211 | unsigned long accum_tb; /* Total accumilated purr for process */ |
212 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
213 | struct perf_event *ptrace_bps[HBP_NUM]; | ||
214 | /* | ||
215 | * Helps identify source of single-step exception and subsequent | ||
216 | * hw-breakpoint enablement | ||
217 | */ | ||
218 | struct perf_event *last_hit_ubp; | ||
219 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
212 | #endif | 220 | #endif |
213 | unsigned long dabr; /* Data address breakpoint register */ | 221 | unsigned long dabr; /* Data address breakpoint register */ |
214 | #ifdef CONFIG_ALTIVEC | 222 | #ifdef CONFIG_ALTIVEC |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index d62fdf4e504b..d8be016d2ede 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -890,7 +890,7 @@ | |||
890 | #ifndef __ASSEMBLY__ | 890 | #ifndef __ASSEMBLY__ |
891 | #define mfmsr() ({unsigned long rval; \ | 891 | #define mfmsr() ({unsigned long rval; \ |
892 | asm volatile("mfmsr %0" : "=r" (rval)); rval;}) | 892 | asm volatile("mfmsr %0" : "=r" (rval)); rval;}) |
893 | #ifdef CONFIG_PPC64 | 893 | #ifdef CONFIG_PPC_BOOK3S_64 |
894 | #define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \ | 894 | #define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \ |
895 | : : "r" (v) : "memory") | 895 | : : "r" (v) : "memory") |
896 | #define mtmsrd(v) __mtmsrd((v), 0) | 896 | #define mtmsrd(v) __mtmsrd((v), 0) |
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index 2360317179a9..667a498eaee1 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h | |||
@@ -29,8 +29,8 @@ | |||
29 | #if defined(CONFIG_PPC_BOOK3E_64) | 29 | #if defined(CONFIG_PPC_BOOK3E_64) |
30 | #define MSR_ MSR_ME | MSR_CE | 30 | #define MSR_ MSR_ME | MSR_CE |
31 | #define MSR_KERNEL MSR_ | MSR_CM | 31 | #define MSR_KERNEL MSR_ | MSR_CM |
32 | #define MSR_USER32 MSR_ | MSR_PR | MSR_EE | 32 | #define MSR_USER32 MSR_ | MSR_PR | MSR_EE | MSR_DE |
33 | #define MSR_USER64 MSR_USER32 | MSR_CM | 33 | #define MSR_USER64 MSR_USER32 | MSR_CM | MSR_DE |
34 | #elif defined (CONFIG_40x) | 34 | #elif defined (CONFIG_40x) |
35 | #define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR|MSR_CE) | 35 | #define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR|MSR_CE) |
36 | #define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE) | 36 | #define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE) |
@@ -62,6 +62,7 @@ | |||
62 | #define SPRN_TLB0PS 0x158 /* TLB 0 Page Size Register */ | 62 | #define SPRN_TLB0PS 0x158 /* TLB 0 Page Size Register */ |
63 | #define SPRN_MAS5_MAS6 0x15c /* MMU Assist Register 5 || 6 */ | 63 | #define SPRN_MAS5_MAS6 0x15c /* MMU Assist Register 5 || 6 */ |
64 | #define SPRN_MAS8_MAS1 0x15d /* MMU Assist Register 8 || 1 */ | 64 | #define SPRN_MAS8_MAS1 0x15d /* MMU Assist Register 8 || 1 */ |
65 | #define SPRN_EPTCFG 0x15e /* Embedded Page Table Config */ | ||
65 | #define SPRN_MAS7_MAS3 0x174 /* MMU Assist Register 7 || 3 */ | 66 | #define SPRN_MAS7_MAS3 0x174 /* MMU Assist Register 7 || 3 */ |
66 | #define SPRN_MAS0_MAS1 0x175 /* MMU Assist Register 0 || 1 */ | 67 | #define SPRN_MAS0_MAS1 0x175 /* MMU Assist Register 0 || 1 */ |
67 | #define SPRN_IVOR0 0x190 /* Interrupt Vector Offset Register 0 */ | 68 | #define SPRN_IVOR0 0x190 /* Interrupt Vector Offset Register 0 */ |
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index 20de73c36682..3d35f8ae377e 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h | |||
@@ -63,6 +63,14 @@ struct rtas_t { | |||
63 | struct device_node *dev; /* virtual address pointer */ | 63 | struct device_node *dev; /* virtual address pointer */ |
64 | }; | 64 | }; |
65 | 65 | ||
66 | struct rtas_suspend_me_data { | ||
67 | atomic_t working; /* number of cpus accessing this struct */ | ||
68 | atomic_t done; | ||
69 | int token; /* ibm,suspend-me */ | ||
70 | atomic_t error; | ||
71 | struct completion *complete; /* wait on this until working == 0 */ | ||
72 | }; | ||
73 | |||
66 | /* RTAS event classes */ | 74 | /* RTAS event classes */ |
67 | #define RTAS_INTERNAL_ERROR 0x80000000 /* set bit 0 */ | 75 | #define RTAS_INTERNAL_ERROR 0x80000000 /* set bit 0 */ |
68 | #define RTAS_EPOW_WARNING 0x40000000 /* set bit 1 */ | 76 | #define RTAS_EPOW_WARNING 0x40000000 /* set bit 1 */ |
@@ -137,6 +145,9 @@ struct rtas_t { | |||
137 | #define RTAS_TYPE_PMGM_CONFIG_CHANGE 0x70 | 145 | #define RTAS_TYPE_PMGM_CONFIG_CHANGE 0x70 |
138 | #define RTAS_TYPE_PMGM_SERVICE_PROC 0x71 | 146 | #define RTAS_TYPE_PMGM_SERVICE_PROC 0x71 |
139 | 147 | ||
148 | /* RTAS check-exception vector offset */ | ||
149 | #define RTAS_VECTOR_EXTERNAL_INTERRUPT 0x500 | ||
150 | |||
140 | struct rtas_error_log { | 151 | struct rtas_error_log { |
141 | unsigned long version:8; /* Architectural version */ | 152 | unsigned long version:8; /* Architectural version */ |
142 | unsigned long severity:3; /* Severity level of error */ | 153 | unsigned long severity:3; /* Severity level of error */ |
@@ -174,6 +185,8 @@ extern int rtas_set_indicator(int indicator, int index, int new_value); | |||
174 | extern int rtas_set_indicator_fast(int indicator, int index, int new_value); | 185 | extern int rtas_set_indicator_fast(int indicator, int index, int new_value); |
175 | extern void rtas_progress(char *s, unsigned short hex); | 186 | extern void rtas_progress(char *s, unsigned short hex); |
176 | extern void rtas_initialize(void); | 187 | extern void rtas_initialize(void); |
188 | extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data); | ||
189 | extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data); | ||
177 | 190 | ||
178 | struct rtc_time; | 191 | struct rtc_time; |
179 | extern unsigned long rtas_get_boot_time(void); | 192 | extern unsigned long rtas_get_boot_time(void); |
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index 27ccb764fdab..dc779dfcf258 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h | |||
@@ -28,16 +28,12 @@ | |||
28 | extern unsigned long tb_ticks_per_jiffy; | 28 | extern unsigned long tb_ticks_per_jiffy; |
29 | extern unsigned long tb_ticks_per_usec; | 29 | extern unsigned long tb_ticks_per_usec; |
30 | extern unsigned long tb_ticks_per_sec; | 30 | extern unsigned long tb_ticks_per_sec; |
31 | extern u64 tb_to_xs; | ||
32 | extern unsigned tb_to_us; | ||
33 | 31 | ||
34 | struct rtc_time; | 32 | struct rtc_time; |
35 | extern void to_tm(int tim, struct rtc_time * tm); | 33 | extern void to_tm(int tim, struct rtc_time * tm); |
36 | extern void GregorianDay(struct rtc_time *tm); | 34 | extern void GregorianDay(struct rtc_time *tm); |
37 | extern time_t last_rtc_update; | ||
38 | 35 | ||
39 | extern void generic_calibrate_decr(void); | 36 | extern void generic_calibrate_decr(void); |
40 | extern void wakeup_decrementer(void); | ||
41 | extern void snapshot_timebase(void); | 37 | extern void snapshot_timebase(void); |
42 | 38 | ||
43 | extern void set_dec_cpu6(unsigned int val); | 39 | extern void set_dec_cpu6(unsigned int val); |
@@ -204,9 +200,6 @@ static inline unsigned long tb_ticks_since(unsigned long tstamp) | |||
204 | extern u64 mulhdu(u64, u64); | 200 | extern u64 mulhdu(u64, u64); |
205 | #endif | 201 | #endif |
206 | 202 | ||
207 | extern void smp_space_timers(unsigned int); | ||
208 | |||
209 | extern unsigned mulhwu_scale_factor(unsigned, unsigned); | ||
210 | extern void div128_by_32(u64 dividend_high, u64 dividend_low, | 203 | extern void div128_by_32(u64 dividend_high, u64 dividend_low, |
211 | unsigned divisor, struct div_result *dr); | 204 | unsigned divisor, struct div_result *dr); |
212 | 205 | ||
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 32adf7280720..3033c1b30745 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h | |||
@@ -87,6 +87,9 @@ static inline int pcibus_to_node(struct pci_bus *bus) | |||
87 | .balance_interval = 1, \ | 87 | .balance_interval = 1, \ |
88 | } | 88 | } |
89 | 89 | ||
90 | extern int __node_distance(int, int); | ||
91 | #define node_distance(a, b) __node_distance(a, b) | ||
92 | |||
90 | extern void __init dump_numa_cpu_topology(void); | 93 | extern void __init dump_numa_cpu_topology(void); |
91 | 94 | ||
92 | extern int sysfs_add_device_to_node(struct sys_device *dev, int nid); | 95 | extern int sysfs_add_device_to_node(struct sys_device *dev, int nid); |
diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h index 13c2c283e178..08679c5319b8 100644 --- a/arch/powerpc/include/asm/vdso_datapage.h +++ b/arch/powerpc/include/asm/vdso_datapage.h | |||
@@ -85,6 +85,7 @@ struct vdso_data { | |||
85 | __s32 wtom_clock_sec; /* Wall to monotonic clock */ | 85 | __s32 wtom_clock_sec; /* Wall to monotonic clock */ |
86 | __s32 wtom_clock_nsec; | 86 | __s32 wtom_clock_nsec; |
87 | struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ | 87 | struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ |
88 | __u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */ | ||
88 | __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */ | 89 | __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */ |
89 | __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ | 90 | __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ |
90 | }; | 91 | }; |
@@ -105,6 +106,7 @@ struct vdso_data { | |||
105 | __s32 wtom_clock_sec; /* Wall to monotonic clock */ | 106 | __s32 wtom_clock_sec; /* Wall to monotonic clock */ |
106 | __s32 wtom_clock_nsec; | 107 | __s32 wtom_clock_nsec; |
107 | struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ | 108 | struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ |
109 | __u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */ | ||
108 | __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ | 110 | __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ |
109 | __u32 dcache_block_size; /* L1 d-cache block size */ | 111 | __u32 dcache_block_size; /* L1 d-cache block size */ |
110 | __u32 icache_block_size; /* L1 i-cache block size */ | 112 | __u32 icache_block_size; /* L1 i-cache block size */ |
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 58d0572de6f9..77d831a1cc32 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -34,9 +34,10 @@ obj-y += vdso32/ | |||
34 | obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ | 34 | obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ |
35 | signal_64.o ptrace32.o \ | 35 | signal_64.o ptrace32.o \ |
36 | paca.o nvram_64.o firmware.o | 36 | paca.o nvram_64.o firmware.o |
37 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o | ||
37 | obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o | 38 | obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o |
38 | obj64-$(CONFIG_RELOCATABLE) += reloc_64.o | 39 | obj64-$(CONFIG_RELOCATABLE) += reloc_64.o |
39 | obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o | 40 | obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_book3e.o |
40 | obj-$(CONFIG_PPC64) += vdso64/ | 41 | obj-$(CONFIG_PPC64) += vdso64/ |
41 | obj-$(CONFIG_ALTIVEC) += vecemu.o | 42 | obj-$(CONFIG_ALTIVEC) += vecemu.o |
42 | obj-$(CONFIG_PPC_970_NAP) += idle_power4.o | 43 | obj-$(CONFIG_PPC_970_NAP) += idle_power4.o |
@@ -67,6 +68,7 @@ obj64-$(CONFIG_HIBERNATION) += swsusp_asm64.o | |||
67 | obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o | 68 | obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o |
68 | obj-$(CONFIG_44x) += cpu_setup_44x.o | 69 | obj-$(CONFIG_44x) += cpu_setup_44x.o |
69 | obj-$(CONFIG_FSL_BOOKE) += cpu_setup_fsl_booke.o dbell.o | 70 | obj-$(CONFIG_FSL_BOOKE) += cpu_setup_fsl_booke.o dbell.o |
71 | obj-$(CONFIG_PPC_BOOK3E_64) += dbell.o | ||
70 | 72 | ||
71 | extra-y := head_$(CONFIG_WORD_SIZE).o | 73 | extra-y := head_$(CONFIG_WORD_SIZE).o |
72 | extra-$(CONFIG_PPC_BOOK3E_32) := head_new_booke.o | 74 | extra-$(CONFIG_PPC_BOOK3E_32) := head_new_booke.o |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 496cc5b3984f..1c0607ddccc0 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -194,7 +194,6 @@ int main(void) | |||
194 | DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr)); | 194 | DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr)); |
195 | DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); | 195 | DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); |
196 | DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); | 196 | DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); |
197 | DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset)); | ||
198 | DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save)); | 197 | DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save)); |
199 | #ifdef CONFIG_KVM_BOOK3S_64_HANDLER | 198 | #ifdef CONFIG_KVM_BOOK3S_64_HANDLER |
200 | DEFINE(PACA_KVM_SVCPU, offsetof(struct paca_struct, shadow_vcpu)); | 199 | DEFINE(PACA_KVM_SVCPU, offsetof(struct paca_struct, shadow_vcpu)); |
@@ -342,6 +341,7 @@ int main(void) | |||
342 | DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec)); | 341 | DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec)); |
343 | DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); | 342 | DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); |
344 | DEFINE(STAMP_XTIME, offsetof(struct vdso_data, stamp_xtime)); | 343 | DEFINE(STAMP_XTIME, offsetof(struct vdso_data, stamp_xtime)); |
344 | DEFINE(STAMP_SEC_FRAC, offsetof(struct vdso_data, stamp_sec_fraction)); | ||
345 | DEFINE(CFG_ICACHE_BLOCKSZ, offsetof(struct vdso_data, icache_block_size)); | 345 | DEFINE(CFG_ICACHE_BLOCKSZ, offsetof(struct vdso_data, icache_block_size)); |
346 | DEFINE(CFG_DCACHE_BLOCKSZ, offsetof(struct vdso_data, dcache_block_size)); | 346 | DEFINE(CFG_DCACHE_BLOCKSZ, offsetof(struct vdso_data, dcache_block_size)); |
347 | DEFINE(CFG_ICACHE_LOGBLOCKSZ, offsetof(struct vdso_data, icache_log_block_size)); | 347 | DEFINE(CFG_ICACHE_LOGBLOCKSZ, offsetof(struct vdso_data, icache_log_block_size)); |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 87aa0f3c6047..65e2b4e10f97 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -1364,10 +1364,10 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1364 | .machine_check = machine_check_4xx, | 1364 | .machine_check = machine_check_4xx, |
1365 | .platform = "ppc405", | 1365 | .platform = "ppc405", |
1366 | }, | 1366 | }, |
1367 | { /* 405EX */ | 1367 | { /* 405EX Rev. A/B with Security */ |
1368 | .pvr_mask = 0xffff0004, | 1368 | .pvr_mask = 0xffff000f, |
1369 | .pvr_value = 0x12910004, | 1369 | .pvr_value = 0x12910007, |
1370 | .cpu_name = "405EX", | 1370 | .cpu_name = "405EX Rev. A/B", |
1371 | .cpu_features = CPU_FTRS_40X, | 1371 | .cpu_features = CPU_FTRS_40X, |
1372 | .cpu_user_features = PPC_FEATURE_32 | | 1372 | .cpu_user_features = PPC_FEATURE_32 | |
1373 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1373 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
@@ -1377,10 +1377,114 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1377 | .machine_check = machine_check_4xx, | 1377 | .machine_check = machine_check_4xx, |
1378 | .platform = "ppc405", | 1378 | .platform = "ppc405", |
1379 | }, | 1379 | }, |
1380 | { /* 405EXr */ | 1380 | { /* 405EX Rev. C without Security */ |
1381 | .pvr_mask = 0xffff0004, | 1381 | .pvr_mask = 0xffff000f, |
1382 | .pvr_value = 0x1291000d, | ||
1383 | .cpu_name = "405EX Rev. C", | ||
1384 | .cpu_features = CPU_FTRS_40X, | ||
1385 | .cpu_user_features = PPC_FEATURE_32 | | ||
1386 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
1387 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1388 | .icache_bsize = 32, | ||
1389 | .dcache_bsize = 32, | ||
1390 | .machine_check = machine_check_4xx, | ||
1391 | .platform = "ppc405", | ||
1392 | }, | ||
1393 | { /* 405EX Rev. C with Security */ | ||
1394 | .pvr_mask = 0xffff000f, | ||
1395 | .pvr_value = 0x1291000f, | ||
1396 | .cpu_name = "405EX Rev. C", | ||
1397 | .cpu_features = CPU_FTRS_40X, | ||
1398 | .cpu_user_features = PPC_FEATURE_32 | | ||
1399 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
1400 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1401 | .icache_bsize = 32, | ||
1402 | .dcache_bsize = 32, | ||
1403 | .machine_check = machine_check_4xx, | ||
1404 | .platform = "ppc405", | ||
1405 | }, | ||
1406 | { /* 405EX Rev. D without Security */ | ||
1407 | .pvr_mask = 0xffff000f, | ||
1408 | .pvr_value = 0x12910003, | ||
1409 | .cpu_name = "405EX Rev. D", | ||
1410 | .cpu_features = CPU_FTRS_40X, | ||
1411 | .cpu_user_features = PPC_FEATURE_32 | | ||
1412 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
1413 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1414 | .icache_bsize = 32, | ||
1415 | .dcache_bsize = 32, | ||
1416 | .machine_check = machine_check_4xx, | ||
1417 | .platform = "ppc405", | ||
1418 | }, | ||
1419 | { /* 405EX Rev. D with Security */ | ||
1420 | .pvr_mask = 0xffff000f, | ||
1421 | .pvr_value = 0x12910005, | ||
1422 | .cpu_name = "405EX Rev. D", | ||
1423 | .cpu_features = CPU_FTRS_40X, | ||
1424 | .cpu_user_features = PPC_FEATURE_32 | | ||
1425 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
1426 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1427 | .icache_bsize = 32, | ||
1428 | .dcache_bsize = 32, | ||
1429 | .machine_check = machine_check_4xx, | ||
1430 | .platform = "ppc405", | ||
1431 | }, | ||
1432 | { /* 405EXr Rev. A/B without Security */ | ||
1433 | .pvr_mask = 0xffff000f, | ||
1434 | .pvr_value = 0x12910001, | ||
1435 | .cpu_name = "405EXr Rev. A/B", | ||
1436 | .cpu_features = CPU_FTRS_40X, | ||
1437 | .cpu_user_features = PPC_FEATURE_32 | | ||
1438 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
1439 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1440 | .icache_bsize = 32, | ||
1441 | .dcache_bsize = 32, | ||
1442 | .machine_check = machine_check_4xx, | ||
1443 | .platform = "ppc405", | ||
1444 | }, | ||
1445 | { /* 405EXr Rev. C without Security */ | ||
1446 | .pvr_mask = 0xffff000f, | ||
1447 | .pvr_value = 0x12910009, | ||
1448 | .cpu_name = "405EXr Rev. C", | ||
1449 | .cpu_features = CPU_FTRS_40X, | ||
1450 | .cpu_user_features = PPC_FEATURE_32 | | ||
1451 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
1452 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1453 | .icache_bsize = 32, | ||
1454 | .dcache_bsize = 32, | ||
1455 | .machine_check = machine_check_4xx, | ||
1456 | .platform = "ppc405", | ||
1457 | }, | ||
1458 | { /* 405EXr Rev. C with Security */ | ||
1459 | .pvr_mask = 0xffff000f, | ||
1460 | .pvr_value = 0x1291000b, | ||
1461 | .cpu_name = "405EXr Rev. C", | ||
1462 | .cpu_features = CPU_FTRS_40X, | ||
1463 | .cpu_user_features = PPC_FEATURE_32 | | ||
1464 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
1465 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1466 | .icache_bsize = 32, | ||
1467 | .dcache_bsize = 32, | ||
1468 | .machine_check = machine_check_4xx, | ||
1469 | .platform = "ppc405", | ||
1470 | }, | ||
1471 | { /* 405EXr Rev. D without Security */ | ||
1472 | .pvr_mask = 0xffff000f, | ||
1382 | .pvr_value = 0x12910000, | 1473 | .pvr_value = 0x12910000, |
1383 | .cpu_name = "405EXr", | 1474 | .cpu_name = "405EXr Rev. D", |
1475 | .cpu_features = CPU_FTRS_40X, | ||
1476 | .cpu_user_features = PPC_FEATURE_32 | | ||
1477 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
1478 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1479 | .icache_bsize = 32, | ||
1480 | .dcache_bsize = 32, | ||
1481 | .machine_check = machine_check_4xx, | ||
1482 | .platform = "ppc405", | ||
1483 | }, | ||
1484 | { /* 405EXr Rev. D with Security */ | ||
1485 | .pvr_mask = 0xffff000f, | ||
1486 | .pvr_value = 0x12910002, | ||
1487 | .cpu_name = "405EXr Rev. D", | ||
1384 | .cpu_features = CPU_FTRS_40X, | 1488 | .cpu_features = CPU_FTRS_40X, |
1385 | .cpu_user_features = PPC_FEATURE_32 | | 1489 | .cpu_user_features = PPC_FEATURE_32 | |
1386 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1490 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index 40f524643ba6..8e05c16344e4 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c | |||
@@ -128,9 +128,9 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, | |||
128 | if (!csize) | 128 | if (!csize) |
129 | return 0; | 129 | return 0; |
130 | 130 | ||
131 | csize = min(csize, PAGE_SIZE); | 131 | csize = min_t(size_t, csize, PAGE_SIZE); |
132 | 132 | ||
133 | if (pfn < max_pfn) { | 133 | if ((min_low_pfn < pfn) && (pfn < max_pfn)) { |
134 | vaddr = __va(pfn << PAGE_SHIFT); | 134 | vaddr = __va(pfn << PAGE_SHIFT); |
135 | csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); | 135 | csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); |
136 | } else { | 136 | } else { |
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c index 1493734cd871..3307a52d797f 100644 --- a/arch/powerpc/kernel/dbell.c +++ b/arch/powerpc/kernel/dbell.c | |||
@@ -13,32 +13,88 @@ | |||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/smp.h> | 14 | #include <linux/smp.h> |
15 | #include <linux/threads.h> | 15 | #include <linux/threads.h> |
16 | #include <linux/percpu.h> | ||
16 | 17 | ||
17 | #include <asm/dbell.h> | 18 | #include <asm/dbell.h> |
19 | #include <asm/irq_regs.h> | ||
18 | 20 | ||
19 | #ifdef CONFIG_SMP | 21 | #ifdef CONFIG_SMP |
20 | unsigned long dbell_smp_message[NR_CPUS]; | 22 | struct doorbell_cpu_info { |
23 | unsigned long messages; /* current messages bits */ | ||
24 | unsigned int tag; /* tag value */ | ||
25 | }; | ||
21 | 26 | ||
22 | void smp_dbell_message_pass(int target, int msg) | 27 | static DEFINE_PER_CPU(struct doorbell_cpu_info, doorbell_cpu_info); |
28 | |||
29 | void doorbell_setup_this_cpu(void) | ||
30 | { | ||
31 | struct doorbell_cpu_info *info = &__get_cpu_var(doorbell_cpu_info); | ||
32 | |||
33 | info->messages = 0; | ||
34 | info->tag = mfspr(SPRN_PIR) & 0x3fff; | ||
35 | } | ||
36 | |||
37 | void doorbell_message_pass(int target, int msg) | ||
23 | { | 38 | { |
39 | struct doorbell_cpu_info *info; | ||
24 | int i; | 40 | int i; |
25 | 41 | ||
26 | if(target < NR_CPUS) { | 42 | if (target < NR_CPUS) { |
27 | set_bit(msg, &dbell_smp_message[target]); | 43 | info = &per_cpu(doorbell_cpu_info, target); |
28 | ppc_msgsnd(PPC_DBELL, 0, target); | 44 | set_bit(msg, &info->messages); |
45 | ppc_msgsnd(PPC_DBELL, 0, info->tag); | ||
29 | } | 46 | } |
30 | else if(target == MSG_ALL_BUT_SELF) { | 47 | else if (target == MSG_ALL_BUT_SELF) { |
31 | for_each_online_cpu(i) { | 48 | for_each_online_cpu(i) { |
32 | if (i == smp_processor_id()) | 49 | if (i == smp_processor_id()) |
33 | continue; | 50 | continue; |
34 | set_bit(msg, &dbell_smp_message[i]); | 51 | info = &per_cpu(doorbell_cpu_info, i); |
35 | ppc_msgsnd(PPC_DBELL, 0, i); | 52 | set_bit(msg, &info->messages); |
53 | ppc_msgsnd(PPC_DBELL, 0, info->tag); | ||
36 | } | 54 | } |
37 | } | 55 | } |
38 | else { /* target == MSG_ALL */ | 56 | else { /* target == MSG_ALL */ |
39 | for_each_online_cpu(i) | 57 | for_each_online_cpu(i) { |
40 | set_bit(msg, &dbell_smp_message[i]); | 58 | info = &per_cpu(doorbell_cpu_info, i); |
59 | set_bit(msg, &info->messages); | ||
60 | } | ||
41 | ppc_msgsnd(PPC_DBELL, PPC_DBELL_MSG_BRDCAST, 0); | 61 | ppc_msgsnd(PPC_DBELL, PPC_DBELL_MSG_BRDCAST, 0); |
42 | } | 62 | } |
43 | } | 63 | } |
44 | #endif | 64 | |
65 | void doorbell_exception(struct pt_regs *regs) | ||
66 | { | ||
67 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
68 | struct doorbell_cpu_info *info = &__get_cpu_var(doorbell_cpu_info); | ||
69 | int msg; | ||
70 | |||
71 | /* Warning: regs can be NULL when called from irq enable */ | ||
72 | |||
73 | if (!info->messages || (num_online_cpus() < 2)) | ||
74 | goto out; | ||
75 | |||
76 | for (msg = 0; msg < 4; msg++) | ||
77 | if (test_and_clear_bit(msg, &info->messages)) | ||
78 | smp_message_recv(msg); | ||
79 | |||
80 | out: | ||
81 | set_irq_regs(old_regs); | ||
82 | } | ||
83 | |||
84 | void doorbell_check_self(void) | ||
85 | { | ||
86 | struct doorbell_cpu_info *info = &__get_cpu_var(doorbell_cpu_info); | ||
87 | |||
88 | if (!info->messages) | ||
89 | return; | ||
90 | |||
91 | ppc_msgsnd(PPC_DBELL, 0, info->tag); | ||
92 | } | ||
93 | |||
94 | #else /* CONFIG_SMP */ | ||
95 | void doorbell_exception(struct pt_regs *regs) | ||
96 | { | ||
97 | printk(KERN_WARNING "Received doorbell on non-smp system\n"); | ||
98 | } | ||
99 | #endif /* CONFIG_SMP */ | ||
100 | |||
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index 24dcc0ecf246..5c43063d2506 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S | |||
@@ -191,6 +191,12 @@ exc_##n##_bad_stack: \ | |||
191 | sth r1,PACA_TRAP_SAVE(r13); /* store trap */ \ | 191 | sth r1,PACA_TRAP_SAVE(r13); /* store trap */ \ |
192 | b bad_stack_book3e; /* bad stack error */ | 192 | b bad_stack_book3e; /* bad stack error */ |
193 | 193 | ||
194 | /* WARNING: If you change the layout of this stub, make sure you chcek | ||
195 | * the debug exception handler which handles single stepping | ||
196 | * into exceptions from userspace, and the MM code in | ||
197 | * arch/powerpc/mm/tlb_nohash.c which patches the branch here | ||
198 | * and would need to be updated if that branch is moved | ||
199 | */ | ||
194 | #define EXCEPTION_STUB(loc, label) \ | 200 | #define EXCEPTION_STUB(loc, label) \ |
195 | . = interrupt_base_book3e + loc; \ | 201 | . = interrupt_base_book3e + loc; \ |
196 | nop; /* To make debug interrupts happy */ \ | 202 | nop; /* To make debug interrupts happy */ \ |
@@ -204,11 +210,30 @@ exc_##n##_bad_stack: \ | |||
204 | lis r,TSR_FIS@h; \ | 210 | lis r,TSR_FIS@h; \ |
205 | mtspr SPRN_TSR,r | 211 | mtspr SPRN_TSR,r |
206 | 212 | ||
213 | /* Used by asynchronous interrupt that may happen in the idle loop. | ||
214 | * | ||
215 | * This check if the thread was in the idle loop, and if yes, returns | ||
216 | * to the caller rather than the PC. This is to avoid a race if | ||
217 | * interrupts happen before the wait instruction. | ||
218 | */ | ||
219 | #define CHECK_NAPPING() \ | ||
220 | clrrdi r11,r1,THREAD_SHIFT; \ | ||
221 | ld r10,TI_LOCAL_FLAGS(r11); \ | ||
222 | andi. r9,r10,_TLF_NAPPING; \ | ||
223 | beq+ 1f; \ | ||
224 | ld r8,_LINK(r1); \ | ||
225 | rlwinm r7,r10,0,~_TLF_NAPPING; \ | ||
226 | std r8,_NIP(r1); \ | ||
227 | std r7,TI_LOCAL_FLAGS(r11); \ | ||
228 | 1: | ||
229 | |||
230 | |||
207 | #define MASKABLE_EXCEPTION(trapnum, label, hdlr, ack) \ | 231 | #define MASKABLE_EXCEPTION(trapnum, label, hdlr, ack) \ |
208 | START_EXCEPTION(label); \ | 232 | START_EXCEPTION(label); \ |
209 | NORMAL_EXCEPTION_PROLOG(trapnum, PROLOG_ADDITION_MASKABLE) \ | 233 | NORMAL_EXCEPTION_PROLOG(trapnum, PROLOG_ADDITION_MASKABLE) \ |
210 | EXCEPTION_COMMON(trapnum, PACA_EXGEN, INTS_DISABLE_ALL) \ | 234 | EXCEPTION_COMMON(trapnum, PACA_EXGEN, INTS_DISABLE_ALL) \ |
211 | ack(r8); \ | 235 | ack(r8); \ |
236 | CHECK_NAPPING(); \ | ||
212 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 237 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
213 | bl hdlr; \ | 238 | bl hdlr; \ |
214 | b .ret_from_except_lite; | 239 | b .ret_from_except_lite; |
@@ -246,11 +271,9 @@ interrupt_base_book3e: /* fake trap */ | |||
246 | EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */ | 271 | EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */ |
247 | EXCEPTION_STUB(0x1c0, data_tlb_miss) | 272 | EXCEPTION_STUB(0x1c0, data_tlb_miss) |
248 | EXCEPTION_STUB(0x1e0, instruction_tlb_miss) | 273 | EXCEPTION_STUB(0x1e0, instruction_tlb_miss) |
274 | EXCEPTION_STUB(0x280, doorbell) | ||
275 | EXCEPTION_STUB(0x2a0, doorbell_crit) | ||
249 | 276 | ||
250 | #if 0 | ||
251 | EXCEPTION_STUB(0x280, processor_doorbell) | ||
252 | EXCEPTION_STUB(0x220, processor_doorbell_crit) | ||
253 | #endif | ||
254 | .globl interrupt_end_book3e | 277 | .globl interrupt_end_book3e |
255 | interrupt_end_book3e: | 278 | interrupt_end_book3e: |
256 | 279 | ||
@@ -259,6 +282,7 @@ interrupt_end_book3e: | |||
259 | CRIT_EXCEPTION_PROLOG(0x100, PROLOG_ADDITION_NONE) | 282 | CRIT_EXCEPTION_PROLOG(0x100, PROLOG_ADDITION_NONE) |
260 | // EXCEPTION_COMMON(0x100, PACA_EXCRIT, INTS_DISABLE_ALL) | 283 | // EXCEPTION_COMMON(0x100, PACA_EXCRIT, INTS_DISABLE_ALL) |
261 | // bl special_reg_save_crit | 284 | // bl special_reg_save_crit |
285 | // CHECK_NAPPING(); | ||
262 | // addi r3,r1,STACK_FRAME_OVERHEAD | 286 | // addi r3,r1,STACK_FRAME_OVERHEAD |
263 | // bl .critical_exception | 287 | // bl .critical_exception |
264 | // b ret_from_crit_except | 288 | // b ret_from_crit_except |
@@ -270,6 +294,7 @@ interrupt_end_book3e: | |||
270 | // EXCEPTION_COMMON(0x200, PACA_EXMC, INTS_DISABLE_ALL) | 294 | // EXCEPTION_COMMON(0x200, PACA_EXMC, INTS_DISABLE_ALL) |
271 | // bl special_reg_save_mc | 295 | // bl special_reg_save_mc |
272 | // addi r3,r1,STACK_FRAME_OVERHEAD | 296 | // addi r3,r1,STACK_FRAME_OVERHEAD |
297 | // CHECK_NAPPING(); | ||
273 | // bl .machine_check_exception | 298 | // bl .machine_check_exception |
274 | // b ret_from_mc_except | 299 | // b ret_from_mc_except |
275 | b . | 300 | b . |
@@ -340,6 +365,7 @@ interrupt_end_book3e: | |||
340 | CRIT_EXCEPTION_PROLOG(0x9f0, PROLOG_ADDITION_NONE) | 365 | CRIT_EXCEPTION_PROLOG(0x9f0, PROLOG_ADDITION_NONE) |
341 | // EXCEPTION_COMMON(0x9f0, PACA_EXCRIT, INTS_DISABLE_ALL) | 366 | // EXCEPTION_COMMON(0x9f0, PACA_EXCRIT, INTS_DISABLE_ALL) |
342 | // bl special_reg_save_crit | 367 | // bl special_reg_save_crit |
368 | // CHECK_NAPPING(); | ||
343 | // addi r3,r1,STACK_FRAME_OVERHEAD | 369 | // addi r3,r1,STACK_FRAME_OVERHEAD |
344 | // bl .unknown_exception | 370 | // bl .unknown_exception |
345 | // b ret_from_crit_except | 371 | // b ret_from_crit_except |
@@ -428,6 +454,20 @@ interrupt_end_book3e: | |||
428 | kernel_dbg_exc: | 454 | kernel_dbg_exc: |
429 | b . /* NYI */ | 455 | b . /* NYI */ |
430 | 456 | ||
457 | /* Doorbell interrupt */ | ||
458 | MASKABLE_EXCEPTION(0x2070, doorbell, .doorbell_exception, ACK_NONE) | ||
459 | |||
460 | /* Doorbell critical Interrupt */ | ||
461 | START_EXCEPTION(doorbell_crit); | ||
462 | CRIT_EXCEPTION_PROLOG(0x2080, PROLOG_ADDITION_NONE) | ||
463 | // EXCEPTION_COMMON(0x2080, PACA_EXCRIT, INTS_DISABLE_ALL) | ||
464 | // bl special_reg_save_crit | ||
465 | // CHECK_NAPPING(); | ||
466 | // addi r3,r1,STACK_FRAME_OVERHEAD | ||
467 | // bl .doorbell_critical_exception | ||
468 | // b ret_from_crit_except | ||
469 | b . | ||
470 | |||
431 | 471 | ||
432 | /* | 472 | /* |
433 | * An interrupt came in while soft-disabled; clear EE in SRR1, | 473 | * An interrupt came in while soft-disabled; clear EE in SRR1, |
@@ -563,6 +603,8 @@ BAD_STACK_TRAMPOLINE(0xd00) | |||
563 | BAD_STACK_TRAMPOLINE(0xe00) | 603 | BAD_STACK_TRAMPOLINE(0xe00) |
564 | BAD_STACK_TRAMPOLINE(0xf00) | 604 | BAD_STACK_TRAMPOLINE(0xf00) |
565 | BAD_STACK_TRAMPOLINE(0xf20) | 605 | BAD_STACK_TRAMPOLINE(0xf20) |
606 | BAD_STACK_TRAMPOLINE(0x2070) | ||
607 | BAD_STACK_TRAMPOLINE(0x2080) | ||
566 | 608 | ||
567 | .globl bad_stack_book3e | 609 | .globl bad_stack_book3e |
568 | bad_stack_book3e: | 610 | bad_stack_book3e: |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 3e423fbad6bc..f53029a01554 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -828,6 +828,7 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) | |||
828 | 828 | ||
829 | /* We have a data breakpoint exception - handle it */ | 829 | /* We have a data breakpoint exception - handle it */ |
830 | handle_dabr_fault: | 830 | handle_dabr_fault: |
831 | bl .save_nvgprs | ||
831 | ld r4,_DAR(r1) | 832 | ld r4,_DAR(r1) |
832 | ld r5,_DSISR(r1) | 833 | ld r5,_DSISR(r1) |
833 | addi r3,r1,STACK_FRAME_OVERHEAD | 834 | addi r3,r1,STACK_FRAME_OVERHEAD |
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c new file mode 100644 index 000000000000..5ecd0401cdb1 --- /dev/null +++ b/arch/powerpc/kernel/hw_breakpoint.c | |||
@@ -0,0 +1,364 @@ | |||
1 | /* | ||
2 | * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility, | ||
3 | * using the CPU's debug registers. Derived from | ||
4 | * "arch/x86/kernel/hw_breakpoint.c" | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | * | ||
20 | * Copyright 2010 IBM Corporation | ||
21 | * Author: K.Prasad <prasad@linux.vnet.ibm.com> | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <linux/hw_breakpoint.h> | ||
26 | #include <linux/notifier.h> | ||
27 | #include <linux/kprobes.h> | ||
28 | #include <linux/percpu.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/sched.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/smp.h> | ||
34 | |||
35 | #include <asm/hw_breakpoint.h> | ||
36 | #include <asm/processor.h> | ||
37 | #include <asm/sstep.h> | ||
38 | #include <asm/uaccess.h> | ||
39 | |||
40 | /* | ||
41 | * Stores the breakpoints currently in use on each breakpoint address | ||
42 | * register for every cpu | ||
43 | */ | ||
44 | static DEFINE_PER_CPU(struct perf_event *, bp_per_reg); | ||
45 | |||
46 | /* | ||
47 | * Returns total number of data or instruction breakpoints available. | ||
48 | */ | ||
49 | int hw_breakpoint_slots(int type) | ||
50 | { | ||
51 | if (type == TYPE_DATA) | ||
52 | return HBP_NUM; | ||
53 | return 0; /* no instruction breakpoints available */ | ||
54 | } | ||
55 | |||
56 | /* | ||
57 | * Install a perf counter breakpoint. | ||
58 | * | ||
59 | * We seek a free debug address register and use it for this | ||
60 | * breakpoint. | ||
61 | * | ||
62 | * Atomic: we hold the counter->ctx->lock and we only handle variables | ||
63 | * and registers local to this cpu. | ||
64 | */ | ||
65 | int arch_install_hw_breakpoint(struct perf_event *bp) | ||
66 | { | ||
67 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | ||
68 | struct perf_event **slot = &__get_cpu_var(bp_per_reg); | ||
69 | |||
70 | *slot = bp; | ||
71 | |||
72 | /* | ||
73 | * Do not install DABR values if the instruction must be single-stepped. | ||
74 | * If so, DABR will be populated in single_step_dabr_instruction(). | ||
75 | */ | ||
76 | if (current->thread.last_hit_ubp != bp) | ||
77 | set_dabr(info->address | info->type | DABR_TRANSLATION); | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | /* | ||
83 | * Uninstall the breakpoint contained in the given counter. | ||
84 | * | ||
85 | * First we search the debug address register it uses and then we disable | ||
86 | * it. | ||
87 | * | ||
88 | * Atomic: we hold the counter->ctx->lock and we only handle variables | ||
89 | * and registers local to this cpu. | ||
90 | */ | ||
91 | void arch_uninstall_hw_breakpoint(struct perf_event *bp) | ||
92 | { | ||
93 | struct perf_event **slot = &__get_cpu_var(bp_per_reg); | ||
94 | |||
95 | if (*slot != bp) { | ||
96 | WARN_ONCE(1, "Can't find the breakpoint"); | ||
97 | return; | ||
98 | } | ||
99 | |||
100 | *slot = NULL; | ||
101 | set_dabr(0); | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * Perform cleanup of arch-specific counters during unregistration | ||
106 | * of the perf-event | ||
107 | */ | ||
108 | void arch_unregister_hw_breakpoint(struct perf_event *bp) | ||
109 | { | ||
110 | /* | ||
111 | * If the breakpoint is unregistered between a hw_breakpoint_handler() | ||
112 | * and the single_step_dabr_instruction(), then cleanup the breakpoint | ||
113 | * restoration variables to prevent dangling pointers. | ||
114 | */ | ||
115 | if (bp->ctx->task) | ||
116 | bp->ctx->task->thread.last_hit_ubp = NULL; | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * Check for virtual address in kernel space. | ||
121 | */ | ||
122 | int arch_check_bp_in_kernelspace(struct perf_event *bp) | ||
123 | { | ||
124 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | ||
125 | |||
126 | return is_kernel_addr(info->address); | ||
127 | } | ||
128 | |||
129 | int arch_bp_generic_fields(int type, int *gen_bp_type) | ||
130 | { | ||
131 | switch (type) { | ||
132 | case DABR_DATA_READ: | ||
133 | *gen_bp_type = HW_BREAKPOINT_R; | ||
134 | break; | ||
135 | case DABR_DATA_WRITE: | ||
136 | *gen_bp_type = HW_BREAKPOINT_W; | ||
137 | break; | ||
138 | case (DABR_DATA_WRITE | DABR_DATA_READ): | ||
139 | *gen_bp_type = (HW_BREAKPOINT_W | HW_BREAKPOINT_R); | ||
140 | break; | ||
141 | default: | ||
142 | return -EINVAL; | ||
143 | } | ||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | /* | ||
148 | * Validate the arch-specific HW Breakpoint register settings | ||
149 | */ | ||
150 | int arch_validate_hwbkpt_settings(struct perf_event *bp) | ||
151 | { | ||
152 | int ret = -EINVAL; | ||
153 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | ||
154 | |||
155 | if (!bp) | ||
156 | return ret; | ||
157 | |||
158 | switch (bp->attr.bp_type) { | ||
159 | case HW_BREAKPOINT_R: | ||
160 | info->type = DABR_DATA_READ; | ||
161 | break; | ||
162 | case HW_BREAKPOINT_W: | ||
163 | info->type = DABR_DATA_WRITE; | ||
164 | break; | ||
165 | case HW_BREAKPOINT_R | HW_BREAKPOINT_W: | ||
166 | info->type = (DABR_DATA_READ | DABR_DATA_WRITE); | ||
167 | break; | ||
168 | default: | ||
169 | return ret; | ||
170 | } | ||
171 | |||
172 | info->address = bp->attr.bp_addr; | ||
173 | info->len = bp->attr.bp_len; | ||
174 | |||
175 | /* | ||
176 | * Since breakpoint length can be a maximum of HW_BREAKPOINT_LEN(8) | ||
177 | * and breakpoint addresses are aligned to nearest double-word | ||
178 | * HW_BREAKPOINT_ALIGN by rounding off to the lower address, the | ||
179 | * 'symbolsize' should satisfy the check below. | ||
180 | */ | ||
181 | if (info->len > | ||
182 | (HW_BREAKPOINT_LEN - (info->address & HW_BREAKPOINT_ALIGN))) | ||
183 | return -EINVAL; | ||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | /* | ||
188 | * Restores the breakpoint on the debug registers. | ||
189 | * Invoke this function if it is known that the execution context is | ||
190 | * about to change to cause loss of MSR_SE settings. | ||
191 | */ | ||
192 | void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs) | ||
193 | { | ||
194 | struct arch_hw_breakpoint *info; | ||
195 | |||
196 | if (likely(!tsk->thread.last_hit_ubp)) | ||
197 | return; | ||
198 | |||
199 | info = counter_arch_bp(tsk->thread.last_hit_ubp); | ||
200 | regs->msr &= ~MSR_SE; | ||
201 | set_dabr(info->address | info->type | DABR_TRANSLATION); | ||
202 | tsk->thread.last_hit_ubp = NULL; | ||
203 | } | ||
204 | |||
205 | /* | ||
206 | * Handle debug exception notifications. | ||
207 | */ | ||
208 | int __kprobes hw_breakpoint_handler(struct die_args *args) | ||
209 | { | ||
210 | int rc = NOTIFY_STOP; | ||
211 | struct perf_event *bp; | ||
212 | struct pt_regs *regs = args->regs; | ||
213 | int stepped = 1; | ||
214 | struct arch_hw_breakpoint *info; | ||
215 | unsigned int instr; | ||
216 | unsigned long dar = regs->dar; | ||
217 | |||
218 | /* Disable breakpoints during exception handling */ | ||
219 | set_dabr(0); | ||
220 | |||
221 | /* | ||
222 | * The counter may be concurrently released but that can only | ||
223 | * occur from a call_rcu() path. We can then safely fetch | ||
224 | * the breakpoint, use its callback, touch its counter | ||
225 | * while we are in an rcu_read_lock() path. | ||
226 | */ | ||
227 | rcu_read_lock(); | ||
228 | |||
229 | bp = __get_cpu_var(bp_per_reg); | ||
230 | if (!bp) | ||
231 | goto out; | ||
232 | info = counter_arch_bp(bp); | ||
233 | |||
234 | /* | ||
235 | * Return early after invoking user-callback function without restoring | ||
236 | * DABR if the breakpoint is from ptrace which always operates in | ||
237 | * one-shot mode. The ptrace-ed process will receive the SIGTRAP signal | ||
238 | * generated in do_dabr(). | ||
239 | */ | ||
240 | if (bp->overflow_handler == ptrace_triggered) { | ||
241 | perf_bp_event(bp, regs); | ||
242 | rc = NOTIFY_DONE; | ||
243 | goto out; | ||
244 | } | ||
245 | |||
246 | /* | ||
247 | * Verify if dar lies within the address range occupied by the symbol | ||
248 | * being watched to filter extraneous exceptions. If it doesn't, | ||
249 | * we still need to single-step the instruction, but we don't | ||
250 | * generate an event. | ||
251 | */ | ||
252 | info->extraneous_interrupt = !((bp->attr.bp_addr <= dar) && | ||
253 | (dar - bp->attr.bp_addr < bp->attr.bp_len)); | ||
254 | |||
255 | /* Do not emulate user-space instructions, instead single-step them */ | ||
256 | if (user_mode(regs)) { | ||
257 | bp->ctx->task->thread.last_hit_ubp = bp; | ||
258 | regs->msr |= MSR_SE; | ||
259 | goto out; | ||
260 | } | ||
261 | |||
262 | stepped = 0; | ||
263 | instr = 0; | ||
264 | if (!__get_user_inatomic(instr, (unsigned int *) regs->nip)) | ||
265 | stepped = emulate_step(regs, instr); | ||
266 | |||
267 | /* | ||
268 | * emulate_step() could not execute it. We've failed in reliably | ||
269 | * handling the hw-breakpoint. Unregister it and throw a warning | ||
270 | * message to let the user know about it. | ||
271 | */ | ||
272 | if (!stepped) { | ||
273 | WARN(1, "Unable to handle hardware breakpoint. Breakpoint at " | ||
274 | "0x%lx will be disabled.", info->address); | ||
275 | perf_event_disable(bp); | ||
276 | goto out; | ||
277 | } | ||
278 | /* | ||
279 | * As a policy, the callback is invoked in a 'trigger-after-execute' | ||
280 | * fashion | ||
281 | */ | ||
282 | if (!info->extraneous_interrupt) | ||
283 | perf_bp_event(bp, regs); | ||
284 | |||
285 | set_dabr(info->address | info->type | DABR_TRANSLATION); | ||
286 | out: | ||
287 | rcu_read_unlock(); | ||
288 | return rc; | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * Handle single-step exceptions following a DABR hit. | ||
293 | */ | ||
294 | int __kprobes single_step_dabr_instruction(struct die_args *args) | ||
295 | { | ||
296 | struct pt_regs *regs = args->regs; | ||
297 | struct perf_event *bp = NULL; | ||
298 | struct arch_hw_breakpoint *bp_info; | ||
299 | |||
300 | bp = current->thread.last_hit_ubp; | ||
301 | /* | ||
302 | * Check if we are single-stepping as a result of a | ||
303 | * previous HW Breakpoint exception | ||
304 | */ | ||
305 | if (!bp) | ||
306 | return NOTIFY_DONE; | ||
307 | |||
308 | bp_info = counter_arch_bp(bp); | ||
309 | |||
310 | /* | ||
311 | * We shall invoke the user-defined callback function in the single | ||
312 | * stepping handler to confirm to 'trigger-after-execute' semantics | ||
313 | */ | ||
314 | if (!bp_info->extraneous_interrupt) | ||
315 | perf_bp_event(bp, regs); | ||
316 | |||
317 | set_dabr(bp_info->address | bp_info->type | DABR_TRANSLATION); | ||
318 | current->thread.last_hit_ubp = NULL; | ||
319 | |||
320 | /* | ||
321 | * If the process was being single-stepped by ptrace, let the | ||
322 | * other single-step actions occur (e.g. generate SIGTRAP). | ||
323 | */ | ||
324 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
325 | return NOTIFY_DONE; | ||
326 | |||
327 | return NOTIFY_STOP; | ||
328 | } | ||
329 | |||
330 | /* | ||
331 | * Handle debug exception notifications. | ||
332 | */ | ||
333 | int __kprobes hw_breakpoint_exceptions_notify( | ||
334 | struct notifier_block *unused, unsigned long val, void *data) | ||
335 | { | ||
336 | int ret = NOTIFY_DONE; | ||
337 | |||
338 | switch (val) { | ||
339 | case DIE_DABR_MATCH: | ||
340 | ret = hw_breakpoint_handler(data); | ||
341 | break; | ||
342 | case DIE_SSTEP: | ||
343 | ret = single_step_dabr_instruction(data); | ||
344 | break; | ||
345 | } | ||
346 | |||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | /* | ||
351 | * Release the user breakpoints used by ptrace | ||
352 | */ | ||
353 | void flush_ptrace_hw_breakpoint(struct task_struct *tsk) | ||
354 | { | ||
355 | struct thread_struct *t = &tsk->thread; | ||
356 | |||
357 | unregister_hw_breakpoint(t->ptrace_bps[0]); | ||
358 | t->ptrace_bps[0] = NULL; | ||
359 | } | ||
360 | |||
361 | void hw_breakpoint_pmu_read(struct perf_event *bp) | ||
362 | { | ||
363 | /* TODO */ | ||
364 | } | ||
diff --git a/arch/powerpc/kernel/idle_book3e.S b/arch/powerpc/kernel/idle_book3e.S new file mode 100644 index 000000000000..16c002d6bdf1 --- /dev/null +++ b/arch/powerpc/kernel/idle_book3e.S | |||
@@ -0,0 +1,86 @@ | |||
1 | /* | ||
2 | * Copyright 2010 IBM Corp, Benjamin Herrenschmidt <benh@kernel.crashing.org> | ||
3 | * | ||
4 | * Generic idle routine for Book3E processors | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/threads.h> | ||
13 | #include <asm/reg.h> | ||
14 | #include <asm/ppc_asm.h> | ||
15 | #include <asm/asm-offsets.h> | ||
16 | #include <asm/ppc-opcode.h> | ||
17 | #include <asm/processor.h> | ||
18 | #include <asm/thread_info.h> | ||
19 | |||
20 | /* 64-bit version only for now */ | ||
21 | #ifdef CONFIG_PPC64 | ||
22 | |||
23 | _GLOBAL(book3e_idle) | ||
24 | /* Save LR for later */ | ||
25 | mflr r0 | ||
26 | std r0,16(r1) | ||
27 | |||
28 | /* Hard disable interrupts */ | ||
29 | wrteei 0 | ||
30 | |||
31 | /* Now check if an interrupt came in while we were soft disabled | ||
32 | * since we may otherwise lose it (doorbells etc...). We know | ||
33 | * that since PACAHARDIRQEN will have been cleared in that case. | ||
34 | */ | ||
35 | lbz r3,PACAHARDIRQEN(r13) | ||
36 | cmpwi cr0,r3,0 | ||
37 | beqlr | ||
38 | |||
39 | /* Now we are going to mark ourselves as soft and hard enables in | ||
40 | * order to be able to take interrupts while asleep. We inform lockdep | ||
41 | * of that. We don't actually turn interrupts on just yet tho. | ||
42 | */ | ||
43 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
44 | stdu r1,-128(r1) | ||
45 | bl .trace_hardirqs_on | ||
46 | #endif | ||
47 | li r0,1 | ||
48 | stb r0,PACASOFTIRQEN(r13) | ||
49 | stb r0,PACAHARDIRQEN(r13) | ||
50 | |||
51 | /* Interrupts will make use return to LR, so get something we want | ||
52 | * in there | ||
53 | */ | ||
54 | bl 1f | ||
55 | |||
56 | /* Hard disable interrupts again */ | ||
57 | wrteei 0 | ||
58 | |||
59 | /* Mark them off again in the PACA as well */ | ||
60 | li r0,0 | ||
61 | stb r0,PACASOFTIRQEN(r13) | ||
62 | stb r0,PACAHARDIRQEN(r13) | ||
63 | |||
64 | /* Tell lockdep about it */ | ||
65 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
66 | bl .trace_hardirqs_off | ||
67 | addi r1,r1,128 | ||
68 | #endif | ||
69 | ld r0,16(r1) | ||
70 | mtlr r0 | ||
71 | blr | ||
72 | |||
73 | 1: /* Let's set the _TLF_NAPPING flag so interrupts make us return | ||
74 | * to the right spot | ||
75 | */ | ||
76 | clrrdi r11,r1,THREAD_SHIFT | ||
77 | ld r10,TI_LOCAL_FLAGS(r11) | ||
78 | ori r10,r10,_TLF_NAPPING | ||
79 | std r10,TI_LOCAL_FLAGS(r11) | ||
80 | |||
81 | /* We can now re-enable hard interrupts and go to sleep */ | ||
82 | wrteei 1 | ||
83 | 1: PPC_WAIT(0) | ||
84 | b 1b | ||
85 | |||
86 | #endif /* CONFIG_PPC64 */ | ||
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 77be3d058a65..8f96d3198905 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -64,6 +64,8 @@ | |||
64 | #include <asm/ptrace.h> | 64 | #include <asm/ptrace.h> |
65 | #include <asm/machdep.h> | 65 | #include <asm/machdep.h> |
66 | #include <asm/udbg.h> | 66 | #include <asm/udbg.h> |
67 | #include <asm/dbell.h> | ||
68 | |||
67 | #ifdef CONFIG_PPC64 | 69 | #ifdef CONFIG_PPC64 |
68 | #include <asm/paca.h> | 70 | #include <asm/paca.h> |
69 | #include <asm/firmware.h> | 71 | #include <asm/firmware.h> |
@@ -153,14 +155,28 @@ notrace void raw_local_irq_restore(unsigned long en) | |||
153 | if (get_hard_enabled()) | 155 | if (get_hard_enabled()) |
154 | return; | 156 | return; |
155 | 157 | ||
158 | #if defined(CONFIG_BOOKE) && defined(CONFIG_SMP) | ||
159 | /* Check for pending doorbell interrupts and resend to ourself */ | ||
160 | doorbell_check_self(); | ||
161 | #endif | ||
162 | |||
156 | /* | 163 | /* |
157 | * Need to hard-enable interrupts here. Since currently disabled, | 164 | * Need to hard-enable interrupts here. Since currently disabled, |
158 | * no need to take further asm precautions against preemption; but | 165 | * no need to take further asm precautions against preemption; but |
159 | * use local_paca instead of get_paca() to avoid preemption checking. | 166 | * use local_paca instead of get_paca() to avoid preemption checking. |
160 | */ | 167 | */ |
161 | local_paca->hard_enabled = en; | 168 | local_paca->hard_enabled = en; |
169 | |||
170 | #ifndef CONFIG_BOOKE | ||
171 | /* On server, re-trigger the decrementer if it went negative since | ||
172 | * some processors only trigger on edge transitions of the sign bit. | ||
173 | * | ||
174 | * BookE has a level sensitive decrementer (latches in TSR) so we | ||
175 | * don't need that | ||
176 | */ | ||
162 | if ((int)mfspr(SPRN_DEC) < 0) | 177 | if ((int)mfspr(SPRN_DEC) < 0) |
163 | mtspr(SPRN_DEC, 1); | 178 | mtspr(SPRN_DEC, 1); |
179 | #endif /* CONFIG_BOOKE */ | ||
164 | 180 | ||
165 | /* | 181 | /* |
166 | * Force the delivery of pending soft-disabled interrupts on PS3. | 182 | * Force the delivery of pending soft-disabled interrupts on PS3. |
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index 89f005116aac..dd6c141f1662 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c | |||
@@ -45,6 +45,18 @@ void machine_kexec_cleanup(struct kimage *image) | |||
45 | ppc_md.machine_kexec_cleanup(image); | 45 | ppc_md.machine_kexec_cleanup(image); |
46 | } | 46 | } |
47 | 47 | ||
48 | void arch_crash_save_vmcoreinfo(void) | ||
49 | { | ||
50 | |||
51 | #ifdef CONFIG_NEED_MULTIPLE_NODES | ||
52 | VMCOREINFO_SYMBOL(node_data); | ||
53 | VMCOREINFO_LENGTH(node_data, MAX_NUMNODES); | ||
54 | #endif | ||
55 | #ifndef CONFIG_NEED_MULTIPLE_NODES | ||
56 | VMCOREINFO_SYMBOL(contig_page_data); | ||
57 | #endif | ||
58 | } | ||
59 | |||
48 | /* | 60 | /* |
49 | * Do not allocate memory (or fail in any way) in machine_kexec(). | 61 | * Do not allocate memory (or fail in any way) in machine_kexec(). |
50 | * We are past the point of no return, committed to rebooting now. | 62 | * We are past the point of no return, committed to rebooting now. |
@@ -144,24 +156,24 @@ int overlaps_crashkernel(unsigned long start, unsigned long size) | |||
144 | } | 156 | } |
145 | 157 | ||
146 | /* Values we need to export to the second kernel via the device tree. */ | 158 | /* Values we need to export to the second kernel via the device tree. */ |
147 | static unsigned long kernel_end; | 159 | static phys_addr_t kernel_end; |
148 | static unsigned long crashk_size; | 160 | static phys_addr_t crashk_size; |
149 | 161 | ||
150 | static struct property kernel_end_prop = { | 162 | static struct property kernel_end_prop = { |
151 | .name = "linux,kernel-end", | 163 | .name = "linux,kernel-end", |
152 | .length = sizeof(unsigned long), | 164 | .length = sizeof(phys_addr_t), |
153 | .value = &kernel_end, | 165 | .value = &kernel_end, |
154 | }; | 166 | }; |
155 | 167 | ||
156 | static struct property crashk_base_prop = { | 168 | static struct property crashk_base_prop = { |
157 | .name = "linux,crashkernel-base", | 169 | .name = "linux,crashkernel-base", |
158 | .length = sizeof(unsigned long), | 170 | .length = sizeof(phys_addr_t), |
159 | .value = &crashk_res.start, | 171 | .value = &crashk_res.start, |
160 | }; | 172 | }; |
161 | 173 | ||
162 | static struct property crashk_size_prop = { | 174 | static struct property crashk_size_prop = { |
163 | .name = "linux,crashkernel-size", | 175 | .name = "linux,crashkernel-size", |
164 | .length = sizeof(unsigned long), | 176 | .length = sizeof(phys_addr_t), |
165 | .value = &crashk_size, | 177 | .value = &crashk_size, |
166 | }; | 178 | }; |
167 | 179 | ||
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index ed31a29c4ff7..583af70c4b14 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/thread_info.h> | 15 | #include <linux/thread_info.h> |
16 | #include <linux/init_task.h> | 16 | #include <linux/init_task.h> |
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | #include <linux/kernel.h> | ||
19 | #include <linux/cpu.h> | ||
18 | 20 | ||
19 | #include <asm/page.h> | 21 | #include <asm/page.h> |
20 | #include <asm/current.h> | 22 | #include <asm/current.h> |
@@ -25,6 +27,7 @@ | |||
25 | #include <asm/sections.h> /* _end */ | 27 | #include <asm/sections.h> /* _end */ |
26 | #include <asm/prom.h> | 28 | #include <asm/prom.h> |
27 | #include <asm/smp.h> | 29 | #include <asm/smp.h> |
30 | #include <asm/hw_breakpoint.h> | ||
28 | 31 | ||
29 | int default_machine_kexec_prepare(struct kimage *image) | 32 | int default_machine_kexec_prepare(struct kimage *image) |
30 | { | 33 | { |
@@ -165,6 +168,7 @@ static void kexec_smp_down(void *arg) | |||
165 | while(kexec_all_irq_disabled == 0) | 168 | while(kexec_all_irq_disabled == 0) |
166 | cpu_relax(); | 169 | cpu_relax(); |
167 | mb(); /* make sure all irqs are disabled before this */ | 170 | mb(); /* make sure all irqs are disabled before this */ |
171 | hw_breakpoint_disable(); | ||
168 | /* | 172 | /* |
169 | * Now every CPU has IRQs off, we can clear out any pending | 173 | * Now every CPU has IRQs off, we can clear out any pending |
170 | * IPIs and be sure that no more will come in after this. | 174 | * IPIs and be sure that no more will come in after this. |
@@ -180,8 +184,22 @@ static void kexec_prepare_cpus_wait(int wait_state) | |||
180 | { | 184 | { |
181 | int my_cpu, i, notified=-1; | 185 | int my_cpu, i, notified=-1; |
182 | 186 | ||
187 | hw_breakpoint_disable(); | ||
183 | my_cpu = get_cpu(); | 188 | my_cpu = get_cpu(); |
184 | /* Make sure each CPU has atleast made it to the state we need */ | 189 | /* Make sure each CPU has at least made it to the state we need. |
190 | * | ||
191 | * FIXME: There is a (slim) chance of a problem if not all of the CPUs | ||
192 | * are correctly onlined. If somehow we start a CPU on boot with RTAS | ||
193 | * start-cpu, but somehow that CPU doesn't write callin_cpu_map[] in | ||
194 | * time, the boot CPU will timeout. If it does eventually execute | ||
195 | * stuff, the secondary will start up (paca[].cpu_start was written) and | ||
196 | * get into a peculiar state. If the platform supports | ||
197 | * smp_ops->take_timebase(), the secondary CPU will probably be spinning | ||
198 | * in there. If not (i.e. pseries), the secondary will continue on and | ||
199 | * try to online itself/idle/etc. If it survives that, we need to find | ||
200 | * these possible-but-not-online-but-should-be CPUs and chaperone them | ||
201 | * into kexec_smp_wait(). | ||
202 | */ | ||
185 | for_each_online_cpu(i) { | 203 | for_each_online_cpu(i) { |
186 | if (i == my_cpu) | 204 | if (i == my_cpu) |
187 | continue; | 205 | continue; |
@@ -189,9 +207,9 @@ static void kexec_prepare_cpus_wait(int wait_state) | |||
189 | while (paca[i].kexec_state < wait_state) { | 207 | while (paca[i].kexec_state < wait_state) { |
190 | barrier(); | 208 | barrier(); |
191 | if (i != notified) { | 209 | if (i != notified) { |
192 | printk( "kexec: waiting for cpu %d (physical" | 210 | printk(KERN_INFO "kexec: waiting for cpu %d " |
193 | " %d) to enter %i state\n", | 211 | "(physical %d) to enter %i state\n", |
194 | i, paca[i].hw_cpu_id, wait_state); | 212 | i, paca[i].hw_cpu_id, wait_state); |
195 | notified = i; | 213 | notified = i; |
196 | } | 214 | } |
197 | } | 215 | } |
@@ -199,9 +217,32 @@ static void kexec_prepare_cpus_wait(int wait_state) | |||
199 | mb(); | 217 | mb(); |
200 | } | 218 | } |
201 | 219 | ||
202 | static void kexec_prepare_cpus(void) | 220 | /* |
221 | * We need to make sure each present CPU is online. The next kernel will scan | ||
222 | * the device tree and assume primary threads are online and query secondary | ||
223 | * threads via RTAS to online them if required. If we don't online primary | ||
224 | * threads, they will be stuck. However, we also online secondary threads as we | ||
225 | * may be using 'cede offline'. In this case RTAS doesn't see the secondary | ||
226 | * threads as offline -- and again, these CPUs will be stuck. | ||
227 | * | ||
228 | * So, we online all CPUs that should be running, including secondary threads. | ||
229 | */ | ||
230 | static void wake_offline_cpus(void) | ||
203 | { | 231 | { |
232 | int cpu = 0; | ||
204 | 233 | ||
234 | for_each_present_cpu(cpu) { | ||
235 | if (!cpu_online(cpu)) { | ||
236 | printk(KERN_INFO "kexec: Waking offline cpu %d.\n", | ||
237 | cpu); | ||
238 | cpu_up(cpu); | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | |||
243 | static void kexec_prepare_cpus(void) | ||
244 | { | ||
245 | wake_offline_cpus(); | ||
205 | smp_call_function(kexec_smp_down, NULL, /* wait */0); | 246 | smp_call_function(kexec_smp_down, NULL, /* wait */0); |
206 | local_irq_disable(); | 247 | local_irq_disable(); |
207 | mb(); /* make sure IRQs are disabled before we say they are */ | 248 | mb(); /* make sure IRQs are disabled before we say they are */ |
@@ -215,7 +256,10 @@ static void kexec_prepare_cpus(void) | |||
215 | if (ppc_md.kexec_cpu_down) | 256 | if (ppc_md.kexec_cpu_down) |
216 | ppc_md.kexec_cpu_down(0, 0); | 257 | ppc_md.kexec_cpu_down(0, 0); |
217 | 258 | ||
218 | /* Before removing MMU mapings make sure all CPUs have entered real mode */ | 259 | /* |
260 | * Before removing MMU mappings make sure all CPUs have entered real | ||
261 | * mode: | ||
262 | */ | ||
219 | kexec_prepare_cpus_wait(KEXEC_STATE_REAL_MODE); | 263 | kexec_prepare_cpus_wait(KEXEC_STATE_REAL_MODE); |
220 | 264 | ||
221 | put_cpu(); | 265 | put_cpu(); |
@@ -257,6 +301,12 @@ static void kexec_prepare_cpus(void) | |||
257 | static union thread_union kexec_stack __init_task_data = | 301 | static union thread_union kexec_stack __init_task_data = |
258 | { }; | 302 | { }; |
259 | 303 | ||
304 | /* | ||
305 | * For similar reasons to the stack above, the kexecing CPU needs to be on a | ||
306 | * static PACA; we switch to kexec_paca. | ||
307 | */ | ||
308 | struct paca_struct kexec_paca; | ||
309 | |||
260 | /* Our assembly helper, in kexec_stub.S */ | 310 | /* Our assembly helper, in kexec_stub.S */ |
261 | extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start, | 311 | extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start, |
262 | void *image, void *control, | 312 | void *image, void *control, |
@@ -278,12 +328,28 @@ void default_machine_kexec(struct kimage *image) | |||
278 | if (crashing_cpu == -1) | 328 | if (crashing_cpu == -1) |
279 | kexec_prepare_cpus(); | 329 | kexec_prepare_cpus(); |
280 | 330 | ||
331 | pr_debug("kexec: Starting switchover sequence.\n"); | ||
332 | |||
281 | /* switch to a staticly allocated stack. Based on irq stack code. | 333 | /* switch to a staticly allocated stack. Based on irq stack code. |
282 | * XXX: the task struct will likely be invalid once we do the copy! | 334 | * XXX: the task struct will likely be invalid once we do the copy! |
283 | */ | 335 | */ |
284 | kexec_stack.thread_info.task = current_thread_info()->task; | 336 | kexec_stack.thread_info.task = current_thread_info()->task; |
285 | kexec_stack.thread_info.flags = 0; | 337 | kexec_stack.thread_info.flags = 0; |
286 | 338 | ||
339 | /* We need a static PACA, too; copy this CPU's PACA over and switch to | ||
340 | * it. Also poison per_cpu_offset to catch anyone using non-static | ||
341 | * data. | ||
342 | */ | ||
343 | memcpy(&kexec_paca, get_paca(), sizeof(struct paca_struct)); | ||
344 | kexec_paca.data_offset = 0xedeaddeadeeeeeeeUL; | ||
345 | paca = (struct paca_struct *)RELOC_HIDE(&kexec_paca, 0) - | ||
346 | kexec_paca.paca_index; | ||
347 | setup_paca(&kexec_paca); | ||
348 | |||
349 | /* XXX: If anyone does 'dynamic lppacas' this will also need to be | ||
350 | * switched to a static version! | ||
351 | */ | ||
352 | |||
287 | /* Some things are best done in assembly. Finding globals with | 353 | /* Some things are best done in assembly. Finding globals with |
288 | * a toc is easier in C, so pass in what we can. | 354 | * a toc is easier in C, so pass in what we can. |
289 | */ | 355 | */ |
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 139a773853f4..d0a26f1770fe 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c | |||
@@ -105,6 +105,16 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu) | |||
105 | #endif /* CONFIG_PPC_STD_MMU_64 */ | 105 | #endif /* CONFIG_PPC_STD_MMU_64 */ |
106 | } | 106 | } |
107 | 107 | ||
108 | /* Put the paca pointer into r13 and SPRG_PACA */ | ||
109 | void setup_paca(struct paca_struct *new_paca) | ||
110 | { | ||
111 | local_paca = new_paca; | ||
112 | mtspr(SPRN_SPRG_PACA, local_paca); | ||
113 | #ifdef CONFIG_PPC_BOOK3E | ||
114 | mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb); | ||
115 | #endif | ||
116 | } | ||
117 | |||
108 | static int __initdata paca_size; | 118 | static int __initdata paca_size; |
109 | 119 | ||
110 | void __init allocate_pacas(void) | 120 | void __init allocate_pacas(void) |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 773424df828a..551f6713ff42 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/kernel_stat.h> | 37 | #include <linux/kernel_stat.h> |
38 | #include <linux/personality.h> | 38 | #include <linux/personality.h> |
39 | #include <linux/random.h> | 39 | #include <linux/random.h> |
40 | #include <linux/hw_breakpoint.h> | ||
40 | 41 | ||
41 | #include <asm/pgtable.h> | 42 | #include <asm/pgtable.h> |
42 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
@@ -462,14 +463,42 @@ struct task_struct *__switch_to(struct task_struct *prev, | |||
462 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS | 463 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS |
463 | switch_booke_debug_regs(&new->thread); | 464 | switch_booke_debug_regs(&new->thread); |
464 | #else | 465 | #else |
466 | /* | ||
467 | * For PPC_BOOK3S_64, we use the hw-breakpoint interfaces that would | ||
468 | * schedule DABR | ||
469 | */ | ||
470 | #ifndef CONFIG_HAVE_HW_BREAKPOINT | ||
465 | if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) | 471 | if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) |
466 | set_dabr(new->thread.dabr); | 472 | set_dabr(new->thread.dabr); |
473 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
467 | #endif | 474 | #endif |
468 | 475 | ||
469 | 476 | ||
470 | new_thread = &new->thread; | 477 | new_thread = &new->thread; |
471 | old_thread = ¤t->thread; | 478 | old_thread = ¤t->thread; |
472 | 479 | ||
480 | #if defined(CONFIG_PPC_BOOK3E_64) | ||
481 | /* XXX Current Book3E code doesn't deal with kernel side DBCR0, | ||
482 | * we always hold the user values, so we set it now. | ||
483 | * | ||
484 | * However, we ensure the kernel MSR:DE is appropriately cleared too | ||
485 | * to avoid spurrious single step exceptions in the kernel. | ||
486 | * | ||
487 | * This will have to change to merge with the ppc32 code at some point, | ||
488 | * but I don't like much what ppc32 is doing today so there's some | ||
489 | * thinking needed there | ||
490 | */ | ||
491 | if ((new_thread->dbcr0 | old_thread->dbcr0) & DBCR0_IDM) { | ||
492 | u32 dbcr0; | ||
493 | |||
494 | mtmsr(mfmsr() & ~MSR_DE); | ||
495 | isync(); | ||
496 | dbcr0 = mfspr(SPRN_DBCR0); | ||
497 | dbcr0 = (dbcr0 & DBCR0_EDM) | new_thread->dbcr0; | ||
498 | mtspr(SPRN_DBCR0, dbcr0); | ||
499 | } | ||
500 | #endif /* CONFIG_PPC64_BOOK3E */ | ||
501 | |||
473 | #ifdef CONFIG_PPC64 | 502 | #ifdef CONFIG_PPC64 |
474 | /* | 503 | /* |
475 | * Collect processor utilization data per process | 504 | * Collect processor utilization data per process |
@@ -642,7 +671,11 @@ void flush_thread(void) | |||
642 | { | 671 | { |
643 | discard_lazy_cpu_state(); | 672 | discard_lazy_cpu_state(); |
644 | 673 | ||
674 | #ifdef CONFIG_HAVE_HW_BREAKPOINTS | ||
675 | flush_ptrace_hw_breakpoint(current); | ||
676 | #else /* CONFIG_HAVE_HW_BREAKPOINTS */ | ||
645 | set_debug_reg_defaults(¤t->thread); | 677 | set_debug_reg_defaults(¤t->thread); |
678 | #endif /* CONFIG_HAVE_HW_BREAKPOINTS */ | ||
646 | } | 679 | } |
647 | 680 | ||
648 | void | 681 | void |
@@ -660,6 +693,9 @@ void prepare_to_copy(struct task_struct *tsk) | |||
660 | flush_altivec_to_thread(current); | 693 | flush_altivec_to_thread(current); |
661 | flush_vsx_to_thread(current); | 694 | flush_vsx_to_thread(current); |
662 | flush_spe_to_thread(current); | 695 | flush_spe_to_thread(current); |
696 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
697 | flush_ptrace_hw_breakpoint(tsk); | ||
698 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
663 | } | 699 | } |
664 | 700 | ||
665 | /* | 701 | /* |
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 3b6f8ae9b8cc..941ff4dbc567 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -311,6 +311,24 @@ static void __init prom_print_hex(unsigned long val) | |||
311 | call_prom("write", 3, 1, _prom->stdout, buf, nibbles); | 311 | call_prom("write", 3, 1, _prom->stdout, buf, nibbles); |
312 | } | 312 | } |
313 | 313 | ||
314 | /* max number of decimal digits in an unsigned long */ | ||
315 | #define UL_DIGITS 21 | ||
316 | static void __init prom_print_dec(unsigned long val) | ||
317 | { | ||
318 | int i, size; | ||
319 | char buf[UL_DIGITS+1]; | ||
320 | struct prom_t *_prom = &RELOC(prom); | ||
321 | |||
322 | for (i = UL_DIGITS-1; i >= 0; i--) { | ||
323 | buf[i] = (val % 10) + '0'; | ||
324 | val = val/10; | ||
325 | if (val == 0) | ||
326 | break; | ||
327 | } | ||
328 | /* shift stuff down */ | ||
329 | size = UL_DIGITS - i; | ||
330 | call_prom("write", 3, 1, _prom->stdout, buf+i, size); | ||
331 | } | ||
314 | 332 | ||
315 | static void __init prom_printf(const char *format, ...) | 333 | static void __init prom_printf(const char *format, ...) |
316 | { | 334 | { |
@@ -350,6 +368,14 @@ static void __init prom_printf(const char *format, ...) | |||
350 | v = va_arg(args, unsigned long); | 368 | v = va_arg(args, unsigned long); |
351 | prom_print_hex(v); | 369 | prom_print_hex(v); |
352 | break; | 370 | break; |
371 | case 'l': | ||
372 | ++q; | ||
373 | if (*q == 'u') { /* '%lu' */ | ||
374 | ++q; | ||
375 | v = va_arg(args, unsigned long); | ||
376 | prom_print_dec(v); | ||
377 | } | ||
378 | break; | ||
353 | } | 379 | } |
354 | } | 380 | } |
355 | } | 381 | } |
@@ -835,11 +861,11 @@ static int __init prom_count_smt_threads(void) | |||
835 | if (plen == PROM_ERROR) | 861 | if (plen == PROM_ERROR) |
836 | break; | 862 | break; |
837 | plen >>= 2; | 863 | plen >>= 2; |
838 | prom_debug("Found 0x%x smt threads per core\n", (unsigned long)plen); | 864 | prom_debug("Found %lu smt threads per core\n", (unsigned long)plen); |
839 | 865 | ||
840 | /* Sanity check */ | 866 | /* Sanity check */ |
841 | if (plen < 1 || plen > 64) { | 867 | if (plen < 1 || plen > 64) { |
842 | prom_printf("Threads per core 0x%x out of bounds, assuming 1\n", | 868 | prom_printf("Threads per core %lu out of bounds, assuming 1\n", |
843 | (unsigned long)plen); | 869 | (unsigned long)plen); |
844 | return 1; | 870 | return 1; |
845 | } | 871 | } |
@@ -869,12 +895,12 @@ static void __init prom_send_capabilities(void) | |||
869 | cores = (u32 *)PTRRELOC(&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET]); | 895 | cores = (u32 *)PTRRELOC(&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET]); |
870 | if (*cores != NR_CPUS) { | 896 | if (*cores != NR_CPUS) { |
871 | prom_printf("WARNING ! " | 897 | prom_printf("WARNING ! " |
872 | "ibm_architecture_vec structure inconsistent: 0x%x !\n", | 898 | "ibm_architecture_vec structure inconsistent: %lu!\n", |
873 | *cores); | 899 | *cores); |
874 | } else { | 900 | } else { |
875 | *cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads()); | 901 | *cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads()); |
876 | prom_printf("Max number of cores passed to firmware: 0x%x\n", | 902 | prom_printf("Max number of cores passed to firmware: %lu (NR_CPUS = %lu)\n", |
877 | (unsigned long)*cores); | 903 | *cores, NR_CPUS); |
878 | } | 904 | } |
879 | 905 | ||
880 | /* try calling the ibm,client-architecture-support method */ | 906 | /* try calling the ibm,client-architecture-support method */ |
@@ -1482,7 +1508,7 @@ static void __init prom_hold_cpus(void) | |||
1482 | reg = -1; | 1508 | reg = -1; |
1483 | prom_getprop(node, "reg", ®, sizeof(reg)); | 1509 | prom_getprop(node, "reg", ®, sizeof(reg)); |
1484 | 1510 | ||
1485 | prom_debug("cpu hw idx = 0x%x\n", reg); | 1511 | prom_debug("cpu hw idx = %lu\n", reg); |
1486 | 1512 | ||
1487 | /* Init the acknowledge var which will be reset by | 1513 | /* Init the acknowledge var which will be reset by |
1488 | * the secondary cpu when it awakens from its OF | 1514 | * the secondary cpu when it awakens from its OF |
@@ -1492,7 +1518,7 @@ static void __init prom_hold_cpus(void) | |||
1492 | 1518 | ||
1493 | if (reg != _prom->cpu) { | 1519 | if (reg != _prom->cpu) { |
1494 | /* Primary Thread of non-boot cpu */ | 1520 | /* Primary Thread of non-boot cpu */ |
1495 | prom_printf("starting cpu hw idx %x... ", reg); | 1521 | prom_printf("starting cpu hw idx %lu... ", reg); |
1496 | call_prom("start-cpu", 3, 0, node, | 1522 | call_prom("start-cpu", 3, 0, node, |
1497 | secondary_hold, reg); | 1523 | secondary_hold, reg); |
1498 | 1524 | ||
@@ -1507,7 +1533,7 @@ static void __init prom_hold_cpus(void) | |||
1507 | } | 1533 | } |
1508 | #ifdef CONFIG_SMP | 1534 | #ifdef CONFIG_SMP |
1509 | else | 1535 | else |
1510 | prom_printf("boot cpu hw idx %x\n", reg); | 1536 | prom_printf("boot cpu hw idx %lu\n", reg); |
1511 | #endif /* CONFIG_SMP */ | 1537 | #endif /* CONFIG_SMP */ |
1512 | } | 1538 | } |
1513 | 1539 | ||
@@ -2420,7 +2446,7 @@ static void __init prom_find_boot_cpu(void) | |||
2420 | prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval)); | 2446 | prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval)); |
2421 | _prom->cpu = getprop_rval; | 2447 | _prom->cpu = getprop_rval; |
2422 | 2448 | ||
2423 | prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu); | 2449 | prom_debug("Booting CPU hw index = %lu\n", _prom->cpu); |
2424 | } | 2450 | } |
2425 | 2451 | ||
2426 | static void __init prom_check_initrd(unsigned long r3, unsigned long r4) | 2452 | static void __init prom_check_initrd(unsigned long r3, unsigned long r4) |
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 7a0c0199ea28..11f3cd9c832f 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #ifdef CONFIG_PPC32 | 32 | #ifdef CONFIG_PPC32 |
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #endif | 34 | #endif |
35 | #include <linux/hw_breakpoint.h> | ||
36 | #include <linux/perf_event.h> | ||
35 | 37 | ||
36 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
37 | #include <asm/page.h> | 39 | #include <asm/page.h> |
@@ -866,9 +868,34 @@ void user_disable_single_step(struct task_struct *task) | |||
866 | clear_tsk_thread_flag(task, TIF_SINGLESTEP); | 868 | clear_tsk_thread_flag(task, TIF_SINGLESTEP); |
867 | } | 869 | } |
868 | 870 | ||
871 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
872 | void ptrace_triggered(struct perf_event *bp, int nmi, | ||
873 | struct perf_sample_data *data, struct pt_regs *regs) | ||
874 | { | ||
875 | struct perf_event_attr attr; | ||
876 | |||
877 | /* | ||
878 | * Disable the breakpoint request here since ptrace has defined a | ||
879 | * one-shot behaviour for breakpoint exceptions in PPC64. | ||
880 | * The SIGTRAP signal is generated automatically for us in do_dabr(). | ||
881 | * We don't have to do anything about that here | ||
882 | */ | ||
883 | attr = bp->attr; | ||
884 | attr.disabled = true; | ||
885 | modify_user_hw_breakpoint(bp, &attr); | ||
886 | } | ||
887 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
888 | |||
869 | int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, | 889 | int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, |
870 | unsigned long data) | 890 | unsigned long data) |
871 | { | 891 | { |
892 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
893 | int ret; | ||
894 | struct thread_struct *thread = &(task->thread); | ||
895 | struct perf_event *bp; | ||
896 | struct perf_event_attr attr; | ||
897 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
898 | |||
872 | /* For ppc64 we support one DABR and no IABR's at the moment (ppc64). | 899 | /* For ppc64 we support one DABR and no IABR's at the moment (ppc64). |
873 | * For embedded processors we support one DAC and no IAC's at the | 900 | * For embedded processors we support one DAC and no IAC's at the |
874 | * moment. | 901 | * moment. |
@@ -896,6 +923,43 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, | |||
896 | /* Ensure breakpoint translation bit is set */ | 923 | /* Ensure breakpoint translation bit is set */ |
897 | if (data && !(data & DABR_TRANSLATION)) | 924 | if (data && !(data & DABR_TRANSLATION)) |
898 | return -EIO; | 925 | return -EIO; |
926 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
927 | bp = thread->ptrace_bps[0]; | ||
928 | if ((!data) || !(data & (DABR_DATA_WRITE | DABR_DATA_READ))) { | ||
929 | if (bp) { | ||
930 | unregister_hw_breakpoint(bp); | ||
931 | thread->ptrace_bps[0] = NULL; | ||
932 | } | ||
933 | return 0; | ||
934 | } | ||
935 | if (bp) { | ||
936 | attr = bp->attr; | ||
937 | attr.bp_addr = data & ~HW_BREAKPOINT_ALIGN; | ||
938 | arch_bp_generic_fields(data & | ||
939 | (DABR_DATA_WRITE | DABR_DATA_READ), | ||
940 | &attr.bp_type); | ||
941 | ret = modify_user_hw_breakpoint(bp, &attr); | ||
942 | if (ret) | ||
943 | return ret; | ||
944 | thread->ptrace_bps[0] = bp; | ||
945 | thread->dabr = data; | ||
946 | return 0; | ||
947 | } | ||
948 | |||
949 | /* Create a new breakpoint request if one doesn't exist already */ | ||
950 | hw_breakpoint_init(&attr); | ||
951 | attr.bp_addr = data & ~HW_BREAKPOINT_ALIGN; | ||
952 | arch_bp_generic_fields(data & (DABR_DATA_WRITE | DABR_DATA_READ), | ||
953 | &attr.bp_type); | ||
954 | |||
955 | thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr, | ||
956 | ptrace_triggered, task); | ||
957 | if (IS_ERR(bp)) { | ||
958 | thread->ptrace_bps[0] = NULL; | ||
959 | return PTR_ERR(bp); | ||
960 | } | ||
961 | |||
962 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
899 | 963 | ||
900 | /* Move contents to the DABR register */ | 964 | /* Move contents to the DABR register */ |
901 | task->thread.dabr = data; | 965 | task->thread.dabr = data; |
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index d0516dbee762..41048de3c6c3 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
@@ -47,14 +47,6 @@ struct rtas_t rtas = { | |||
47 | }; | 47 | }; |
48 | EXPORT_SYMBOL(rtas); | 48 | EXPORT_SYMBOL(rtas); |
49 | 49 | ||
50 | struct rtas_suspend_me_data { | ||
51 | atomic_t working; /* number of cpus accessing this struct */ | ||
52 | atomic_t done; | ||
53 | int token; /* ibm,suspend-me */ | ||
54 | int error; | ||
55 | struct completion *complete; /* wait on this until working == 0 */ | ||
56 | }; | ||
57 | |||
58 | DEFINE_SPINLOCK(rtas_data_buf_lock); | 50 | DEFINE_SPINLOCK(rtas_data_buf_lock); |
59 | EXPORT_SYMBOL(rtas_data_buf_lock); | 51 | EXPORT_SYMBOL(rtas_data_buf_lock); |
60 | 52 | ||
@@ -714,14 +706,53 @@ void rtas_os_term(char *str) | |||
714 | 706 | ||
715 | static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE; | 707 | static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE; |
716 | #ifdef CONFIG_PPC_PSERIES | 708 | #ifdef CONFIG_PPC_PSERIES |
717 | static void rtas_percpu_suspend_me(void *info) | 709 | static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_when_done) |
710 | { | ||
711 | u16 slb_size = mmu_slb_size; | ||
712 | int rc = H_MULTI_THREADS_ACTIVE; | ||
713 | int cpu; | ||
714 | |||
715 | slb_set_size(SLB_MIN_SIZE); | ||
716 | printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", smp_processor_id()); | ||
717 | |||
718 | while (rc == H_MULTI_THREADS_ACTIVE && !atomic_read(&data->done) && | ||
719 | !atomic_read(&data->error)) | ||
720 | rc = rtas_call(data->token, 0, 1, NULL); | ||
721 | |||
722 | if (rc || atomic_read(&data->error)) { | ||
723 | printk(KERN_DEBUG "ibm,suspend-me returned %d\n", rc); | ||
724 | slb_set_size(slb_size); | ||
725 | } | ||
726 | |||
727 | if (atomic_read(&data->error)) | ||
728 | rc = atomic_read(&data->error); | ||
729 | |||
730 | atomic_set(&data->error, rc); | ||
731 | |||
732 | if (wake_when_done) { | ||
733 | atomic_set(&data->done, 1); | ||
734 | |||
735 | for_each_online_cpu(cpu) | ||
736 | plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu)); | ||
737 | } | ||
738 | |||
739 | if (atomic_dec_return(&data->working) == 0) | ||
740 | complete(data->complete); | ||
741 | |||
742 | return rc; | ||
743 | } | ||
744 | |||
745 | int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data) | ||
746 | { | ||
747 | atomic_inc(&data->working); | ||
748 | return __rtas_suspend_last_cpu(data, 0); | ||
749 | } | ||
750 | |||
751 | static int __rtas_suspend_cpu(struct rtas_suspend_me_data *data, int wake_when_done) | ||
718 | { | 752 | { |
719 | long rc = H_SUCCESS; | 753 | long rc = H_SUCCESS; |
720 | unsigned long msr_save; | 754 | unsigned long msr_save; |
721 | u16 slb_size = mmu_slb_size; | ||
722 | int cpu; | 755 | int cpu; |
723 | struct rtas_suspend_me_data *data = | ||
724 | (struct rtas_suspend_me_data *)info; | ||
725 | 756 | ||
726 | atomic_inc(&data->working); | 757 | atomic_inc(&data->working); |
727 | 758 | ||
@@ -729,7 +760,7 @@ static void rtas_percpu_suspend_me(void *info) | |||
729 | msr_save = mfmsr(); | 760 | msr_save = mfmsr(); |
730 | mtmsr(msr_save & ~(MSR_EE)); | 761 | mtmsr(msr_save & ~(MSR_EE)); |
731 | 762 | ||
732 | while (rc == H_SUCCESS && !atomic_read(&data->done)) | 763 | while (rc == H_SUCCESS && !atomic_read(&data->done) && !atomic_read(&data->error)) |
733 | rc = plpar_hcall_norets(H_JOIN); | 764 | rc = plpar_hcall_norets(H_JOIN); |
734 | 765 | ||
735 | mtmsr(msr_save); | 766 | mtmsr(msr_save); |
@@ -741,33 +772,37 @@ static void rtas_percpu_suspend_me(void *info) | |||
741 | /* All other cpus are in H_JOIN, this cpu does | 772 | /* All other cpus are in H_JOIN, this cpu does |
742 | * the suspend. | 773 | * the suspend. |
743 | */ | 774 | */ |
744 | slb_set_size(SLB_MIN_SIZE); | 775 | return __rtas_suspend_last_cpu(data, wake_when_done); |
745 | printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", | ||
746 | smp_processor_id()); | ||
747 | data->error = rtas_call(data->token, 0, 1, NULL); | ||
748 | |||
749 | if (data->error) { | ||
750 | printk(KERN_DEBUG "ibm,suspend-me returned %d\n", | ||
751 | data->error); | ||
752 | slb_set_size(slb_size); | ||
753 | } | ||
754 | } else { | 776 | } else { |
755 | printk(KERN_ERR "H_JOIN on cpu %i failed with rc = %ld\n", | 777 | printk(KERN_ERR "H_JOIN on cpu %i failed with rc = %ld\n", |
756 | smp_processor_id(), rc); | 778 | smp_processor_id(), rc); |
757 | data->error = rc; | 779 | atomic_set(&data->error, rc); |
758 | } | 780 | } |
759 | 781 | ||
760 | atomic_set(&data->done, 1); | 782 | if (wake_when_done) { |
783 | atomic_set(&data->done, 1); | ||
761 | 784 | ||
762 | /* This cpu did the suspend or got an error; in either case, | 785 | /* This cpu did the suspend or got an error; in either case, |
763 | * we need to prod all other other cpus out of join state. | 786 | * we need to prod all other other cpus out of join state. |
764 | * Extra prods are harmless. | 787 | * Extra prods are harmless. |
765 | */ | 788 | */ |
766 | for_each_online_cpu(cpu) | 789 | for_each_online_cpu(cpu) |
767 | plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu)); | 790 | plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu)); |
791 | } | ||
768 | out: | 792 | out: |
769 | if (atomic_dec_return(&data->working) == 0) | 793 | if (atomic_dec_return(&data->working) == 0) |
770 | complete(data->complete); | 794 | complete(data->complete); |
795 | return rc; | ||
796 | } | ||
797 | |||
798 | int rtas_suspend_cpu(struct rtas_suspend_me_data *data) | ||
799 | { | ||
800 | return __rtas_suspend_cpu(data, 0); | ||
801 | } | ||
802 | |||
803 | static void rtas_percpu_suspend_me(void *info) | ||
804 | { | ||
805 | __rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1); | ||
771 | } | 806 | } |
772 | 807 | ||
773 | static int rtas_ibm_suspend_me(struct rtas_args *args) | 808 | static int rtas_ibm_suspend_me(struct rtas_args *args) |
@@ -802,22 +837,22 @@ static int rtas_ibm_suspend_me(struct rtas_args *args) | |||
802 | 837 | ||
803 | atomic_set(&data.working, 0); | 838 | atomic_set(&data.working, 0); |
804 | atomic_set(&data.done, 0); | 839 | atomic_set(&data.done, 0); |
840 | atomic_set(&data.error, 0); | ||
805 | data.token = rtas_token("ibm,suspend-me"); | 841 | data.token = rtas_token("ibm,suspend-me"); |
806 | data.error = 0; | ||
807 | data.complete = &done; | 842 | data.complete = &done; |
808 | 843 | ||
809 | /* Call function on all CPUs. One of us will make the | 844 | /* Call function on all CPUs. One of us will make the |
810 | * rtas call | 845 | * rtas call |
811 | */ | 846 | */ |
812 | if (on_each_cpu(rtas_percpu_suspend_me, &data, 0)) | 847 | if (on_each_cpu(rtas_percpu_suspend_me, &data, 0)) |
813 | data.error = -EINVAL; | 848 | atomic_set(&data.error, -EINVAL); |
814 | 849 | ||
815 | wait_for_completion(&done); | 850 | wait_for_completion(&done); |
816 | 851 | ||
817 | if (data.error != 0) | 852 | if (atomic_read(&data.error) != 0) |
818 | printk(KERN_ERR "Error doing global join\n"); | 853 | printk(KERN_ERR "Error doing global join\n"); |
819 | 854 | ||
820 | return data.error; | 855 | return atomic_read(&data.error); |
821 | } | 856 | } |
822 | #else /* CONFIG_PPC_PSERIES */ | 857 | #else /* CONFIG_PPC_PSERIES */ |
823 | static int rtas_ibm_suspend_me(struct rtas_args *args) | 858 | static int rtas_ibm_suspend_me(struct rtas_args *args) |
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index b7e6c7e193ae..70decd8068ca 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c | |||
@@ -94,6 +94,10 @@ struct screen_info screen_info = { | |||
94 | .orig_video_points = 16 | 94 | .orig_video_points = 16 |
95 | }; | 95 | }; |
96 | 96 | ||
97 | /* Variables required to store legacy IO irq routing */ | ||
98 | int of_i8042_kbd_irq; | ||
99 | int of_i8042_aux_irq; | ||
100 | |||
97 | #ifdef __DO_IRQ_CANON | 101 | #ifdef __DO_IRQ_CANON |
98 | /* XXX should go elsewhere eventually */ | 102 | /* XXX should go elsewhere eventually */ |
99 | int ppc_do_canonicalize_irqs; | 103 | int ppc_do_canonicalize_irqs; |
@@ -575,6 +579,15 @@ int check_legacy_ioport(unsigned long base_port) | |||
575 | np = of_find_compatible_node(NULL, NULL, "pnpPNP,f03"); | 579 | np = of_find_compatible_node(NULL, NULL, "pnpPNP,f03"); |
576 | if (np) { | 580 | if (np) { |
577 | parent = of_get_parent(np); | 581 | parent = of_get_parent(np); |
582 | |||
583 | of_i8042_kbd_irq = irq_of_parse_and_map(parent, 0); | ||
584 | if (!of_i8042_kbd_irq) | ||
585 | of_i8042_kbd_irq = 1; | ||
586 | |||
587 | of_i8042_aux_irq = irq_of_parse_and_map(parent, 1); | ||
588 | if (!of_i8042_aux_irq) | ||
589 | of_i8042_aux_irq = 12; | ||
590 | |||
578 | of_node_put(np); | 591 | of_node_put(np); |
579 | np = parent; | 592 | np = parent; |
580 | break; | 593 | break; |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index d135f93cb0f6..1bee4b68fa45 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -142,16 +142,6 @@ early_param("smt-enabled", early_smt_enabled); | |||
142 | #define check_smt_enabled() | 142 | #define check_smt_enabled() |
143 | #endif /* CONFIG_SMP */ | 143 | #endif /* CONFIG_SMP */ |
144 | 144 | ||
145 | /* Put the paca pointer into r13 and SPRG_PACA */ | ||
146 | static void __init setup_paca(struct paca_struct *new_paca) | ||
147 | { | ||
148 | local_paca = new_paca; | ||
149 | mtspr(SPRN_SPRG_PACA, local_paca); | ||
150 | #ifdef CONFIG_PPC_BOOK3E | ||
151 | mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb); | ||
152 | #endif | ||
153 | } | ||
154 | |||
155 | /* | 145 | /* |
156 | * Early initialization entry point. This is called by head.S | 146 | * Early initialization entry point. This is called by head.S |
157 | * with MMU translation disabled. We rely on the "feature" of | 147 | * with MMU translation disabled. We rely on the "feature" of |
@@ -600,6 +590,9 @@ static int pcpu_cpu_distance(unsigned int from, unsigned int to) | |||
600 | return REMOTE_DISTANCE; | 590 | return REMOTE_DISTANCE; |
601 | } | 591 | } |
602 | 592 | ||
593 | unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; | ||
594 | EXPORT_SYMBOL(__per_cpu_offset); | ||
595 | |||
603 | void __init setup_per_cpu_areas(void) | 596 | void __init setup_per_cpu_areas(void) |
604 | { | 597 | { |
605 | const size_t dyn_size = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE; | 598 | const size_t dyn_size = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE; |
@@ -624,8 +617,10 @@ void __init setup_per_cpu_areas(void) | |||
624 | panic("cannot initialize percpu area (err=%d)", rc); | 617 | panic("cannot initialize percpu area (err=%d)", rc); |
625 | 618 | ||
626 | delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start; | 619 | delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start; |
627 | for_each_possible_cpu(cpu) | 620 | for_each_possible_cpu(cpu) { |
628 | paca[cpu].data_offset = delta + pcpu_unit_offsets[cpu]; | 621 | __per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu]; |
622 | paca[cpu].data_offset = __per_cpu_offset[cpu]; | ||
623 | } | ||
629 | } | 624 | } |
630 | #endif | 625 | #endif |
631 | 626 | ||
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index a0afb555a7c9..7109f5b1baa8 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/tracehook.h> | 12 | #include <linux/tracehook.h> |
13 | #include <linux/signal.h> | 13 | #include <linux/signal.h> |
14 | #include <asm/hw_breakpoint.h> | ||
14 | #include <asm/uaccess.h> | 15 | #include <asm/uaccess.h> |
15 | #include <asm/unistd.h> | 16 | #include <asm/unistd.h> |
16 | 17 | ||
@@ -149,6 +150,8 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs) | |||
149 | if (current->thread.dabr) | 150 | if (current->thread.dabr) |
150 | set_dabr(current->thread.dabr); | 151 | set_dabr(current->thread.dabr); |
151 | #endif | 152 | #endif |
153 | /* Re-enable the breakpoints for the signal stack */ | ||
154 | thread_change_pc(current, regs); | ||
152 | 155 | ||
153 | if (is32) { | 156 | if (is32) { |
154 | if (ka.sa.sa_flags & SA_SIGINFO) | 157 | if (ka.sa.sa_flags & SA_SIGINFO) |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 5c196d1086d9..a61b3ddd7bb3 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -288,8 +288,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
288 | max_cpus = NR_CPUS; | 288 | max_cpus = NR_CPUS; |
289 | else | 289 | else |
290 | max_cpus = 1; | 290 | max_cpus = 1; |
291 | |||
292 | smp_space_timers(max_cpus); | ||
293 | 291 | ||
294 | for_each_possible_cpu(cpu) | 292 | for_each_possible_cpu(cpu) |
295 | if (cpu != boot_cpuid) | 293 | if (cpu != boot_cpuid) |
@@ -501,14 +499,6 @@ int __devinit start_secondary(void *unused) | |||
501 | current->active_mm = &init_mm; | 499 | current->active_mm = &init_mm; |
502 | 500 | ||
503 | smp_store_cpu_info(cpu); | 501 | smp_store_cpu_info(cpu); |
504 | |||
505 | #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) | ||
506 | /* Clear any pending timer interrupts */ | ||
507 | mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); | ||
508 | |||
509 | /* Enable decrementer interrupt */ | ||
510 | mtspr(SPRN_TCR, TCR_DIE); | ||
511 | #endif | ||
512 | set_dec(tb_ticks_per_jiffy); | 502 | set_dec(tb_ticks_per_jiffy); |
513 | preempt_disable(); | 503 | preempt_disable(); |
514 | cpu_callin_map[cpu] = 1; | 504 | cpu_callin_map[cpu] = 1; |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 0441bbdadbd1..ccb8759c8532 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -149,16 +149,6 @@ unsigned long tb_ticks_per_usec = 100; /* sane default */ | |||
149 | EXPORT_SYMBOL(tb_ticks_per_usec); | 149 | EXPORT_SYMBOL(tb_ticks_per_usec); |
150 | unsigned long tb_ticks_per_sec; | 150 | unsigned long tb_ticks_per_sec; |
151 | EXPORT_SYMBOL(tb_ticks_per_sec); /* for cputime_t conversions */ | 151 | EXPORT_SYMBOL(tb_ticks_per_sec); /* for cputime_t conversions */ |
152 | u64 tb_to_xs; | ||
153 | unsigned tb_to_us; | ||
154 | |||
155 | #define TICKLEN_SCALE NTP_SCALE_SHIFT | ||
156 | static u64 last_tick_len; /* units are ns / 2^TICKLEN_SCALE */ | ||
157 | static u64 ticklen_to_xs; /* 0.64 fraction */ | ||
158 | |||
159 | /* If last_tick_len corresponds to about 1/HZ seconds, then | ||
160 | last_tick_len << TICKLEN_SHIFT will be about 2^63. */ | ||
161 | #define TICKLEN_SHIFT (63 - 30 - TICKLEN_SCALE + SHIFT_HZ) | ||
162 | 152 | ||
163 | DEFINE_SPINLOCK(rtc_lock); | 153 | DEFINE_SPINLOCK(rtc_lock); |
164 | EXPORT_SYMBOL_GPL(rtc_lock); | 154 | EXPORT_SYMBOL_GPL(rtc_lock); |
@@ -174,7 +164,6 @@ unsigned long ppc_proc_freq; | |||
174 | EXPORT_SYMBOL(ppc_proc_freq); | 164 | EXPORT_SYMBOL(ppc_proc_freq); |
175 | unsigned long ppc_tb_freq; | 165 | unsigned long ppc_tb_freq; |
176 | 166 | ||
177 | static u64 tb_last_jiffy __cacheline_aligned_in_smp; | ||
178 | static DEFINE_PER_CPU(u64, last_jiffy); | 167 | static DEFINE_PER_CPU(u64, last_jiffy); |
179 | 168 | ||
180 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 169 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
@@ -423,30 +412,6 @@ void udelay(unsigned long usecs) | |||
423 | } | 412 | } |
424 | EXPORT_SYMBOL(udelay); | 413 | EXPORT_SYMBOL(udelay); |
425 | 414 | ||
426 | static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec, | ||
427 | u64 new_tb_to_xs) | ||
428 | { | ||
429 | /* | ||
430 | * tb_update_count is used to allow the userspace gettimeofday code | ||
431 | * to assure itself that it sees a consistent view of the tb_to_xs and | ||
432 | * stamp_xsec variables. It reads the tb_update_count, then reads | ||
433 | * tb_to_xs and stamp_xsec and then reads tb_update_count again. If | ||
434 | * the two values of tb_update_count match and are even then the | ||
435 | * tb_to_xs and stamp_xsec values are consistent. If not, then it | ||
436 | * loops back and reads them again until this criteria is met. | ||
437 | * We expect the caller to have done the first increment of | ||
438 | * vdso_data->tb_update_count already. | ||
439 | */ | ||
440 | vdso_data->tb_orig_stamp = new_tb_stamp; | ||
441 | vdso_data->stamp_xsec = new_stamp_xsec; | ||
442 | vdso_data->tb_to_xs = new_tb_to_xs; | ||
443 | vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec; | ||
444 | vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec; | ||
445 | vdso_data->stamp_xtime = xtime; | ||
446 | smp_wmb(); | ||
447 | ++(vdso_data->tb_update_count); | ||
448 | } | ||
449 | |||
450 | #ifdef CONFIG_SMP | 415 | #ifdef CONFIG_SMP |
451 | unsigned long profile_pc(struct pt_regs *regs) | 416 | unsigned long profile_pc(struct pt_regs *regs) |
452 | { | 417 | { |
@@ -470,7 +435,6 @@ EXPORT_SYMBOL(profile_pc); | |||
470 | 435 | ||
471 | static int __init iSeries_tb_recal(void) | 436 | static int __init iSeries_tb_recal(void) |
472 | { | 437 | { |
473 | struct div_result divres; | ||
474 | unsigned long titan, tb; | 438 | unsigned long titan, tb; |
475 | 439 | ||
476 | /* Make sure we only run on iSeries */ | 440 | /* Make sure we only run on iSeries */ |
@@ -501,10 +465,7 @@ static int __init iSeries_tb_recal(void) | |||
501 | tb_ticks_per_jiffy = new_tb_ticks_per_jiffy; | 465 | tb_ticks_per_jiffy = new_tb_ticks_per_jiffy; |
502 | tb_ticks_per_sec = new_tb_ticks_per_sec; | 466 | tb_ticks_per_sec = new_tb_ticks_per_sec; |
503 | calc_cputime_factors(); | 467 | calc_cputime_factors(); |
504 | div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres ); | ||
505 | tb_to_xs = divres.result_low; | ||
506 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; | 468 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; |
507 | vdso_data->tb_to_xs = tb_to_xs; | ||
508 | setup_cputime_one_jiffy(); | 469 | setup_cputime_one_jiffy(); |
509 | } | 470 | } |
510 | else { | 471 | else { |
@@ -667,27 +628,9 @@ void timer_interrupt(struct pt_regs * regs) | |||
667 | trace_timer_interrupt_exit(regs); | 628 | trace_timer_interrupt_exit(regs); |
668 | } | 629 | } |
669 | 630 | ||
670 | void wakeup_decrementer(void) | ||
671 | { | ||
672 | unsigned long ticks; | ||
673 | |||
674 | /* | ||
675 | * The timebase gets saved on sleep and restored on wakeup, | ||
676 | * so all we need to do is to reset the decrementer. | ||
677 | */ | ||
678 | ticks = tb_ticks_since(__get_cpu_var(last_jiffy)); | ||
679 | if (ticks < tb_ticks_per_jiffy) | ||
680 | ticks = tb_ticks_per_jiffy - ticks; | ||
681 | else | ||
682 | ticks = 1; | ||
683 | set_dec(ticks); | ||
684 | } | ||
685 | |||
686 | #ifdef CONFIG_SUSPEND | 631 | #ifdef CONFIG_SUSPEND |
687 | void generic_suspend_disable_irqs(void) | 632 | static void generic_suspend_disable_irqs(void) |
688 | { | 633 | { |
689 | preempt_disable(); | ||
690 | |||
691 | /* Disable the decrementer, so that it doesn't interfere | 634 | /* Disable the decrementer, so that it doesn't interfere |
692 | * with suspending. | 635 | * with suspending. |
693 | */ | 636 | */ |
@@ -697,12 +640,9 @@ void generic_suspend_disable_irqs(void) | |||
697 | set_dec(0x7fffffff); | 640 | set_dec(0x7fffffff); |
698 | } | 641 | } |
699 | 642 | ||
700 | void generic_suspend_enable_irqs(void) | 643 | static void generic_suspend_enable_irqs(void) |
701 | { | 644 | { |
702 | wakeup_decrementer(); | ||
703 | |||
704 | local_irq_enable(); | 645 | local_irq_enable(); |
705 | preempt_enable(); | ||
706 | } | 646 | } |
707 | 647 | ||
708 | /* Overrides the weak version in kernel/power/main.c */ | 648 | /* Overrides the weak version in kernel/power/main.c */ |
@@ -722,23 +662,6 @@ void arch_suspend_enable_irqs(void) | |||
722 | } | 662 | } |
723 | #endif | 663 | #endif |
724 | 664 | ||
725 | #ifdef CONFIG_SMP | ||
726 | void __init smp_space_timers(unsigned int max_cpus) | ||
727 | { | ||
728 | int i; | ||
729 | u64 previous_tb = per_cpu(last_jiffy, boot_cpuid); | ||
730 | |||
731 | /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */ | ||
732 | previous_tb -= tb_ticks_per_jiffy; | ||
733 | |||
734 | for_each_possible_cpu(i) { | ||
735 | if (i == boot_cpuid) | ||
736 | continue; | ||
737 | per_cpu(last_jiffy, i) = previous_tb; | ||
738 | } | ||
739 | } | ||
740 | #endif | ||
741 | |||
742 | /* | 665 | /* |
743 | * Scheduler clock - returns current time in nanosec units. | 666 | * Scheduler clock - returns current time in nanosec units. |
744 | * | 667 | * |
@@ -873,10 +796,37 @@ static cycle_t timebase_read(struct clocksource *cs) | |||
873 | return (cycle_t)get_tb(); | 796 | return (cycle_t)get_tb(); |
874 | } | 797 | } |
875 | 798 | ||
799 | static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec, | ||
800 | u64 new_tb_to_xs, struct timespec *now, | ||
801 | u32 frac_sec) | ||
802 | { | ||
803 | /* | ||
804 | * tb_update_count is used to allow the userspace gettimeofday code | ||
805 | * to assure itself that it sees a consistent view of the tb_to_xs and | ||
806 | * stamp_xsec variables. It reads the tb_update_count, then reads | ||
807 | * tb_to_xs and stamp_xsec and then reads tb_update_count again. If | ||
808 | * the two values of tb_update_count match and are even then the | ||
809 | * tb_to_xs and stamp_xsec values are consistent. If not, then it | ||
810 | * loops back and reads them again until this criteria is met. | ||
811 | * We expect the caller to have done the first increment of | ||
812 | * vdso_data->tb_update_count already. | ||
813 | */ | ||
814 | vdso_data->tb_orig_stamp = new_tb_stamp; | ||
815 | vdso_data->stamp_xsec = new_stamp_xsec; | ||
816 | vdso_data->tb_to_xs = new_tb_to_xs; | ||
817 | vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec; | ||
818 | vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec; | ||
819 | vdso_data->stamp_xtime = *now; | ||
820 | vdso_data->stamp_sec_fraction = frac_sec; | ||
821 | smp_wmb(); | ||
822 | ++(vdso_data->tb_update_count); | ||
823 | } | ||
824 | |||
876 | void update_vsyscall(struct timespec *wall_time, struct clocksource *clock, | 825 | void update_vsyscall(struct timespec *wall_time, struct clocksource *clock, |
877 | u32 mult) | 826 | u32 mult) |
878 | { | 827 | { |
879 | u64 t2x, stamp_xsec; | 828 | u64 t2x, stamp_xsec; |
829 | u32 frac_sec; | ||
880 | 830 | ||
881 | if (clock != &clocksource_timebase) | 831 | if (clock != &clocksource_timebase) |
882 | return; | 832 | return; |
@@ -888,10 +838,14 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock, | |||
888 | /* XXX this assumes clock->shift == 22 */ | 838 | /* XXX this assumes clock->shift == 22 */ |
889 | /* 4611686018 ~= 2^(20+64-22) / 1e9 */ | 839 | /* 4611686018 ~= 2^(20+64-22) / 1e9 */ |
890 | t2x = (u64) mult * 4611686018ULL; | 840 | t2x = (u64) mult * 4611686018ULL; |
891 | stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC; | 841 | stamp_xsec = (u64) wall_time->tv_nsec * XSEC_PER_SEC; |
892 | do_div(stamp_xsec, 1000000000); | 842 | do_div(stamp_xsec, 1000000000); |
893 | stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC; | 843 | stamp_xsec += (u64) wall_time->tv_sec * XSEC_PER_SEC; |
894 | update_gtod(clock->cycle_last, stamp_xsec, t2x); | 844 | |
845 | BUG_ON(wall_time->tv_nsec >= NSEC_PER_SEC); | ||
846 | /* this is tv_nsec / 1e9 as a 0.32 fraction */ | ||
847 | frac_sec = ((u64) wall_time->tv_nsec * 18446744073ULL) >> 32; | ||
848 | update_gtod(clock->cycle_last, stamp_xsec, t2x, wall_time, frac_sec); | ||
895 | } | 849 | } |
896 | 850 | ||
897 | void update_vsyscall_tz(void) | 851 | void update_vsyscall_tz(void) |
@@ -1007,15 +961,13 @@ void secondary_cpu_time_init(void) | |||
1007 | /* This function is only called on the boot processor */ | 961 | /* This function is only called on the boot processor */ |
1008 | void __init time_init(void) | 962 | void __init time_init(void) |
1009 | { | 963 | { |
1010 | unsigned long flags; | ||
1011 | struct div_result res; | 964 | struct div_result res; |
1012 | u64 scale, x; | 965 | u64 scale; |
1013 | unsigned shift; | 966 | unsigned shift; |
1014 | 967 | ||
1015 | if (__USE_RTC()) { | 968 | if (__USE_RTC()) { |
1016 | /* 601 processor: dec counts down by 128 every 128ns */ | 969 | /* 601 processor: dec counts down by 128 every 128ns */ |
1017 | ppc_tb_freq = 1000000000; | 970 | ppc_tb_freq = 1000000000; |
1018 | tb_last_jiffy = get_rtcl(); | ||
1019 | } else { | 971 | } else { |
1020 | /* Normal PowerPC with timebase register */ | 972 | /* Normal PowerPC with timebase register */ |
1021 | ppc_md.calibrate_decr(); | 973 | ppc_md.calibrate_decr(); |
@@ -1023,50 +975,15 @@ void __init time_init(void) | |||
1023 | ppc_tb_freq / 1000000, ppc_tb_freq % 1000000); | 975 | ppc_tb_freq / 1000000, ppc_tb_freq % 1000000); |
1024 | printk(KERN_DEBUG "time_init: processor frequency = %lu.%.6lu MHz\n", | 976 | printk(KERN_DEBUG "time_init: processor frequency = %lu.%.6lu MHz\n", |
1025 | ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); | 977 | ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); |
1026 | tb_last_jiffy = get_tb(); | ||
1027 | } | 978 | } |
1028 | 979 | ||
1029 | tb_ticks_per_jiffy = ppc_tb_freq / HZ; | 980 | tb_ticks_per_jiffy = ppc_tb_freq / HZ; |
1030 | tb_ticks_per_sec = ppc_tb_freq; | 981 | tb_ticks_per_sec = ppc_tb_freq; |
1031 | tb_ticks_per_usec = ppc_tb_freq / 1000000; | 982 | tb_ticks_per_usec = ppc_tb_freq / 1000000; |
1032 | tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000); | ||
1033 | calc_cputime_factors(); | 983 | calc_cputime_factors(); |
1034 | setup_cputime_one_jiffy(); | 984 | setup_cputime_one_jiffy(); |
1035 | 985 | ||
1036 | /* | 986 | /* |
1037 | * Calculate the length of each tick in ns. It will not be | ||
1038 | * exactly 1e9/HZ unless ppc_tb_freq is divisible by HZ. | ||
1039 | * We compute 1e9 * tb_ticks_per_jiffy / ppc_tb_freq, | ||
1040 | * rounded up. | ||
1041 | */ | ||
1042 | x = (u64) NSEC_PER_SEC * tb_ticks_per_jiffy + ppc_tb_freq - 1; | ||
1043 | do_div(x, ppc_tb_freq); | ||
1044 | tick_nsec = x; | ||
1045 | last_tick_len = x << TICKLEN_SCALE; | ||
1046 | |||
1047 | /* | ||
1048 | * Compute ticklen_to_xs, which is a factor which gets multiplied | ||
1049 | * by (last_tick_len << TICKLEN_SHIFT) to get a tb_to_xs value. | ||
1050 | * It is computed as: | ||
1051 | * ticklen_to_xs = 2^N / (tb_ticks_per_jiffy * 1e9) | ||
1052 | * where N = 64 + 20 - TICKLEN_SCALE - TICKLEN_SHIFT | ||
1053 | * which turns out to be N = 51 - SHIFT_HZ. | ||
1054 | * This gives the result as a 0.64 fixed-point fraction. | ||
1055 | * That value is reduced by an offset amounting to 1 xsec per | ||
1056 | * 2^31 timebase ticks to avoid problems with time going backwards | ||
1057 | * by 1 xsec when we do timer_recalc_offset due to losing the | ||
1058 | * fractional xsec. That offset is equal to ppc_tb_freq/2^51 | ||
1059 | * since there are 2^20 xsec in a second. | ||
1060 | */ | ||
1061 | div128_by_32((1ULL << 51) - ppc_tb_freq, 0, | ||
1062 | tb_ticks_per_jiffy << SHIFT_HZ, &res); | ||
1063 | div128_by_32(res.result_high, res.result_low, NSEC_PER_SEC, &res); | ||
1064 | ticklen_to_xs = res.result_low; | ||
1065 | |||
1066 | /* Compute tb_to_xs from tick_nsec */ | ||
1067 | tb_to_xs = mulhdu(last_tick_len << TICKLEN_SHIFT, ticklen_to_xs); | ||
1068 | |||
1069 | /* | ||
1070 | * Compute scale factor for sched_clock. | 987 | * Compute scale factor for sched_clock. |
1071 | * The calibrate_decr() function has set tb_ticks_per_sec, | 988 | * The calibrate_decr() function has set tb_ticks_per_sec, |
1072 | * which is the timebase frequency. | 989 | * which is the timebase frequency. |
@@ -1087,21 +1004,14 @@ void __init time_init(void) | |||
1087 | /* Save the current timebase to pretty up CONFIG_PRINTK_TIME */ | 1004 | /* Save the current timebase to pretty up CONFIG_PRINTK_TIME */ |
1088 | boot_tb = get_tb_or_rtc(); | 1005 | boot_tb = get_tb_or_rtc(); |
1089 | 1006 | ||
1090 | write_seqlock_irqsave(&xtime_lock, flags); | ||
1091 | |||
1092 | /* If platform provided a timezone (pmac), we correct the time */ | 1007 | /* If platform provided a timezone (pmac), we correct the time */ |
1093 | if (timezone_offset) { | 1008 | if (timezone_offset) { |
1094 | sys_tz.tz_minuteswest = -timezone_offset / 60; | 1009 | sys_tz.tz_minuteswest = -timezone_offset / 60; |
1095 | sys_tz.tz_dsttime = 0; | 1010 | sys_tz.tz_dsttime = 0; |
1096 | } | 1011 | } |
1097 | 1012 | ||
1098 | vdso_data->tb_orig_stamp = tb_last_jiffy; | ||
1099 | vdso_data->tb_update_count = 0; | 1013 | vdso_data->tb_update_count = 0; |
1100 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; | 1014 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; |
1101 | vdso_data->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC; | ||
1102 | vdso_data->tb_to_xs = tb_to_xs; | ||
1103 | |||
1104 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
1105 | 1015 | ||
1106 | /* Start the decrementer on CPUs that have manual control | 1016 | /* Start the decrementer on CPUs that have manual control |
1107 | * such as BookE | 1017 | * such as BookE |
@@ -1195,39 +1105,6 @@ void to_tm(int tim, struct rtc_time * tm) | |||
1195 | GregorianDay(tm); | 1105 | GregorianDay(tm); |
1196 | } | 1106 | } |
1197 | 1107 | ||
1198 | /* Auxiliary function to compute scaling factors */ | ||
1199 | /* Actually the choice of a timebase running at 1/4 the of the bus | ||
1200 | * frequency giving resolution of a few tens of nanoseconds is quite nice. | ||
1201 | * It makes this computation very precise (27-28 bits typically) which | ||
1202 | * is optimistic considering the stability of most processor clock | ||
1203 | * oscillators and the precision with which the timebase frequency | ||
1204 | * is measured but does not harm. | ||
1205 | */ | ||
1206 | unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale) | ||
1207 | { | ||
1208 | unsigned mlt=0, tmp, err; | ||
1209 | /* No concern for performance, it's done once: use a stupid | ||
1210 | * but safe and compact method to find the multiplier. | ||
1211 | */ | ||
1212 | |||
1213 | for (tmp = 1U<<31; tmp != 0; tmp >>= 1) { | ||
1214 | if (mulhwu(inscale, mlt|tmp) < outscale) | ||
1215 | mlt |= tmp; | ||
1216 | } | ||
1217 | |||
1218 | /* We might still be off by 1 for the best approximation. | ||
1219 | * A side effect of this is that if outscale is too large | ||
1220 | * the returned value will be zero. | ||
1221 | * Many corner cases have been checked and seem to work, | ||
1222 | * some might have been forgotten in the test however. | ||
1223 | */ | ||
1224 | |||
1225 | err = inscale * (mlt+1); | ||
1226 | if (err <= inscale/2) | ||
1227 | mlt++; | ||
1228 | return mlt; | ||
1229 | } | ||
1230 | |||
1231 | /* | 1108 | /* |
1232 | * Divide a 128-bit dividend by a 32-bit divisor, leaving a 128 bit | 1109 | * Divide a 128-bit dividend by a 32-bit divisor, leaving a 128 bit |
1233 | * result. | 1110 | * result. |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 25fc33984c2b..a45a63c3a0c7 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -55,9 +55,6 @@ | |||
55 | #endif | 55 | #endif |
56 | #include <asm/kexec.h> | 56 | #include <asm/kexec.h> |
57 | #include <asm/ppc-opcode.h> | 57 | #include <asm/ppc-opcode.h> |
58 | #ifdef CONFIG_FSL_BOOKE | ||
59 | #include <asm/dbell.h> | ||
60 | #endif | ||
61 | 58 | ||
62 | #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) | 59 | #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) |
63 | int (*__debugger)(struct pt_regs *regs) __read_mostly; | 60 | int (*__debugger)(struct pt_regs *regs) __read_mostly; |
@@ -688,7 +685,7 @@ void RunModeException(struct pt_regs *regs) | |||
688 | 685 | ||
689 | void __kprobes single_step_exception(struct pt_regs *regs) | 686 | void __kprobes single_step_exception(struct pt_regs *regs) |
690 | { | 687 | { |
691 | regs->msr &= ~(MSR_SE | MSR_BE); /* Turn off 'trace' bits */ | 688 | clear_single_step(regs); |
692 | 689 | ||
693 | if (notify_die(DIE_SSTEP, "single_step", regs, 5, | 690 | if (notify_die(DIE_SSTEP, "single_step", regs, 5, |
694 | 5, SIGTRAP) == NOTIFY_STOP) | 691 | 5, SIGTRAP) == NOTIFY_STOP) |
@@ -707,10 +704,8 @@ void __kprobes single_step_exception(struct pt_regs *regs) | |||
707 | */ | 704 | */ |
708 | static void emulate_single_step(struct pt_regs *regs) | 705 | static void emulate_single_step(struct pt_regs *regs) |
709 | { | 706 | { |
710 | if (single_stepping(regs)) { | 707 | if (single_stepping(regs)) |
711 | clear_single_step(regs); | 708 | single_step_exception(regs); |
712 | _exception(SIGTRAP, regs, TRAP_TRACE, 0); | ||
713 | } | ||
714 | } | 709 | } |
715 | 710 | ||
716 | static inline int __parse_fpscr(unsigned long fpscr) | 711 | static inline int __parse_fpscr(unsigned long fpscr) |
@@ -1344,24 +1339,6 @@ void vsx_assist_exception(struct pt_regs *regs) | |||
1344 | #endif /* CONFIG_VSX */ | 1339 | #endif /* CONFIG_VSX */ |
1345 | 1340 | ||
1346 | #ifdef CONFIG_FSL_BOOKE | 1341 | #ifdef CONFIG_FSL_BOOKE |
1347 | |||
1348 | void doorbell_exception(struct pt_regs *regs) | ||
1349 | { | ||
1350 | #ifdef CONFIG_SMP | ||
1351 | int cpu = smp_processor_id(); | ||
1352 | int msg; | ||
1353 | |||
1354 | if (num_online_cpus() < 2) | ||
1355 | return; | ||
1356 | |||
1357 | for (msg = 0; msg < 4; msg++) | ||
1358 | if (test_and_clear_bit(msg, &dbell_smp_message[cpu])) | ||
1359 | smp_message_recv(msg); | ||
1360 | #else | ||
1361 | printk(KERN_WARNING "Received doorbell on non-smp system\n"); | ||
1362 | #endif | ||
1363 | } | ||
1364 | |||
1365 | void CacheLockingException(struct pt_regs *regs, unsigned long address, | 1342 | void CacheLockingException(struct pt_regs *regs, unsigned long address, |
1366 | unsigned long error_code) | 1343 | unsigned long error_code) |
1367 | { | 1344 | { |
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S index ee038d4bf252..4ee09ee2e836 100644 --- a/arch/powerpc/kernel/vdso32/gettimeofday.S +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S | |||
@@ -19,8 +19,10 @@ | |||
19 | /* Offset for the low 32-bit part of a field of long type */ | 19 | /* Offset for the low 32-bit part of a field of long type */ |
20 | #ifdef CONFIG_PPC64 | 20 | #ifdef CONFIG_PPC64 |
21 | #define LOPART 4 | 21 | #define LOPART 4 |
22 | #define TSPEC_TV_SEC TSPC64_TV_SEC+LOPART | ||
22 | #else | 23 | #else |
23 | #define LOPART 0 | 24 | #define LOPART 0 |
25 | #define TSPEC_TV_SEC TSPC32_TV_SEC | ||
24 | #endif | 26 | #endif |
25 | 27 | ||
26 | .text | 28 | .text |
@@ -41,23 +43,11 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday) | |||
41 | mr r9, r3 /* datapage ptr in r9 */ | 43 | mr r9, r3 /* datapage ptr in r9 */ |
42 | cmplwi r10,0 /* check if tv is NULL */ | 44 | cmplwi r10,0 /* check if tv is NULL */ |
43 | beq 3f | 45 | beq 3f |
44 | bl __do_get_xsec@local /* get xsec from tb & kernel */ | 46 | lis r7,1000000@ha /* load up USEC_PER_SEC */ |
45 | bne- 2f /* out of line -> do syscall */ | 47 | addi r7,r7,1000000@l /* so we get microseconds in r4 */ |
46 | 48 | bl __do_get_tspec@local /* get sec/usec from tb & kernel */ | |
47 | /* seconds are xsec >> 20 */ | 49 | stw r3,TVAL32_TV_SEC(r10) |
48 | rlwinm r5,r4,12,20,31 | 50 | stw r4,TVAL32_TV_USEC(r10) |
49 | rlwimi r5,r3,12,0,19 | ||
50 | stw r5,TVAL32_TV_SEC(r10) | ||
51 | |||
52 | /* get remaining xsec and convert to usec. we scale | ||
53 | * up remaining xsec by 12 bits and get the top 32 bits | ||
54 | * of the multiplication | ||
55 | */ | ||
56 | rlwinm r5,r4,12,0,19 | ||
57 | lis r6,1000000@h | ||
58 | ori r6,r6,1000000@l | ||
59 | mulhwu r5,r5,r6 | ||
60 | stw r5,TVAL32_TV_USEC(r10) | ||
61 | 51 | ||
62 | 3: cmplwi r11,0 /* check if tz is NULL */ | 52 | 3: cmplwi r11,0 /* check if tz is NULL */ |
63 | beq 1f | 53 | beq 1f |
@@ -70,14 +60,6 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday) | |||
70 | crclr cr0*4+so | 60 | crclr cr0*4+so |
71 | li r3,0 | 61 | li r3,0 |
72 | blr | 62 | blr |
73 | |||
74 | 2: | ||
75 | mtlr r12 | ||
76 | mr r3,r10 | ||
77 | mr r4,r11 | ||
78 | li r0,__NR_gettimeofday | ||
79 | sc | ||
80 | blr | ||
81 | .cfi_endproc | 63 | .cfi_endproc |
82 | V_FUNCTION_END(__kernel_gettimeofday) | 64 | V_FUNCTION_END(__kernel_gettimeofday) |
83 | 65 | ||
@@ -100,7 +82,8 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
100 | mr r11,r4 /* r11 saves tp */ | 82 | mr r11,r4 /* r11 saves tp */ |
101 | bl __get_datapage@local /* get data page */ | 83 | bl __get_datapage@local /* get data page */ |
102 | mr r9,r3 /* datapage ptr in r9 */ | 84 | mr r9,r3 /* datapage ptr in r9 */ |
103 | 85 | lis r7,NSEC_PER_SEC@h /* want nanoseconds */ | |
86 | ori r7,r7,NSEC_PER_SEC@l | ||
104 | 50: bl __do_get_tspec@local /* get sec/nsec from tb & kernel */ | 87 | 50: bl __do_get_tspec@local /* get sec/nsec from tb & kernel */ |
105 | bne cr1,80f /* not monotonic -> all done */ | 88 | bne cr1,80f /* not monotonic -> all done */ |
106 | 89 | ||
@@ -198,83 +181,12 @@ V_FUNCTION_END(__kernel_clock_getres) | |||
198 | 181 | ||
199 | 182 | ||
200 | /* | 183 | /* |
201 | * This is the core of gettimeofday() & friends, it returns the xsec | 184 | * This is the core of clock_gettime() and gettimeofday(), |
202 | * value in r3 & r4 and expects the datapage ptr (non clobbered) | 185 | * it returns the current time in r3 (seconds) and r4. |
203 | * in r9. clobbers r0,r4,r5,r6,r7,r8. | 186 | * On entry, r7 gives the resolution of r4, either USEC_PER_SEC |
204 | * When returning, r8 contains the counter value that can be reused | 187 | * or NSEC_PER_SEC, giving r4 in microseconds or nanoseconds. |
205 | * by the monotonic clock implementation | ||
206 | */ | ||
207 | __do_get_xsec: | ||
208 | .cfi_startproc | ||
209 | /* Check for update count & load values. We use the low | ||
210 | * order 32 bits of the update count | ||
211 | */ | ||
212 | 1: lwz r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9) | ||
213 | andi. r0,r8,1 /* pending update ? loop */ | ||
214 | bne- 1b | ||
215 | xor r0,r8,r8 /* create dependency */ | ||
216 | add r9,r9,r0 | ||
217 | |||
218 | /* Load orig stamp (offset to TB) */ | ||
219 | lwz r5,CFG_TB_ORIG_STAMP(r9) | ||
220 | lwz r6,(CFG_TB_ORIG_STAMP+4)(r9) | ||
221 | |||
222 | /* Get a stable TB value */ | ||
223 | 2: mftbu r3 | ||
224 | mftbl r4 | ||
225 | mftbu r0 | ||
226 | cmpl cr0,r3,r0 | ||
227 | bne- 2b | ||
228 | |||
229 | /* Substract tb orig stamp. If the high part is non-zero, we jump to | ||
230 | * the slow path which call the syscall. | ||
231 | * If it's ok, then we have our 32 bits tb_ticks value in r7 | ||
232 | */ | ||
233 | subfc r7,r6,r4 | ||
234 | subfe. r0,r5,r3 | ||
235 | bne- 3f | ||
236 | |||
237 | /* Load scale factor & do multiplication */ | ||
238 | lwz r5,CFG_TB_TO_XS(r9) /* load values */ | ||
239 | lwz r6,(CFG_TB_TO_XS+4)(r9) | ||
240 | mulhwu r4,r7,r5 | ||
241 | mulhwu r6,r7,r6 | ||
242 | mullw r0,r7,r5 | ||
243 | addc r6,r6,r0 | ||
244 | |||
245 | /* At this point, we have the scaled xsec value in r4 + XER:CA | ||
246 | * we load & add the stamp since epoch | ||
247 | */ | ||
248 | lwz r5,CFG_STAMP_XSEC(r9) | ||
249 | lwz r6,(CFG_STAMP_XSEC+4)(r9) | ||
250 | adde r4,r4,r6 | ||
251 | addze r3,r5 | ||
252 | |||
253 | /* We now have our result in r3,r4. We create a fake dependency | ||
254 | * on that result and re-check the counter | ||
255 | */ | ||
256 | or r6,r4,r3 | ||
257 | xor r0,r6,r6 | ||
258 | add r9,r9,r0 | ||
259 | lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9) | ||
260 | cmpl cr0,r8,r0 /* check if updated */ | ||
261 | bne- 1b | ||
262 | |||
263 | /* Warning ! The caller expects CR:EQ to be set to indicate a | ||
264 | * successful calculation (so it won't fallback to the syscall | ||
265 | * method). We have overriden that CR bit in the counter check, | ||
266 | * but fortunately, the loop exit condition _is_ CR:EQ set, so | ||
267 | * we can exit safely here. If you change this code, be careful | ||
268 | * of that side effect. | ||
269 | */ | ||
270 | 3: blr | ||
271 | .cfi_endproc | ||
272 | |||
273 | /* | ||
274 | * This is the core of clock_gettime(), it returns the current | ||
275 | * time in seconds and nanoseconds in r3 and r4. | ||
276 | * It expects the datapage ptr in r9 and doesn't clobber it. | 188 | * It expects the datapage ptr in r9 and doesn't clobber it. |
277 | * It clobbers r0, r5, r6, r10 and returns NSEC_PER_SEC in r7. | 189 | * It clobbers r0, r5 and r6. |
278 | * On return, r8 contains the counter value that can be reused. | 190 | * On return, r8 contains the counter value that can be reused. |
279 | * This clobbers cr0 but not any other cr field. | 191 | * This clobbers cr0 but not any other cr field. |
280 | */ | 192 | */ |
@@ -297,70 +209,58 @@ __do_get_tspec: | |||
297 | 2: mftbu r3 | 209 | 2: mftbu r3 |
298 | mftbl r4 | 210 | mftbl r4 |
299 | mftbu r0 | 211 | mftbu r0 |
300 | cmpl cr0,r3,r0 | 212 | cmplw cr0,r3,r0 |
301 | bne- 2b | 213 | bne- 2b |
302 | 214 | ||
303 | /* Subtract tb orig stamp and shift left 12 bits. | 215 | /* Subtract tb orig stamp and shift left 12 bits. |
304 | */ | 216 | */ |
305 | subfc r7,r6,r4 | 217 | subfc r4,r6,r4 |
306 | subfe r0,r5,r3 | 218 | subfe r0,r5,r3 |
307 | slwi r0,r0,12 | 219 | slwi r0,r0,12 |
308 | rlwimi. r0,r7,12,20,31 | 220 | rlwimi. r0,r4,12,20,31 |
309 | slwi r7,r7,12 | 221 | slwi r4,r4,12 |
310 | 222 | ||
311 | /* Load scale factor & do multiplication */ | 223 | /* |
224 | * Load scale factor & do multiplication. | ||
225 | * We only use the high 32 bits of the tb_to_xs value. | ||
226 | * Even with a 1GHz timebase clock, the high 32 bits of | ||
227 | * tb_to_xs will be at least 4 million, so the error from | ||
228 | * ignoring the low 32 bits will be no more than 0.25ppm. | ||
229 | * The error will just make the clock run very very slightly | ||
230 | * slow until the next time the kernel updates the VDSO data, | ||
231 | * at which point the clock will catch up to the kernel's value, | ||
232 | * so there is no long-term error accumulation. | ||
233 | */ | ||
312 | lwz r5,CFG_TB_TO_XS(r9) /* load values */ | 234 | lwz r5,CFG_TB_TO_XS(r9) /* load values */ |
313 | lwz r6,(CFG_TB_TO_XS+4)(r9) | 235 | mulhwu r4,r4,r5 |
314 | mulhwu r3,r7,r6 | ||
315 | mullw r10,r7,r5 | ||
316 | mulhwu r4,r7,r5 | ||
317 | addc r10,r3,r10 | ||
318 | li r3,0 | 236 | li r3,0 |
319 | 237 | ||
320 | beq+ 4f /* skip high part computation if 0 */ | 238 | beq+ 4f /* skip high part computation if 0 */ |
321 | mulhwu r3,r0,r5 | 239 | mulhwu r3,r0,r5 |
322 | mullw r7,r0,r5 | 240 | mullw r5,r0,r5 |
323 | mulhwu r5,r0,r6 | ||
324 | mullw r6,r0,r6 | ||
325 | adde r4,r4,r7 | ||
326 | addze r3,r3 | ||
327 | addc r4,r4,r5 | 241 | addc r4,r4,r5 |
328 | addze r3,r3 | 242 | addze r3,r3 |
329 | addc r10,r10,r6 | 243 | 4: |
330 | 244 | /* At this point, we have seconds since the xtime stamp | |
331 | 4: addze r4,r4 /* add in carry */ | 245 | * as a 32.32 fixed-point number in r3 and r4. |
332 | lis r7,NSEC_PER_SEC@h | 246 | * Load & add the xtime stamp. |
333 | ori r7,r7,NSEC_PER_SEC@l | ||
334 | mulhwu r4,r4,r7 /* convert to nanoseconds */ | ||
335 | |||
336 | /* At this point, we have seconds & nanoseconds since the xtime | ||
337 | * stamp in r3+CA and r4. Load & add the xtime stamp. | ||
338 | */ | 247 | */ |
339 | #ifdef CONFIG_PPC64 | 248 | lwz r5,STAMP_XTIME+TSPEC_TV_SEC(r9) |
340 | lwz r5,STAMP_XTIME+TSPC64_TV_SEC+LOPART(r9) | 249 | lwz r6,STAMP_SEC_FRAC(r9) |
341 | lwz r6,STAMP_XTIME+TSPC64_TV_NSEC+LOPART(r9) | 250 | addc r4,r4,r6 |
342 | #else | ||
343 | lwz r5,STAMP_XTIME+TSPC32_TV_SEC(r9) | ||
344 | lwz r6,STAMP_XTIME+TSPC32_TV_NSEC(r9) | ||
345 | #endif | ||
346 | add r4,r4,r6 | ||
347 | adde r3,r3,r5 | 251 | adde r3,r3,r5 |
348 | 252 | ||
349 | /* We now have our result in r3,r4. We create a fake dependency | 253 | /* We create a fake dependency on the result in r3/r4 |
350 | * on that result and re-check the counter | 254 | * and re-check the counter |
351 | */ | 255 | */ |
352 | or r6,r4,r3 | 256 | or r6,r4,r3 |
353 | xor r0,r6,r6 | 257 | xor r0,r6,r6 |
354 | add r9,r9,r0 | 258 | add r9,r9,r0 |
355 | lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9) | 259 | lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9) |
356 | cmpl cr0,r8,r0 /* check if updated */ | 260 | cmplw cr0,r8,r0 /* check if updated */ |
357 | bne- 1b | 261 | bne- 1b |
358 | 262 | ||
359 | /* check for nanosecond overflow and adjust if necessary */ | 263 | mulhwu r4,r4,r7 /* convert to micro or nanoseconds */ |
360 | cmpw r4,r7 | ||
361 | bltlr /* all done if no overflow */ | ||
362 | subf r4,r7,r4 /* adjust if overflow */ | ||
363 | addi r3,r3,1 | ||
364 | 264 | ||
365 | blr | 265 | blr |
366 | .cfi_endproc | 266 | .cfi_endproc |
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S index 262cd5857a56..e97a9a0dc4ac 100644 --- a/arch/powerpc/kernel/vdso64/gettimeofday.S +++ b/arch/powerpc/kernel/vdso64/gettimeofday.S | |||
@@ -33,18 +33,11 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday) | |||
33 | bl V_LOCAL_FUNC(__get_datapage) /* get data page */ | 33 | bl V_LOCAL_FUNC(__get_datapage) /* get data page */ |
34 | cmpldi r11,0 /* check if tv is NULL */ | 34 | cmpldi r11,0 /* check if tv is NULL */ |
35 | beq 2f | 35 | beq 2f |
36 | bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ | 36 | lis r7,1000000@ha /* load up USEC_PER_SEC */ |
37 | lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */ | 37 | addi r7,r7,1000000@l |
38 | ori r7,r7,16960 | 38 | bl V_LOCAL_FUNC(__do_get_tspec) /* get sec/us from tb & kernel */ |
39 | rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ | 39 | std r4,TVAL64_TV_SEC(r11) /* store sec in tv */ |
40 | rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ | 40 | std r5,TVAL64_TV_USEC(r11) /* store usec in tv */ |
41 | std r5,TVAL64_TV_SEC(r11) /* store sec in tv */ | ||
42 | subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ | ||
43 | mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) / | ||
44 | * XSEC_PER_SEC | ||
45 | */ | ||
46 | rldicl r0,r0,44,20 | ||
47 | std r0,TVAL64_TV_USEC(r11) /* store usec in tv */ | ||
48 | 2: cmpldi r10,0 /* check if tz is NULL */ | 41 | 2: cmpldi r10,0 /* check if tz is NULL */ |
49 | beq 1f | 42 | beq 1f |
50 | lwz r4,CFG_TZ_MINUTEWEST(r3)/* fill tz */ | 43 | lwz r4,CFG_TZ_MINUTEWEST(r3)/* fill tz */ |
@@ -77,6 +70,8 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
77 | .cfi_register lr,r12 | 70 | .cfi_register lr,r12 |
78 | mr r11,r4 /* r11 saves tp */ | 71 | mr r11,r4 /* r11 saves tp */ |
79 | bl V_LOCAL_FUNC(__get_datapage) /* get data page */ | 72 | bl V_LOCAL_FUNC(__get_datapage) /* get data page */ |
73 | lis r7,NSEC_PER_SEC@h /* want nanoseconds */ | ||
74 | ori r7,r7,NSEC_PER_SEC@l | ||
80 | 50: bl V_LOCAL_FUNC(__do_get_tspec) /* get time from tb & kernel */ | 75 | 50: bl V_LOCAL_FUNC(__do_get_tspec) /* get time from tb & kernel */ |
81 | bne cr1,80f /* if not monotonic, all done */ | 76 | bne cr1,80f /* if not monotonic, all done */ |
82 | 77 | ||
@@ -171,49 +166,12 @@ V_FUNCTION_END(__kernel_clock_getres) | |||
171 | 166 | ||
172 | 167 | ||
173 | /* | 168 | /* |
174 | * This is the core of gettimeofday(), it returns the xsec | 169 | * This is the core of clock_gettime() and gettimeofday(), |
175 | * value in r4 and expects the datapage ptr (non clobbered) | 170 | * it returns the current time in r4 (seconds) and r5. |
176 | * in r3. clobbers r0,r4,r5,r6,r7,r8 | 171 | * On entry, r7 gives the resolution of r5, either USEC_PER_SEC |
177 | * When returning, r8 contains the counter value that can be reused | 172 | * or NSEC_PER_SEC, giving r5 in microseconds or nanoseconds. |
178 | */ | ||
179 | V_FUNCTION_BEGIN(__do_get_xsec) | ||
180 | .cfi_startproc | ||
181 | /* check for update count & load values */ | ||
182 | 1: ld r8,CFG_TB_UPDATE_COUNT(r3) | ||
183 | andi. r0,r8,1 /* pending update ? loop */ | ||
184 | bne- 1b | ||
185 | xor r0,r8,r8 /* create dependency */ | ||
186 | add r3,r3,r0 | ||
187 | |||
188 | /* Get TB & offset it. We use the MFTB macro which will generate | ||
189 | * workaround code for Cell. | ||
190 | */ | ||
191 | MFTB(r7) | ||
192 | ld r9,CFG_TB_ORIG_STAMP(r3) | ||
193 | subf r7,r9,r7 | ||
194 | |||
195 | /* Scale result */ | ||
196 | ld r5,CFG_TB_TO_XS(r3) | ||
197 | mulhdu r7,r7,r5 | ||
198 | |||
199 | /* Add stamp since epoch */ | ||
200 | ld r6,CFG_STAMP_XSEC(r3) | ||
201 | add r4,r6,r7 | ||
202 | |||
203 | xor r0,r4,r4 | ||
204 | add r3,r3,r0 | ||
205 | ld r0,CFG_TB_UPDATE_COUNT(r3) | ||
206 | cmpld cr0,r0,r8 /* check if updated */ | ||
207 | bne- 1b | ||
208 | blr | ||
209 | .cfi_endproc | ||
210 | V_FUNCTION_END(__do_get_xsec) | ||
211 | |||
212 | /* | ||
213 | * This is the core of clock_gettime(), it returns the current | ||
214 | * time in seconds and nanoseconds in r4 and r5. | ||
215 | * It expects the datapage ptr in r3 and doesn't clobber it. | 173 | * It expects the datapage ptr in r3 and doesn't clobber it. |
216 | * It clobbers r0 and r6 and returns NSEC_PER_SEC in r7. | 174 | * It clobbers r0, r6 and r9. |
217 | * On return, r8 contains the counter value that can be reused. | 175 | * On return, r8 contains the counter value that can be reused. |
218 | * This clobbers cr0 but not any other cr field. | 176 | * This clobbers cr0 but not any other cr field. |
219 | */ | 177 | */ |
@@ -229,18 +187,18 @@ V_FUNCTION_BEGIN(__do_get_tspec) | |||
229 | /* Get TB & offset it. We use the MFTB macro which will generate | 187 | /* Get TB & offset it. We use the MFTB macro which will generate |
230 | * workaround code for Cell. | 188 | * workaround code for Cell. |
231 | */ | 189 | */ |
232 | MFTB(r7) | 190 | MFTB(r6) |
233 | ld r9,CFG_TB_ORIG_STAMP(r3) | 191 | ld r9,CFG_TB_ORIG_STAMP(r3) |
234 | subf r7,r9,r7 | 192 | subf r6,r9,r6 |
235 | 193 | ||
236 | /* Scale result */ | 194 | /* Scale result */ |
237 | ld r5,CFG_TB_TO_XS(r3) | 195 | ld r5,CFG_TB_TO_XS(r3) |
238 | sldi r7,r7,12 /* compute time since stamp_xtime */ | 196 | sldi r6,r6,12 /* compute time since stamp_xtime */ |
239 | mulhdu r6,r7,r5 /* in units of 2^-32 seconds */ | 197 | mulhdu r6,r6,r5 /* in units of 2^-32 seconds */ |
240 | 198 | ||
241 | /* Add stamp since epoch */ | 199 | /* Add stamp since epoch */ |
242 | ld r4,STAMP_XTIME+TSPC64_TV_SEC(r3) | 200 | ld r4,STAMP_XTIME+TSPC64_TV_SEC(r3) |
243 | ld r5,STAMP_XTIME+TSPC64_TV_NSEC(r3) | 201 | lwz r5,STAMP_SEC_FRAC(r3) |
244 | or r0,r4,r5 | 202 | or r0,r4,r5 |
245 | or r0,r0,r6 | 203 | or r0,r0,r6 |
246 | xor r0,r0,r0 | 204 | xor r0,r0,r0 |
@@ -250,17 +208,11 @@ V_FUNCTION_BEGIN(__do_get_tspec) | |||
250 | bne- 1b /* reload if so */ | 208 | bne- 1b /* reload if so */ |
251 | 209 | ||
252 | /* convert to seconds & nanoseconds and add to stamp */ | 210 | /* convert to seconds & nanoseconds and add to stamp */ |
253 | lis r7,NSEC_PER_SEC@h | 211 | add r6,r6,r5 /* add on fractional seconds of xtime */ |
254 | ori r7,r7,NSEC_PER_SEC@l | 212 | mulhwu r5,r6,r7 /* compute micro or nanoseconds and */ |
255 | mulhwu r0,r6,r7 /* compute nanoseconds and */ | ||
256 | srdi r6,r6,32 /* seconds since stamp_xtime */ | 213 | srdi r6,r6,32 /* seconds since stamp_xtime */ |
257 | clrldi r0,r0,32 | 214 | clrldi r5,r5,32 |
258 | add r5,r5,r0 /* add nanoseconds together */ | ||
259 | cmpd r5,r7 /* overflow? */ | ||
260 | add r4,r4,r6 | 215 | add r4,r4,r6 |
261 | bltlr /* all done if no overflow */ | ||
262 | subf r5,r7,r5 /* if overflow, adjust */ | ||
263 | addi r4,r4,1 | ||
264 | blr | 216 | blr |
265 | .cfi_endproc | 217 | .cfi_endproc |
266 | V_FUNCTION_END(__do_get_tspec) | 218 | V_FUNCTION_END(__do_get_tspec) |
diff --git a/arch/powerpc/kvm/timing.c b/arch/powerpc/kvm/timing.c index 70378551c0cc..46fa04f12a9b 100644 --- a/arch/powerpc/kvm/timing.c +++ b/arch/powerpc/kvm/timing.c | |||
@@ -182,7 +182,7 @@ static ssize_t kvmppc_exit_timing_write(struct file *file, | |||
182 | } | 182 | } |
183 | 183 | ||
184 | if (c == 'c') { | 184 | if (c == 'c') { |
185 | struct seq_file *seqf = (struct seq_file *)file->private_data; | 185 | struct seq_file *seqf = file->private_data; |
186 | struct kvm_vcpu *vcpu = seqf->private; | 186 | struct kvm_vcpu *vcpu = seqf->private; |
187 | /* Write does not affect our buffers previously generated with | 187 | /* Write does not affect our buffers previously generated with |
188 | * show. seq_file is locked here to prevent races of init with | 188 | * show. seq_file is locked here to prevent races of init with |
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 111da1c03a11..5bb89c828070 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile | |||
@@ -18,8 +18,9 @@ obj-$(CONFIG_HAS_IOMEM) += devres.o | |||
18 | 18 | ||
19 | obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \ | 19 | obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \ |
20 | memcpy_64.o usercopy_64.o mem_64.o string.o | 20 | memcpy_64.o usercopy_64.o mem_64.o string.o |
21 | obj-$(CONFIG_XMON) += sstep.o | 21 | obj-$(CONFIG_XMON) += sstep.o ldstfp.o |
22 | obj-$(CONFIG_KPROBES) += sstep.o | 22 | obj-$(CONFIG_KPROBES) += sstep.o ldstfp.o |
23 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += sstep.o ldstfp.o | ||
23 | 24 | ||
24 | ifeq ($(CONFIG_PPC64),y) | 25 | ifeq ($(CONFIG_PPC64),y) |
25 | obj-$(CONFIG_SMP) += locks.o | 26 | obj-$(CONFIG_SMP) += locks.o |
diff --git a/arch/powerpc/lib/ldstfp.S b/arch/powerpc/lib/ldstfp.S new file mode 100644 index 000000000000..f6448636baf5 --- /dev/null +++ b/arch/powerpc/lib/ldstfp.S | |||
@@ -0,0 +1,375 @@ | |||
1 | /* | ||
2 | * Floating-point, VMX/Altivec and VSX loads and stores | ||
3 | * for use in instruction emulation. | ||
4 | * | ||
5 | * Copyright 2010 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version | ||
10 | * 2 of the License, or (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <asm/processor.h> | ||
14 | #include <asm/ppc_asm.h> | ||
15 | #include <asm/ppc-opcode.h> | ||
16 | #include <asm/reg.h> | ||
17 | #include <asm/asm-offsets.h> | ||
18 | #include <linux/errno.h> | ||
19 | |||
20 | #define STKFRM (PPC_MIN_STKFRM + 16) | ||
21 | |||
22 | .macro extab instr,handler | ||
23 | .section __ex_table,"a" | ||
24 | PPC_LONG \instr,\handler | ||
25 | .previous | ||
26 | .endm | ||
27 | |||
28 | .macro inst32 op | ||
29 | reg = 0 | ||
30 | .rept 32 | ||
31 | 20: \op reg,0,r4 | ||
32 | b 3f | ||
33 | extab 20b,99f | ||
34 | reg = reg + 1 | ||
35 | .endr | ||
36 | .endm | ||
37 | |||
38 | /* Get the contents of frN into fr0; N is in r3. */ | ||
39 | _GLOBAL(get_fpr) | ||
40 | mflr r0 | ||
41 | rlwinm r3,r3,3,0xf8 | ||
42 | bcl 20,31,1f | ||
43 | blr /* fr0 is already in fr0 */ | ||
44 | nop | ||
45 | reg = 1 | ||
46 | .rept 31 | ||
47 | fmr fr0,reg | ||
48 | blr | ||
49 | reg = reg + 1 | ||
50 | .endr | ||
51 | 1: mflr r5 | ||
52 | add r5,r3,r5 | ||
53 | mtctr r5 | ||
54 | mtlr r0 | ||
55 | bctr | ||
56 | |||
57 | /* Put the contents of fr0 into frN; N is in r3. */ | ||
58 | _GLOBAL(put_fpr) | ||
59 | mflr r0 | ||
60 | rlwinm r3,r3,3,0xf8 | ||
61 | bcl 20,31,1f | ||
62 | blr /* fr0 is already in fr0 */ | ||
63 | nop | ||
64 | reg = 1 | ||
65 | .rept 31 | ||
66 | fmr reg,fr0 | ||
67 | blr | ||
68 | reg = reg + 1 | ||
69 | .endr | ||
70 | 1: mflr r5 | ||
71 | add r5,r3,r5 | ||
72 | mtctr r5 | ||
73 | mtlr r0 | ||
74 | bctr | ||
75 | |||
76 | /* Load FP reg N from float at *p. N is in r3, p in r4. */ | ||
77 | _GLOBAL(do_lfs) | ||
78 | PPC_STLU r1,-STKFRM(r1) | ||
79 | mflr r0 | ||
80 | PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
81 | mfmsr r6 | ||
82 | ori r7,r6,MSR_FP | ||
83 | cmpwi cr7,r3,0 | ||
84 | mtmsrd r7 | ||
85 | isync | ||
86 | beq cr7,1f | ||
87 | stfd fr0,STKFRM-16(r1) | ||
88 | 1: li r9,-EFAULT | ||
89 | 2: lfs fr0,0(r4) | ||
90 | li r9,0 | ||
91 | 3: bl put_fpr | ||
92 | beq cr7,4f | ||
93 | lfd fr0,STKFRM-16(r1) | ||
94 | 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
95 | mtlr r0 | ||
96 | mtmsrd r6 | ||
97 | isync | ||
98 | mr r3,r9 | ||
99 | addi r1,r1,STKFRM | ||
100 | blr | ||
101 | extab 2b,3b | ||
102 | |||
103 | /* Load FP reg N from double at *p. N is in r3, p in r4. */ | ||
104 | _GLOBAL(do_lfd) | ||
105 | PPC_STLU r1,-STKFRM(r1) | ||
106 | mflr r0 | ||
107 | PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
108 | mfmsr r6 | ||
109 | ori r7,r6,MSR_FP | ||
110 | cmpwi cr7,r3,0 | ||
111 | mtmsrd r7 | ||
112 | isync | ||
113 | beq cr7,1f | ||
114 | stfd fr0,STKFRM-16(r1) | ||
115 | 1: li r9,-EFAULT | ||
116 | 2: lfd fr0,0(r4) | ||
117 | li r9,0 | ||
118 | 3: beq cr7,4f | ||
119 | bl put_fpr | ||
120 | lfd fr0,STKFRM-16(r1) | ||
121 | 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
122 | mtlr r0 | ||
123 | mtmsrd r6 | ||
124 | isync | ||
125 | mr r3,r9 | ||
126 | addi r1,r1,STKFRM | ||
127 | blr | ||
128 | extab 2b,3b | ||
129 | |||
130 | /* Store FP reg N to float at *p. N is in r3, p in r4. */ | ||
131 | _GLOBAL(do_stfs) | ||
132 | PPC_STLU r1,-STKFRM(r1) | ||
133 | mflr r0 | ||
134 | PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
135 | mfmsr r6 | ||
136 | ori r7,r6,MSR_FP | ||
137 | cmpwi cr7,r3,0 | ||
138 | mtmsrd r7 | ||
139 | isync | ||
140 | beq cr7,1f | ||
141 | stfd fr0,STKFRM-16(r1) | ||
142 | bl get_fpr | ||
143 | 1: li r9,-EFAULT | ||
144 | 2: stfs fr0,0(r4) | ||
145 | li r9,0 | ||
146 | 3: beq cr7,4f | ||
147 | lfd fr0,STKFRM-16(r1) | ||
148 | 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
149 | mtlr r0 | ||
150 | mtmsrd r6 | ||
151 | isync | ||
152 | mr r3,r9 | ||
153 | addi r1,r1,STKFRM | ||
154 | blr | ||
155 | extab 2b,3b | ||
156 | |||
157 | /* Store FP reg N to double at *p. N is in r3, p in r4. */ | ||
158 | _GLOBAL(do_stfd) | ||
159 | PPC_STLU r1,-STKFRM(r1) | ||
160 | mflr r0 | ||
161 | PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
162 | mfmsr r6 | ||
163 | ori r7,r6,MSR_FP | ||
164 | cmpwi cr7,r3,0 | ||
165 | mtmsrd r7 | ||
166 | isync | ||
167 | beq cr7,1f | ||
168 | stfd fr0,STKFRM-16(r1) | ||
169 | bl get_fpr | ||
170 | 1: li r9,-EFAULT | ||
171 | 2: stfd fr0,0(r4) | ||
172 | li r9,0 | ||
173 | 3: beq cr7,4f | ||
174 | lfd fr0,STKFRM-16(r1) | ||
175 | 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
176 | mtlr r0 | ||
177 | mtmsrd r6 | ||
178 | isync | ||
179 | mr r3,r9 | ||
180 | addi r1,r1,STKFRM | ||
181 | blr | ||
182 | extab 2b,3b | ||
183 | |||
184 | #ifdef CONFIG_ALTIVEC | ||
185 | /* Get the contents of vrN into vr0; N is in r3. */ | ||
186 | _GLOBAL(get_vr) | ||
187 | mflr r0 | ||
188 | rlwinm r3,r3,3,0xf8 | ||
189 | bcl 20,31,1f | ||
190 | blr /* vr0 is already in vr0 */ | ||
191 | nop | ||
192 | reg = 1 | ||
193 | .rept 31 | ||
194 | vor vr0,reg,reg /* assembler doesn't know vmr? */ | ||
195 | blr | ||
196 | reg = reg + 1 | ||
197 | .endr | ||
198 | 1: mflr r5 | ||
199 | add r5,r3,r5 | ||
200 | mtctr r5 | ||
201 | mtlr r0 | ||
202 | bctr | ||
203 | |||
204 | /* Put the contents of vr0 into vrN; N is in r3. */ | ||
205 | _GLOBAL(put_vr) | ||
206 | mflr r0 | ||
207 | rlwinm r3,r3,3,0xf8 | ||
208 | bcl 20,31,1f | ||
209 | blr /* vr0 is already in vr0 */ | ||
210 | nop | ||
211 | reg = 1 | ||
212 | .rept 31 | ||
213 | vor reg,vr0,vr0 | ||
214 | blr | ||
215 | reg = reg + 1 | ||
216 | .endr | ||
217 | 1: mflr r5 | ||
218 | add r5,r3,r5 | ||
219 | mtctr r5 | ||
220 | mtlr r0 | ||
221 | bctr | ||
222 | |||
223 | /* Load vector reg N from *p. N is in r3, p in r4. */ | ||
224 | _GLOBAL(do_lvx) | ||
225 | PPC_STLU r1,-STKFRM(r1) | ||
226 | mflr r0 | ||
227 | PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
228 | mfmsr r6 | ||
229 | oris r7,r6,MSR_VEC@h | ||
230 | cmpwi cr7,r3,0 | ||
231 | li r8,STKFRM-16 | ||
232 | mtmsrd r7 | ||
233 | isync | ||
234 | beq cr7,1f | ||
235 | stvx vr0,r1,r8 | ||
236 | 1: li r9,-EFAULT | ||
237 | 2: lvx vr0,0,r4 | ||
238 | li r9,0 | ||
239 | 3: beq cr7,4f | ||
240 | bl put_vr | ||
241 | lvx vr0,r1,r8 | ||
242 | 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
243 | mtlr r0 | ||
244 | mtmsrd r6 | ||
245 | isync | ||
246 | mr r3,r9 | ||
247 | addi r1,r1,STKFRM | ||
248 | blr | ||
249 | extab 2b,3b | ||
250 | |||
251 | /* Store vector reg N to *p. N is in r3, p in r4. */ | ||
252 | _GLOBAL(do_stvx) | ||
253 | PPC_STLU r1,-STKFRM(r1) | ||
254 | mflr r0 | ||
255 | PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
256 | mfmsr r6 | ||
257 | oris r7,r6,MSR_VEC@h | ||
258 | cmpwi cr7,r3,0 | ||
259 | li r8,STKFRM-16 | ||
260 | mtmsrd r7 | ||
261 | isync | ||
262 | beq cr7,1f | ||
263 | stvx vr0,r1,r8 | ||
264 | bl get_vr | ||
265 | 1: li r9,-EFAULT | ||
266 | 2: stvx vr0,0,r4 | ||
267 | li r9,0 | ||
268 | 3: beq cr7,4f | ||
269 | lvx vr0,r1,r8 | ||
270 | 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
271 | mtlr r0 | ||
272 | mtmsrd r6 | ||
273 | isync | ||
274 | mr r3,r9 | ||
275 | addi r1,r1,STKFRM | ||
276 | blr | ||
277 | extab 2b,3b | ||
278 | #endif /* CONFIG_ALTIVEC */ | ||
279 | |||
280 | #ifdef CONFIG_VSX | ||
281 | /* Get the contents of vsrN into vsr0; N is in r3. */ | ||
282 | _GLOBAL(get_vsr) | ||
283 | mflr r0 | ||
284 | rlwinm r3,r3,3,0x1f8 | ||
285 | bcl 20,31,1f | ||
286 | blr /* vsr0 is already in vsr0 */ | ||
287 | nop | ||
288 | reg = 1 | ||
289 | .rept 63 | ||
290 | XXLOR(0,reg,reg) | ||
291 | blr | ||
292 | reg = reg + 1 | ||
293 | .endr | ||
294 | 1: mflr r5 | ||
295 | add r5,r3,r5 | ||
296 | mtctr r5 | ||
297 | mtlr r0 | ||
298 | bctr | ||
299 | |||
300 | /* Put the contents of vsr0 into vsrN; N is in r3. */ | ||
301 | _GLOBAL(put_vsr) | ||
302 | mflr r0 | ||
303 | rlwinm r3,r3,3,0x1f8 | ||
304 | bcl 20,31,1f | ||
305 | blr /* vr0 is already in vr0 */ | ||
306 | nop | ||
307 | reg = 1 | ||
308 | .rept 63 | ||
309 | XXLOR(reg,0,0) | ||
310 | blr | ||
311 | reg = reg + 1 | ||
312 | .endr | ||
313 | 1: mflr r5 | ||
314 | add r5,r3,r5 | ||
315 | mtctr r5 | ||
316 | mtlr r0 | ||
317 | bctr | ||
318 | |||
319 | /* Load VSX reg N from vector doubleword *p. N is in r3, p in r4. */ | ||
320 | _GLOBAL(do_lxvd2x) | ||
321 | PPC_STLU r1,-STKFRM(r1) | ||
322 | mflr r0 | ||
323 | PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
324 | mfmsr r6 | ||
325 | oris r7,r6,MSR_VSX@h | ||
326 | cmpwi cr7,r3,0 | ||
327 | li r8,STKFRM-16 | ||
328 | mtmsrd r7 | ||
329 | isync | ||
330 | beq cr7,1f | ||
331 | STXVD2X(0,r1,r8) | ||
332 | 1: li r9,-EFAULT | ||
333 | 2: LXVD2X(0,0,r4) | ||
334 | li r9,0 | ||
335 | 3: beq cr7,4f | ||
336 | bl put_vsr | ||
337 | LXVD2X(0,r1,r8) | ||
338 | 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
339 | mtlr r0 | ||
340 | mtmsrd r6 | ||
341 | isync | ||
342 | mr r3,r9 | ||
343 | addi r1,r1,STKFRM | ||
344 | blr | ||
345 | extab 2b,3b | ||
346 | |||
347 | /* Store VSX reg N to vector doubleword *p. N is in r3, p in r4. */ | ||
348 | _GLOBAL(do_stxvd2x) | ||
349 | PPC_STLU r1,-STKFRM(r1) | ||
350 | mflr r0 | ||
351 | PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
352 | mfmsr r6 | ||
353 | oris r7,r6,MSR_VSX@h | ||
354 | cmpwi cr7,r3,0 | ||
355 | li r8,STKFRM-16 | ||
356 | mtmsrd r7 | ||
357 | isync | ||
358 | beq cr7,1f | ||
359 | STXVD2X(0,r1,r8) | ||
360 | bl get_vsr | ||
361 | 1: li r9,-EFAULT | ||
362 | 2: STXVD2X(0,0,r4) | ||
363 | li r9,0 | ||
364 | 3: beq cr7,4f | ||
365 | LXVD2X(0,r1,r8) | ||
366 | 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) | ||
367 | mtlr r0 | ||
368 | mtmsrd r6 | ||
369 | isync | ||
370 | mr r3,r9 | ||
371 | addi r1,r1,STKFRM | ||
372 | blr | ||
373 | extab 2b,3b | ||
374 | |||
375 | #endif /* CONFIG_VSX */ | ||
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index 13b7d54f185b..e0a9858d537e 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c | |||
@@ -13,6 +13,8 @@ | |||
13 | #include <linux/ptrace.h> | 13 | #include <linux/ptrace.h> |
14 | #include <asm/sstep.h> | 14 | #include <asm/sstep.h> |
15 | #include <asm/processor.h> | 15 | #include <asm/processor.h> |
16 | #include <asm/uaccess.h> | ||
17 | #include <asm/cputable.h> | ||
16 | 18 | ||
17 | extern char system_call_common[]; | 19 | extern char system_call_common[]; |
18 | 20 | ||
@@ -23,6 +25,23 @@ extern char system_call_common[]; | |||
23 | #define MSR_MASK 0x87c0ffff | 25 | #define MSR_MASK 0x87c0ffff |
24 | #endif | 26 | #endif |
25 | 27 | ||
28 | /* Bits in XER */ | ||
29 | #define XER_SO 0x80000000U | ||
30 | #define XER_OV 0x40000000U | ||
31 | #define XER_CA 0x20000000U | ||
32 | |||
33 | /* | ||
34 | * Functions in ldstfp.S | ||
35 | */ | ||
36 | extern int do_lfs(int rn, unsigned long ea); | ||
37 | extern int do_lfd(int rn, unsigned long ea); | ||
38 | extern int do_stfs(int rn, unsigned long ea); | ||
39 | extern int do_stfd(int rn, unsigned long ea); | ||
40 | extern int do_lvx(int rn, unsigned long ea); | ||
41 | extern int do_stvx(int rn, unsigned long ea); | ||
42 | extern int do_lxvd2x(int rn, unsigned long ea); | ||
43 | extern int do_stxvd2x(int rn, unsigned long ea); | ||
44 | |||
26 | /* | 45 | /* |
27 | * Determine whether a conditional branch instruction would branch. | 46 | * Determine whether a conditional branch instruction would branch. |
28 | */ | 47 | */ |
@@ -46,16 +65,499 @@ static int __kprobes branch_taken(unsigned int instr, struct pt_regs *regs) | |||
46 | return 1; | 65 | return 1; |
47 | } | 66 | } |
48 | 67 | ||
68 | |||
69 | static long __kprobes address_ok(struct pt_regs *regs, unsigned long ea, int nb) | ||
70 | { | ||
71 | if (!user_mode(regs)) | ||
72 | return 1; | ||
73 | return __access_ok(ea, nb, USER_DS); | ||
74 | } | ||
75 | |||
76 | /* | ||
77 | * Calculate effective address for a D-form instruction | ||
78 | */ | ||
79 | static unsigned long __kprobes dform_ea(unsigned int instr, struct pt_regs *regs) | ||
80 | { | ||
81 | int ra; | ||
82 | unsigned long ea; | ||
83 | |||
84 | ra = (instr >> 16) & 0x1f; | ||
85 | ea = (signed short) instr; /* sign-extend */ | ||
86 | if (ra) { | ||
87 | ea += regs->gpr[ra]; | ||
88 | if (instr & 0x04000000) /* update forms */ | ||
89 | regs->gpr[ra] = ea; | ||
90 | } | ||
91 | #ifdef __powerpc64__ | ||
92 | if (!(regs->msr & MSR_SF)) | ||
93 | ea &= 0xffffffffUL; | ||
94 | #endif | ||
95 | return ea; | ||
96 | } | ||
97 | |||
98 | #ifdef __powerpc64__ | ||
99 | /* | ||
100 | * Calculate effective address for a DS-form instruction | ||
101 | */ | ||
102 | static unsigned long __kprobes dsform_ea(unsigned int instr, struct pt_regs *regs) | ||
103 | { | ||
104 | int ra; | ||
105 | unsigned long ea; | ||
106 | |||
107 | ra = (instr >> 16) & 0x1f; | ||
108 | ea = (signed short) (instr & ~3); /* sign-extend */ | ||
109 | if (ra) { | ||
110 | ea += regs->gpr[ra]; | ||
111 | if ((instr & 3) == 1) /* update forms */ | ||
112 | regs->gpr[ra] = ea; | ||
113 | } | ||
114 | if (!(regs->msr & MSR_SF)) | ||
115 | ea &= 0xffffffffUL; | ||
116 | return ea; | ||
117 | } | ||
118 | #endif /* __powerpc64 */ | ||
119 | |||
120 | /* | ||
121 | * Calculate effective address for an X-form instruction | ||
122 | */ | ||
123 | static unsigned long __kprobes xform_ea(unsigned int instr, struct pt_regs *regs, | ||
124 | int do_update) | ||
125 | { | ||
126 | int ra, rb; | ||
127 | unsigned long ea; | ||
128 | |||
129 | ra = (instr >> 16) & 0x1f; | ||
130 | rb = (instr >> 11) & 0x1f; | ||
131 | ea = regs->gpr[rb]; | ||
132 | if (ra) { | ||
133 | ea += regs->gpr[ra]; | ||
134 | if (do_update) /* update forms */ | ||
135 | regs->gpr[ra] = ea; | ||
136 | } | ||
137 | #ifdef __powerpc64__ | ||
138 | if (!(regs->msr & MSR_SF)) | ||
139 | ea &= 0xffffffffUL; | ||
140 | #endif | ||
141 | return ea; | ||
142 | } | ||
143 | |||
144 | /* | ||
145 | * Return the largest power of 2, not greater than sizeof(unsigned long), | ||
146 | * such that x is a multiple of it. | ||
147 | */ | ||
148 | static inline unsigned long max_align(unsigned long x) | ||
149 | { | ||
150 | x |= sizeof(unsigned long); | ||
151 | return x & -x; /* isolates rightmost bit */ | ||
152 | } | ||
153 | |||
154 | |||
155 | static inline unsigned long byterev_2(unsigned long x) | ||
156 | { | ||
157 | return ((x >> 8) & 0xff) | ((x & 0xff) << 8); | ||
158 | } | ||
159 | |||
160 | static inline unsigned long byterev_4(unsigned long x) | ||
161 | { | ||
162 | return ((x >> 24) & 0xff) | ((x >> 8) & 0xff00) | | ||
163 | ((x & 0xff00) << 8) | ((x & 0xff) << 24); | ||
164 | } | ||
165 | |||
166 | #ifdef __powerpc64__ | ||
167 | static inline unsigned long byterev_8(unsigned long x) | ||
168 | { | ||
169 | return (byterev_4(x) << 32) | byterev_4(x >> 32); | ||
170 | } | ||
171 | #endif | ||
172 | |||
173 | static int __kprobes read_mem_aligned(unsigned long *dest, unsigned long ea, | ||
174 | int nb) | ||
175 | { | ||
176 | int err = 0; | ||
177 | unsigned long x = 0; | ||
178 | |||
179 | switch (nb) { | ||
180 | case 1: | ||
181 | err = __get_user(x, (unsigned char __user *) ea); | ||
182 | break; | ||
183 | case 2: | ||
184 | err = __get_user(x, (unsigned short __user *) ea); | ||
185 | break; | ||
186 | case 4: | ||
187 | err = __get_user(x, (unsigned int __user *) ea); | ||
188 | break; | ||
189 | #ifdef __powerpc64__ | ||
190 | case 8: | ||
191 | err = __get_user(x, (unsigned long __user *) ea); | ||
192 | break; | ||
193 | #endif | ||
194 | } | ||
195 | if (!err) | ||
196 | *dest = x; | ||
197 | return err; | ||
198 | } | ||
199 | |||
200 | static int __kprobes read_mem_unaligned(unsigned long *dest, unsigned long ea, | ||
201 | int nb, struct pt_regs *regs) | ||
202 | { | ||
203 | int err; | ||
204 | unsigned long x, b, c; | ||
205 | |||
206 | /* unaligned, do this in pieces */ | ||
207 | x = 0; | ||
208 | for (; nb > 0; nb -= c) { | ||
209 | c = max_align(ea); | ||
210 | if (c > nb) | ||
211 | c = max_align(nb); | ||
212 | err = read_mem_aligned(&b, ea, c); | ||
213 | if (err) | ||
214 | return err; | ||
215 | x = (x << (8 * c)) + b; | ||
216 | ea += c; | ||
217 | } | ||
218 | *dest = x; | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | /* | ||
223 | * Read memory at address ea for nb bytes, return 0 for success | ||
224 | * or -EFAULT if an error occurred. | ||
225 | */ | ||
226 | static int __kprobes read_mem(unsigned long *dest, unsigned long ea, int nb, | ||
227 | struct pt_regs *regs) | ||
228 | { | ||
229 | if (!address_ok(regs, ea, nb)) | ||
230 | return -EFAULT; | ||
231 | if ((ea & (nb - 1)) == 0) | ||
232 | return read_mem_aligned(dest, ea, nb); | ||
233 | return read_mem_unaligned(dest, ea, nb, regs); | ||
234 | } | ||
235 | |||
236 | static int __kprobes write_mem_aligned(unsigned long val, unsigned long ea, | ||
237 | int nb) | ||
238 | { | ||
239 | int err = 0; | ||
240 | |||
241 | switch (nb) { | ||
242 | case 1: | ||
243 | err = __put_user(val, (unsigned char __user *) ea); | ||
244 | break; | ||
245 | case 2: | ||
246 | err = __put_user(val, (unsigned short __user *) ea); | ||
247 | break; | ||
248 | case 4: | ||
249 | err = __put_user(val, (unsigned int __user *) ea); | ||
250 | break; | ||
251 | #ifdef __powerpc64__ | ||
252 | case 8: | ||
253 | err = __put_user(val, (unsigned long __user *) ea); | ||
254 | break; | ||
255 | #endif | ||
256 | } | ||
257 | return err; | ||
258 | } | ||
259 | |||
260 | static int __kprobes write_mem_unaligned(unsigned long val, unsigned long ea, | ||
261 | int nb, struct pt_regs *regs) | ||
262 | { | ||
263 | int err; | ||
264 | unsigned long c; | ||
265 | |||
266 | /* unaligned or little-endian, do this in pieces */ | ||
267 | for (; nb > 0; nb -= c) { | ||
268 | c = max_align(ea); | ||
269 | if (c > nb) | ||
270 | c = max_align(nb); | ||
271 | err = write_mem_aligned(val >> (nb - c) * 8, ea, c); | ||
272 | if (err) | ||
273 | return err; | ||
274 | ++ea; | ||
275 | } | ||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | /* | ||
280 | * Write memory at address ea for nb bytes, return 0 for success | ||
281 | * or -EFAULT if an error occurred. | ||
282 | */ | ||
283 | static int __kprobes write_mem(unsigned long val, unsigned long ea, int nb, | ||
284 | struct pt_regs *regs) | ||
285 | { | ||
286 | if (!address_ok(regs, ea, nb)) | ||
287 | return -EFAULT; | ||
288 | if ((ea & (nb - 1)) == 0) | ||
289 | return write_mem_aligned(val, ea, nb); | ||
290 | return write_mem_unaligned(val, ea, nb, regs); | ||
291 | } | ||
292 | |||
49 | /* | 293 | /* |
50 | * Emulate instructions that cause a transfer of control. | 294 | * Check the address and alignment, and call func to do the actual |
295 | * load or store. | ||
296 | */ | ||
297 | static int __kprobes do_fp_load(int rn, int (*func)(int, unsigned long), | ||
298 | unsigned long ea, int nb, | ||
299 | struct pt_regs *regs) | ||
300 | { | ||
301 | int err; | ||
302 | unsigned long val[sizeof(double) / sizeof(long)]; | ||
303 | unsigned long ptr; | ||
304 | |||
305 | if (!address_ok(regs, ea, nb)) | ||
306 | return -EFAULT; | ||
307 | if ((ea & 3) == 0) | ||
308 | return (*func)(rn, ea); | ||
309 | ptr = (unsigned long) &val[0]; | ||
310 | if (sizeof(unsigned long) == 8 || nb == 4) { | ||
311 | err = read_mem_unaligned(&val[0], ea, nb, regs); | ||
312 | ptr += sizeof(unsigned long) - nb; | ||
313 | } else { | ||
314 | /* reading a double on 32-bit */ | ||
315 | err = read_mem_unaligned(&val[0], ea, 4, regs); | ||
316 | if (!err) | ||
317 | err = read_mem_unaligned(&val[1], ea + 4, 4, regs); | ||
318 | } | ||
319 | if (err) | ||
320 | return err; | ||
321 | return (*func)(rn, ptr); | ||
322 | } | ||
323 | |||
324 | static int __kprobes do_fp_store(int rn, int (*func)(int, unsigned long), | ||
325 | unsigned long ea, int nb, | ||
326 | struct pt_regs *regs) | ||
327 | { | ||
328 | int err; | ||
329 | unsigned long val[sizeof(double) / sizeof(long)]; | ||
330 | unsigned long ptr; | ||
331 | |||
332 | if (!address_ok(regs, ea, nb)) | ||
333 | return -EFAULT; | ||
334 | if ((ea & 3) == 0) | ||
335 | return (*func)(rn, ea); | ||
336 | ptr = (unsigned long) &val[0]; | ||
337 | if (sizeof(unsigned long) == 8 || nb == 4) { | ||
338 | ptr += sizeof(unsigned long) - nb; | ||
339 | err = (*func)(rn, ptr); | ||
340 | if (err) | ||
341 | return err; | ||
342 | err = write_mem_unaligned(val[0], ea, nb, regs); | ||
343 | } else { | ||
344 | /* writing a double on 32-bit */ | ||
345 | err = (*func)(rn, ptr); | ||
346 | if (err) | ||
347 | return err; | ||
348 | err = write_mem_unaligned(val[0], ea, 4, regs); | ||
349 | if (!err) | ||
350 | err = write_mem_unaligned(val[1], ea + 4, 4, regs); | ||
351 | } | ||
352 | return err; | ||
353 | } | ||
354 | |||
355 | #ifdef CONFIG_ALTIVEC | ||
356 | /* For Altivec/VMX, no need to worry about alignment */ | ||
357 | static int __kprobes do_vec_load(int rn, int (*func)(int, unsigned long), | ||
358 | unsigned long ea, struct pt_regs *regs) | ||
359 | { | ||
360 | if (!address_ok(regs, ea & ~0xfUL, 16)) | ||
361 | return -EFAULT; | ||
362 | return (*func)(rn, ea); | ||
363 | } | ||
364 | |||
365 | static int __kprobes do_vec_store(int rn, int (*func)(int, unsigned long), | ||
366 | unsigned long ea, struct pt_regs *regs) | ||
367 | { | ||
368 | if (!address_ok(regs, ea & ~0xfUL, 16)) | ||
369 | return -EFAULT; | ||
370 | return (*func)(rn, ea); | ||
371 | } | ||
372 | #endif /* CONFIG_ALTIVEC */ | ||
373 | |||
374 | #ifdef CONFIG_VSX | ||
375 | static int __kprobes do_vsx_load(int rn, int (*func)(int, unsigned long), | ||
376 | unsigned long ea, struct pt_regs *regs) | ||
377 | { | ||
378 | int err; | ||
379 | unsigned long val[2]; | ||
380 | |||
381 | if (!address_ok(regs, ea, 16)) | ||
382 | return -EFAULT; | ||
383 | if ((ea & 3) == 0) | ||
384 | return (*func)(rn, ea); | ||
385 | err = read_mem_unaligned(&val[0], ea, 8, regs); | ||
386 | if (!err) | ||
387 | err = read_mem_unaligned(&val[1], ea + 8, 8, regs); | ||
388 | if (!err) | ||
389 | err = (*func)(rn, (unsigned long) &val[0]); | ||
390 | return err; | ||
391 | } | ||
392 | |||
393 | static int __kprobes do_vsx_store(int rn, int (*func)(int, unsigned long), | ||
394 | unsigned long ea, struct pt_regs *regs) | ||
395 | { | ||
396 | int err; | ||
397 | unsigned long val[2]; | ||
398 | |||
399 | if (!address_ok(regs, ea, 16)) | ||
400 | return -EFAULT; | ||
401 | if ((ea & 3) == 0) | ||
402 | return (*func)(rn, ea); | ||
403 | err = (*func)(rn, (unsigned long) &val[0]); | ||
404 | if (err) | ||
405 | return err; | ||
406 | err = write_mem_unaligned(val[0], ea, 8, regs); | ||
407 | if (!err) | ||
408 | err = write_mem_unaligned(val[1], ea + 8, 8, regs); | ||
409 | return err; | ||
410 | } | ||
411 | #endif /* CONFIG_VSX */ | ||
412 | |||
413 | #define __put_user_asmx(x, addr, err, op, cr) \ | ||
414 | __asm__ __volatile__( \ | ||
415 | "1: " op " %2,0,%3\n" \ | ||
416 | " mfcr %1\n" \ | ||
417 | "2:\n" \ | ||
418 | ".section .fixup,\"ax\"\n" \ | ||
419 | "3: li %0,%4\n" \ | ||
420 | " b 2b\n" \ | ||
421 | ".previous\n" \ | ||
422 | ".section __ex_table,\"a\"\n" \ | ||
423 | PPC_LONG_ALIGN "\n" \ | ||
424 | PPC_LONG "1b,3b\n" \ | ||
425 | ".previous" \ | ||
426 | : "=r" (err), "=r" (cr) \ | ||
427 | : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err)) | ||
428 | |||
429 | #define __get_user_asmx(x, addr, err, op) \ | ||
430 | __asm__ __volatile__( \ | ||
431 | "1: "op" %1,0,%2\n" \ | ||
432 | "2:\n" \ | ||
433 | ".section .fixup,\"ax\"\n" \ | ||
434 | "3: li %0,%3\n" \ | ||
435 | " b 2b\n" \ | ||
436 | ".previous\n" \ | ||
437 | ".section __ex_table,\"a\"\n" \ | ||
438 | PPC_LONG_ALIGN "\n" \ | ||
439 | PPC_LONG "1b,3b\n" \ | ||
440 | ".previous" \ | ||
441 | : "=r" (err), "=r" (x) \ | ||
442 | : "r" (addr), "i" (-EFAULT), "0" (err)) | ||
443 | |||
444 | #define __cacheop_user_asmx(addr, err, op) \ | ||
445 | __asm__ __volatile__( \ | ||
446 | "1: "op" 0,%1\n" \ | ||
447 | "2:\n" \ | ||
448 | ".section .fixup,\"ax\"\n" \ | ||
449 | "3: li %0,%3\n" \ | ||
450 | " b 2b\n" \ | ||
451 | ".previous\n" \ | ||
452 | ".section __ex_table,\"a\"\n" \ | ||
453 | PPC_LONG_ALIGN "\n" \ | ||
454 | PPC_LONG "1b,3b\n" \ | ||
455 | ".previous" \ | ||
456 | : "=r" (err) \ | ||
457 | : "r" (addr), "i" (-EFAULT), "0" (err)) | ||
458 | |||
459 | static void __kprobes set_cr0(struct pt_regs *regs, int rd) | ||
460 | { | ||
461 | long val = regs->gpr[rd]; | ||
462 | |||
463 | regs->ccr = (regs->ccr & 0x0fffffff) | ((regs->xer >> 3) & 0x10000000); | ||
464 | #ifdef __powerpc64__ | ||
465 | if (!(regs->msr & MSR_SF)) | ||
466 | val = (int) val; | ||
467 | #endif | ||
468 | if (val < 0) | ||
469 | regs->ccr |= 0x80000000; | ||
470 | else if (val > 0) | ||
471 | regs->ccr |= 0x40000000; | ||
472 | else | ||
473 | regs->ccr |= 0x20000000; | ||
474 | } | ||
475 | |||
476 | static void __kprobes add_with_carry(struct pt_regs *regs, int rd, | ||
477 | unsigned long val1, unsigned long val2, | ||
478 | unsigned long carry_in) | ||
479 | { | ||
480 | unsigned long val = val1 + val2; | ||
481 | |||
482 | if (carry_in) | ||
483 | ++val; | ||
484 | regs->gpr[rd] = val; | ||
485 | #ifdef __powerpc64__ | ||
486 | if (!(regs->msr & MSR_SF)) { | ||
487 | val = (unsigned int) val; | ||
488 | val1 = (unsigned int) val1; | ||
489 | } | ||
490 | #endif | ||
491 | if (val < val1 || (carry_in && val == val1)) | ||
492 | regs->xer |= XER_CA; | ||
493 | else | ||
494 | regs->xer &= ~XER_CA; | ||
495 | } | ||
496 | |||
497 | static void __kprobes do_cmp_signed(struct pt_regs *regs, long v1, long v2, | ||
498 | int crfld) | ||
499 | { | ||
500 | unsigned int crval, shift; | ||
501 | |||
502 | crval = (regs->xer >> 31) & 1; /* get SO bit */ | ||
503 | if (v1 < v2) | ||
504 | crval |= 8; | ||
505 | else if (v1 > v2) | ||
506 | crval |= 4; | ||
507 | else | ||
508 | crval |= 2; | ||
509 | shift = (7 - crfld) * 4; | ||
510 | regs->ccr = (regs->ccr & ~(0xf << shift)) | (crval << shift); | ||
511 | } | ||
512 | |||
513 | static void __kprobes do_cmp_unsigned(struct pt_regs *regs, unsigned long v1, | ||
514 | unsigned long v2, int crfld) | ||
515 | { | ||
516 | unsigned int crval, shift; | ||
517 | |||
518 | crval = (regs->xer >> 31) & 1; /* get SO bit */ | ||
519 | if (v1 < v2) | ||
520 | crval |= 8; | ||
521 | else if (v1 > v2) | ||
522 | crval |= 4; | ||
523 | else | ||
524 | crval |= 2; | ||
525 | shift = (7 - crfld) * 4; | ||
526 | regs->ccr = (regs->ccr & ~(0xf << shift)) | (crval << shift); | ||
527 | } | ||
528 | |||
529 | /* | ||
530 | * Elements of 32-bit rotate and mask instructions. | ||
531 | */ | ||
532 | #define MASK32(mb, me) ((0xffffffffUL >> (mb)) + \ | ||
533 | ((signed long)-0x80000000L >> (me)) + ((me) >= (mb))) | ||
534 | #ifdef __powerpc64__ | ||
535 | #define MASK64_L(mb) (~0UL >> (mb)) | ||
536 | #define MASK64_R(me) ((signed long)-0x8000000000000000L >> (me)) | ||
537 | #define MASK64(mb, me) (MASK64_L(mb) + MASK64_R(me) + ((me) >= (mb))) | ||
538 | #define DATA32(x) (((x) & 0xffffffffUL) | (((x) & 0xffffffffUL) << 32)) | ||
539 | #else | ||
540 | #define DATA32(x) (x) | ||
541 | #endif | ||
542 | #define ROTATE(x, n) ((n) ? (((x) << (n)) | ((x) >> (8 * sizeof(long) - (n)))) : (x)) | ||
543 | |||
544 | /* | ||
545 | * Emulate instructions that cause a transfer of control, | ||
546 | * loads and stores, and a few other instructions. | ||
51 | * Returns 1 if the step was emulated, 0 if not, | 547 | * Returns 1 if the step was emulated, 0 if not, |
52 | * or -1 if the instruction is one that should not be stepped, | 548 | * or -1 if the instruction is one that should not be stepped, |
53 | * such as an rfid, or a mtmsrd that would clear MSR_RI. | 549 | * such as an rfid, or a mtmsrd that would clear MSR_RI. |
54 | */ | 550 | */ |
55 | int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | 551 | int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) |
56 | { | 552 | { |
57 | unsigned int opcode, rs, rb, rd, spr; | 553 | unsigned int opcode, ra, rb, rd, spr, u; |
58 | unsigned long int imm; | 554 | unsigned long int imm; |
555 | unsigned long int val, val2; | ||
556 | unsigned long int ea; | ||
557 | unsigned int cr, mb, me, sh; | ||
558 | int err; | ||
559 | unsigned long old_ra; | ||
560 | long ival; | ||
59 | 561 | ||
60 | opcode = instr >> 26; | 562 | opcode = instr >> 26; |
61 | switch (opcode) { | 563 | switch (opcode) { |
@@ -78,7 +580,13 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | |||
78 | * entry code works. If that is changed, this will | 580 | * entry code works. If that is changed, this will |
79 | * need to be changed also. | 581 | * need to be changed also. |
80 | */ | 582 | */ |
583 | if (regs->gpr[0] == 0x1ebe && | ||
584 | cpu_has_feature(CPU_FTR_REAL_LE)) { | ||
585 | regs->msr ^= MSR_LE; | ||
586 | goto instr_done; | ||
587 | } | ||
81 | regs->gpr[9] = regs->gpr[13]; | 588 | regs->gpr[9] = regs->gpr[13]; |
589 | regs->gpr[10] = MSR_KERNEL; | ||
82 | regs->gpr[11] = regs->nip + 4; | 590 | regs->gpr[11] = regs->nip + 4; |
83 | regs->gpr[12] = regs->msr & MSR_MASK; | 591 | regs->gpr[12] = regs->msr & MSR_MASK; |
84 | regs->gpr[13] = (unsigned long) get_paca(); | 592 | regs->gpr[13] = (unsigned long) get_paca(); |
@@ -102,9 +610,9 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | |||
102 | regs->nip = imm; | 610 | regs->nip = imm; |
103 | return 1; | 611 | return 1; |
104 | case 19: | 612 | case 19: |
105 | switch (instr & 0x7fe) { | 613 | switch ((instr >> 1) & 0x3ff) { |
106 | case 0x20: /* bclr */ | 614 | case 16: /* bclr */ |
107 | case 0x420: /* bcctr */ | 615 | case 528: /* bcctr */ |
108 | imm = (instr & 0x400)? regs->ctr: regs->link; | 616 | imm = (instr & 0x400)? regs->ctr: regs->link; |
109 | regs->nip += 4; | 617 | regs->nip += 4; |
110 | if ((regs->msr & MSR_SF) == 0) { | 618 | if ((regs->msr & MSR_SF) == 0) { |
@@ -116,30 +624,233 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | |||
116 | if (branch_taken(instr, regs)) | 624 | if (branch_taken(instr, regs)) |
117 | regs->nip = imm; | 625 | regs->nip = imm; |
118 | return 1; | 626 | return 1; |
119 | case 0x24: /* rfid, scary */ | 627 | |
628 | case 18: /* rfid, scary */ | ||
120 | return -1; | 629 | return -1; |
630 | |||
631 | case 150: /* isync */ | ||
632 | isync(); | ||
633 | goto instr_done; | ||
634 | |||
635 | case 33: /* crnor */ | ||
636 | case 129: /* crandc */ | ||
637 | case 193: /* crxor */ | ||
638 | case 225: /* crnand */ | ||
639 | case 257: /* crand */ | ||
640 | case 289: /* creqv */ | ||
641 | case 417: /* crorc */ | ||
642 | case 449: /* cror */ | ||
643 | ra = (instr >> 16) & 0x1f; | ||
644 | rb = (instr >> 11) & 0x1f; | ||
645 | rd = (instr >> 21) & 0x1f; | ||
646 | ra = (regs->ccr >> (31 - ra)) & 1; | ||
647 | rb = (regs->ccr >> (31 - rb)) & 1; | ||
648 | val = (instr >> (6 + ra * 2 + rb)) & 1; | ||
649 | regs->ccr = (regs->ccr & ~(1UL << (31 - rd))) | | ||
650 | (val << (31 - rd)); | ||
651 | goto instr_done; | ||
652 | } | ||
653 | break; | ||
654 | case 31: | ||
655 | switch ((instr >> 1) & 0x3ff) { | ||
656 | case 598: /* sync */ | ||
657 | #ifdef __powerpc64__ | ||
658 | switch ((instr >> 21) & 3) { | ||
659 | case 1: /* lwsync */ | ||
660 | asm volatile("lwsync" : : : "memory"); | ||
661 | goto instr_done; | ||
662 | case 2: /* ptesync */ | ||
663 | asm volatile("ptesync" : : : "memory"); | ||
664 | goto instr_done; | ||
665 | } | ||
666 | #endif | ||
667 | mb(); | ||
668 | goto instr_done; | ||
669 | |||
670 | case 854: /* eieio */ | ||
671 | eieio(); | ||
672 | goto instr_done; | ||
673 | } | ||
674 | break; | ||
675 | } | ||
676 | |||
677 | /* Following cases refer to regs->gpr[], so we need all regs */ | ||
678 | if (!FULL_REGS(regs)) | ||
679 | return 0; | ||
680 | |||
681 | rd = (instr >> 21) & 0x1f; | ||
682 | ra = (instr >> 16) & 0x1f; | ||
683 | rb = (instr >> 11) & 0x1f; | ||
684 | |||
685 | switch (opcode) { | ||
686 | case 7: /* mulli */ | ||
687 | regs->gpr[rd] = regs->gpr[ra] * (short) instr; | ||
688 | goto instr_done; | ||
689 | |||
690 | case 8: /* subfic */ | ||
691 | imm = (short) instr; | ||
692 | add_with_carry(regs, rd, ~regs->gpr[ra], imm, 1); | ||
693 | goto instr_done; | ||
694 | |||
695 | case 10: /* cmpli */ | ||
696 | imm = (unsigned short) instr; | ||
697 | val = regs->gpr[ra]; | ||
698 | #ifdef __powerpc64__ | ||
699 | if ((rd & 1) == 0) | ||
700 | val = (unsigned int) val; | ||
701 | #endif | ||
702 | do_cmp_unsigned(regs, val, imm, rd >> 2); | ||
703 | goto instr_done; | ||
704 | |||
705 | case 11: /* cmpi */ | ||
706 | imm = (short) instr; | ||
707 | val = regs->gpr[ra]; | ||
708 | #ifdef __powerpc64__ | ||
709 | if ((rd & 1) == 0) | ||
710 | val = (int) val; | ||
711 | #endif | ||
712 | do_cmp_signed(regs, val, imm, rd >> 2); | ||
713 | goto instr_done; | ||
714 | |||
715 | case 12: /* addic */ | ||
716 | imm = (short) instr; | ||
717 | add_with_carry(regs, rd, regs->gpr[ra], imm, 0); | ||
718 | goto instr_done; | ||
719 | |||
720 | case 13: /* addic. */ | ||
721 | imm = (short) instr; | ||
722 | add_with_carry(regs, rd, regs->gpr[ra], imm, 0); | ||
723 | set_cr0(regs, rd); | ||
724 | goto instr_done; | ||
725 | |||
726 | case 14: /* addi */ | ||
727 | imm = (short) instr; | ||
728 | if (ra) | ||
729 | imm += regs->gpr[ra]; | ||
730 | regs->gpr[rd] = imm; | ||
731 | goto instr_done; | ||
732 | |||
733 | case 15: /* addis */ | ||
734 | imm = ((short) instr) << 16; | ||
735 | if (ra) | ||
736 | imm += regs->gpr[ra]; | ||
737 | regs->gpr[rd] = imm; | ||
738 | goto instr_done; | ||
739 | |||
740 | case 20: /* rlwimi */ | ||
741 | mb = (instr >> 6) & 0x1f; | ||
742 | me = (instr >> 1) & 0x1f; | ||
743 | val = DATA32(regs->gpr[rd]); | ||
744 | imm = MASK32(mb, me); | ||
745 | regs->gpr[ra] = (regs->gpr[ra] & ~imm) | (ROTATE(val, rb) & imm); | ||
746 | goto logical_done; | ||
747 | |||
748 | case 21: /* rlwinm */ | ||
749 | mb = (instr >> 6) & 0x1f; | ||
750 | me = (instr >> 1) & 0x1f; | ||
751 | val = DATA32(regs->gpr[rd]); | ||
752 | regs->gpr[ra] = ROTATE(val, rb) & MASK32(mb, me); | ||
753 | goto logical_done; | ||
754 | |||
755 | case 23: /* rlwnm */ | ||
756 | mb = (instr >> 6) & 0x1f; | ||
757 | me = (instr >> 1) & 0x1f; | ||
758 | rb = regs->gpr[rb] & 0x1f; | ||
759 | val = DATA32(regs->gpr[rd]); | ||
760 | regs->gpr[ra] = ROTATE(val, rb) & MASK32(mb, me); | ||
761 | goto logical_done; | ||
762 | |||
763 | case 24: /* ori */ | ||
764 | imm = (unsigned short) instr; | ||
765 | regs->gpr[ra] = regs->gpr[rd] | imm; | ||
766 | goto instr_done; | ||
767 | |||
768 | case 25: /* oris */ | ||
769 | imm = (unsigned short) instr; | ||
770 | regs->gpr[ra] = regs->gpr[rd] | (imm << 16); | ||
771 | goto instr_done; | ||
772 | |||
773 | case 26: /* xori */ | ||
774 | imm = (unsigned short) instr; | ||
775 | regs->gpr[ra] = regs->gpr[rd] ^ imm; | ||
776 | goto instr_done; | ||
777 | |||
778 | case 27: /* xoris */ | ||
779 | imm = (unsigned short) instr; | ||
780 | regs->gpr[ra] = regs->gpr[rd] ^ (imm << 16); | ||
781 | goto instr_done; | ||
782 | |||
783 | case 28: /* andi. */ | ||
784 | imm = (unsigned short) instr; | ||
785 | regs->gpr[ra] = regs->gpr[rd] & imm; | ||
786 | set_cr0(regs, ra); | ||
787 | goto instr_done; | ||
788 | |||
789 | case 29: /* andis. */ | ||
790 | imm = (unsigned short) instr; | ||
791 | regs->gpr[ra] = regs->gpr[rd] & (imm << 16); | ||
792 | set_cr0(regs, ra); | ||
793 | goto instr_done; | ||
794 | |||
795 | #ifdef __powerpc64__ | ||
796 | case 30: /* rld* */ | ||
797 | mb = ((instr >> 6) & 0x1f) | (instr & 0x20); | ||
798 | val = regs->gpr[rd]; | ||
799 | if ((instr & 0x10) == 0) { | ||
800 | sh = rb | ((instr & 2) << 4); | ||
801 | val = ROTATE(val, sh); | ||
802 | switch ((instr >> 2) & 3) { | ||
803 | case 0: /* rldicl */ | ||
804 | regs->gpr[ra] = val & MASK64_L(mb); | ||
805 | goto logical_done; | ||
806 | case 1: /* rldicr */ | ||
807 | regs->gpr[ra] = val & MASK64_R(mb); | ||
808 | goto logical_done; | ||
809 | case 2: /* rldic */ | ||
810 | regs->gpr[ra] = val & MASK64(mb, 63 - sh); | ||
811 | goto logical_done; | ||
812 | case 3: /* rldimi */ | ||
813 | imm = MASK64(mb, 63 - sh); | ||
814 | regs->gpr[ra] = (regs->gpr[ra] & ~imm) | | ||
815 | (val & imm); | ||
816 | goto logical_done; | ||
817 | } | ||
818 | } else { | ||
819 | sh = regs->gpr[rb] & 0x3f; | ||
820 | val = ROTATE(val, sh); | ||
821 | switch ((instr >> 1) & 7) { | ||
822 | case 0: /* rldcl */ | ||
823 | regs->gpr[ra] = val & MASK64_L(mb); | ||
824 | goto logical_done; | ||
825 | case 1: /* rldcr */ | ||
826 | regs->gpr[ra] = val & MASK64_R(mb); | ||
827 | goto logical_done; | ||
828 | } | ||
121 | } | 829 | } |
830 | #endif | ||
831 | |||
122 | case 31: | 832 | case 31: |
123 | rd = (instr >> 21) & 0x1f; | 833 | switch ((instr >> 1) & 0x3ff) { |
124 | switch (instr & 0x7fe) { | 834 | case 83: /* mfmsr */ |
125 | case 0xa6: /* mfmsr */ | 835 | if (regs->msr & MSR_PR) |
836 | break; | ||
126 | regs->gpr[rd] = regs->msr & MSR_MASK; | 837 | regs->gpr[rd] = regs->msr & MSR_MASK; |
127 | regs->nip += 4; | 838 | goto instr_done; |
128 | if ((regs->msr & MSR_SF) == 0) | 839 | case 146: /* mtmsr */ |
129 | regs->nip &= 0xffffffffUL; | 840 | if (regs->msr & MSR_PR) |
130 | return 1; | 841 | break; |
131 | case 0x124: /* mtmsr */ | ||
132 | imm = regs->gpr[rd]; | 842 | imm = regs->gpr[rd]; |
133 | if ((imm & MSR_RI) == 0) | 843 | if ((imm & MSR_RI) == 0) |
134 | /* can't step mtmsr that would clear MSR_RI */ | 844 | /* can't step mtmsr that would clear MSR_RI */ |
135 | return -1; | 845 | return -1; |
136 | regs->msr = imm; | 846 | regs->msr = imm; |
137 | regs->nip += 4; | 847 | goto instr_done; |
138 | return 1; | ||
139 | #ifdef CONFIG_PPC64 | 848 | #ifdef CONFIG_PPC64 |
140 | case 0x164: /* mtmsrd */ | 849 | case 178: /* mtmsrd */ |
141 | /* only MSR_EE and MSR_RI get changed if bit 15 set */ | 850 | /* only MSR_EE and MSR_RI get changed if bit 15 set */ |
142 | /* mtmsrd doesn't change MSR_HV and MSR_ME */ | 851 | /* mtmsrd doesn't change MSR_HV and MSR_ME */ |
852 | if (regs->msr & MSR_PR) | ||
853 | break; | ||
143 | imm = (instr & 0x10000)? 0x8002: 0xefffffffffffefffUL; | 854 | imm = (instr & 0x10000)? 0x8002: 0xefffffffffffefffUL; |
144 | imm = (regs->msr & MSR_MASK & ~imm) | 855 | imm = (regs->msr & MSR_MASK & ~imm) |
145 | | (regs->gpr[rd] & imm); | 856 | | (regs->gpr[rd] & imm); |
@@ -147,57 +858,770 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | |||
147 | /* can't step mtmsrd that would clear MSR_RI */ | 858 | /* can't step mtmsrd that would clear MSR_RI */ |
148 | return -1; | 859 | return -1; |
149 | regs->msr = imm; | 860 | regs->msr = imm; |
150 | regs->nip += 4; | 861 | goto instr_done; |
151 | if ((imm & MSR_SF) == 0) | ||
152 | regs->nip &= 0xffffffffUL; | ||
153 | return 1; | ||
154 | #endif | 862 | #endif |
155 | case 0x26: /* mfcr */ | 863 | case 19: /* mfcr */ |
156 | regs->gpr[rd] = regs->ccr; | 864 | regs->gpr[rd] = regs->ccr; |
157 | regs->gpr[rd] &= 0xffffffffUL; | 865 | regs->gpr[rd] &= 0xffffffffUL; |
158 | goto mtspr_out; | 866 | goto instr_done; |
159 | case 0x2a6: /* mfspr */ | 867 | |
868 | case 144: /* mtcrf */ | ||
869 | imm = 0xf0000000UL; | ||
870 | val = regs->gpr[rd]; | ||
871 | for (sh = 0; sh < 8; ++sh) { | ||
872 | if (instr & (0x80000 >> sh)) | ||
873 | regs->ccr = (regs->ccr & ~imm) | | ||
874 | (val & imm); | ||
875 | imm >>= 4; | ||
876 | } | ||
877 | goto instr_done; | ||
878 | |||
879 | case 339: /* mfspr */ | ||
160 | spr = (instr >> 11) & 0x3ff; | 880 | spr = (instr >> 11) & 0x3ff; |
161 | switch (spr) { | 881 | switch (spr) { |
162 | case 0x20: /* mfxer */ | 882 | case 0x20: /* mfxer */ |
163 | regs->gpr[rd] = regs->xer; | 883 | regs->gpr[rd] = regs->xer; |
164 | regs->gpr[rd] &= 0xffffffffUL; | 884 | regs->gpr[rd] &= 0xffffffffUL; |
165 | goto mtspr_out; | 885 | goto instr_done; |
166 | case 0x100: /* mflr */ | 886 | case 0x100: /* mflr */ |
167 | regs->gpr[rd] = regs->link; | 887 | regs->gpr[rd] = regs->link; |
168 | goto mtspr_out; | 888 | goto instr_done; |
169 | case 0x120: /* mfctr */ | 889 | case 0x120: /* mfctr */ |
170 | regs->gpr[rd] = regs->ctr; | 890 | regs->gpr[rd] = regs->ctr; |
171 | goto mtspr_out; | 891 | goto instr_done; |
172 | } | ||
173 | break; | ||
174 | case 0x378: /* orx */ | ||
175 | if (instr & 1) | ||
176 | break; | ||
177 | rs = (instr >> 21) & 0x1f; | ||
178 | rb = (instr >> 11) & 0x1f; | ||
179 | if (rs == rb) { /* mr */ | ||
180 | rd = (instr >> 16) & 0x1f; | ||
181 | regs->gpr[rd] = regs->gpr[rs]; | ||
182 | goto mtspr_out; | ||
183 | } | 892 | } |
184 | break; | 893 | break; |
185 | case 0x3a6: /* mtspr */ | 894 | |
895 | case 467: /* mtspr */ | ||
186 | spr = (instr >> 11) & 0x3ff; | 896 | spr = (instr >> 11) & 0x3ff; |
187 | switch (spr) { | 897 | switch (spr) { |
188 | case 0x20: /* mtxer */ | 898 | case 0x20: /* mtxer */ |
189 | regs->xer = (regs->gpr[rd] & 0xffffffffUL); | 899 | regs->xer = (regs->gpr[rd] & 0xffffffffUL); |
190 | goto mtspr_out; | 900 | goto instr_done; |
191 | case 0x100: /* mtlr */ | 901 | case 0x100: /* mtlr */ |
192 | regs->link = regs->gpr[rd]; | 902 | regs->link = regs->gpr[rd]; |
193 | goto mtspr_out; | 903 | goto instr_done; |
194 | case 0x120: /* mtctr */ | 904 | case 0x120: /* mtctr */ |
195 | regs->ctr = regs->gpr[rd]; | 905 | regs->ctr = regs->gpr[rd]; |
196 | mtspr_out: | 906 | goto instr_done; |
197 | regs->nip += 4; | ||
198 | return 1; | ||
199 | } | 907 | } |
908 | break; | ||
909 | |||
910 | /* | ||
911 | * Compare instructions | ||
912 | */ | ||
913 | case 0: /* cmp */ | ||
914 | val = regs->gpr[ra]; | ||
915 | val2 = regs->gpr[rb]; | ||
916 | #ifdef __powerpc64__ | ||
917 | if ((rd & 1) == 0) { | ||
918 | /* word (32-bit) compare */ | ||
919 | val = (int) val; | ||
920 | val2 = (int) val2; | ||
921 | } | ||
922 | #endif | ||
923 | do_cmp_signed(regs, val, val2, rd >> 2); | ||
924 | goto instr_done; | ||
925 | |||
926 | case 32: /* cmpl */ | ||
927 | val = regs->gpr[ra]; | ||
928 | val2 = regs->gpr[rb]; | ||
929 | #ifdef __powerpc64__ | ||
930 | if ((rd & 1) == 0) { | ||
931 | /* word (32-bit) compare */ | ||
932 | val = (unsigned int) val; | ||
933 | val2 = (unsigned int) val2; | ||
934 | } | ||
935 | #endif | ||
936 | do_cmp_unsigned(regs, val, val2, rd >> 2); | ||
937 | goto instr_done; | ||
938 | |||
939 | /* | ||
940 | * Arithmetic instructions | ||
941 | */ | ||
942 | case 8: /* subfc */ | ||
943 | add_with_carry(regs, rd, ~regs->gpr[ra], | ||
944 | regs->gpr[rb], 1); | ||
945 | goto arith_done; | ||
946 | #ifdef __powerpc64__ | ||
947 | case 9: /* mulhdu */ | ||
948 | asm("mulhdu %0,%1,%2" : "=r" (regs->gpr[rd]) : | ||
949 | "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); | ||
950 | goto arith_done; | ||
951 | #endif | ||
952 | case 10: /* addc */ | ||
953 | add_with_carry(regs, rd, regs->gpr[ra], | ||
954 | regs->gpr[rb], 0); | ||
955 | goto arith_done; | ||
956 | |||
957 | case 11: /* mulhwu */ | ||
958 | asm("mulhwu %0,%1,%2" : "=r" (regs->gpr[rd]) : | ||
959 | "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); | ||
960 | goto arith_done; | ||
961 | |||
962 | case 40: /* subf */ | ||
963 | regs->gpr[rd] = regs->gpr[rb] - regs->gpr[ra]; | ||
964 | goto arith_done; | ||
965 | #ifdef __powerpc64__ | ||
966 | case 73: /* mulhd */ | ||
967 | asm("mulhd %0,%1,%2" : "=r" (regs->gpr[rd]) : | ||
968 | "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); | ||
969 | goto arith_done; | ||
970 | #endif | ||
971 | case 75: /* mulhw */ | ||
972 | asm("mulhw %0,%1,%2" : "=r" (regs->gpr[rd]) : | ||
973 | "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); | ||
974 | goto arith_done; | ||
975 | |||
976 | case 104: /* neg */ | ||
977 | regs->gpr[rd] = -regs->gpr[ra]; | ||
978 | goto arith_done; | ||
979 | |||
980 | case 136: /* subfe */ | ||
981 | add_with_carry(regs, rd, ~regs->gpr[ra], regs->gpr[rb], | ||
982 | regs->xer & XER_CA); | ||
983 | goto arith_done; | ||
984 | |||
985 | case 138: /* adde */ | ||
986 | add_with_carry(regs, rd, regs->gpr[ra], regs->gpr[rb], | ||
987 | regs->xer & XER_CA); | ||
988 | goto arith_done; | ||
989 | |||
990 | case 200: /* subfze */ | ||
991 | add_with_carry(regs, rd, ~regs->gpr[ra], 0L, | ||
992 | regs->xer & XER_CA); | ||
993 | goto arith_done; | ||
994 | |||
995 | case 202: /* addze */ | ||
996 | add_with_carry(regs, rd, regs->gpr[ra], 0L, | ||
997 | regs->xer & XER_CA); | ||
998 | goto arith_done; | ||
999 | |||
1000 | case 232: /* subfme */ | ||
1001 | add_with_carry(regs, rd, ~regs->gpr[ra], -1L, | ||
1002 | regs->xer & XER_CA); | ||
1003 | goto arith_done; | ||
1004 | #ifdef __powerpc64__ | ||
1005 | case 233: /* mulld */ | ||
1006 | regs->gpr[rd] = regs->gpr[ra] * regs->gpr[rb]; | ||
1007 | goto arith_done; | ||
1008 | #endif | ||
1009 | case 234: /* addme */ | ||
1010 | add_with_carry(regs, rd, regs->gpr[ra], -1L, | ||
1011 | regs->xer & XER_CA); | ||
1012 | goto arith_done; | ||
1013 | |||
1014 | case 235: /* mullw */ | ||
1015 | regs->gpr[rd] = (unsigned int) regs->gpr[ra] * | ||
1016 | (unsigned int) regs->gpr[rb]; | ||
1017 | goto arith_done; | ||
1018 | |||
1019 | case 266: /* add */ | ||
1020 | regs->gpr[rd] = regs->gpr[ra] + regs->gpr[rb]; | ||
1021 | goto arith_done; | ||
1022 | #ifdef __powerpc64__ | ||
1023 | case 457: /* divdu */ | ||
1024 | regs->gpr[rd] = regs->gpr[ra] / regs->gpr[rb]; | ||
1025 | goto arith_done; | ||
1026 | #endif | ||
1027 | case 459: /* divwu */ | ||
1028 | regs->gpr[rd] = (unsigned int) regs->gpr[ra] / | ||
1029 | (unsigned int) regs->gpr[rb]; | ||
1030 | goto arith_done; | ||
1031 | #ifdef __powerpc64__ | ||
1032 | case 489: /* divd */ | ||
1033 | regs->gpr[rd] = (long int) regs->gpr[ra] / | ||
1034 | (long int) regs->gpr[rb]; | ||
1035 | goto arith_done; | ||
1036 | #endif | ||
1037 | case 491: /* divw */ | ||
1038 | regs->gpr[rd] = (int) regs->gpr[ra] / | ||
1039 | (int) regs->gpr[rb]; | ||
1040 | goto arith_done; | ||
1041 | |||
1042 | |||
1043 | /* | ||
1044 | * Logical instructions | ||
1045 | */ | ||
1046 | case 26: /* cntlzw */ | ||
1047 | asm("cntlzw %0,%1" : "=r" (regs->gpr[ra]) : | ||
1048 | "r" (regs->gpr[rd])); | ||
1049 | goto logical_done; | ||
1050 | #ifdef __powerpc64__ | ||
1051 | case 58: /* cntlzd */ | ||
1052 | asm("cntlzd %0,%1" : "=r" (regs->gpr[ra]) : | ||
1053 | "r" (regs->gpr[rd])); | ||
1054 | goto logical_done; | ||
1055 | #endif | ||
1056 | case 28: /* and */ | ||
1057 | regs->gpr[ra] = regs->gpr[rd] & regs->gpr[rb]; | ||
1058 | goto logical_done; | ||
1059 | |||
1060 | case 60: /* andc */ | ||
1061 | regs->gpr[ra] = regs->gpr[rd] & ~regs->gpr[rb]; | ||
1062 | goto logical_done; | ||
1063 | |||
1064 | case 124: /* nor */ | ||
1065 | regs->gpr[ra] = ~(regs->gpr[rd] | regs->gpr[rb]); | ||
1066 | goto logical_done; | ||
1067 | |||
1068 | case 284: /* xor */ | ||
1069 | regs->gpr[ra] = ~(regs->gpr[rd] ^ regs->gpr[rb]); | ||
1070 | goto logical_done; | ||
1071 | |||
1072 | case 316: /* xor */ | ||
1073 | regs->gpr[ra] = regs->gpr[rd] ^ regs->gpr[rb]; | ||
1074 | goto logical_done; | ||
1075 | |||
1076 | case 412: /* orc */ | ||
1077 | regs->gpr[ra] = regs->gpr[rd] | ~regs->gpr[rb]; | ||
1078 | goto logical_done; | ||
1079 | |||
1080 | case 444: /* or */ | ||
1081 | regs->gpr[ra] = regs->gpr[rd] | regs->gpr[rb]; | ||
1082 | goto logical_done; | ||
1083 | |||
1084 | case 476: /* nand */ | ||
1085 | regs->gpr[ra] = ~(regs->gpr[rd] & regs->gpr[rb]); | ||
1086 | goto logical_done; | ||
1087 | |||
1088 | case 922: /* extsh */ | ||
1089 | regs->gpr[ra] = (signed short) regs->gpr[rd]; | ||
1090 | goto logical_done; | ||
1091 | |||
1092 | case 954: /* extsb */ | ||
1093 | regs->gpr[ra] = (signed char) regs->gpr[rd]; | ||
1094 | goto logical_done; | ||
1095 | #ifdef __powerpc64__ | ||
1096 | case 986: /* extsw */ | ||
1097 | regs->gpr[ra] = (signed int) regs->gpr[rd]; | ||
1098 | goto logical_done; | ||
1099 | #endif | ||
1100 | |||
1101 | /* | ||
1102 | * Shift instructions | ||
1103 | */ | ||
1104 | case 24: /* slw */ | ||
1105 | sh = regs->gpr[rb] & 0x3f; | ||
1106 | if (sh < 32) | ||
1107 | regs->gpr[ra] = (regs->gpr[rd] << sh) & 0xffffffffUL; | ||
1108 | else | ||
1109 | regs->gpr[ra] = 0; | ||
1110 | goto logical_done; | ||
1111 | |||
1112 | case 536: /* srw */ | ||
1113 | sh = regs->gpr[rb] & 0x3f; | ||
1114 | if (sh < 32) | ||
1115 | regs->gpr[ra] = (regs->gpr[rd] & 0xffffffffUL) >> sh; | ||
1116 | else | ||
1117 | regs->gpr[ra] = 0; | ||
1118 | goto logical_done; | ||
1119 | |||
1120 | case 792: /* sraw */ | ||
1121 | sh = regs->gpr[rb] & 0x3f; | ||
1122 | ival = (signed int) regs->gpr[rd]; | ||
1123 | regs->gpr[ra] = ival >> (sh < 32 ? sh : 31); | ||
1124 | if (ival < 0 && (sh >= 32 || (ival & ((1 << sh) - 1)) != 0)) | ||
1125 | regs->xer |= XER_CA; | ||
1126 | else | ||
1127 | regs->xer &= ~XER_CA; | ||
1128 | goto logical_done; | ||
1129 | |||
1130 | case 824: /* srawi */ | ||
1131 | sh = rb; | ||
1132 | ival = (signed int) regs->gpr[rd]; | ||
1133 | regs->gpr[ra] = ival >> sh; | ||
1134 | if (ival < 0 && (ival & ((1 << sh) - 1)) != 0) | ||
1135 | regs->xer |= XER_CA; | ||
1136 | else | ||
1137 | regs->xer &= ~XER_CA; | ||
1138 | goto logical_done; | ||
1139 | |||
1140 | #ifdef __powerpc64__ | ||
1141 | case 27: /* sld */ | ||
1142 | sh = regs->gpr[rd] & 0x7f; | ||
1143 | if (sh < 64) | ||
1144 | regs->gpr[ra] = regs->gpr[rd] << sh; | ||
1145 | else | ||
1146 | regs->gpr[ra] = 0; | ||
1147 | goto logical_done; | ||
1148 | |||
1149 | case 539: /* srd */ | ||
1150 | sh = regs->gpr[rb] & 0x7f; | ||
1151 | if (sh < 64) | ||
1152 | regs->gpr[ra] = regs->gpr[rd] >> sh; | ||
1153 | else | ||
1154 | regs->gpr[ra] = 0; | ||
1155 | goto logical_done; | ||
1156 | |||
1157 | case 794: /* srad */ | ||
1158 | sh = regs->gpr[rb] & 0x7f; | ||
1159 | ival = (signed long int) regs->gpr[rd]; | ||
1160 | regs->gpr[ra] = ival >> (sh < 64 ? sh : 63); | ||
1161 | if (ival < 0 && (sh >= 64 || (ival & ((1 << sh) - 1)) != 0)) | ||
1162 | regs->xer |= XER_CA; | ||
1163 | else | ||
1164 | regs->xer &= ~XER_CA; | ||
1165 | goto logical_done; | ||
1166 | |||
1167 | case 826: /* sradi with sh_5 = 0 */ | ||
1168 | case 827: /* sradi with sh_5 = 1 */ | ||
1169 | sh = rb | ((instr & 2) << 4); | ||
1170 | ival = (signed long int) regs->gpr[rd]; | ||
1171 | regs->gpr[ra] = ival >> sh; | ||
1172 | if (ival < 0 && (ival & ((1 << sh) - 1)) != 0) | ||
1173 | regs->xer |= XER_CA; | ||
1174 | else | ||
1175 | regs->xer &= ~XER_CA; | ||
1176 | goto logical_done; | ||
1177 | #endif /* __powerpc64__ */ | ||
1178 | |||
1179 | /* | ||
1180 | * Cache instructions | ||
1181 | */ | ||
1182 | case 54: /* dcbst */ | ||
1183 | ea = xform_ea(instr, regs, 0); | ||
1184 | if (!address_ok(regs, ea, 8)) | ||
1185 | return 0; | ||
1186 | err = 0; | ||
1187 | __cacheop_user_asmx(ea, err, "dcbst"); | ||
1188 | if (err) | ||
1189 | return 0; | ||
1190 | goto instr_done; | ||
1191 | |||
1192 | case 86: /* dcbf */ | ||
1193 | ea = xform_ea(instr, regs, 0); | ||
1194 | if (!address_ok(regs, ea, 8)) | ||
1195 | return 0; | ||
1196 | err = 0; | ||
1197 | __cacheop_user_asmx(ea, err, "dcbf"); | ||
1198 | if (err) | ||
1199 | return 0; | ||
1200 | goto instr_done; | ||
1201 | |||
1202 | case 246: /* dcbtst */ | ||
1203 | if (rd == 0) { | ||
1204 | ea = xform_ea(instr, regs, 0); | ||
1205 | prefetchw((void *) ea); | ||
1206 | } | ||
1207 | goto instr_done; | ||
1208 | |||
1209 | case 278: /* dcbt */ | ||
1210 | if (rd == 0) { | ||
1211 | ea = xform_ea(instr, regs, 0); | ||
1212 | prefetch((void *) ea); | ||
1213 | } | ||
1214 | goto instr_done; | ||
1215 | |||
200 | } | 1216 | } |
1217 | break; | ||
201 | } | 1218 | } |
202 | return 0; | 1219 | |
1220 | /* | ||
1221 | * Following cases are for loads and stores, so bail out | ||
1222 | * if we're in little-endian mode. | ||
1223 | */ | ||
1224 | if (regs->msr & MSR_LE) | ||
1225 | return 0; | ||
1226 | |||
1227 | /* | ||
1228 | * Save register RA in case it's an update form load or store | ||
1229 | * and the access faults. | ||
1230 | */ | ||
1231 | old_ra = regs->gpr[ra]; | ||
1232 | |||
1233 | switch (opcode) { | ||
1234 | case 31: | ||
1235 | u = instr & 0x40; | ||
1236 | switch ((instr >> 1) & 0x3ff) { | ||
1237 | case 20: /* lwarx */ | ||
1238 | ea = xform_ea(instr, regs, 0); | ||
1239 | if (ea & 3) | ||
1240 | break; /* can't handle misaligned */ | ||
1241 | err = -EFAULT; | ||
1242 | if (!address_ok(regs, ea, 4)) | ||
1243 | goto ldst_done; | ||
1244 | err = 0; | ||
1245 | __get_user_asmx(val, ea, err, "lwarx"); | ||
1246 | if (!err) | ||
1247 | regs->gpr[rd] = val; | ||
1248 | goto ldst_done; | ||
1249 | |||
1250 | case 150: /* stwcx. */ | ||
1251 | ea = xform_ea(instr, regs, 0); | ||
1252 | if (ea & 3) | ||
1253 | break; /* can't handle misaligned */ | ||
1254 | err = -EFAULT; | ||
1255 | if (!address_ok(regs, ea, 4)) | ||
1256 | goto ldst_done; | ||
1257 | err = 0; | ||
1258 | __put_user_asmx(regs->gpr[rd], ea, err, "stwcx.", cr); | ||
1259 | if (!err) | ||
1260 | regs->ccr = (regs->ccr & 0x0fffffff) | | ||
1261 | (cr & 0xe0000000) | | ||
1262 | ((regs->xer >> 3) & 0x10000000); | ||
1263 | goto ldst_done; | ||
1264 | |||
1265 | #ifdef __powerpc64__ | ||
1266 | case 84: /* ldarx */ | ||
1267 | ea = xform_ea(instr, regs, 0); | ||
1268 | if (ea & 7) | ||
1269 | break; /* can't handle misaligned */ | ||
1270 | err = -EFAULT; | ||
1271 | if (!address_ok(regs, ea, 8)) | ||
1272 | goto ldst_done; | ||
1273 | err = 0; | ||
1274 | __get_user_asmx(val, ea, err, "ldarx"); | ||
1275 | if (!err) | ||
1276 | regs->gpr[rd] = val; | ||
1277 | goto ldst_done; | ||
1278 | |||
1279 | case 214: /* stdcx. */ | ||
1280 | ea = xform_ea(instr, regs, 0); | ||
1281 | if (ea & 7) | ||
1282 | break; /* can't handle misaligned */ | ||
1283 | err = -EFAULT; | ||
1284 | if (!address_ok(regs, ea, 8)) | ||
1285 | goto ldst_done; | ||
1286 | err = 0; | ||
1287 | __put_user_asmx(regs->gpr[rd], ea, err, "stdcx.", cr); | ||
1288 | if (!err) | ||
1289 | regs->ccr = (regs->ccr & 0x0fffffff) | | ||
1290 | (cr & 0xe0000000) | | ||
1291 | ((regs->xer >> 3) & 0x10000000); | ||
1292 | goto ldst_done; | ||
1293 | |||
1294 | case 21: /* ldx */ | ||
1295 | case 53: /* ldux */ | ||
1296 | err = read_mem(®s->gpr[rd], xform_ea(instr, regs, u), | ||
1297 | 8, regs); | ||
1298 | goto ldst_done; | ||
1299 | #endif | ||
1300 | |||
1301 | case 23: /* lwzx */ | ||
1302 | case 55: /* lwzux */ | ||
1303 | err = read_mem(®s->gpr[rd], xform_ea(instr, regs, u), | ||
1304 | 4, regs); | ||
1305 | goto ldst_done; | ||
1306 | |||
1307 | case 87: /* lbzx */ | ||
1308 | case 119: /* lbzux */ | ||
1309 | err = read_mem(®s->gpr[rd], xform_ea(instr, regs, u), | ||
1310 | 1, regs); | ||
1311 | goto ldst_done; | ||
1312 | |||
1313 | #ifdef CONFIG_ALTIVEC | ||
1314 | case 103: /* lvx */ | ||
1315 | case 359: /* lvxl */ | ||
1316 | if (!(regs->msr & MSR_VEC)) | ||
1317 | break; | ||
1318 | ea = xform_ea(instr, regs, 0); | ||
1319 | err = do_vec_load(rd, do_lvx, ea, regs); | ||
1320 | goto ldst_done; | ||
1321 | |||
1322 | case 231: /* stvx */ | ||
1323 | case 487: /* stvxl */ | ||
1324 | if (!(regs->msr & MSR_VEC)) | ||
1325 | break; | ||
1326 | ea = xform_ea(instr, regs, 0); | ||
1327 | err = do_vec_store(rd, do_stvx, ea, regs); | ||
1328 | goto ldst_done; | ||
1329 | #endif /* CONFIG_ALTIVEC */ | ||
1330 | |||
1331 | #ifdef __powerpc64__ | ||
1332 | case 149: /* stdx */ | ||
1333 | case 181: /* stdux */ | ||
1334 | val = regs->gpr[rd]; | ||
1335 | err = write_mem(val, xform_ea(instr, regs, u), 8, regs); | ||
1336 | goto ldst_done; | ||
1337 | #endif | ||
1338 | |||
1339 | case 151: /* stwx */ | ||
1340 | case 183: /* stwux */ | ||
1341 | val = regs->gpr[rd]; | ||
1342 | err = write_mem(val, xform_ea(instr, regs, u), 4, regs); | ||
1343 | goto ldst_done; | ||
1344 | |||
1345 | case 215: /* stbx */ | ||
1346 | case 247: /* stbux */ | ||
1347 | val = regs->gpr[rd]; | ||
1348 | err = write_mem(val, xform_ea(instr, regs, u), 1, regs); | ||
1349 | goto ldst_done; | ||
1350 | |||
1351 | case 279: /* lhzx */ | ||
1352 | case 311: /* lhzux */ | ||
1353 | err = read_mem(®s->gpr[rd], xform_ea(instr, regs, u), | ||
1354 | 2, regs); | ||
1355 | goto ldst_done; | ||
1356 | |||
1357 | #ifdef __powerpc64__ | ||
1358 | case 341: /* lwax */ | ||
1359 | case 373: /* lwaux */ | ||
1360 | err = read_mem(®s->gpr[rd], xform_ea(instr, regs, u), | ||
1361 | 4, regs); | ||
1362 | if (!err) | ||
1363 | regs->gpr[rd] = (signed int) regs->gpr[rd]; | ||
1364 | goto ldst_done; | ||
1365 | #endif | ||
1366 | |||
1367 | case 343: /* lhax */ | ||
1368 | case 375: /* lhaux */ | ||
1369 | err = read_mem(®s->gpr[rd], xform_ea(instr, regs, u), | ||
1370 | 2, regs); | ||
1371 | if (!err) | ||
1372 | regs->gpr[rd] = (signed short) regs->gpr[rd]; | ||
1373 | goto ldst_done; | ||
1374 | |||
1375 | case 407: /* sthx */ | ||
1376 | case 439: /* sthux */ | ||
1377 | val = regs->gpr[rd]; | ||
1378 | err = write_mem(val, xform_ea(instr, regs, u), 2, regs); | ||
1379 | goto ldst_done; | ||
1380 | |||
1381 | #ifdef __powerpc64__ | ||
1382 | case 532: /* ldbrx */ | ||
1383 | err = read_mem(&val, xform_ea(instr, regs, 0), 8, regs); | ||
1384 | if (!err) | ||
1385 | regs->gpr[rd] = byterev_8(val); | ||
1386 | goto ldst_done; | ||
1387 | |||
1388 | #endif | ||
1389 | |||
1390 | case 534: /* lwbrx */ | ||
1391 | err = read_mem(&val, xform_ea(instr, regs, 0), 4, regs); | ||
1392 | if (!err) | ||
1393 | regs->gpr[rd] = byterev_4(val); | ||
1394 | goto ldst_done; | ||
1395 | |||
1396 | case 535: /* lfsx */ | ||
1397 | case 567: /* lfsux */ | ||
1398 | if (!(regs->msr & MSR_FP)) | ||
1399 | break; | ||
1400 | ea = xform_ea(instr, regs, u); | ||
1401 | err = do_fp_load(rd, do_lfs, ea, 4, regs); | ||
1402 | goto ldst_done; | ||
1403 | |||
1404 | case 599: /* lfdx */ | ||
1405 | case 631: /* lfdux */ | ||
1406 | if (!(regs->msr & MSR_FP)) | ||
1407 | break; | ||
1408 | ea = xform_ea(instr, regs, u); | ||
1409 | err = do_fp_load(rd, do_lfd, ea, 8, regs); | ||
1410 | goto ldst_done; | ||
1411 | |||
1412 | case 663: /* stfsx */ | ||
1413 | case 695: /* stfsux */ | ||
1414 | if (!(regs->msr & MSR_FP)) | ||
1415 | break; | ||
1416 | ea = xform_ea(instr, regs, u); | ||
1417 | err = do_fp_store(rd, do_stfs, ea, 4, regs); | ||
1418 | goto ldst_done; | ||
1419 | |||
1420 | case 727: /* stfdx */ | ||
1421 | case 759: /* stfdux */ | ||
1422 | if (!(regs->msr & MSR_FP)) | ||
1423 | break; | ||
1424 | ea = xform_ea(instr, regs, u); | ||
1425 | err = do_fp_store(rd, do_stfd, ea, 8, regs); | ||
1426 | goto ldst_done; | ||
1427 | |||
1428 | #ifdef __powerpc64__ | ||
1429 | case 660: /* stdbrx */ | ||
1430 | val = byterev_8(regs->gpr[rd]); | ||
1431 | err = write_mem(val, xform_ea(instr, regs, 0), 8, regs); | ||
1432 | goto ldst_done; | ||
1433 | |||
1434 | #endif | ||
1435 | case 662: /* stwbrx */ | ||
1436 | val = byterev_4(regs->gpr[rd]); | ||
1437 | err = write_mem(val, xform_ea(instr, regs, 0), 4, regs); | ||
1438 | goto ldst_done; | ||
1439 | |||
1440 | case 790: /* lhbrx */ | ||
1441 | err = read_mem(&val, xform_ea(instr, regs, 0), 2, regs); | ||
1442 | if (!err) | ||
1443 | regs->gpr[rd] = byterev_2(val); | ||
1444 | goto ldst_done; | ||
1445 | |||
1446 | case 918: /* sthbrx */ | ||
1447 | val = byterev_2(regs->gpr[rd]); | ||
1448 | err = write_mem(val, xform_ea(instr, regs, 0), 2, regs); | ||
1449 | goto ldst_done; | ||
1450 | |||
1451 | #ifdef CONFIG_VSX | ||
1452 | case 844: /* lxvd2x */ | ||
1453 | case 876: /* lxvd2ux */ | ||
1454 | if (!(regs->msr & MSR_VSX)) | ||
1455 | break; | ||
1456 | rd |= (instr & 1) << 5; | ||
1457 | ea = xform_ea(instr, regs, u); | ||
1458 | err = do_vsx_load(rd, do_lxvd2x, ea, regs); | ||
1459 | goto ldst_done; | ||
1460 | |||
1461 | case 972: /* stxvd2x */ | ||
1462 | case 1004: /* stxvd2ux */ | ||
1463 | if (!(regs->msr & MSR_VSX)) | ||
1464 | break; | ||
1465 | rd |= (instr & 1) << 5; | ||
1466 | ea = xform_ea(instr, regs, u); | ||
1467 | err = do_vsx_store(rd, do_stxvd2x, ea, regs); | ||
1468 | goto ldst_done; | ||
1469 | |||
1470 | #endif /* CONFIG_VSX */ | ||
1471 | } | ||
1472 | break; | ||
1473 | |||
1474 | case 32: /* lwz */ | ||
1475 | case 33: /* lwzu */ | ||
1476 | err = read_mem(®s->gpr[rd], dform_ea(instr, regs), 4, regs); | ||
1477 | goto ldst_done; | ||
1478 | |||
1479 | case 34: /* lbz */ | ||
1480 | case 35: /* lbzu */ | ||
1481 | err = read_mem(®s->gpr[rd], dform_ea(instr, regs), 1, regs); | ||
1482 | goto ldst_done; | ||
1483 | |||
1484 | case 36: /* stw */ | ||
1485 | case 37: /* stwu */ | ||
1486 | val = regs->gpr[rd]; | ||
1487 | err = write_mem(val, dform_ea(instr, regs), 4, regs); | ||
1488 | goto ldst_done; | ||
1489 | |||
1490 | case 38: /* stb */ | ||
1491 | case 39: /* stbu */ | ||
1492 | val = regs->gpr[rd]; | ||
1493 | err = write_mem(val, dform_ea(instr, regs), 1, regs); | ||
1494 | goto ldst_done; | ||
1495 | |||
1496 | case 40: /* lhz */ | ||
1497 | case 41: /* lhzu */ | ||
1498 | err = read_mem(®s->gpr[rd], dform_ea(instr, regs), 2, regs); | ||
1499 | goto ldst_done; | ||
1500 | |||
1501 | case 42: /* lha */ | ||
1502 | case 43: /* lhau */ | ||
1503 | err = read_mem(®s->gpr[rd], dform_ea(instr, regs), 2, regs); | ||
1504 | if (!err) | ||
1505 | regs->gpr[rd] = (signed short) regs->gpr[rd]; | ||
1506 | goto ldst_done; | ||
1507 | |||
1508 | case 44: /* sth */ | ||
1509 | case 45: /* sthu */ | ||
1510 | val = regs->gpr[rd]; | ||
1511 | err = write_mem(val, dform_ea(instr, regs), 2, regs); | ||
1512 | goto ldst_done; | ||
1513 | |||
1514 | case 46: /* lmw */ | ||
1515 | ra = (instr >> 16) & 0x1f; | ||
1516 | if (ra >= rd) | ||
1517 | break; /* invalid form, ra in range to load */ | ||
1518 | ea = dform_ea(instr, regs); | ||
1519 | do { | ||
1520 | err = read_mem(®s->gpr[rd], ea, 4, regs); | ||
1521 | if (err) | ||
1522 | return 0; | ||
1523 | ea += 4; | ||
1524 | } while (++rd < 32); | ||
1525 | goto instr_done; | ||
1526 | |||
1527 | case 47: /* stmw */ | ||
1528 | ea = dform_ea(instr, regs); | ||
1529 | do { | ||
1530 | err = write_mem(regs->gpr[rd], ea, 4, regs); | ||
1531 | if (err) | ||
1532 | return 0; | ||
1533 | ea += 4; | ||
1534 | } while (++rd < 32); | ||
1535 | goto instr_done; | ||
1536 | |||
1537 | case 48: /* lfs */ | ||
1538 | case 49: /* lfsu */ | ||
1539 | if (!(regs->msr & MSR_FP)) | ||
1540 | break; | ||
1541 | ea = dform_ea(instr, regs); | ||
1542 | err = do_fp_load(rd, do_lfs, ea, 4, regs); | ||
1543 | goto ldst_done; | ||
1544 | |||
1545 | case 50: /* lfd */ | ||
1546 | case 51: /* lfdu */ | ||
1547 | if (!(regs->msr & MSR_FP)) | ||
1548 | break; | ||
1549 | ea = dform_ea(instr, regs); | ||
1550 | err = do_fp_load(rd, do_lfd, ea, 8, regs); | ||
1551 | goto ldst_done; | ||
1552 | |||
1553 | case 52: /* stfs */ | ||
1554 | case 53: /* stfsu */ | ||
1555 | if (!(regs->msr & MSR_FP)) | ||
1556 | break; | ||
1557 | ea = dform_ea(instr, regs); | ||
1558 | err = do_fp_store(rd, do_stfs, ea, 4, regs); | ||
1559 | goto ldst_done; | ||
1560 | |||
1561 | case 54: /* stfd */ | ||
1562 | case 55: /* stfdu */ | ||
1563 | if (!(regs->msr & MSR_FP)) | ||
1564 | break; | ||
1565 | ea = dform_ea(instr, regs); | ||
1566 | err = do_fp_store(rd, do_stfd, ea, 8, regs); | ||
1567 | goto ldst_done; | ||
1568 | |||
1569 | #ifdef __powerpc64__ | ||
1570 | case 58: /* ld[u], lwa */ | ||
1571 | switch (instr & 3) { | ||
1572 | case 0: /* ld */ | ||
1573 | err = read_mem(®s->gpr[rd], dsform_ea(instr, regs), | ||
1574 | 8, regs); | ||
1575 | goto ldst_done; | ||
1576 | case 1: /* ldu */ | ||
1577 | err = read_mem(®s->gpr[rd], dsform_ea(instr, regs), | ||
1578 | 8, regs); | ||
1579 | goto ldst_done; | ||
1580 | case 2: /* lwa */ | ||
1581 | err = read_mem(®s->gpr[rd], dsform_ea(instr, regs), | ||
1582 | 4, regs); | ||
1583 | if (!err) | ||
1584 | regs->gpr[rd] = (signed int) regs->gpr[rd]; | ||
1585 | goto ldst_done; | ||
1586 | } | ||
1587 | break; | ||
1588 | |||
1589 | case 62: /* std[u] */ | ||
1590 | val = regs->gpr[rd]; | ||
1591 | switch (instr & 3) { | ||
1592 | case 0: /* std */ | ||
1593 | err = write_mem(val, dsform_ea(instr, regs), 8, regs); | ||
1594 | goto ldst_done; | ||
1595 | case 1: /* stdu */ | ||
1596 | err = write_mem(val, dsform_ea(instr, regs), 8, regs); | ||
1597 | goto ldst_done; | ||
1598 | } | ||
1599 | break; | ||
1600 | #endif /* __powerpc64__ */ | ||
1601 | |||
1602 | } | ||
1603 | err = -EINVAL; | ||
1604 | |||
1605 | ldst_done: | ||
1606 | if (err) { | ||
1607 | regs->gpr[ra] = old_ra; | ||
1608 | return 0; /* invoke DSI if -EFAULT? */ | ||
1609 | } | ||
1610 | instr_done: | ||
1611 | regs->nip += 4; | ||
1612 | #ifdef __powerpc64__ | ||
1613 | if ((regs->msr & MSR_SF) == 0) | ||
1614 | regs->nip &= 0xffffffffUL; | ||
1615 | #endif | ||
1616 | return 1; | ||
1617 | |||
1618 | logical_done: | ||
1619 | if (instr & 1) | ||
1620 | set_cr0(regs, ra); | ||
1621 | goto instr_done; | ||
1622 | |||
1623 | arith_done: | ||
1624 | if (instr & 1) | ||
1625 | set_cr0(regs, rd); | ||
1626 | goto instr_done; | ||
203 | } | 1627 | } |
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index cdc7526e9c93..4b66a1ece6d8 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c | |||
@@ -104,9 +104,10 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa) | |||
104 | } | 104 | } |
105 | 105 | ||
106 | /* | 106 | /* |
107 | * Set up one of the I/D BAT (block address translation) register pairs. | 107 | * Set up a variable-size TLB entry (tlbcam). The parameters are not checked; |
108 | * The parameters are not checked; in particular size must be a power | 108 | * in particular size must be a power of 4 between 4k and 256M (or 1G, for cpus |
109 | * of 4 between 4k and 256M. | 109 | * that support extended page sizes). Note that while some cpus support a |
110 | * page size of 4G, we don't allow its use here. | ||
110 | */ | 111 | */ |
111 | static void settlbcam(int index, unsigned long virt, phys_addr_t phys, | 112 | static void settlbcam(int index, unsigned long virt, phys_addr_t phys, |
112 | unsigned long size, unsigned long flags, unsigned int pid) | 113 | unsigned long size, unsigned long flags, unsigned int pid) |
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index aa731af720c0..002878ccf90b 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
@@ -42,6 +42,12 @@ EXPORT_SYMBOL(node_data); | |||
42 | 42 | ||
43 | static int min_common_depth; | 43 | static int min_common_depth; |
44 | static int n_mem_addr_cells, n_mem_size_cells; | 44 | static int n_mem_addr_cells, n_mem_size_cells; |
45 | static int form1_affinity; | ||
46 | |||
47 | #define MAX_DISTANCE_REF_POINTS 4 | ||
48 | static int distance_ref_points_depth; | ||
49 | static const unsigned int *distance_ref_points; | ||
50 | static int distance_lookup_table[MAX_NUMNODES][MAX_DISTANCE_REF_POINTS]; | ||
45 | 51 | ||
46 | /* | 52 | /* |
47 | * Allocate node_to_cpumask_map based on number of available nodes | 53 | * Allocate node_to_cpumask_map based on number of available nodes |
@@ -204,6 +210,39 @@ static const u32 *of_get_usable_memory(struct device_node *memory) | |||
204 | return prop; | 210 | return prop; |
205 | } | 211 | } |
206 | 212 | ||
213 | int __node_distance(int a, int b) | ||
214 | { | ||
215 | int i; | ||
216 | int distance = LOCAL_DISTANCE; | ||
217 | |||
218 | if (!form1_affinity) | ||
219 | return distance; | ||
220 | |||
221 | for (i = 0; i < distance_ref_points_depth; i++) { | ||
222 | if (distance_lookup_table[a][i] == distance_lookup_table[b][i]) | ||
223 | break; | ||
224 | |||
225 | /* Double the distance for each NUMA level */ | ||
226 | distance *= 2; | ||
227 | } | ||
228 | |||
229 | return distance; | ||
230 | } | ||
231 | |||
232 | static void initialize_distance_lookup_table(int nid, | ||
233 | const unsigned int *associativity) | ||
234 | { | ||
235 | int i; | ||
236 | |||
237 | if (!form1_affinity) | ||
238 | return; | ||
239 | |||
240 | for (i = 0; i < distance_ref_points_depth; i++) { | ||
241 | distance_lookup_table[nid][i] = | ||
242 | associativity[distance_ref_points[i]]; | ||
243 | } | ||
244 | } | ||
245 | |||
207 | /* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa | 246 | /* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa |
208 | * info is found. | 247 | * info is found. |
209 | */ | 248 | */ |
@@ -225,6 +264,10 @@ static int of_node_to_nid_single(struct device_node *device) | |||
225 | /* POWER4 LPAR uses 0xffff as invalid node */ | 264 | /* POWER4 LPAR uses 0xffff as invalid node */ |
226 | if (nid == 0xffff || nid >= MAX_NUMNODES) | 265 | if (nid == 0xffff || nid >= MAX_NUMNODES) |
227 | nid = -1; | 266 | nid = -1; |
267 | |||
268 | if (nid > 0 && tmp[0] >= distance_ref_points_depth) | ||
269 | initialize_distance_lookup_table(nid, tmp); | ||
270 | |||
228 | out: | 271 | out: |
229 | return nid; | 272 | return nid; |
230 | } | 273 | } |
@@ -251,26 +294,10 @@ int of_node_to_nid(struct device_node *device) | |||
251 | } | 294 | } |
252 | EXPORT_SYMBOL_GPL(of_node_to_nid); | 295 | EXPORT_SYMBOL_GPL(of_node_to_nid); |
253 | 296 | ||
254 | /* | ||
255 | * In theory, the "ibm,associativity" property may contain multiple | ||
256 | * associativity lists because a resource may be multiply connected | ||
257 | * into the machine. This resource then has different associativity | ||
258 | * characteristics relative to its multiple connections. We ignore | ||
259 | * this for now. We also assume that all cpu and memory sets have | ||
260 | * their distances represented at a common level. This won't be | ||
261 | * true for hierarchical NUMA. | ||
262 | * | ||
263 | * In any case the ibm,associativity-reference-points should give | ||
264 | * the correct depth for a normal NUMA system. | ||
265 | * | ||
266 | * - Dave Hansen <haveblue@us.ibm.com> | ||
267 | */ | ||
268 | static int __init find_min_common_depth(void) | 297 | static int __init find_min_common_depth(void) |
269 | { | 298 | { |
270 | int depth, index; | 299 | int depth; |
271 | const unsigned int *ref_points; | ||
272 | struct device_node *rtas_root; | 300 | struct device_node *rtas_root; |
273 | unsigned int len; | ||
274 | struct device_node *chosen; | 301 | struct device_node *chosen; |
275 | const char *vec5; | 302 | const char *vec5; |
276 | 303 | ||
@@ -280,18 +307,28 @@ static int __init find_min_common_depth(void) | |||
280 | return -1; | 307 | return -1; |
281 | 308 | ||
282 | /* | 309 | /* |
283 | * this property is 2 32-bit integers, each representing a level of | 310 | * This property is a set of 32-bit integers, each representing |
284 | * depth in the associativity nodes. The first is for an SMP | 311 | * an index into the ibm,associativity nodes. |
285 | * configuration (should be all 0's) and the second is for a normal | 312 | * |
286 | * NUMA configuration. | 313 | * With form 0 affinity the first integer is for an SMP configuration |
314 | * (should be all 0's) and the second is for a normal NUMA | ||
315 | * configuration. We have only one level of NUMA. | ||
316 | * | ||
317 | * With form 1 affinity the first integer is the most significant | ||
318 | * NUMA boundary and the following are progressively less significant | ||
319 | * boundaries. There can be more than one level of NUMA. | ||
287 | */ | 320 | */ |
288 | index = 1; | 321 | distance_ref_points = of_get_property(rtas_root, |
289 | ref_points = of_get_property(rtas_root, | 322 | "ibm,associativity-reference-points", |
290 | "ibm,associativity-reference-points", &len); | 323 | &distance_ref_points_depth); |
324 | |||
325 | if (!distance_ref_points) { | ||
326 | dbg("NUMA: ibm,associativity-reference-points not found.\n"); | ||
327 | goto err; | ||
328 | } | ||
329 | |||
330 | distance_ref_points_depth /= sizeof(int); | ||
291 | 331 | ||
292 | /* | ||
293 | * For form 1 affinity information we want the first field | ||
294 | */ | ||
295 | #define VEC5_AFFINITY_BYTE 5 | 332 | #define VEC5_AFFINITY_BYTE 5 |
296 | #define VEC5_AFFINITY 0x80 | 333 | #define VEC5_AFFINITY 0x80 |
297 | chosen = of_find_node_by_path("/chosen"); | 334 | chosen = of_find_node_by_path("/chosen"); |
@@ -299,19 +336,38 @@ static int __init find_min_common_depth(void) | |||
299 | vec5 = of_get_property(chosen, "ibm,architecture-vec-5", NULL); | 336 | vec5 = of_get_property(chosen, "ibm,architecture-vec-5", NULL); |
300 | if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & VEC5_AFFINITY)) { | 337 | if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & VEC5_AFFINITY)) { |
301 | dbg("Using form 1 affinity\n"); | 338 | dbg("Using form 1 affinity\n"); |
302 | index = 0; | 339 | form1_affinity = 1; |
303 | } | 340 | } |
304 | } | 341 | } |
305 | 342 | ||
306 | if ((len >= 2 * sizeof(unsigned int)) && ref_points) { | 343 | if (form1_affinity) { |
307 | depth = ref_points[index]; | 344 | depth = distance_ref_points[0]; |
308 | } else { | 345 | } else { |
309 | dbg("NUMA: ibm,associativity-reference-points not found.\n"); | 346 | if (distance_ref_points_depth < 2) { |
310 | depth = -1; | 347 | printk(KERN_WARNING "NUMA: " |
348 | "short ibm,associativity-reference-points\n"); | ||
349 | goto err; | ||
350 | } | ||
351 | |||
352 | depth = distance_ref_points[1]; | ||
311 | } | 353 | } |
312 | of_node_put(rtas_root); | ||
313 | 354 | ||
355 | /* | ||
356 | * Warn and cap if the hardware supports more than | ||
357 | * MAX_DISTANCE_REF_POINTS domains. | ||
358 | */ | ||
359 | if (distance_ref_points_depth > MAX_DISTANCE_REF_POINTS) { | ||
360 | printk(KERN_WARNING "NUMA: distance array capped at " | ||
361 | "%d entries\n", MAX_DISTANCE_REF_POINTS); | ||
362 | distance_ref_points_depth = MAX_DISTANCE_REF_POINTS; | ||
363 | } | ||
364 | |||
365 | of_node_put(rtas_root); | ||
314 | return depth; | 366 | return depth; |
367 | |||
368 | err: | ||
369 | of_node_put(rtas_root); | ||
370 | return -1; | ||
315 | } | 371 | } |
316 | 372 | ||
317 | static void __init get_n_mem_cells(int *n_addr_cells, int *n_size_cells) | 373 | static void __init get_n_mem_cells(int *n_addr_cells, int *n_size_cells) |
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c index ebc2f38eb381..2c7e801ab20b 100644 --- a/arch/powerpc/mm/pgtable.c +++ b/arch/powerpc/mm/pgtable.c | |||
@@ -92,7 +92,6 @@ static void pte_free_rcu_callback(struct rcu_head *head) | |||
92 | 92 | ||
93 | static void pte_free_submit(struct pte_freelist_batch *batch) | 93 | static void pte_free_submit(struct pte_freelist_batch *batch) |
94 | { | 94 | { |
95 | INIT_RCU_HEAD(&batch->rcu); | ||
96 | call_rcu(&batch->rcu, pte_free_rcu_callback); | 95 | call_rcu(&batch->rcu, pte_free_rcu_callback); |
97 | } | 96 | } |
98 | 97 | ||
diff --git a/arch/powerpc/mm/tlb_hash32.c b/arch/powerpc/mm/tlb_hash32.c index 8aaa8b7eb324..690566b66e8e 100644 --- a/arch/powerpc/mm/tlb_hash32.c +++ b/arch/powerpc/mm/tlb_hash32.c | |||
@@ -89,17 +89,6 @@ void tlb_flush(struct mmu_gather *tlb) | |||
89 | * -- Cort | 89 | * -- Cort |
90 | */ | 90 | */ |
91 | 91 | ||
92 | /* | ||
93 | * 750 SMP is a Bad Idea because the 750 doesn't broadcast all | ||
94 | * the cache operations on the bus. Hence we need to use an IPI | ||
95 | * to get the other CPU(s) to invalidate their TLBs. | ||
96 | */ | ||
97 | #ifdef CONFIG_SMP_750 | ||
98 | #define FINISH_FLUSH smp_send_tlb_invalidate(0) | ||
99 | #else | ||
100 | #define FINISH_FLUSH do { } while (0) | ||
101 | #endif | ||
102 | |||
103 | static void flush_range(struct mm_struct *mm, unsigned long start, | 92 | static void flush_range(struct mm_struct *mm, unsigned long start, |
104 | unsigned long end) | 93 | unsigned long end) |
105 | { | 94 | { |
@@ -138,7 +127,6 @@ static void flush_range(struct mm_struct *mm, unsigned long start, | |||
138 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) | 127 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) |
139 | { | 128 | { |
140 | flush_range(&init_mm, start, end); | 129 | flush_range(&init_mm, start, end); |
141 | FINISH_FLUSH; | ||
142 | } | 130 | } |
143 | EXPORT_SYMBOL(flush_tlb_kernel_range); | 131 | EXPORT_SYMBOL(flush_tlb_kernel_range); |
144 | 132 | ||
@@ -162,7 +150,6 @@ void flush_tlb_mm(struct mm_struct *mm) | |||
162 | */ | 150 | */ |
163 | for (mp = mm->mmap; mp != NULL; mp = mp->vm_next) | 151 | for (mp = mm->mmap; mp != NULL; mp = mp->vm_next) |
164 | flush_range(mp->vm_mm, mp->vm_start, mp->vm_end); | 152 | flush_range(mp->vm_mm, mp->vm_start, mp->vm_end); |
165 | FINISH_FLUSH; | ||
166 | } | 153 | } |
167 | EXPORT_SYMBOL(flush_tlb_mm); | 154 | EXPORT_SYMBOL(flush_tlb_mm); |
168 | 155 | ||
@@ -179,7 +166,6 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) | |||
179 | pmd = pmd_offset(pud_offset(pgd_offset(mm, vmaddr), vmaddr), vmaddr); | 166 | pmd = pmd_offset(pud_offset(pgd_offset(mm, vmaddr), vmaddr), vmaddr); |
180 | if (!pmd_none(*pmd)) | 167 | if (!pmd_none(*pmd)) |
181 | flush_hash_pages(mm->context.id, vmaddr, pmd_val(*pmd), 1); | 168 | flush_hash_pages(mm->context.id, vmaddr, pmd_val(*pmd), 1); |
182 | FINISH_FLUSH; | ||
183 | } | 169 | } |
184 | EXPORT_SYMBOL(flush_tlb_page); | 170 | EXPORT_SYMBOL(flush_tlb_page); |
185 | 171 | ||
@@ -192,6 +178,5 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
192 | unsigned long end) | 178 | unsigned long end) |
193 | { | 179 | { |
194 | flush_range(vma->vm_mm, start, end); | 180 | flush_range(vma->vm_mm, start, end); |
195 | FINISH_FLUSH; | ||
196 | } | 181 | } |
197 | EXPORT_SYMBOL(flush_tlb_range); | 182 | EXPORT_SYMBOL(flush_tlb_range); |
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index d8695b02a968..fe391e942521 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c | |||
@@ -46,6 +46,7 @@ | |||
46 | struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { | 46 | struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { |
47 | [MMU_PAGE_4K] = { | 47 | [MMU_PAGE_4K] = { |
48 | .shift = 12, | 48 | .shift = 12, |
49 | .ind = 20, | ||
49 | .enc = BOOK3E_PAGESZ_4K, | 50 | .enc = BOOK3E_PAGESZ_4K, |
50 | }, | 51 | }, |
51 | [MMU_PAGE_16K] = { | 52 | [MMU_PAGE_16K] = { |
@@ -54,6 +55,7 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { | |||
54 | }, | 55 | }, |
55 | [MMU_PAGE_64K] = { | 56 | [MMU_PAGE_64K] = { |
56 | .shift = 16, | 57 | .shift = 16, |
58 | .ind = 28, | ||
57 | .enc = BOOK3E_PAGESZ_64K, | 59 | .enc = BOOK3E_PAGESZ_64K, |
58 | }, | 60 | }, |
59 | [MMU_PAGE_1M] = { | 61 | [MMU_PAGE_1M] = { |
@@ -62,6 +64,7 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { | |||
62 | }, | 64 | }, |
63 | [MMU_PAGE_16M] = { | 65 | [MMU_PAGE_16M] = { |
64 | .shift = 24, | 66 | .shift = 24, |
67 | .ind = 36, | ||
65 | .enc = BOOK3E_PAGESZ_16M, | 68 | .enc = BOOK3E_PAGESZ_16M, |
66 | }, | 69 | }, |
67 | [MMU_PAGE_256M] = { | 70 | [MMU_PAGE_256M] = { |
@@ -344,16 +347,108 @@ void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address) | |||
344 | } | 347 | } |
345 | } | 348 | } |
346 | 349 | ||
347 | /* | 350 | static void setup_page_sizes(void) |
348 | * Early initialization of the MMU TLB code | 351 | { |
349 | */ | 352 | unsigned int tlb0cfg = mfspr(SPRN_TLB0CFG); |
350 | static void __early_init_mmu(int boot_cpu) | 353 | unsigned int tlb0ps = mfspr(SPRN_TLB0PS); |
354 | unsigned int eptcfg = mfspr(SPRN_EPTCFG); | ||
355 | int i, psize; | ||
356 | |||
357 | /* Look for supported direct sizes */ | ||
358 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { | ||
359 | struct mmu_psize_def *def = &mmu_psize_defs[psize]; | ||
360 | |||
361 | if (tlb0ps & (1U << (def->shift - 10))) | ||
362 | def->flags |= MMU_PAGE_SIZE_DIRECT; | ||
363 | } | ||
364 | |||
365 | /* Indirect page sizes supported ? */ | ||
366 | if ((tlb0cfg & TLBnCFG_IND) == 0) | ||
367 | goto no_indirect; | ||
368 | |||
369 | /* Now, we only deal with one IND page size for each | ||
370 | * direct size. Hopefully all implementations today are | ||
371 | * unambiguous, but we might want to be careful in the | ||
372 | * future. | ||
373 | */ | ||
374 | for (i = 0; i < 3; i++) { | ||
375 | unsigned int ps, sps; | ||
376 | |||
377 | sps = eptcfg & 0x1f; | ||
378 | eptcfg >>= 5; | ||
379 | ps = eptcfg & 0x1f; | ||
380 | eptcfg >>= 5; | ||
381 | if (!ps || !sps) | ||
382 | continue; | ||
383 | for (psize = 0; psize < MMU_PAGE_COUNT; psize++) { | ||
384 | struct mmu_psize_def *def = &mmu_psize_defs[psize]; | ||
385 | |||
386 | if (ps == (def->shift - 10)) | ||
387 | def->flags |= MMU_PAGE_SIZE_INDIRECT; | ||
388 | if (sps == (def->shift - 10)) | ||
389 | def->ind = ps + 10; | ||
390 | } | ||
391 | } | ||
392 | no_indirect: | ||
393 | |||
394 | /* Cleanup array and print summary */ | ||
395 | pr_info("MMU: Supported page sizes\n"); | ||
396 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { | ||
397 | struct mmu_psize_def *def = &mmu_psize_defs[psize]; | ||
398 | const char *__page_type_names[] = { | ||
399 | "unsupported", | ||
400 | "direct", | ||
401 | "indirect", | ||
402 | "direct & indirect" | ||
403 | }; | ||
404 | if (def->flags == 0) { | ||
405 | def->shift = 0; | ||
406 | continue; | ||
407 | } | ||
408 | pr_info(" %8ld KB as %s\n", 1ul << (def->shift - 10), | ||
409 | __page_type_names[def->flags & 0x3]); | ||
410 | } | ||
411 | } | ||
412 | |||
413 | static void setup_mmu_htw(void) | ||
351 | { | 414 | { |
352 | extern unsigned int interrupt_base_book3e; | 415 | extern unsigned int interrupt_base_book3e; |
353 | extern unsigned int exc_data_tlb_miss_htw_book3e; | 416 | extern unsigned int exc_data_tlb_miss_htw_book3e; |
354 | extern unsigned int exc_instruction_tlb_miss_htw_book3e; | 417 | extern unsigned int exc_instruction_tlb_miss_htw_book3e; |
355 | 418 | ||
356 | unsigned int *ibase = &interrupt_base_book3e; | 419 | unsigned int *ibase = &interrupt_base_book3e; |
420 | |||
421 | /* Check if HW tablewalk is present, and if yes, enable it by: | ||
422 | * | ||
423 | * - patching the TLB miss handlers to branch to the | ||
424 | * one dedicates to it | ||
425 | * | ||
426 | * - setting the global book3e_htw_enabled | ||
427 | */ | ||
428 | unsigned int tlb0cfg = mfspr(SPRN_TLB0CFG); | ||
429 | |||
430 | if ((tlb0cfg & TLBnCFG_IND) && | ||
431 | (tlb0cfg & TLBnCFG_PT)) { | ||
432 | /* Our exceptions vectors start with a NOP and -then- a branch | ||
433 | * to deal with single stepping from userspace which stops on | ||
434 | * the second instruction. Thus we need to patch the second | ||
435 | * instruction of the exception, not the first one | ||
436 | */ | ||
437 | patch_branch(ibase + (0x1c0 / 4) + 1, | ||
438 | (unsigned long)&exc_data_tlb_miss_htw_book3e, 0); | ||
439 | patch_branch(ibase + (0x1e0 / 4) + 1, | ||
440 | (unsigned long)&exc_instruction_tlb_miss_htw_book3e, 0); | ||
441 | book3e_htw_enabled = 1; | ||
442 | } | ||
443 | pr_info("MMU: Book3E Page Tables %s\n", | ||
444 | book3e_htw_enabled ? "Enabled" : "Disabled"); | ||
445 | } | ||
446 | |||
447 | /* | ||
448 | * Early initialization of the MMU TLB code | ||
449 | */ | ||
450 | static void __early_init_mmu(int boot_cpu) | ||
451 | { | ||
357 | unsigned int mas4; | 452 | unsigned int mas4; |
358 | 453 | ||
359 | /* XXX This will have to be decided at runtime, but right | 454 | /* XXX This will have to be decided at runtime, but right |
@@ -370,35 +465,17 @@ static void __early_init_mmu(int boot_cpu) | |||
370 | */ | 465 | */ |
371 | mmu_vmemmap_psize = MMU_PAGE_16M; | 466 | mmu_vmemmap_psize = MMU_PAGE_16M; |
372 | 467 | ||
373 | /* Check if HW tablewalk is present, and if yes, enable it by: | ||
374 | * | ||
375 | * - patching the TLB miss handlers to branch to the | ||
376 | * one dedicates to it | ||
377 | * | ||
378 | * - setting the global book3e_htw_enabled | ||
379 | * | ||
380 | * - Set MAS4:INDD and default page size | ||
381 | */ | ||
382 | |||
383 | /* XXX This code only checks for TLB 0 capabilities and doesn't | 468 | /* XXX This code only checks for TLB 0 capabilities and doesn't |
384 | * check what page size combos are supported by the HW. It | 469 | * check what page size combos are supported by the HW. It |
385 | * also doesn't handle the case where a separate array holds | 470 | * also doesn't handle the case where a separate array holds |
386 | * the IND entries from the array loaded by the PT. | 471 | * the IND entries from the array loaded by the PT. |
387 | */ | 472 | */ |
388 | if (boot_cpu) { | 473 | if (boot_cpu) { |
389 | unsigned int tlb0cfg = mfspr(SPRN_TLB0CFG); | 474 | /* Look for supported page sizes */ |
475 | setup_page_sizes(); | ||
390 | 476 | ||
391 | /* Check if HW loader is supported */ | 477 | /* Look for HW tablewalk support */ |
392 | if ((tlb0cfg & TLBnCFG_IND) && | 478 | setup_mmu_htw(); |
393 | (tlb0cfg & TLBnCFG_PT)) { | ||
394 | patch_branch(ibase + (0x1c0 / 4), | ||
395 | (unsigned long)&exc_data_tlb_miss_htw_book3e, 0); | ||
396 | patch_branch(ibase + (0x1e0 / 4), | ||
397 | (unsigned long)&exc_instruction_tlb_miss_htw_book3e, 0); | ||
398 | book3e_htw_enabled = 1; | ||
399 | } | ||
400 | pr_info("MMU: Book3E Page Tables %s\n", | ||
401 | book3e_htw_enabled ? "Enabled" : "Disabled"); | ||
402 | } | 479 | } |
403 | 480 | ||
404 | /* Set MAS4 based on page table setting */ | 481 | /* Set MAS4 based on page table setting */ |
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile index 73e1c2ca0552..e219ca43962d 100644 --- a/arch/powerpc/oprofile/Makefile +++ b/arch/powerpc/oprofile/Makefile | |||
@@ -16,6 +16,6 @@ oprofile-y := $(DRIVER_OBJS) common.o backtrace.o | |||
16 | oprofile-$(CONFIG_OPROFILE_CELL) += op_model_cell.o \ | 16 | oprofile-$(CONFIG_OPROFILE_CELL) += op_model_cell.o \ |
17 | cell/spu_profiler.o cell/vma_map.o \ | 17 | cell/spu_profiler.o cell/vma_map.o \ |
18 | cell/spu_task_sync.o | 18 | cell/spu_task_sync.o |
19 | oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o op_model_pa6t.o | 19 | oprofile-$(CONFIG_PPC_BOOK3S_64) += op_model_rs64.o op_model_power4.o op_model_pa6t.o |
20 | oprofile-$(CONFIG_FSL_EMB_PERFMON) += op_model_fsl_emb.o | 20 | oprofile-$(CONFIG_FSL_EMB_PERFMON) += op_model_fsl_emb.o |
21 | oprofile-$(CONFIG_6xx) += op_model_7450.o | 21 | oprofile-$(CONFIG_6xx) += op_model_7450.o |
diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c index 21f16edf6c8d..d65e68f3cb25 100644 --- a/arch/powerpc/oprofile/common.c +++ b/arch/powerpc/oprofile/common.c | |||
@@ -199,7 +199,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
199 | return -ENODEV; | 199 | return -ENODEV; |
200 | 200 | ||
201 | switch (cur_cpu_spec->oprofile_type) { | 201 | switch (cur_cpu_spec->oprofile_type) { |
202 | #ifdef CONFIG_PPC64 | 202 | #ifdef CONFIG_PPC_BOOK3S_64 |
203 | #ifdef CONFIG_OPROFILE_CELL | 203 | #ifdef CONFIG_OPROFILE_CELL |
204 | case PPC_OPROFILE_CELL: | 204 | case PPC_OPROFILE_CELL: |
205 | if (firmware_has_feature(FW_FEATURE_LPAR)) | 205 | if (firmware_has_feature(FW_FEATURE_LPAR)) |
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig index ec64264f7a50..b72176434ebe 100644 --- a/arch/powerpc/platforms/40x/Kconfig +++ b/arch/powerpc/platforms/40x/Kconfig | |||
@@ -71,22 +71,6 @@ config MAKALU | |||
71 | help | 71 | help |
72 | This option enables support for the AMCC PPC405EX board. | 72 | This option enables support for the AMCC PPC405EX board. |
73 | 73 | ||
74 | #config REDWOOD_5 | ||
75 | # bool "Redwood-5" | ||
76 | # depends on 40x | ||
77 | # default n | ||
78 | # select STB03xxx | ||
79 | # help | ||
80 | # This option enables support for the IBM STB04 evaluation board. | ||
81 | |||
82 | #config REDWOOD_6 | ||
83 | # bool "Redwood-6" | ||
84 | # depends on 40x | ||
85 | # default n | ||
86 | # select STB03xxx | ||
87 | # help | ||
88 | # This option enables support for the IBM STBx25xx evaluation board. | ||
89 | |||
90 | #config SYCAMORE | 74 | #config SYCAMORE |
91 | # bool "Sycamore" | 75 | # bool "Sycamore" |
92 | # depends on 40x | 76 | # depends on 40x |
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig index 4dac9b0525a4..27b0651221d1 100644 --- a/arch/powerpc/platforms/512x/Kconfig +++ b/arch/powerpc/platforms/512x/Kconfig | |||
@@ -1,32 +1,34 @@ | |||
1 | config PPC_MPC512x | 1 | config PPC_MPC512x |
2 | bool | 2 | bool "512x-based boards" |
3 | depends on 6xx | ||
3 | select FSL_SOC | 4 | select FSL_SOC |
4 | select IPIC | 5 | select IPIC |
5 | select PPC_CLOCK | 6 | select PPC_CLOCK |
6 | select PPC_PCI_CHOICE | 7 | select PPC_PCI_CHOICE |
7 | select FSL_PCI if PCI | 8 | select FSL_PCI if PCI |
8 | 9 | ||
9 | config PPC_MPC5121 | ||
10 | bool | ||
11 | select PPC_MPC512x | ||
12 | |||
13 | config MPC5121_ADS | 10 | config MPC5121_ADS |
14 | bool "Freescale MPC5121E ADS" | 11 | bool "Freescale MPC5121E ADS" |
15 | depends on 6xx | 12 | depends on PPC_MPC512x |
16 | select DEFAULT_UIMAGE | 13 | select DEFAULT_UIMAGE |
17 | select PPC_MPC5121 | ||
18 | select MPC5121_ADS_CPLD | 14 | select MPC5121_ADS_CPLD |
19 | help | 15 | help |
20 | This option enables support for the MPC5121E ADS board. | 16 | This option enables support for the MPC5121E ADS board. |
21 | 17 | ||
22 | config MPC5121_GENERIC | 18 | config MPC5121_GENERIC |
23 | bool "Generic support for simple MPC5121 based boards" | 19 | bool "Generic support for simple MPC5121 based boards" |
24 | depends on 6xx | 20 | depends on PPC_MPC512x |
25 | select DEFAULT_UIMAGE | 21 | select DEFAULT_UIMAGE |
26 | select PPC_MPC5121 | ||
27 | help | 22 | help |
28 | This option enables support for simple MPC5121 based boards | 23 | This option enables support for simple MPC5121 based boards |
29 | which do not need custom platform specific setup. | 24 | which do not need custom platform specific setup. |
30 | 25 | ||
31 | Compatible boards include: Protonic LVT base boards (ZANMCU | 26 | Compatible boards include: Protonic LVT base boards (ZANMCU |
32 | and VICVT2). | 27 | and VICVT2). |
28 | |||
29 | config PDM360NG | ||
30 | bool "ifm PDM360NG board" | ||
31 | depends on PPC_MPC512x | ||
32 | select DEFAULT_UIMAGE | ||
33 | help | ||
34 | This option enables support for the PDM360NG board. | ||
diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile index 90be2f5717e6..4efc1c4b6fb5 100644 --- a/arch/powerpc/platforms/512x/Makefile +++ b/arch/powerpc/platforms/512x/Makefile | |||
@@ -4,3 +4,4 @@ | |||
4 | obj-y += clock.o mpc512x_shared.o | 4 | obj-y += clock.o mpc512x_shared.o |
5 | obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o | 5 | obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o |
6 | obj-$(CONFIG_MPC5121_GENERIC) += mpc5121_generic.o | 6 | obj-$(CONFIG_MPC5121_GENERIC) += mpc5121_generic.o |
7 | obj-$(CONFIG_PDM360NG) += pdm360ng.o | ||
diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c index 4c42246b86a7..e1c5cd6650b1 100644 --- a/arch/powerpc/platforms/512x/clock.c +++ b/arch/powerpc/platforms/512x/clock.c | |||
@@ -292,6 +292,15 @@ static void diu_clk_calc(struct clk *clk) | |||
292 | clk->rate = rate; | 292 | clk->rate = rate; |
293 | } | 293 | } |
294 | 294 | ||
295 | static void viu_clk_calc(struct clk *clk) | ||
296 | { | ||
297 | unsigned long rate; | ||
298 | |||
299 | rate = sys_clk.rate; | ||
300 | rate /= 2; | ||
301 | clk->rate = rate; | ||
302 | } | ||
303 | |||
295 | static void half_clk_calc(struct clk *clk) | 304 | static void half_clk_calc(struct clk *clk) |
296 | { | 305 | { |
297 | clk->rate = clk->parent->rate / 2; | 306 | clk->rate = clk->parent->rate / 2; |
@@ -412,6 +421,14 @@ static struct clk diu_clk = { | |||
412 | .calc = diu_clk_calc, | 421 | .calc = diu_clk_calc, |
413 | }; | 422 | }; |
414 | 423 | ||
424 | static struct clk viu_clk = { | ||
425 | .name = "viu_clk", | ||
426 | .flags = CLK_HAS_CTRL, | ||
427 | .reg = 1, | ||
428 | .bit = 18, | ||
429 | .calc = viu_clk_calc, | ||
430 | }; | ||
431 | |||
415 | static struct clk axe_clk = { | 432 | static struct clk axe_clk = { |
416 | .name = "axe_clk", | 433 | .name = "axe_clk", |
417 | .flags = CLK_HAS_CTRL, | 434 | .flags = CLK_HAS_CTRL, |
@@ -535,6 +552,7 @@ struct clk *rate_clks[] = { | |||
535 | &ref_clk, | 552 | &ref_clk, |
536 | &sys_clk, | 553 | &sys_clk, |
537 | &diu_clk, | 554 | &diu_clk, |
555 | &viu_clk, | ||
538 | &csb_clk, | 556 | &csb_clk, |
539 | &e300_clk, | 557 | &e300_clk, |
540 | &ips_clk, | 558 | &ips_clk, |
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads.c b/arch/powerpc/platforms/512x/mpc5121_ads.c index ee6ae129c25c..dcef6ade48e1 100644 --- a/arch/powerpc/platforms/512x/mpc5121_ads.c +++ b/arch/powerpc/platforms/512x/mpc5121_ads.c | |||
@@ -42,6 +42,7 @@ static void __init mpc5121_ads_setup_arch(void) | |||
42 | for_each_compatible_node(np, "pci", "fsl,mpc5121-pci") | 42 | for_each_compatible_node(np, "pci", "fsl,mpc5121-pci") |
43 | mpc83xx_add_bridge(np); | 43 | mpc83xx_add_bridge(np); |
44 | #endif | 44 | #endif |
45 | mpc512x_setup_diu(); | ||
45 | } | 46 | } |
46 | 47 | ||
47 | static void __init mpc5121_ads_init_IRQ(void) | 48 | static void __init mpc5121_ads_init_IRQ(void) |
@@ -65,6 +66,7 @@ define_machine(mpc5121_ads) { | |||
65 | .probe = mpc5121_ads_probe, | 66 | .probe = mpc5121_ads_probe, |
66 | .setup_arch = mpc5121_ads_setup_arch, | 67 | .setup_arch = mpc5121_ads_setup_arch, |
67 | .init = mpc512x_init, | 68 | .init = mpc512x_init, |
69 | .init_early = mpc512x_init_diu, | ||
68 | .init_IRQ = mpc5121_ads_init_IRQ, | 70 | .init_IRQ = mpc5121_ads_init_IRQ, |
69 | .get_irq = ipic_get_irq, | 71 | .get_irq = ipic_get_irq, |
70 | .calibrate_decr = generic_calibrate_decr, | 72 | .calibrate_decr = generic_calibrate_decr, |
diff --git a/arch/powerpc/platforms/512x/mpc5121_generic.c b/arch/powerpc/platforms/512x/mpc5121_generic.c index a6c0e3a2615d..e487eb06ec6b 100644 --- a/arch/powerpc/platforms/512x/mpc5121_generic.c +++ b/arch/powerpc/platforms/512x/mpc5121_generic.c | |||
@@ -52,6 +52,8 @@ define_machine(mpc5121_generic) { | |||
52 | .name = "MPC5121 generic", | 52 | .name = "MPC5121 generic", |
53 | .probe = mpc5121_generic_probe, | 53 | .probe = mpc5121_generic_probe, |
54 | .init = mpc512x_init, | 54 | .init = mpc512x_init, |
55 | .init_early = mpc512x_init_diu, | ||
56 | .setup_arch = mpc512x_setup_diu, | ||
55 | .init_IRQ = mpc512x_init_IRQ, | 57 | .init_IRQ = mpc512x_init_IRQ, |
56 | .get_irq = ipic_get_irq, | 58 | .get_irq = ipic_get_irq, |
57 | .calibrate_decr = generic_calibrate_decr, | 59 | .calibrate_decr = generic_calibrate_decr, |
diff --git a/arch/powerpc/platforms/512x/mpc512x.h b/arch/powerpc/platforms/512x/mpc512x.h index b2daca0d1488..1ab6d11d0b19 100644 --- a/arch/powerpc/platforms/512x/mpc512x.h +++ b/arch/powerpc/platforms/512x/mpc512x.h | |||
@@ -16,4 +16,6 @@ extern void __init mpc512x_init(void); | |||
16 | extern int __init mpc5121_clk_init(void); | 16 | extern int __init mpc5121_clk_init(void); |
17 | void __init mpc512x_declare_of_platform_devices(void); | 17 | void __init mpc512x_declare_of_platform_devices(void); |
18 | extern void mpc512x_restart(char *cmd); | 18 | extern void mpc512x_restart(char *cmd); |
19 | extern void mpc512x_init_diu(void); | ||
20 | extern void mpc512x_setup_diu(void); | ||
19 | #endif /* __MPC512X_H__ */ | 21 | #endif /* __MPC512X_H__ */ |
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c index 707e572b7c40..e41ebbdb3e12 100644 --- a/arch/powerpc/platforms/512x/mpc512x_shared.c +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c | |||
@@ -16,7 +16,11 @@ | |||
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
18 | #include <linux/of_platform.h> | 18 | #include <linux/of_platform.h> |
19 | #include <linux/fsl-diu-fb.h> | ||
20 | #include <linux/bootmem.h> | ||
21 | #include <sysdev/fsl_soc.h> | ||
19 | 22 | ||
23 | #include <asm/cacheflush.h> | ||
20 | #include <asm/machdep.h> | 24 | #include <asm/machdep.h> |
21 | #include <asm/ipic.h> | 25 | #include <asm/ipic.h> |
22 | #include <asm/prom.h> | 26 | #include <asm/prom.h> |
@@ -54,6 +58,286 @@ void mpc512x_restart(char *cmd) | |||
54 | ; | 58 | ; |
55 | } | 59 | } |
56 | 60 | ||
61 | struct fsl_diu_shared_fb { | ||
62 | u8 gamma[0x300]; /* 32-bit aligned! */ | ||
63 | struct diu_ad ad0; /* 32-bit aligned! */ | ||
64 | phys_addr_t fb_phys; | ||
65 | size_t fb_len; | ||
66 | bool in_use; | ||
67 | }; | ||
68 | |||
69 | unsigned int mpc512x_get_pixel_format(unsigned int bits_per_pixel, | ||
70 | int monitor_port) | ||
71 | { | ||
72 | switch (bits_per_pixel) { | ||
73 | case 32: | ||
74 | return 0x88883316; | ||
75 | case 24: | ||
76 | return 0x88082219; | ||
77 | case 16: | ||
78 | return 0x65053118; | ||
79 | } | ||
80 | return 0x00000400; | ||
81 | } | ||
82 | |||
83 | void mpc512x_set_gamma_table(int monitor_port, char *gamma_table_base) | ||
84 | { | ||
85 | } | ||
86 | |||
87 | void mpc512x_set_monitor_port(int monitor_port) | ||
88 | { | ||
89 | } | ||
90 | |||
91 | #define DIU_DIV_MASK 0x000000ff | ||
92 | void mpc512x_set_pixel_clock(unsigned int pixclock) | ||
93 | { | ||
94 | unsigned long bestval, bestfreq, speed, busfreq; | ||
95 | unsigned long minpixclock, maxpixclock, pixval; | ||
96 | struct mpc512x_ccm __iomem *ccm; | ||
97 | struct device_node *np; | ||
98 | u32 temp; | ||
99 | long err; | ||
100 | int i; | ||
101 | |||
102 | np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock"); | ||
103 | if (!np) { | ||
104 | pr_err("Can't find clock control module.\n"); | ||
105 | return; | ||
106 | } | ||
107 | |||
108 | ccm = of_iomap(np, 0); | ||
109 | of_node_put(np); | ||
110 | if (!ccm) { | ||
111 | pr_err("Can't map clock control module reg.\n"); | ||
112 | return; | ||
113 | } | ||
114 | |||
115 | np = of_find_node_by_type(NULL, "cpu"); | ||
116 | if (np) { | ||
117 | const unsigned int *prop = | ||
118 | of_get_property(np, "bus-frequency", NULL); | ||
119 | |||
120 | of_node_put(np); | ||
121 | if (prop) { | ||
122 | busfreq = *prop; | ||
123 | } else { | ||
124 | pr_err("Can't get bus-frequency property\n"); | ||
125 | return; | ||
126 | } | ||
127 | } else { | ||
128 | pr_err("Can't find 'cpu' node.\n"); | ||
129 | return; | ||
130 | } | ||
131 | |||
132 | /* Pixel Clock configuration */ | ||
133 | pr_debug("DIU: Bus Frequency = %lu\n", busfreq); | ||
134 | speed = busfreq * 4; /* DIU_DIV ratio is 4 * CSB_CLK / DIU_CLK */ | ||
135 | |||
136 | /* Calculate the pixel clock with the smallest error */ | ||
137 | /* calculate the following in steps to avoid overflow */ | ||
138 | pr_debug("DIU pixclock in ps - %d\n", pixclock); | ||
139 | temp = (1000000000 / pixclock) * 1000; | ||
140 | pixclock = temp; | ||
141 | pr_debug("DIU pixclock freq - %u\n", pixclock); | ||
142 | |||
143 | temp = temp / 20; /* pixclock * 0.05 */ | ||
144 | pr_debug("deviation = %d\n", temp); | ||
145 | minpixclock = pixclock - temp; | ||
146 | maxpixclock = pixclock + temp; | ||
147 | pr_debug("DIU minpixclock - %lu\n", minpixclock); | ||
148 | pr_debug("DIU maxpixclock - %lu\n", maxpixclock); | ||
149 | pixval = speed/pixclock; | ||
150 | pr_debug("DIU pixval = %lu\n", pixval); | ||
151 | |||
152 | err = LONG_MAX; | ||
153 | bestval = pixval; | ||
154 | pr_debug("DIU bestval = %lu\n", bestval); | ||
155 | |||
156 | bestfreq = 0; | ||
157 | for (i = -1; i <= 1; i++) { | ||
158 | temp = speed / (pixval+i); | ||
159 | pr_debug("DIU test pixval i=%d, pixval=%lu, temp freq. = %u\n", | ||
160 | i, pixval, temp); | ||
161 | if ((temp < minpixclock) || (temp > maxpixclock)) | ||
162 | pr_debug("DIU exceeds monitor range (%lu to %lu)\n", | ||
163 | minpixclock, maxpixclock); | ||
164 | else if (abs(temp - pixclock) < err) { | ||
165 | pr_debug("Entered the else if block %d\n", i); | ||
166 | err = abs(temp - pixclock); | ||
167 | bestval = pixval + i; | ||
168 | bestfreq = temp; | ||
169 | } | ||
170 | } | ||
171 | |||
172 | pr_debug("DIU chose = %lx\n", bestval); | ||
173 | pr_debug("DIU error = %ld\n NomPixClk ", err); | ||
174 | pr_debug("DIU: Best Freq = %lx\n", bestfreq); | ||
175 | /* Modify DIU_DIV in CCM SCFR1 */ | ||
176 | temp = in_be32(&ccm->scfr1); | ||
177 | pr_debug("DIU: Current value of SCFR1: 0x%08x\n", temp); | ||
178 | temp &= ~DIU_DIV_MASK; | ||
179 | temp |= (bestval & DIU_DIV_MASK); | ||
180 | out_be32(&ccm->scfr1, temp); | ||
181 | pr_debug("DIU: Modified value of SCFR1: 0x%08x\n", temp); | ||
182 | iounmap(ccm); | ||
183 | } | ||
184 | |||
185 | ssize_t mpc512x_show_monitor_port(int monitor_port, char *buf) | ||
186 | { | ||
187 | return sprintf(buf, "0 - 5121 LCD\n"); | ||
188 | } | ||
189 | |||
190 | int mpc512x_set_sysfs_monitor_port(int val) | ||
191 | { | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static struct fsl_diu_shared_fb __attribute__ ((__aligned__(8))) diu_shared_fb; | ||
196 | |||
197 | #if defined(CONFIG_FB_FSL_DIU) || \ | ||
198 | defined(CONFIG_FB_FSL_DIU_MODULE) | ||
199 | static inline void mpc512x_free_bootmem(struct page *page) | ||
200 | { | ||
201 | __ClearPageReserved(page); | ||
202 | BUG_ON(PageTail(page)); | ||
203 | BUG_ON(atomic_read(&page->_count) > 1); | ||
204 | atomic_set(&page->_count, 1); | ||
205 | __free_page(page); | ||
206 | totalram_pages++; | ||
207 | } | ||
208 | |||
209 | void mpc512x_release_bootmem(void) | ||
210 | { | ||
211 | unsigned long addr = diu_shared_fb.fb_phys & PAGE_MASK; | ||
212 | unsigned long size = diu_shared_fb.fb_len; | ||
213 | unsigned long start, end; | ||
214 | |||
215 | if (diu_shared_fb.in_use) { | ||
216 | start = PFN_UP(addr); | ||
217 | end = PFN_DOWN(addr + size); | ||
218 | |||
219 | for (; start < end; start++) | ||
220 | mpc512x_free_bootmem(pfn_to_page(start)); | ||
221 | |||
222 | diu_shared_fb.in_use = false; | ||
223 | } | ||
224 | diu_ops.release_bootmem = NULL; | ||
225 | } | ||
226 | #endif | ||
227 | |||
228 | /* | ||
229 | * Check if DIU was pre-initialized. If so, perform steps | ||
230 | * needed to continue displaying through the whole boot process. | ||
231 | * Move area descriptor and gamma table elsewhere, they are | ||
232 | * destroyed by bootmem allocator otherwise. The frame buffer | ||
233 | * address range will be reserved in setup_arch() after bootmem | ||
234 | * allocator is up. | ||
235 | */ | ||
236 | void __init mpc512x_init_diu(void) | ||
237 | { | ||
238 | struct device_node *np; | ||
239 | struct diu __iomem *diu_reg; | ||
240 | phys_addr_t desc; | ||
241 | void __iomem *vaddr; | ||
242 | unsigned long mode, pix_fmt, res, bpp; | ||
243 | unsigned long dst; | ||
244 | |||
245 | np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-diu"); | ||
246 | if (!np) { | ||
247 | pr_err("No DIU node\n"); | ||
248 | return; | ||
249 | } | ||
250 | |||
251 | diu_reg = of_iomap(np, 0); | ||
252 | of_node_put(np); | ||
253 | if (!diu_reg) { | ||
254 | pr_err("Can't map DIU\n"); | ||
255 | return; | ||
256 | } | ||
257 | |||
258 | mode = in_be32(&diu_reg->diu_mode); | ||
259 | if (mode != MFB_MODE1) { | ||
260 | pr_info("%s: DIU OFF\n", __func__); | ||
261 | goto out; | ||
262 | } | ||
263 | |||
264 | desc = in_be32(&diu_reg->desc[0]); | ||
265 | vaddr = ioremap(desc, sizeof(struct diu_ad)); | ||
266 | if (!vaddr) { | ||
267 | pr_err("Can't map DIU area desc.\n"); | ||
268 | goto out; | ||
269 | } | ||
270 | memcpy(&diu_shared_fb.ad0, vaddr, sizeof(struct diu_ad)); | ||
271 | /* flush fb area descriptor */ | ||
272 | dst = (unsigned long)&diu_shared_fb.ad0; | ||
273 | flush_dcache_range(dst, dst + sizeof(struct diu_ad) - 1); | ||
274 | |||
275 | res = in_be32(&diu_reg->disp_size); | ||
276 | pix_fmt = in_le32(vaddr); | ||
277 | bpp = ((pix_fmt >> 16) & 0x3) + 1; | ||
278 | diu_shared_fb.fb_phys = in_le32(vaddr + 4); | ||
279 | diu_shared_fb.fb_len = ((res & 0xfff0000) >> 16) * (res & 0xfff) * bpp; | ||
280 | diu_shared_fb.in_use = true; | ||
281 | iounmap(vaddr); | ||
282 | |||
283 | desc = in_be32(&diu_reg->gamma); | ||
284 | vaddr = ioremap(desc, sizeof(diu_shared_fb.gamma)); | ||
285 | if (!vaddr) { | ||
286 | pr_err("Can't map DIU area desc.\n"); | ||
287 | diu_shared_fb.in_use = false; | ||
288 | goto out; | ||
289 | } | ||
290 | memcpy(&diu_shared_fb.gamma, vaddr, sizeof(diu_shared_fb.gamma)); | ||
291 | /* flush gamma table */ | ||
292 | dst = (unsigned long)&diu_shared_fb.gamma; | ||
293 | flush_dcache_range(dst, dst + sizeof(diu_shared_fb.gamma) - 1); | ||
294 | |||
295 | iounmap(vaddr); | ||
296 | out_be32(&diu_reg->gamma, virt_to_phys(&diu_shared_fb.gamma)); | ||
297 | out_be32(&diu_reg->desc[1], 0); | ||
298 | out_be32(&diu_reg->desc[2], 0); | ||
299 | out_be32(&diu_reg->desc[0], virt_to_phys(&diu_shared_fb.ad0)); | ||
300 | |||
301 | out: | ||
302 | iounmap(diu_reg); | ||
303 | } | ||
304 | |||
305 | void __init mpc512x_setup_diu(void) | ||
306 | { | ||
307 | int ret; | ||
308 | |||
309 | /* | ||
310 | * We do not allocate and configure new area for bitmap buffer | ||
311 | * because it would requere copying bitmap data (splash image) | ||
312 | * and so negatively affect boot time. Instead we reserve the | ||
313 | * already configured frame buffer area so that it won't be | ||
314 | * destroyed. The starting address of the area to reserve and | ||
315 | * also it's length is passed to reserve_bootmem(). It will be | ||
316 | * freed later on first open of fbdev, when splash image is not | ||
317 | * needed any more. | ||
318 | */ | ||
319 | if (diu_shared_fb.in_use) { | ||
320 | ret = reserve_bootmem(diu_shared_fb.fb_phys, | ||
321 | diu_shared_fb.fb_len, | ||
322 | BOOTMEM_EXCLUSIVE); | ||
323 | if (ret) { | ||
324 | pr_err("%s: reserve bootmem failed\n", __func__); | ||
325 | diu_shared_fb.in_use = false; | ||
326 | } | ||
327 | } | ||
328 | |||
329 | #if defined(CONFIG_FB_FSL_DIU) || \ | ||
330 | defined(CONFIG_FB_FSL_DIU_MODULE) | ||
331 | diu_ops.get_pixel_format = mpc512x_get_pixel_format; | ||
332 | diu_ops.set_gamma_table = mpc512x_set_gamma_table; | ||
333 | diu_ops.set_monitor_port = mpc512x_set_monitor_port; | ||
334 | diu_ops.set_pixel_clock = mpc512x_set_pixel_clock; | ||
335 | diu_ops.show_monitor_port = mpc512x_show_monitor_port; | ||
336 | diu_ops.set_sysfs_monitor_port = mpc512x_set_sysfs_monitor_port; | ||
337 | diu_ops.release_bootmem = mpc512x_release_bootmem; | ||
338 | #endif | ||
339 | } | ||
340 | |||
57 | void __init mpc512x_init_IRQ(void) | 341 | void __init mpc512x_init_IRQ(void) |
58 | { | 342 | { |
59 | struct device_node *np; | 343 | struct device_node *np; |
diff --git a/arch/powerpc/platforms/512x/pdm360ng.c b/arch/powerpc/platforms/512x/pdm360ng.c new file mode 100644 index 000000000000..0575e858291c --- /dev/null +++ b/arch/powerpc/platforms/512x/pdm360ng.c | |||
@@ -0,0 +1,129 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 DENX Software Engineering | ||
3 | * | ||
4 | * Anatolij Gustschin, <agust@denx.de> | ||
5 | * | ||
6 | * PDM360NG board setup | ||
7 | * | ||
8 | * This is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/of_platform.h> | ||
18 | |||
19 | #include <asm/machdep.h> | ||
20 | #include <asm/ipic.h> | ||
21 | |||
22 | #include "mpc512x.h" | ||
23 | |||
24 | #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ | ||
25 | defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/spi/ads7846.h> | ||
28 | #include <linux/spi/spi.h> | ||
29 | #include <linux/notifier.h> | ||
30 | |||
31 | static void *pdm360ng_gpio_base; | ||
32 | |||
33 | static int pdm360ng_get_pendown_state(void) | ||
34 | { | ||
35 | u32 reg; | ||
36 | |||
37 | reg = in_be32(pdm360ng_gpio_base + 0xc); | ||
38 | if (reg & 0x40) | ||
39 | setbits32(pdm360ng_gpio_base + 0xc, 0x40); | ||
40 | |||
41 | reg = in_be32(pdm360ng_gpio_base + 0x8); | ||
42 | |||
43 | /* return 1 if pen is down */ | ||
44 | return (reg & 0x40) == 0; | ||
45 | } | ||
46 | |||
47 | static struct ads7846_platform_data pdm360ng_ads7846_pdata = { | ||
48 | .model = 7845, | ||
49 | .get_pendown_state = pdm360ng_get_pendown_state, | ||
50 | .irq_flags = IRQF_TRIGGER_LOW, | ||
51 | }; | ||
52 | |||
53 | static int __init pdm360ng_penirq_init(void) | ||
54 | { | ||
55 | struct device_node *np; | ||
56 | |||
57 | np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-gpio"); | ||
58 | if (!np) { | ||
59 | pr_err("%s: Can't find 'mpc5121-gpio' node\n", __func__); | ||
60 | return -ENODEV; | ||
61 | } | ||
62 | |||
63 | pdm360ng_gpio_base = of_iomap(np, 0); | ||
64 | of_node_put(np); | ||
65 | if (!pdm360ng_gpio_base) { | ||
66 | pr_err("%s: Can't map gpio regs.\n", __func__); | ||
67 | return -ENODEV; | ||
68 | } | ||
69 | out_be32(pdm360ng_gpio_base + 0xc, 0xffffffff); | ||
70 | setbits32(pdm360ng_gpio_base + 0x18, 0x2000); | ||
71 | setbits32(pdm360ng_gpio_base + 0x10, 0x40); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static int pdm360ng_touchscreen_notifier_call(struct notifier_block *nb, | ||
77 | unsigned long event, void *__dev) | ||
78 | { | ||
79 | struct device *dev = __dev; | ||
80 | |||
81 | if ((event == BUS_NOTIFY_ADD_DEVICE) && | ||
82 | of_device_is_compatible(dev->of_node, "ti,ads7846")) { | ||
83 | dev->platform_data = &pdm360ng_ads7846_pdata; | ||
84 | return NOTIFY_OK; | ||
85 | } | ||
86 | return NOTIFY_DONE; | ||
87 | } | ||
88 | |||
89 | static struct notifier_block pdm360ng_touchscreen_nb = { | ||
90 | .notifier_call = pdm360ng_touchscreen_notifier_call, | ||
91 | }; | ||
92 | |||
93 | static void __init pdm360ng_touchscreen_init(void) | ||
94 | { | ||
95 | if (pdm360ng_penirq_init()) | ||
96 | return; | ||
97 | |||
98 | bus_register_notifier(&spi_bus_type, &pdm360ng_touchscreen_nb); | ||
99 | } | ||
100 | #else | ||
101 | static inline void __init pdm360ng_touchscreen_init(void) | ||
102 | { | ||
103 | } | ||
104 | #endif /* CONFIG_TOUCHSCREEN_ADS7846 */ | ||
105 | |||
106 | void __init pdm360ng_init(void) | ||
107 | { | ||
108 | mpc512x_init(); | ||
109 | pdm360ng_touchscreen_init(); | ||
110 | } | ||
111 | |||
112 | static int __init pdm360ng_probe(void) | ||
113 | { | ||
114 | unsigned long root = of_get_flat_dt_root(); | ||
115 | |||
116 | return of_flat_dt_is_compatible(root, "ifm,pdm360ng"); | ||
117 | } | ||
118 | |||
119 | define_machine(pdm360ng) { | ||
120 | .name = "PDM360NG", | ||
121 | .probe = pdm360ng_probe, | ||
122 | .setup_arch = mpc512x_setup_diu, | ||
123 | .init = pdm360ng_init, | ||
124 | .init_early = mpc512x_init_diu, | ||
125 | .init_IRQ = mpc512x_init_IRQ, | ||
126 | .get_irq = ipic_get_irq, | ||
127 | .calibrate_decr = generic_calibrate_decr, | ||
128 | .restart = mpc512x_restart, | ||
129 | }; | ||
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c index b5c753db125e..80234e5921f5 100644 --- a/arch/powerpc/platforms/52xx/lite5200_pm.c +++ b/arch/powerpc/platforms/52xx/lite5200_pm.c | |||
@@ -216,9 +216,6 @@ static int lite5200_pm_enter(suspend_state_t state) | |||
216 | 216 | ||
217 | lite5200_restore_regs(); | 217 | lite5200_restore_regs(); |
218 | 218 | ||
219 | /* restart jiffies */ | ||
220 | wakeup_decrementer(); | ||
221 | |||
222 | iounmap(mbar); | 219 | iounmap(mbar); |
223 | return 0; | 220 | return 0; |
224 | } | 221 | } |
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c index 76722532bd95..568cef636275 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c | |||
@@ -171,9 +171,6 @@ int mpc52xx_pm_enter(suspend_state_t state) | |||
171 | /* restore SRAM */ | 171 | /* restore SRAM */ |
172 | memcpy(sram, saved_sram, sram_size); | 172 | memcpy(sram, saved_sram, sram_size); |
173 | 173 | ||
174 | /* restart jiffies */ | ||
175 | wakeup_decrementer(); | ||
176 | |||
177 | /* reenable interrupts in PIC */ | 174 | /* reenable interrupts in PIC */ |
178 | out_be32(&intr->main_mask, intr_main_mask); | 175 | out_be32(&intr->main_mask, intr_main_mask); |
179 | 176 | ||
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig index f49a2548c5ff..021763a32c2f 100644 --- a/arch/powerpc/platforms/83xx/Kconfig +++ b/arch/powerpc/platforms/83xx/Kconfig | |||
@@ -9,6 +9,14 @@ menuconfig PPC_83xx | |||
9 | 9 | ||
10 | if PPC_83xx | 10 | if PPC_83xx |
11 | 11 | ||
12 | config MPC830x_RDB | ||
13 | bool "Freescale MPC830x RDB" | ||
14 | select DEFAULT_UIMAGE | ||
15 | select PPC_MPC831x | ||
16 | select FSL_GTM | ||
17 | help | ||
18 | This option enables support for the MPC8308 RDB board. | ||
19 | |||
12 | config MPC831x_RDB | 20 | config MPC831x_RDB |
13 | bool "Freescale MPC831x RDB" | 21 | bool "Freescale MPC831x RDB" |
14 | select DEFAULT_UIMAGE | 22 | select DEFAULT_UIMAGE |
diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile index e139c36572ec..6e8bbbbcfdf8 100644 --- a/arch/powerpc/platforms/83xx/Makefile +++ b/arch/powerpc/platforms/83xx/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | obj-y := misc.o usb.o | 4 | obj-y := misc.o usb.o |
5 | obj-$(CONFIG_SUSPEND) += suspend.o suspend-asm.o | 5 | obj-$(CONFIG_SUSPEND) += suspend.o suspend-asm.o |
6 | obj-$(CONFIG_MCU_MPC8349EMITX) += mcu_mpc8349emitx.o | 6 | obj-$(CONFIG_MCU_MPC8349EMITX) += mcu_mpc8349emitx.o |
7 | obj-$(CONFIG_MPC830x_RDB) += mpc830x_rdb.o | ||
7 | obj-$(CONFIG_MPC831x_RDB) += mpc831x_rdb.o | 8 | obj-$(CONFIG_MPC831x_RDB) += mpc831x_rdb.o |
8 | obj-$(CONFIG_MPC832x_RDB) += mpc832x_rdb.o | 9 | obj-$(CONFIG_MPC832x_RDB) += mpc832x_rdb.o |
9 | obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o | 10 | obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o |
diff --git a/arch/powerpc/platforms/83xx/mpc830x_rdb.c b/arch/powerpc/platforms/83xx/mpc830x_rdb.c new file mode 100644 index 000000000000..ac102ee9abe8 --- /dev/null +++ b/arch/powerpc/platforms/83xx/mpc830x_rdb.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * arch/powerpc/platforms/83xx/mpc830x_rdb.c | ||
3 | * | ||
4 | * Description: MPC830x RDB board specific routines. | ||
5 | * This file is based on mpc831x_rdb.c | ||
6 | * | ||
7 | * Copyright (C) Freescale Semiconductor, Inc. 2009. All rights reserved. | ||
8 | * Copyright (C) 2010. Ilya Yanok, Emcraft Systems, yanok@emcraft.com | ||
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 | |||
16 | #include <linux/pci.h> | ||
17 | #include <linux/of_platform.h> | ||
18 | #include <asm/time.h> | ||
19 | #include <asm/ipic.h> | ||
20 | #include <asm/udbg.h> | ||
21 | #include <sysdev/fsl_pci.h> | ||
22 | #include <sysdev/fsl_soc.h> | ||
23 | #include "mpc83xx.h" | ||
24 | |||
25 | /* | ||
26 | * Setup the architecture | ||
27 | */ | ||
28 | static void __init mpc830x_rdb_setup_arch(void) | ||
29 | { | ||
30 | #ifdef CONFIG_PCI | ||
31 | struct device_node *np; | ||
32 | #endif | ||
33 | |||
34 | if (ppc_md.progress) | ||
35 | ppc_md.progress("mpc830x_rdb_setup_arch()", 0); | ||
36 | |||
37 | #ifdef CONFIG_PCI | ||
38 | for_each_compatible_node(np, "pci", "fsl,mpc8308-pcie") | ||
39 | mpc83xx_add_bridge(np); | ||
40 | #endif | ||
41 | mpc831x_usb_cfg(); | ||
42 | } | ||
43 | |||
44 | static void __init mpc830x_rdb_init_IRQ(void) | ||
45 | { | ||
46 | struct device_node *np; | ||
47 | |||
48 | np = of_find_node_by_type(NULL, "ipic"); | ||
49 | if (!np) | ||
50 | return; | ||
51 | |||
52 | ipic_init(np, 0); | ||
53 | |||
54 | /* Initialize the default interrupt mapping priorities, | ||
55 | * in case the boot rom changed something on us. | ||
56 | */ | ||
57 | ipic_set_default_priority(); | ||
58 | } | ||
59 | |||
60 | /* | ||
61 | * Called very early, MMU is off, device-tree isn't unflattened | ||
62 | */ | ||
63 | static int __init mpc830x_rdb_probe(void) | ||
64 | { | ||
65 | unsigned long root = of_get_flat_dt_root(); | ||
66 | |||
67 | return of_flat_dt_is_compatible(root, "MPC8308RDB") || | ||
68 | of_flat_dt_is_compatible(root, "fsl,mpc8308rdb"); | ||
69 | } | ||
70 | |||
71 | static struct of_device_id __initdata of_bus_ids[] = { | ||
72 | { .compatible = "simple-bus" }, | ||
73 | { .compatible = "gianfar" }, | ||
74 | {}, | ||
75 | }; | ||
76 | |||
77 | static int __init declare_of_platform_devices(void) | ||
78 | { | ||
79 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
80 | return 0; | ||
81 | } | ||
82 | machine_device_initcall(mpc830x_rdb, declare_of_platform_devices); | ||
83 | |||
84 | define_machine(mpc830x_rdb) { | ||
85 | .name = "MPC830x RDB", | ||
86 | .probe = mpc830x_rdb_probe, | ||
87 | .setup_arch = mpc830x_rdb_setup_arch, | ||
88 | .init_IRQ = mpc830x_rdb_init_IRQ, | ||
89 | .get_irq = ipic_get_irq, | ||
90 | .restart = mpc83xx_restart, | ||
91 | .time_init = mpc83xx_time_init, | ||
92 | .calibrate_decr = generic_calibrate_decr, | ||
93 | .progress = udbg_progress, | ||
94 | }; | ||
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index 3a2ade2e443f..bea1f5905ad4 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig | |||
@@ -65,6 +65,14 @@ config MPC85xx_RDB | |||
65 | help | 65 | help |
66 | This option enables support for the MPC85xx RDB (P2020 RDB) board | 66 | This option enables support for the MPC85xx RDB (P2020 RDB) board |
67 | 67 | ||
68 | config P1022_DS | ||
69 | bool "Freescale P1022 DS" | ||
70 | select DEFAULT_UIMAGE | ||
71 | select CONFIG_PHYS_64BIT # The DTS has 36-bit addresses | ||
72 | select SWIOTLB | ||
73 | help | ||
74 | This option enables support for the Freescale P1022DS reference board. | ||
75 | |||
68 | config SOCRATES | 76 | config SOCRATES |
69 | bool "Socrates" | 77 | bool "Socrates" |
70 | select DEFAULT_UIMAGE | 78 | select DEFAULT_UIMAGE |
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 387c128f2c8c..a2ec3f8f4d06 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile | |||
@@ -10,6 +10,7 @@ obj-$(CONFIG_MPC8536_DS) += mpc8536_ds.o | |||
10 | obj-$(CONFIG_MPC85xx_DS) += mpc85xx_ds.o | 10 | obj-$(CONFIG_MPC85xx_DS) += mpc85xx_ds.o |
11 | obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o | 11 | obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o |
12 | obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o | 12 | obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o |
13 | obj-$(CONFIG_P1022_DS) += p1022_ds.o | ||
13 | obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o | 14 | obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o |
14 | obj-$(CONFIG_STX_GP3) += stx_gp3.o | 15 | obj-$(CONFIG_STX_GP3) += stx_gp3.o |
15 | obj-$(CONFIG_TQM85xx) += tqm85xx.o | 16 | obj-$(CONFIG_TQM85xx) += tqm85xx.o |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 494513682d70..da64be19d099 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c | |||
@@ -158,51 +158,108 @@ static int mpc8568_mds_phy_fixups(struct phy_device *phydev) | |||
158 | extern void __init mpc85xx_smp_init(void); | 158 | extern void __init mpc85xx_smp_init(void); |
159 | #endif | 159 | #endif |
160 | 160 | ||
161 | static void __init mpc85xx_mds_setup_arch(void) | 161 | #ifdef CONFIG_QUICC_ENGINE |
162 | static struct of_device_id mpc85xx_qe_ids[] __initdata = { | ||
163 | { .type = "qe", }, | ||
164 | { .compatible = "fsl,qe", }, | ||
165 | { }, | ||
166 | }; | ||
167 | |||
168 | static void __init mpc85xx_publish_qe_devices(void) | ||
162 | { | 169 | { |
163 | struct device_node *np; | 170 | struct device_node *np; |
164 | static u8 __iomem *bcsr_regs = NULL; | ||
165 | #ifdef CONFIG_PCI | ||
166 | struct pci_controller *hose; | ||
167 | #endif | ||
168 | dma_addr_t max = 0xffffffff; | ||
169 | 171 | ||
170 | if (ppc_md.progress) | 172 | np = of_find_compatible_node(NULL, NULL, "fsl,qe"); |
171 | ppc_md.progress("mpc85xx_mds_setup_arch()", 0); | 173 | if (!of_device_is_available(np)) { |
174 | of_node_put(np); | ||
175 | return; | ||
176 | } | ||
177 | |||
178 | of_platform_bus_probe(NULL, mpc85xx_qe_ids, NULL); | ||
179 | } | ||
180 | |||
181 | static void __init mpc85xx_mds_reset_ucc_phys(void) | ||
182 | { | ||
183 | struct device_node *np; | ||
184 | static u8 __iomem *bcsr_regs; | ||
172 | 185 | ||
173 | /* Map BCSR area */ | 186 | /* Map BCSR area */ |
174 | np = of_find_node_by_name(NULL, "bcsr"); | 187 | np = of_find_node_by_name(NULL, "bcsr"); |
175 | if (np != NULL) { | 188 | if (!np) |
176 | struct resource res; | 189 | return; |
177 | 190 | ||
178 | of_address_to_resource(np, 0, &res); | 191 | bcsr_regs = of_iomap(np, 0); |
179 | bcsr_regs = ioremap(res.start, res.end - res.start +1); | 192 | of_node_put(np); |
180 | of_node_put(np); | 193 | if (!bcsr_regs) |
181 | } | 194 | return; |
182 | 195 | ||
183 | #ifdef CONFIG_PCI | 196 | if (machine_is(mpc8568_mds)) { |
184 | for_each_node_by_type(np, "pci") { | 197 | #define BCSR_UCC1_GETH_EN (0x1 << 7) |
185 | if (of_device_is_compatible(np, "fsl,mpc8540-pci") || | 198 | #define BCSR_UCC2_GETH_EN (0x1 << 7) |
186 | of_device_is_compatible(np, "fsl,mpc8548-pcie")) { | 199 | #define BCSR_UCC1_MODE_MSK (0x3 << 4) |
187 | struct resource rsrc; | 200 | #define BCSR_UCC2_MODE_MSK (0x3 << 0) |
188 | of_address_to_resource(np, 0, &rsrc); | ||
189 | if ((rsrc.start & 0xfffff) == 0x8000) | ||
190 | fsl_add_bridge(np, 1); | ||
191 | else | ||
192 | fsl_add_bridge(np, 0); | ||
193 | 201 | ||
194 | hose = pci_find_hose_for_OF_device(np); | 202 | /* Turn off UCC1 & UCC2 */ |
195 | max = min(max, hose->dma_window_base_cur + | 203 | clrbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN); |
196 | hose->dma_window_size); | 204 | clrbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN); |
205 | |||
206 | /* Mode is RGMII, all bits clear */ | ||
207 | clrbits8(&bcsr_regs[11], BCSR_UCC1_MODE_MSK | | ||
208 | BCSR_UCC2_MODE_MSK); | ||
209 | |||
210 | /* Turn UCC1 & UCC2 on */ | ||
211 | setbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN); | ||
212 | setbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN); | ||
213 | } else if (machine_is(mpc8569_mds)) { | ||
214 | #define BCSR7_UCC12_GETHnRST (0x1 << 2) | ||
215 | #define BCSR8_UEM_MARVELL_RST (0x1 << 1) | ||
216 | #define BCSR_UCC_RGMII (0x1 << 6) | ||
217 | #define BCSR_UCC_RTBI (0x1 << 5) | ||
218 | /* | ||
219 | * U-Boot mangles interrupt polarity for Marvell PHYs, | ||
220 | * so reset built-in and UEM Marvell PHYs, this puts | ||
221 | * the PHYs into their normal state. | ||
222 | */ | ||
223 | clrbits8(&bcsr_regs[7], BCSR7_UCC12_GETHnRST); | ||
224 | setbits8(&bcsr_regs[8], BCSR8_UEM_MARVELL_RST); | ||
225 | |||
226 | setbits8(&bcsr_regs[7], BCSR7_UCC12_GETHnRST); | ||
227 | clrbits8(&bcsr_regs[8], BCSR8_UEM_MARVELL_RST); | ||
228 | |||
229 | for (np = NULL; (np = of_find_compatible_node(np, | ||
230 | "network", | ||
231 | "ucc_geth")) != NULL;) { | ||
232 | const unsigned int *prop; | ||
233 | int ucc_num; | ||
234 | |||
235 | prop = of_get_property(np, "cell-index", NULL); | ||
236 | if (prop == NULL) | ||
237 | continue; | ||
238 | |||
239 | ucc_num = *prop - 1; | ||
240 | |||
241 | prop = of_get_property(np, "phy-connection-type", NULL); | ||
242 | if (prop == NULL) | ||
243 | continue; | ||
244 | |||
245 | if (strcmp("rtbi", (const char *)prop) == 0) | ||
246 | clrsetbits_8(&bcsr_regs[7 + ucc_num], | ||
247 | BCSR_UCC_RGMII, BCSR_UCC_RTBI); | ||
197 | } | 248 | } |
249 | } else if (machine_is(p1021_mds)) { | ||
250 | #define BCSR11_ENET_MICRST (0x1 << 5) | ||
251 | /* Reset Micrel PHY */ | ||
252 | clrbits8(&bcsr_regs[11], BCSR11_ENET_MICRST); | ||
253 | setbits8(&bcsr_regs[11], BCSR11_ENET_MICRST); | ||
198 | } | 254 | } |
199 | #endif | ||
200 | 255 | ||
201 | #ifdef CONFIG_SMP | 256 | iounmap(bcsr_regs); |
202 | mpc85xx_smp_init(); | 257 | } |
203 | #endif | 258 | |
259 | static void __init mpc85xx_mds_qe_init(void) | ||
260 | { | ||
261 | struct device_node *np; | ||
204 | 262 | ||
205 | #ifdef CONFIG_QUICC_ENGINE | ||
206 | np = of_find_compatible_node(NULL, NULL, "fsl,qe"); | 263 | np = of_find_compatible_node(NULL, NULL, "fsl,qe"); |
207 | if (!np) { | 264 | if (!np) { |
208 | np = of_find_node_by_name(NULL, "qe"); | 265 | np = of_find_node_by_name(NULL, "qe"); |
@@ -210,6 +267,11 @@ static void __init mpc85xx_mds_setup_arch(void) | |||
210 | return; | 267 | return; |
211 | } | 268 | } |
212 | 269 | ||
270 | if (!of_device_is_available(np)) { | ||
271 | of_node_put(np); | ||
272 | return; | ||
273 | } | ||
274 | |||
213 | qe_reset(); | 275 | qe_reset(); |
214 | of_node_put(np); | 276 | of_node_put(np); |
215 | 277 | ||
@@ -224,70 +286,7 @@ static void __init mpc85xx_mds_setup_arch(void) | |||
224 | par_io_of_config(ucc); | 286 | par_io_of_config(ucc); |
225 | } | 287 | } |
226 | 288 | ||
227 | if (bcsr_regs) { | 289 | mpc85xx_mds_reset_ucc_phys(); |
228 | if (machine_is(mpc8568_mds)) { | ||
229 | #define BCSR_UCC1_GETH_EN (0x1 << 7) | ||
230 | #define BCSR_UCC2_GETH_EN (0x1 << 7) | ||
231 | #define BCSR_UCC1_MODE_MSK (0x3 << 4) | ||
232 | #define BCSR_UCC2_MODE_MSK (0x3 << 0) | ||
233 | |||
234 | /* Turn off UCC1 & UCC2 */ | ||
235 | clrbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN); | ||
236 | clrbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN); | ||
237 | |||
238 | /* Mode is RGMII, all bits clear */ | ||
239 | clrbits8(&bcsr_regs[11], BCSR_UCC1_MODE_MSK | | ||
240 | BCSR_UCC2_MODE_MSK); | ||
241 | |||
242 | /* Turn UCC1 & UCC2 on */ | ||
243 | setbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN); | ||
244 | setbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN); | ||
245 | } else if (machine_is(mpc8569_mds)) { | ||
246 | #define BCSR7_UCC12_GETHnRST (0x1 << 2) | ||
247 | #define BCSR8_UEM_MARVELL_RST (0x1 << 1) | ||
248 | #define BCSR_UCC_RGMII (0x1 << 6) | ||
249 | #define BCSR_UCC_RTBI (0x1 << 5) | ||
250 | /* | ||
251 | * U-Boot mangles interrupt polarity for Marvell PHYs, | ||
252 | * so reset built-in and UEM Marvell PHYs, this puts | ||
253 | * the PHYs into their normal state. | ||
254 | */ | ||
255 | clrbits8(&bcsr_regs[7], BCSR7_UCC12_GETHnRST); | ||
256 | setbits8(&bcsr_regs[8], BCSR8_UEM_MARVELL_RST); | ||
257 | |||
258 | setbits8(&bcsr_regs[7], BCSR7_UCC12_GETHnRST); | ||
259 | clrbits8(&bcsr_regs[8], BCSR8_UEM_MARVELL_RST); | ||
260 | |||
261 | for (np = NULL; (np = of_find_compatible_node(np, | ||
262 | "network", | ||
263 | "ucc_geth")) != NULL;) { | ||
264 | const unsigned int *prop; | ||
265 | int ucc_num; | ||
266 | |||
267 | prop = of_get_property(np, "cell-index", NULL); | ||
268 | if (prop == NULL) | ||
269 | continue; | ||
270 | |||
271 | ucc_num = *prop - 1; | ||
272 | |||
273 | prop = of_get_property(np, "phy-connection-type", NULL); | ||
274 | if (prop == NULL) | ||
275 | continue; | ||
276 | |||
277 | if (strcmp("rtbi", (const char *)prop) == 0) | ||
278 | clrsetbits_8(&bcsr_regs[7 + ucc_num], | ||
279 | BCSR_UCC_RGMII, BCSR_UCC_RTBI); | ||
280 | } | ||
281 | |||
282 | } else if (machine_is(p1021_mds)) { | ||
283 | #define BCSR11_ENET_MICRST (0x1 << 5) | ||
284 | /* Reset Micrel PHY */ | ||
285 | clrbits8(&bcsr_regs[11], BCSR11_ENET_MICRST); | ||
286 | setbits8(&bcsr_regs[11], BCSR11_ENET_MICRST); | ||
287 | } | ||
288 | |||
289 | iounmap(bcsr_regs); | ||
290 | } | ||
291 | 290 | ||
292 | if (machine_is(p1021_mds)) { | 291 | if (machine_is(p1021_mds)) { |
293 | #define MPC85xx_PMUXCR_OFFSET 0x60 | 292 | #define MPC85xx_PMUXCR_OFFSET 0x60 |
@@ -322,8 +321,72 @@ static void __init mpc85xx_mds_setup_arch(void) | |||
322 | } | 321 | } |
323 | 322 | ||
324 | } | 323 | } |
324 | } | ||
325 | |||
326 | static void __init mpc85xx_mds_qeic_init(void) | ||
327 | { | ||
328 | struct device_node *np; | ||
329 | |||
330 | np = of_find_compatible_node(NULL, NULL, "fsl,qe"); | ||
331 | if (!of_device_is_available(np)) { | ||
332 | of_node_put(np); | ||
333 | return; | ||
334 | } | ||
335 | |||
336 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
337 | if (!np) { | ||
338 | np = of_find_node_by_type(NULL, "qeic"); | ||
339 | if (!np) | ||
340 | return; | ||
341 | } | ||
342 | |||
343 | if (machine_is(p1021_mds)) | ||
344 | qe_ic_init(np, 0, qe_ic_cascade_low_mpic, | ||
345 | qe_ic_cascade_high_mpic); | ||
346 | else | ||
347 | qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL); | ||
348 | of_node_put(np); | ||
349 | } | ||
350 | #else | ||
351 | static void __init mpc85xx_publish_qe_devices(void) { } | ||
352 | static void __init mpc85xx_mds_qe_init(void) { } | ||
353 | static void __init mpc85xx_mds_qeic_init(void) { } | ||
325 | #endif /* CONFIG_QUICC_ENGINE */ | 354 | #endif /* CONFIG_QUICC_ENGINE */ |
326 | 355 | ||
356 | static void __init mpc85xx_mds_setup_arch(void) | ||
357 | { | ||
358 | #ifdef CONFIG_PCI | ||
359 | struct pci_controller *hose; | ||
360 | #endif | ||
361 | dma_addr_t max = 0xffffffff; | ||
362 | |||
363 | if (ppc_md.progress) | ||
364 | ppc_md.progress("mpc85xx_mds_setup_arch()", 0); | ||
365 | |||
366 | #ifdef CONFIG_PCI | ||
367 | for_each_node_by_type(np, "pci") { | ||
368 | if (of_device_is_compatible(np, "fsl,mpc8540-pci") || | ||
369 | of_device_is_compatible(np, "fsl,mpc8548-pcie")) { | ||
370 | struct resource rsrc; | ||
371 | of_address_to_resource(np, 0, &rsrc); | ||
372 | if ((rsrc.start & 0xfffff) == 0x8000) | ||
373 | fsl_add_bridge(np, 1); | ||
374 | else | ||
375 | fsl_add_bridge(np, 0); | ||
376 | |||
377 | hose = pci_find_hose_for_OF_device(np); | ||
378 | max = min(max, hose->dma_window_base_cur + | ||
379 | hose->dma_window_size); | ||
380 | } | ||
381 | } | ||
382 | #endif | ||
383 | |||
384 | #ifdef CONFIG_SMP | ||
385 | mpc85xx_smp_init(); | ||
386 | #endif | ||
387 | |||
388 | mpc85xx_mds_qe_init(); | ||
389 | |||
327 | #ifdef CONFIG_SWIOTLB | 390 | #ifdef CONFIG_SWIOTLB |
328 | if (memblock_end_of_DRAM() > max) { | 391 | if (memblock_end_of_DRAM() > max) { |
329 | ppc_swiotlb_enable = 1; | 392 | ppc_swiotlb_enable = 1; |
@@ -369,8 +432,6 @@ static struct of_device_id mpc85xx_ids[] = { | |||
369 | { .type = "soc", }, | 432 | { .type = "soc", }, |
370 | { .compatible = "soc", }, | 433 | { .compatible = "soc", }, |
371 | { .compatible = "simple-bus", }, | 434 | { .compatible = "simple-bus", }, |
372 | { .type = "qe", }, | ||
373 | { .compatible = "fsl,qe", }, | ||
374 | { .compatible = "gianfar", }, | 435 | { .compatible = "gianfar", }, |
375 | { .compatible = "fsl,rapidio-delta", }, | 436 | { .compatible = "fsl,rapidio-delta", }, |
376 | { .compatible = "fsl,mpc8548-guts", }, | 437 | { .compatible = "fsl,mpc8548-guts", }, |
@@ -382,8 +443,6 @@ static struct of_device_id p1021_ids[] = { | |||
382 | { .type = "soc", }, | 443 | { .type = "soc", }, |
383 | { .compatible = "soc", }, | 444 | { .compatible = "soc", }, |
384 | { .compatible = "simple-bus", }, | 445 | { .compatible = "simple-bus", }, |
385 | { .type = "qe", }, | ||
386 | { .compatible = "fsl,qe", }, | ||
387 | { .compatible = "gianfar", }, | 446 | { .compatible = "gianfar", }, |
388 | {}, | 447 | {}, |
389 | }; | 448 | }; |
@@ -395,16 +454,16 @@ static int __init mpc85xx_publish_devices(void) | |||
395 | if (machine_is(mpc8569_mds)) | 454 | if (machine_is(mpc8569_mds)) |
396 | simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio"); | 455 | simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio"); |
397 | 456 | ||
398 | /* Publish the QE devices */ | ||
399 | of_platform_bus_probe(NULL, mpc85xx_ids, NULL); | 457 | of_platform_bus_probe(NULL, mpc85xx_ids, NULL); |
458 | mpc85xx_publish_qe_devices(); | ||
400 | 459 | ||
401 | return 0; | 460 | return 0; |
402 | } | 461 | } |
403 | 462 | ||
404 | static int __init p1021_publish_devices(void) | 463 | static int __init p1021_publish_devices(void) |
405 | { | 464 | { |
406 | /* Publish the QE devices */ | ||
407 | of_platform_bus_probe(NULL, p1021_ids, NULL); | 465 | of_platform_bus_probe(NULL, p1021_ids, NULL); |
466 | mpc85xx_publish_qe_devices(); | ||
408 | 467 | ||
409 | return 0; | 468 | return 0; |
410 | } | 469 | } |
@@ -441,21 +500,7 @@ static void __init mpc85xx_mds_pic_init(void) | |||
441 | of_node_put(np); | 500 | of_node_put(np); |
442 | 501 | ||
443 | mpic_init(mpic); | 502 | mpic_init(mpic); |
444 | 503 | mpc85xx_mds_qeic_init(); | |
445 | #ifdef CONFIG_QUICC_ENGINE | ||
446 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
447 | if (!np) { | ||
448 | np = of_find_node_by_type(NULL, "qeic"); | ||
449 | if (!np) | ||
450 | return; | ||
451 | } | ||
452 | if (machine_is(p1021_mds)) | ||
453 | qe_ic_init(np, 0, qe_ic_cascade_low_mpic, | ||
454 | qe_ic_cascade_high_mpic); | ||
455 | else | ||
456 | qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL); | ||
457 | of_node_put(np); | ||
458 | #endif /* CONFIG_QUICC_ENGINE */ | ||
459 | } | 504 | } |
460 | 505 | ||
461 | static int __init mpc85xx_mds_probe(void) | 506 | static int __init mpc85xx_mds_probe(void) |
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c new file mode 100644 index 000000000000..e1467c937450 --- /dev/null +++ b/arch/powerpc/platforms/85xx/p1022_ds.c | |||
@@ -0,0 +1,148 @@ | |||
1 | /* | ||
2 | * P1022DS board specific routines | ||
3 | * | ||
4 | * Authors: Travis Wheatley <travis.wheatley@freescale.com> | ||
5 | * Dave Liu <daveliu@freescale.com> | ||
6 | * Timur Tabi <timur@freescale.com> | ||
7 | * | ||
8 | * Copyright 2010 Freescale Semiconductor, Inc. | ||
9 | * | ||
10 | * This file is taken from the Freescale P1022DS BSP, with modifications: | ||
11 | * 1) No DIU support (pending rewrite of DIU code) | ||
12 | * 2) No AMP support | ||
13 | * 3) No PCI endpoint support | ||
14 | * | ||
15 | * This file is licensed under the terms of the GNU General Public License | ||
16 | * version 2. This program is licensed "as is" without any warranty of any | ||
17 | * kind, whether express or implied. | ||
18 | */ | ||
19 | |||
20 | #include <linux/pci.h> | ||
21 | #include <linux/of_platform.h> | ||
22 | #include <linux/lmb.h> | ||
23 | |||
24 | #include <asm/mpic.h> | ||
25 | #include <asm/swiotlb.h> | ||
26 | |||
27 | #include <sysdev/fsl_soc.h> | ||
28 | #include <sysdev/fsl_pci.h> | ||
29 | |||
30 | void __init p1022_ds_pic_init(void) | ||
31 | { | ||
32 | struct mpic *mpic; | ||
33 | struct resource r; | ||
34 | struct device_node *np; | ||
35 | |||
36 | np = of_find_node_by_type(NULL, "open-pic"); | ||
37 | if (!np) { | ||
38 | pr_err("Could not find open-pic node\n"); | ||
39 | return; | ||
40 | } | ||
41 | |||
42 | if (of_address_to_resource(np, 0, &r)) { | ||
43 | pr_err("Failed to map mpic register space\n"); | ||
44 | of_node_put(np); | ||
45 | return; | ||
46 | } | ||
47 | |||
48 | mpic = mpic_alloc(np, r.start, | ||
49 | MPIC_PRIMARY | MPIC_WANTS_RESET | | ||
50 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | | ||
51 | MPIC_SINGLE_DEST_CPU, | ||
52 | 0, 256, " OpenPIC "); | ||
53 | |||
54 | BUG_ON(mpic == NULL); | ||
55 | of_node_put(np); | ||
56 | |||
57 | mpic_init(mpic); | ||
58 | } | ||
59 | |||
60 | #ifdef CONFIG_SMP | ||
61 | void __init mpc85xx_smp_init(void); | ||
62 | #endif | ||
63 | |||
64 | /* | ||
65 | * Setup the architecture | ||
66 | */ | ||
67 | static void __init p1022_ds_setup_arch(void) | ||
68 | { | ||
69 | #ifdef CONFIG_PCI | ||
70 | struct device_node *np; | ||
71 | #endif | ||
72 | dma_addr_t max = 0xffffffff; | ||
73 | |||
74 | if (ppc_md.progress) | ||
75 | ppc_md.progress("p1022_ds_setup_arch()", 0); | ||
76 | |||
77 | #ifdef CONFIG_PCI | ||
78 | for_each_compatible_node(np, "pci", "fsl,p1022-pcie") { | ||
79 | struct resource rsrc; | ||
80 | struct pci_controller *hose; | ||
81 | |||
82 | of_address_to_resource(np, 0, &rsrc); | ||
83 | |||
84 | if ((rsrc.start & 0xfffff) == 0x8000) | ||
85 | fsl_add_bridge(np, 1); | ||
86 | else | ||
87 | fsl_add_bridge(np, 0); | ||
88 | |||
89 | hose = pci_find_hose_for_OF_device(np); | ||
90 | max = min(max, hose->dma_window_base_cur + | ||
91 | hose->dma_window_size); | ||
92 | } | ||
93 | #endif | ||
94 | |||
95 | #ifdef CONFIG_SMP | ||
96 | mpc85xx_smp_init(); | ||
97 | #endif | ||
98 | |||
99 | #ifdef CONFIG_SWIOTLB | ||
100 | if (lmb_end_of_DRAM() > max) { | ||
101 | ppc_swiotlb_enable = 1; | ||
102 | set_pci_dma_ops(&swiotlb_dma_ops); | ||
103 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; | ||
104 | } | ||
105 | #endif | ||
106 | |||
107 | pr_info("Freescale P1022 DS reference board\n"); | ||
108 | } | ||
109 | |||
110 | static struct of_device_id __initdata p1022_ds_ids[] = { | ||
111 | { .type = "soc", }, | ||
112 | { .compatible = "soc", }, | ||
113 | { .compatible = "simple-bus", }, | ||
114 | { .compatible = "gianfar", }, | ||
115 | {}, | ||
116 | }; | ||
117 | |||
118 | static int __init p1022_ds_publish_devices(void) | ||
119 | { | ||
120 | return of_platform_bus_probe(NULL, p1022_ds_ids, NULL); | ||
121 | } | ||
122 | machine_device_initcall(p1022_ds, p1022_ds_publish_devices); | ||
123 | |||
124 | machine_arch_initcall(p1022_ds, swiotlb_setup_bus_notifier); | ||
125 | |||
126 | /* | ||
127 | * Called very early, device-tree isn't unflattened | ||
128 | */ | ||
129 | static int __init p1022_ds_probe(void) | ||
130 | { | ||
131 | unsigned long root = of_get_flat_dt_root(); | ||
132 | |||
133 | return of_flat_dt_is_compatible(root, "fsl,p1022ds"); | ||
134 | } | ||
135 | |||
136 | define_machine(p1022_ds) { | ||
137 | .name = "P1022 DS", | ||
138 | .probe = p1022_ds_probe, | ||
139 | .setup_arch = p1022_ds_setup_arch, | ||
140 | .init_IRQ = p1022_ds_pic_init, | ||
141 | #ifdef CONFIG_PCI | ||
142 | .pcibios_fixup_bus = fsl_pcibios_fixup_bus, | ||
143 | #endif | ||
144 | .get_irq = mpic_get_irq, | ||
145 | .restart = fsl_rstcr_restart, | ||
146 | .calibrate_decr = generic_calibrate_decr, | ||
147 | .progress = udbg_progress, | ||
148 | }; | ||
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index a15f582300d8..a6b106557be4 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
18 | #include <linux/kexec.h> | ||
18 | 19 | ||
19 | #include <asm/machdep.h> | 20 | #include <asm/machdep.h> |
20 | #include <asm/pgtable.h> | 21 | #include <asm/pgtable.h> |
@@ -24,6 +25,7 @@ | |||
24 | #include <asm/dbell.h> | 25 | #include <asm/dbell.h> |
25 | 26 | ||
26 | #include <sysdev/fsl_soc.h> | 27 | #include <sysdev/fsl_soc.h> |
28 | #include <sysdev/mpic.h> | ||
27 | 29 | ||
28 | extern void __early_start(void); | 30 | extern void __early_start(void); |
29 | 31 | ||
@@ -99,12 +101,70 @@ static void __init | |||
99 | smp_85xx_setup_cpu(int cpu_nr) | 101 | smp_85xx_setup_cpu(int cpu_nr) |
100 | { | 102 | { |
101 | mpic_setup_this_cpu(); | 103 | mpic_setup_this_cpu(); |
104 | if (cpu_has_feature(CPU_FTR_DBELL)) | ||
105 | doorbell_setup_this_cpu(); | ||
102 | } | 106 | } |
103 | 107 | ||
104 | struct smp_ops_t smp_85xx_ops = { | 108 | struct smp_ops_t smp_85xx_ops = { |
105 | .kick_cpu = smp_85xx_kick_cpu, | 109 | .kick_cpu = smp_85xx_kick_cpu, |
110 | #ifdef CONFIG_KEXEC | ||
111 | .give_timebase = smp_generic_give_timebase, | ||
112 | .take_timebase = smp_generic_take_timebase, | ||
113 | #endif | ||
106 | }; | 114 | }; |
107 | 115 | ||
116 | #ifdef CONFIG_KEXEC | ||
117 | static int kexec_down_cpus = 0; | ||
118 | |||
119 | void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary) | ||
120 | { | ||
121 | mpic_teardown_this_cpu(1); | ||
122 | |||
123 | /* When crashing, this gets called on all CPU's we only | ||
124 | * take down the non-boot cpus */ | ||
125 | if (smp_processor_id() != boot_cpuid) | ||
126 | { | ||
127 | local_irq_disable(); | ||
128 | kexec_down_cpus++; | ||
129 | |||
130 | while (1); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | static void mpc85xx_smp_kexec_down(void *arg) | ||
135 | { | ||
136 | if (ppc_md.kexec_cpu_down) | ||
137 | ppc_md.kexec_cpu_down(0,1); | ||
138 | } | ||
139 | |||
140 | static void mpc85xx_smp_machine_kexec(struct kimage *image) | ||
141 | { | ||
142 | int timeout = 2000; | ||
143 | int i; | ||
144 | |||
145 | set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid)); | ||
146 | |||
147 | smp_call_function(mpc85xx_smp_kexec_down, NULL, 0); | ||
148 | |||
149 | while ( (kexec_down_cpus != (num_online_cpus() - 1)) && | ||
150 | ( timeout > 0 ) ) | ||
151 | { | ||
152 | timeout--; | ||
153 | } | ||
154 | |||
155 | if ( !timeout ) | ||
156 | printk(KERN_ERR "Unable to bring down secondary cpu(s)"); | ||
157 | |||
158 | for (i = 0; i < num_present_cpus(); i++) | ||
159 | { | ||
160 | if ( i == smp_processor_id() ) continue; | ||
161 | mpic_reset_core(i); | ||
162 | } | ||
163 | |||
164 | default_machine_kexec(image); | ||
165 | } | ||
166 | #endif /* CONFIG_KEXEC */ | ||
167 | |||
108 | void __init mpc85xx_smp_init(void) | 168 | void __init mpc85xx_smp_init(void) |
109 | { | 169 | { |
110 | struct device_node *np; | 170 | struct device_node *np; |
@@ -117,9 +177,14 @@ void __init mpc85xx_smp_init(void) | |||
117 | } | 177 | } |
118 | 178 | ||
119 | if (cpu_has_feature(CPU_FTR_DBELL)) | 179 | if (cpu_has_feature(CPU_FTR_DBELL)) |
120 | smp_85xx_ops.message_pass = smp_dbell_message_pass; | 180 | smp_85xx_ops.message_pass = doorbell_message_pass; |
121 | 181 | ||
122 | BUG_ON(!smp_85xx_ops.message_pass); | 182 | BUG_ON(!smp_85xx_ops.message_pass); |
123 | 183 | ||
124 | smp_ops = &smp_85xx_ops; | 184 | smp_ops = &smp_85xx_ops; |
185 | |||
186 | #ifdef CONFIG_KEXEC | ||
187 | ppc_md.kexec_cpu_down = mpc85xx_smp_kexec_cpu_down; | ||
188 | ppc_md.machine_kexec = mpc85xx_smp_machine_kexec; | ||
189 | #endif | ||
125 | } | 190 | } |
diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c index 5b0ab9966e90..8f29bbce5360 100644 --- a/arch/powerpc/platforms/85xx/tqm85xx.c +++ b/arch/powerpc/platforms/85xx/tqm85xx.c | |||
@@ -151,6 +151,27 @@ static void tqm85xx_show_cpuinfo(struct seq_file *m) | |||
151 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); | 151 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); |
152 | } | 152 | } |
153 | 153 | ||
154 | static void __init tqm85xx_ti1520_fixup(struct pci_dev *pdev) | ||
155 | { | ||
156 | unsigned int val; | ||
157 | |||
158 | /* Do not do the fixup on other platforms! */ | ||
159 | if (!machine_is(tqm85xx)) | ||
160 | return; | ||
161 | |||
162 | dev_info(&pdev->dev, "Using TI 1520 fixup on TQM85xx\n"); | ||
163 | |||
164 | /* | ||
165 | * Enable P2CCLK bit in system control register | ||
166 | * to enable CLOCK output to power chip | ||
167 | */ | ||
168 | pci_read_config_dword(pdev, 0x80, &val); | ||
169 | pci_write_config_dword(pdev, 0x80, val | (1 << 27)); | ||
170 | |||
171 | } | ||
172 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1520, | ||
173 | tqm85xx_ti1520_fixup); | ||
174 | |||
154 | static struct of_device_id __initdata of_bus_ids[] = { | 175 | static struct of_device_id __initdata of_bus_ids[] = { |
155 | { .compatible = "simple-bus", }, | 176 | { .compatible = "simple-bus", }, |
156 | { .compatible = "gianfar", }, | 177 | { .compatible = "gianfar", }, |
diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig index 48a920a98e7b..dd35ce081cff 100644 --- a/arch/powerpc/platforms/8xx/Kconfig +++ b/arch/powerpc/platforms/8xx/Kconfig | |||
@@ -55,6 +55,12 @@ config PPC_MGSUVD | |||
55 | help | 55 | help |
56 | This enables support for the Keymile MGSUVD board. | 56 | This enables support for the Keymile MGSUVD board. |
57 | 57 | ||
58 | config TQM8XX | ||
59 | bool "TQM8XX" | ||
60 | select CPM1 | ||
61 | help | ||
62 | support for the mpc8xx based boards from TQM. | ||
63 | |||
58 | endchoice | 64 | endchoice |
59 | 65 | ||
60 | menu "Freescale Ethernet driver platform-specific options" | 66 | menu "Freescale Ethernet driver platform-specific options" |
diff --git a/arch/powerpc/platforms/8xx/Makefile b/arch/powerpc/platforms/8xx/Makefile index bdbfd7496018..a491fe6b94fc 100644 --- a/arch/powerpc/platforms/8xx/Makefile +++ b/arch/powerpc/platforms/8xx/Makefile | |||
@@ -7,3 +7,4 @@ obj-$(CONFIG_MPC86XADS) += mpc86xads_setup.o | |||
7 | obj-$(CONFIG_PPC_EP88XC) += ep88xc.o | 7 | obj-$(CONFIG_PPC_EP88XC) += ep88xc.o |
8 | obj-$(CONFIG_PPC_ADDER875) += adder875.o | 8 | obj-$(CONFIG_PPC_ADDER875) += adder875.o |
9 | obj-$(CONFIG_PPC_MGSUVD) += mgsuvd.o | 9 | obj-$(CONFIG_PPC_MGSUVD) += mgsuvd.o |
10 | obj-$(CONFIG_TQM8XX) += tqm8xx_setup.o | ||
diff --git a/arch/powerpc/platforms/8xx/tqm8xx_setup.c b/arch/powerpc/platforms/8xx/tqm8xx_setup.c new file mode 100644 index 000000000000..b71c650fbb11 --- /dev/null +++ b/arch/powerpc/platforms/8xx/tqm8xx_setup.c | |||
@@ -0,0 +1,156 @@ | |||
1 | /* | ||
2 | * Platform setup for the MPC8xx based boards from TQM. | ||
3 | * | ||
4 | * Heiko Schocher <hs@denx.de> | ||
5 | * Copyright 2010 DENX Software Engineering GmbH | ||
6 | * | ||
7 | * based on: | ||
8 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
9 | * | ||
10 | * Copyright 2005 MontaVista Software Inc. | ||
11 | * | ||
12 | * Heavily modified by Scott Wood <scottwood@freescale.com> | ||
13 | * Copyright 2007 Freescale Semiconductor, Inc. | ||
14 | * | ||
15 | * This file is licensed under the terms of the GNU General Public License | ||
16 | * version 2. This program is licensed "as is" without any warranty of any | ||
17 | * kind, whether express or implied. | ||
18 | */ | ||
19 | |||
20 | #include <linux/init.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/param.h> | ||
23 | #include <linux/string.h> | ||
24 | #include <linux/ioport.h> | ||
25 | #include <linux/device.h> | ||
26 | #include <linux/delay.h> | ||
27 | |||
28 | #include <linux/fs_enet_pd.h> | ||
29 | #include <linux/fs_uart_pd.h> | ||
30 | #include <linux/fsl_devices.h> | ||
31 | #include <linux/mii.h> | ||
32 | #include <linux/of_platform.h> | ||
33 | |||
34 | #include <asm/delay.h> | ||
35 | #include <asm/io.h> | ||
36 | #include <asm/machdep.h> | ||
37 | #include <asm/page.h> | ||
38 | #include <asm/processor.h> | ||
39 | #include <asm/system.h> | ||
40 | #include <asm/time.h> | ||
41 | #include <asm/mpc8xx.h> | ||
42 | #include <asm/8xx_immap.h> | ||
43 | #include <asm/cpm1.h> | ||
44 | #include <asm/fs_pd.h> | ||
45 | #include <asm/udbg.h> | ||
46 | |||
47 | #include "mpc8xx.h" | ||
48 | |||
49 | struct cpm_pin { | ||
50 | int port, pin, flags; | ||
51 | }; | ||
52 | |||
53 | static struct __initdata cpm_pin tqm8xx_pins[] = { | ||
54 | /* SMC1 */ | ||
55 | {CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */ | ||
56 | {CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */ | ||
57 | |||
58 | /* SCC1 */ | ||
59 | {CPM_PORTA, 5, CPM_PIN_INPUT}, /* CLK1 */ | ||
60 | {CPM_PORTA, 7, CPM_PIN_INPUT}, /* CLK2 */ | ||
61 | {CPM_PORTA, 14, CPM_PIN_INPUT}, /* TX */ | ||
62 | {CPM_PORTA, 15, CPM_PIN_INPUT}, /* RX */ | ||
63 | {CPM_PORTC, 15, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TENA */ | ||
64 | {CPM_PORTC, 10, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, | ||
65 | {CPM_PORTC, 11, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, | ||
66 | }; | ||
67 | |||
68 | static struct __initdata cpm_pin tqm8xx_fec_pins[] = { | ||
69 | /* MII */ | ||
70 | {CPM_PORTD, 3, CPM_PIN_OUTPUT}, | ||
71 | {CPM_PORTD, 4, CPM_PIN_OUTPUT}, | ||
72 | {CPM_PORTD, 5, CPM_PIN_OUTPUT}, | ||
73 | {CPM_PORTD, 6, CPM_PIN_OUTPUT}, | ||
74 | {CPM_PORTD, 7, CPM_PIN_OUTPUT}, | ||
75 | {CPM_PORTD, 8, CPM_PIN_OUTPUT}, | ||
76 | {CPM_PORTD, 9, CPM_PIN_OUTPUT}, | ||
77 | {CPM_PORTD, 10, CPM_PIN_OUTPUT}, | ||
78 | {CPM_PORTD, 11, CPM_PIN_OUTPUT}, | ||
79 | {CPM_PORTD, 12, CPM_PIN_OUTPUT}, | ||
80 | {CPM_PORTD, 13, CPM_PIN_OUTPUT}, | ||
81 | {CPM_PORTD, 14, CPM_PIN_OUTPUT}, | ||
82 | {CPM_PORTD, 15, CPM_PIN_OUTPUT}, | ||
83 | }; | ||
84 | |||
85 | static void __init init_pins(int n, struct cpm_pin *pin) | ||
86 | { | ||
87 | int i; | ||
88 | |||
89 | for (i = 0; i < n; i++) { | ||
90 | cpm1_set_pin(pin->port, pin->pin, pin->flags); | ||
91 | pin++; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | static void __init init_ioports(void) | ||
96 | { | ||
97 | struct device_node *dnode; | ||
98 | struct property *prop; | ||
99 | int len; | ||
100 | |||
101 | init_pins(ARRAY_SIZE(tqm8xx_pins), &tqm8xx_pins[0]); | ||
102 | |||
103 | cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX); | ||
104 | |||
105 | dnode = of_find_node_by_name(NULL, "aliases"); | ||
106 | if (dnode == NULL) | ||
107 | return; | ||
108 | prop = of_find_property(dnode, "ethernet1", &len); | ||
109 | if (prop == NULL) | ||
110 | return; | ||
111 | |||
112 | /* init FEC pins */ | ||
113 | init_pins(ARRAY_SIZE(tqm8xx_fec_pins), &tqm8xx_fec_pins[0]); | ||
114 | } | ||
115 | |||
116 | static void __init tqm8xx_setup_arch(void) | ||
117 | { | ||
118 | cpm_reset(); | ||
119 | init_ioports(); | ||
120 | } | ||
121 | |||
122 | static int __init tqm8xx_probe(void) | ||
123 | { | ||
124 | unsigned long node = of_get_flat_dt_root(); | ||
125 | |||
126 | return of_flat_dt_is_compatible(node, "tqc,tqm8xx"); | ||
127 | } | ||
128 | |||
129 | static struct of_device_id __initdata of_bus_ids[] = { | ||
130 | { .name = "soc", }, | ||
131 | { .name = "cpm", }, | ||
132 | { .name = "localbus", }, | ||
133 | { .compatible = "simple-bus" }, | ||
134 | {}, | ||
135 | }; | ||
136 | |||
137 | static int __init declare_of_platform_devices(void) | ||
138 | { | ||
139 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | machine_device_initcall(tqm8xx, declare_of_platform_devices); | ||
144 | |||
145 | define_machine(tqm8xx) { | ||
146 | .name = "TQM8xx", | ||
147 | .probe = tqm8xx_probe, | ||
148 | .setup_arch = tqm8xx_setup_arch, | ||
149 | .init_IRQ = mpc8xx_pics_init, | ||
150 | .get_irq = mpc8xx_get_irq, | ||
151 | .restart = mpc8xx_restart, | ||
152 | .calibrate_decr = mpc8xx_calibrate_decr, | ||
153 | .set_rtc_time = mpc8xx_set_rtc_time, | ||
154 | .get_rtc_time = mpc8xx_get_rtc_time, | ||
155 | .progress = udbg_progress, | ||
156 | }; | ||
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c index 00b6730bc48f..b6db7cef83b4 100644 --- a/arch/powerpc/platforms/iseries/vio.c +++ b/arch/powerpc/platforms/iseries/vio.c | |||
@@ -87,12 +87,11 @@ static struct device_node *new_node(const char *path, | |||
87 | 87 | ||
88 | if (!np) | 88 | if (!np) |
89 | return NULL; | 89 | return NULL; |
90 | np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL); | 90 | np->full_name = kstrdup(path, GFP_KERNEL); |
91 | if (!np->full_name) { | 91 | if (!np->full_name) { |
92 | kfree(np); | 92 | kfree(np); |
93 | return NULL; | 93 | return NULL; |
94 | } | 94 | } |
95 | strcpy(np->full_name, path); | ||
96 | of_node_set_flag(np, OF_DYNAMIC); | 95 | of_node_set_flag(np, OF_DYNAMIC); |
97 | kref_init(&np->kref); | 96 | kref_init(&np->kref); |
98 | np->parent = of_node_get(parent); | 97 | np->parent = of_node_get(parent); |
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c index 1e9eba175ff0..415ca6d6b273 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_32.c +++ b/arch/powerpc/platforms/powermac/cpufreq_32.c | |||
@@ -310,8 +310,12 @@ static int pmu_set_cpu_speed(int low_speed) | |||
310 | /* Restore low level PMU operations */ | 310 | /* Restore low level PMU operations */ |
311 | pmu_unlock(); | 311 | pmu_unlock(); |
312 | 312 | ||
313 | /* Restore decrementer */ | 313 | /* |
314 | wakeup_decrementer(); | 314 | * Restore decrementer; we'll take a decrementer interrupt |
315 | * as soon as interrupts are re-enabled and the generic | ||
316 | * clockevents code will reprogram it with the right value. | ||
317 | */ | ||
318 | set_dec(1); | ||
315 | 319 | ||
316 | /* Restore interrupts */ | 320 | /* Restore interrupts */ |
317 | mpic_cpu_set_priority(pic_prio); | 321 | mpic_cpu_set_priority(pic_prio); |
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index 9e1b9fd75206..79bd3e89dbaf 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c | |||
@@ -2191,7 +2191,11 @@ static struct pmac_mb_def pmac_mb_defs[] = { | |||
2191 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | 2191 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, |
2192 | PMAC_MB_MAY_SLEEP, | 2192 | PMAC_MB_MAY_SLEEP, |
2193 | }, | 2193 | }, |
2194 | { "iMac,1", "iMac (first generation)", | 2194 | { "PowerMac10,2", "Mac mini (Late 2005)", |
2195 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
2196 | PMAC_MB_MAY_SLEEP, | ||
2197 | }, | ||
2198 | { "iMac,1", "iMac (first generation)", | ||
2195 | PMAC_TYPE_ORIG_IMAC, paddington_features, | 2199 | PMAC_TYPE_ORIG_IMAC, paddington_features, |
2196 | 0 | 2200 | 0 |
2197 | }, | 2201 | }, |
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 3dbef309bc8d..046ace9c4381 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile | |||
@@ -26,3 +26,7 @@ obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o | |||
26 | obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o | 26 | obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o |
27 | obj-$(CONFIG_CMM) += cmm.o | 27 | obj-$(CONFIG_CMM) += cmm.o |
28 | obj-$(CONFIG_DTL) += dtl.o | 28 | obj-$(CONFIG_DTL) += dtl.o |
29 | |||
30 | ifeq ($(CONFIG_PPC_PSERIES),y) | ||
31 | obj-$(CONFIG_SUSPEND) += suspend.o | ||
32 | endif | ||
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index d71e58584086..227c1c3d585e 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c | |||
@@ -463,6 +463,7 @@ static int dlpar_offline_cpu(struct device_node *dn) | |||
463 | break; | 463 | break; |
464 | 464 | ||
465 | if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) { | 465 | if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) { |
466 | set_preferred_offline_state(cpu, CPU_STATE_OFFLINE); | ||
466 | cpu_maps_update_done(); | 467 | cpu_maps_update_done(); |
467 | rc = cpu_down(cpu); | 468 | rc = cpu_down(cpu); |
468 | if (rc) | 469 | if (rc) |
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c index 30b987b73c20..8ed0d2d0e1b5 100644 --- a/arch/powerpc/platforms/pseries/eeh_cache.c +++ b/arch/powerpc/platforms/pseries/eeh_cache.c | |||
@@ -288,8 +288,7 @@ void __init pci_addr_cache_build(void) | |||
288 | 288 | ||
289 | spin_lock_init(&pci_io_addr_cache_root.piar_lock); | 289 | spin_lock_init(&pci_io_addr_cache_root.piar_lock); |
290 | 290 | ||
291 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 291 | for_each_pci_dev(dev) { |
292 | |||
293 | pci_addr_cache_insert_device(dev); | 292 | pci_addr_cache_insert_device(dev); |
294 | 293 | ||
295 | dn = pci_device_to_OF_node(dev); | 294 | dn = pci_device_to_OF_node(dev); |
diff --git a/arch/powerpc/platforms/pseries/event_sources.c b/arch/powerpc/platforms/pseries/event_sources.c index e889c9d9586a..2605c310166a 100644 --- a/arch/powerpc/platforms/pseries/event_sources.c +++ b/arch/powerpc/platforms/pseries/event_sources.c | |||
@@ -41,9 +41,12 @@ void request_event_sources_irqs(struct device_node *np, | |||
41 | if (count > 15) | 41 | if (count > 15) |
42 | break; | 42 | break; |
43 | virqs[count] = irq_create_mapping(NULL, *(opicprop++)); | 43 | virqs[count] = irq_create_mapping(NULL, *(opicprop++)); |
44 | if (virqs[count] == NO_IRQ) | 44 | if (virqs[count] == NO_IRQ) { |
45 | printk(KERN_ERR "Unable to allocate interrupt " | 45 | pr_err("event-sources: Unable to allocate " |
46 | "number for %s\n", np->full_name); | 46 | "interrupt number for %s\n", |
47 | np->full_name); | ||
48 | WARN_ON(1); | ||
49 | } | ||
47 | else | 50 | else |
48 | count++; | 51 | count++; |
49 | 52 | ||
@@ -59,9 +62,12 @@ void request_event_sources_irqs(struct device_node *np, | |||
59 | virqs[count] = irq_create_of_mapping(oirq.controller, | 62 | virqs[count] = irq_create_of_mapping(oirq.controller, |
60 | oirq.specifier, | 63 | oirq.specifier, |
61 | oirq.size); | 64 | oirq.size); |
62 | if (virqs[count] == NO_IRQ) | 65 | if (virqs[count] == NO_IRQ) { |
63 | printk(KERN_ERR "Unable to allocate interrupt " | 66 | pr_err("event-sources: Unable to allocate " |
64 | "number for %s\n", np->full_name); | 67 | "interrupt number for %s\n", |
68 | np->full_name); | ||
69 | WARN_ON(1); | ||
70 | } | ||
65 | else | 71 | else |
66 | count++; | 72 | count++; |
67 | } | 73 | } |
@@ -70,8 +76,9 @@ void request_event_sources_irqs(struct device_node *np, | |||
70 | /* Now request them */ | 76 | /* Now request them */ |
71 | for (i = 0; i < count; i++) { | 77 | for (i = 0; i < count; i++) { |
72 | if (request_irq(virqs[i], handler, 0, name, NULL)) { | 78 | if (request_irq(virqs[i], handler, 0, name, NULL)) { |
73 | printk(KERN_ERR "Unable to request interrupt %d for " | 79 | pr_err("event-sources: Unable to request interrupt " |
74 | "%s\n", virqs[i], np->full_name); | 80 | "%d for %s\n", virqs[i], np->full_name); |
81 | WARN_ON(1); | ||
75 | return; | 82 | return; |
76 | } | 83 | } |
77 | } | 84 | } |
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 8f85f399ab9f..fd50ccd4bac1 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c | |||
@@ -116,6 +116,9 @@ static void pseries_mach_cpu_die(void) | |||
116 | 116 | ||
117 | if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) { | 117 | if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) { |
118 | set_cpu_current_state(cpu, CPU_STATE_INACTIVE); | 118 | set_cpu_current_state(cpu, CPU_STATE_INACTIVE); |
119 | if (ppc_md.suspend_disable_cpu) | ||
120 | ppc_md.suspend_disable_cpu(); | ||
121 | |||
119 | cede_latency_hint = 2; | 122 | cede_latency_hint = 2; |
120 | 123 | ||
121 | get_lppaca()->idle = 1; | 124 | get_lppaca()->idle = 1; |
@@ -190,12 +193,12 @@ static void pseries_cpu_die(unsigned int cpu) | |||
190 | 193 | ||
191 | if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) { | 194 | if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) { |
192 | cpu_status = 1; | 195 | cpu_status = 1; |
193 | for (tries = 0; tries < 1000; tries++) { | 196 | for (tries = 0; tries < 5000; tries++) { |
194 | if (get_cpu_current_state(cpu) == CPU_STATE_INACTIVE) { | 197 | if (get_cpu_current_state(cpu) == CPU_STATE_INACTIVE) { |
195 | cpu_status = 0; | 198 | cpu_status = 0; |
196 | break; | 199 | break; |
197 | } | 200 | } |
198 | cpu_relax(); | 201 | msleep(1); |
199 | } | 202 | } |
200 | } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) { | 203 | } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) { |
201 | 204 | ||
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index 41a3e9a039ed..a4fc6da87c2e 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c | |||
@@ -61,7 +61,6 @@ static int ras_check_exception_token; | |||
61 | 61 | ||
62 | #define EPOW_SENSOR_TOKEN 9 | 62 | #define EPOW_SENSOR_TOKEN 9 |
63 | #define EPOW_SENSOR_INDEX 0 | 63 | #define EPOW_SENSOR_INDEX 0 |
64 | #define RAS_VECTOR_OFFSET 0x500 | ||
65 | 64 | ||
66 | static irqreturn_t ras_epow_interrupt(int irq, void *dev_id); | 65 | static irqreturn_t ras_epow_interrupt(int irq, void *dev_id); |
67 | static irqreturn_t ras_error_interrupt(int irq, void *dev_id); | 66 | static irqreturn_t ras_error_interrupt(int irq, void *dev_id); |
@@ -121,7 +120,7 @@ static irqreturn_t ras_epow_interrupt(int irq, void *dev_id) | |||
121 | spin_lock(&ras_log_buf_lock); | 120 | spin_lock(&ras_log_buf_lock); |
122 | 121 | ||
123 | status = rtas_call(ras_check_exception_token, 6, 1, NULL, | 122 | status = rtas_call(ras_check_exception_token, 6, 1, NULL, |
124 | RAS_VECTOR_OFFSET, | 123 | RTAS_VECTOR_EXTERNAL_INTERRUPT, |
125 | irq_map[irq].hwirq, | 124 | irq_map[irq].hwirq, |
126 | RTAS_EPOW_WARNING | RTAS_POWERMGM_EVENTS, | 125 | RTAS_EPOW_WARNING | RTAS_POWERMGM_EVENTS, |
127 | critical, __pa(&ras_log_buf), | 126 | critical, __pa(&ras_log_buf), |
@@ -156,7 +155,7 @@ static irqreturn_t ras_error_interrupt(int irq, void *dev_id) | |||
156 | spin_lock(&ras_log_buf_lock); | 155 | spin_lock(&ras_log_buf_lock); |
157 | 156 | ||
158 | status = rtas_call(ras_check_exception_token, 6, 1, NULL, | 157 | status = rtas_call(ras_check_exception_token, 6, 1, NULL, |
159 | RAS_VECTOR_OFFSET, | 158 | RTAS_VECTOR_EXTERNAL_INTERRUPT, |
160 | irq_map[irq].hwirq, | 159 | irq_map[irq].hwirq, |
161 | RTAS_INTERNAL_ERROR, 1 /*Time Critical */, | 160 | RTAS_INTERNAL_ERROR, 1 /*Time Critical */, |
162 | __pa(&ras_log_buf), | 161 | __pa(&ras_log_buf), |
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index 1a58637bcea5..57ddbb43b33a 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c | |||
@@ -118,12 +118,10 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist | |||
118 | if (!np) | 118 | if (!np) |
119 | goto out_err; | 119 | goto out_err; |
120 | 120 | ||
121 | np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL); | 121 | np->full_name = kstrdup(path, GFP_KERNEL); |
122 | if (!np->full_name) | 122 | if (!np->full_name) |
123 | goto out_err; | 123 | goto out_err; |
124 | 124 | ||
125 | strcpy(np->full_name, path); | ||
126 | |||
127 | np->properties = proplist; | 125 | np->properties = proplist; |
128 | of_node_set_flag(np, OF_DYNAMIC); | 126 | of_node_set_flag(np, OF_DYNAMIC); |
129 | kref_init(&np->kref); | 127 | kref_init(&np->kref); |
diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c new file mode 100644 index 000000000000..ed72098bb4e3 --- /dev/null +++ b/arch/powerpc/platforms/pseries/suspend.c | |||
@@ -0,0 +1,214 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Brian King IBM Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | |||
19 | #include <linux/delay.h> | ||
20 | #include <linux/suspend.h> | ||
21 | #include <asm/firmware.h> | ||
22 | #include <asm/hvcall.h> | ||
23 | #include <asm/machdep.h> | ||
24 | #include <asm/mmu.h> | ||
25 | #include <asm/rtas.h> | ||
26 | |||
27 | static u64 stream_id; | ||
28 | static struct sys_device suspend_sysdev; | ||
29 | static DECLARE_COMPLETION(suspend_work); | ||
30 | static struct rtas_suspend_me_data suspend_data; | ||
31 | static atomic_t suspending; | ||
32 | |||
33 | /** | ||
34 | * pseries_suspend_begin - First phase of hibernation | ||
35 | * | ||
36 | * Check to ensure we are in a valid state to hibernate | ||
37 | * | ||
38 | * Return value: | ||
39 | * 0 on success / other on failure | ||
40 | **/ | ||
41 | static int pseries_suspend_begin(suspend_state_t state) | ||
42 | { | ||
43 | long vasi_state, rc; | ||
44 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; | ||
45 | |||
46 | /* Make sure the state is valid */ | ||
47 | rc = plpar_hcall(H_VASI_STATE, retbuf, stream_id); | ||
48 | |||
49 | vasi_state = retbuf[0]; | ||
50 | |||
51 | if (rc) { | ||
52 | pr_err("pseries_suspend_begin: vasi_state returned %ld\n",rc); | ||
53 | return rc; | ||
54 | } else if (vasi_state == H_VASI_ENABLED) { | ||
55 | return -EAGAIN; | ||
56 | } else if (vasi_state != H_VASI_SUSPENDING) { | ||
57 | pr_err("pseries_suspend_begin: vasi_state returned state %ld\n", | ||
58 | vasi_state); | ||
59 | return -EIO; | ||
60 | } | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | /** | ||
66 | * pseries_suspend_cpu - Suspend a single CPU | ||
67 | * | ||
68 | * Makes the H_JOIN call to suspend the CPU | ||
69 | * | ||
70 | **/ | ||
71 | static int pseries_suspend_cpu(void) | ||
72 | { | ||
73 | if (atomic_read(&suspending)) | ||
74 | return rtas_suspend_cpu(&suspend_data); | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | /** | ||
79 | * pseries_suspend_enter - Final phase of hibernation | ||
80 | * | ||
81 | * Return value: | ||
82 | * 0 on success / other on failure | ||
83 | **/ | ||
84 | static int pseries_suspend_enter(suspend_state_t state) | ||
85 | { | ||
86 | int rc = rtas_suspend_last_cpu(&suspend_data); | ||
87 | |||
88 | atomic_set(&suspending, 0); | ||
89 | atomic_set(&suspend_data.done, 1); | ||
90 | return rc; | ||
91 | } | ||
92 | |||
93 | /** | ||
94 | * pseries_prepare_late - Prepare to suspend all other CPUs | ||
95 | * | ||
96 | * Return value: | ||
97 | * 0 on success / other on failure | ||
98 | **/ | ||
99 | static int pseries_prepare_late(void) | ||
100 | { | ||
101 | atomic_set(&suspending, 1); | ||
102 | atomic_set(&suspend_data.working, 0); | ||
103 | atomic_set(&suspend_data.done, 0); | ||
104 | atomic_set(&suspend_data.error, 0); | ||
105 | suspend_data.complete = &suspend_work; | ||
106 | INIT_COMPLETION(suspend_work); | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | /** | ||
111 | * store_hibernate - Initiate partition hibernation | ||
112 | * @classdev: sysdev class struct | ||
113 | * @attr: class device attribute struct | ||
114 | * @buf: buffer | ||
115 | * @count: buffer size | ||
116 | * | ||
117 | * Write the stream ID received from the HMC to this file | ||
118 | * to trigger hibernating the partition | ||
119 | * | ||
120 | * Return value: | ||
121 | * number of bytes printed to buffer / other on failure | ||
122 | **/ | ||
123 | static ssize_t store_hibernate(struct sysdev_class *classdev, | ||
124 | struct sysdev_class_attribute *attr, | ||
125 | const char *buf, size_t count) | ||
126 | { | ||
127 | int rc; | ||
128 | |||
129 | if (!capable(CAP_SYS_ADMIN)) | ||
130 | return -EPERM; | ||
131 | |||
132 | stream_id = simple_strtoul(buf, NULL, 16); | ||
133 | |||
134 | do { | ||
135 | rc = pseries_suspend_begin(PM_SUSPEND_MEM); | ||
136 | if (rc == -EAGAIN) | ||
137 | ssleep(1); | ||
138 | } while (rc == -EAGAIN); | ||
139 | |||
140 | if (!rc) | ||
141 | rc = pm_suspend(PM_SUSPEND_MEM); | ||
142 | |||
143 | stream_id = 0; | ||
144 | |||
145 | if (!rc) | ||
146 | rc = count; | ||
147 | return rc; | ||
148 | } | ||
149 | |||
150 | static SYSDEV_CLASS_ATTR(hibernate, S_IWUSR, NULL, store_hibernate); | ||
151 | |||
152 | static struct sysdev_class suspend_sysdev_class = { | ||
153 | .name = "power", | ||
154 | }; | ||
155 | |||
156 | static struct platform_suspend_ops pseries_suspend_ops = { | ||
157 | .valid = suspend_valid_only_mem, | ||
158 | .begin = pseries_suspend_begin, | ||
159 | .prepare_late = pseries_prepare_late, | ||
160 | .enter = pseries_suspend_enter, | ||
161 | }; | ||
162 | |||
163 | /** | ||
164 | * pseries_suspend_sysfs_register - Register with sysfs | ||
165 | * | ||
166 | * Return value: | ||
167 | * 0 on success / other on failure | ||
168 | **/ | ||
169 | static int pseries_suspend_sysfs_register(struct sys_device *sysdev) | ||
170 | { | ||
171 | int rc; | ||
172 | |||
173 | if ((rc = sysdev_class_register(&suspend_sysdev_class))) | ||
174 | return rc; | ||
175 | |||
176 | sysdev->id = 0; | ||
177 | sysdev->cls = &suspend_sysdev_class; | ||
178 | |||
179 | if ((rc = sysdev_class_create_file(&suspend_sysdev_class, &attr_hibernate))) | ||
180 | goto class_unregister; | ||
181 | |||
182 | return 0; | ||
183 | |||
184 | class_unregister: | ||
185 | sysdev_class_unregister(&suspend_sysdev_class); | ||
186 | return rc; | ||
187 | } | ||
188 | |||
189 | /** | ||
190 | * pseries_suspend_init - initcall for pSeries suspend | ||
191 | * | ||
192 | * Return value: | ||
193 | * 0 on success / other on failure | ||
194 | **/ | ||
195 | static int __init pseries_suspend_init(void) | ||
196 | { | ||
197 | int rc; | ||
198 | |||
199 | if (!machine_is(pseries) || !firmware_has_feature(FW_FEATURE_LPAR)) | ||
200 | return 0; | ||
201 | |||
202 | suspend_data.token = rtas_token("ibm,suspend-me"); | ||
203 | if (suspend_data.token == RTAS_UNKNOWN_SERVICE) | ||
204 | return 0; | ||
205 | |||
206 | if ((rc = pseries_suspend_sysfs_register(&suspend_sysdev))) | ||
207 | return rc; | ||
208 | |||
209 | ppc_md.suspend_disable_cpu = pseries_suspend_cpu; | ||
210 | suspend_set_ops(&pseries_suspend_ops); | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | __initcall(pseries_suspend_init); | ||
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index f19d19468393..5b22b07c8f67 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
@@ -549,8 +549,6 @@ static irqreturn_t xics_ipi_dispatch(int cpu) | |||
549 | { | 549 | { |
550 | unsigned long *tgt = &per_cpu(xics_ipi_message, cpu); | 550 | unsigned long *tgt = &per_cpu(xics_ipi_message, cpu); |
551 | 551 | ||
552 | WARN_ON(cpu_is_offline(cpu)); | ||
553 | |||
554 | mb(); /* order mmio clearing qirr */ | 552 | mb(); /* order mmio clearing qirr */ |
555 | while (*tgt) { | 553 | while (*tgt) { |
556 | if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, tgt)) { | 554 | if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, tgt)) { |
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 356c6a0e1b23..209384b6e039 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
@@ -412,6 +412,7 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4080, quirk_fsl_pcie_header); | |||
412 | #endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */ | 412 | #endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */ |
413 | 413 | ||
414 | #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x) | 414 | #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x) |
415 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8308, quirk_fsl_pcie_header); | ||
415 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8314E, quirk_fsl_pcie_header); | 416 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8314E, quirk_fsl_pcie_header); |
416 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8314, quirk_fsl_pcie_header); | 417 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8314, quirk_fsl_pcie_header); |
417 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8315E, quirk_fsl_pcie_header); | 418 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8315E, quirk_fsl_pcie_header); |
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h index 42381bb6cd51..53609489a62b 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h | |||
@@ -30,6 +30,7 @@ struct platform_diu_data_ops { | |||
30 | void (*set_pixel_clock) (unsigned int pixclock); | 30 | void (*set_pixel_clock) (unsigned int pixclock); |
31 | ssize_t (*show_monitor_port) (int monitor_port, char *buf); | 31 | ssize_t (*show_monitor_port) (int monitor_port, char *buf); |
32 | int (*set_sysfs_monitor_port) (int val); | 32 | int (*set_sysfs_monitor_port) (int val); |
33 | void (*release_bootmem) (void); | ||
33 | }; | 34 | }; |
34 | 35 | ||
35 | extern struct platform_diu_data_ops diu_ops; | 36 | extern struct platform_diu_data_ops diu_ops; |
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 20b73c025a45..7c1342618a30 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -1636,6 +1636,24 @@ void __devinit smp_mpic_setup_cpu(int cpu) | |||
1636 | { | 1636 | { |
1637 | mpic_setup_this_cpu(); | 1637 | mpic_setup_this_cpu(); |
1638 | } | 1638 | } |
1639 | |||
1640 | void mpic_reset_core(int cpu) | ||
1641 | { | ||
1642 | struct mpic *mpic = mpic_primary; | ||
1643 | u32 pir; | ||
1644 | int cpuid = get_hard_smp_processor_id(cpu); | ||
1645 | |||
1646 | /* Set target bit for core reset */ | ||
1647 | pir = mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); | ||
1648 | pir |= (1 << cpuid); | ||
1649 | mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir); | ||
1650 | mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); | ||
1651 | |||
1652 | /* Restore target bit after reset complete */ | ||
1653 | pir &= ~(1 << cpuid); | ||
1654 | mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir); | ||
1655 | mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); | ||
1656 | } | ||
1639 | #endif /* CONFIG_SMP */ | 1657 | #endif /* CONFIG_SMP */ |
1640 | 1658 | ||
1641 | #ifdef CONFIG_PM | 1659 | #ifdef CONFIG_PM |
diff --git a/arch/powerpc/sysdev/mpic.h b/arch/powerpc/sysdev/mpic.h index eff433c322a0..e4a6df77b8d7 100644 --- a/arch/powerpc/sysdev/mpic.h +++ b/arch/powerpc/sysdev/mpic.h | |||
@@ -37,5 +37,6 @@ static inline int mpic_pasemi_msi_init(struct mpic *mpic) | |||
37 | extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type); | 37 | extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type); |
38 | extern void mpic_set_vector(unsigned int virq, unsigned int vector); | 38 | extern void mpic_set_vector(unsigned int virq, unsigned int vector); |
39 | extern int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask); | 39 | extern int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask); |
40 | extern void mpic_reset_core(int cpu); | ||
40 | 41 | ||
41 | #endif /* _POWERPC_SYSDEV_MPIC_H */ | 42 | #endif /* _POWERPC_SYSDEV_MPIC_H */ |
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 8bad7d5f32af..0554445200bf 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
@@ -155,6 +155,9 @@ static int do_spu_cmd(void); | |||
155 | #ifdef CONFIG_44x | 155 | #ifdef CONFIG_44x |
156 | static void dump_tlb_44x(void); | 156 | static void dump_tlb_44x(void); |
157 | #endif | 157 | #endif |
158 | #ifdef CONFIG_PPC_BOOK3E | ||
159 | static void dump_tlb_book3e(void); | ||
160 | #endif | ||
158 | 161 | ||
159 | static int xmon_no_auto_backtrace; | 162 | static int xmon_no_auto_backtrace; |
160 | 163 | ||
@@ -888,6 +891,11 @@ cmds(struct pt_regs *excp) | |||
888 | dump_tlb_44x(); | 891 | dump_tlb_44x(); |
889 | break; | 892 | break; |
890 | #endif | 893 | #endif |
894 | #ifdef CONFIG_PPC_BOOK3E | ||
895 | case 'u': | ||
896 | dump_tlb_book3e(); | ||
897 | break; | ||
898 | #endif | ||
891 | default: | 899 | default: |
892 | printf("Unrecognized command: "); | 900 | printf("Unrecognized command: "); |
893 | do { | 901 | do { |
@@ -2701,6 +2709,150 @@ static void dump_tlb_44x(void) | |||
2701 | } | 2709 | } |
2702 | #endif /* CONFIG_44x */ | 2710 | #endif /* CONFIG_44x */ |
2703 | 2711 | ||
2712 | #ifdef CONFIG_PPC_BOOK3E | ||
2713 | static void dump_tlb_book3e(void) | ||
2714 | { | ||
2715 | u32 mmucfg, pidmask, lpidmask; | ||
2716 | u64 ramask; | ||
2717 | int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0; | ||
2718 | int mmu_version; | ||
2719 | static const char *pgsz_names[] = { | ||
2720 | " 1K", | ||
2721 | " 2K", | ||
2722 | " 4K", | ||
2723 | " 8K", | ||
2724 | " 16K", | ||
2725 | " 32K", | ||
2726 | " 64K", | ||
2727 | "128K", | ||
2728 | "256K", | ||
2729 | "512K", | ||
2730 | " 1M", | ||
2731 | " 2M", | ||
2732 | " 4M", | ||
2733 | " 8M", | ||
2734 | " 16M", | ||
2735 | " 32M", | ||
2736 | " 64M", | ||
2737 | "128M", | ||
2738 | "256M", | ||
2739 | "512M", | ||
2740 | " 1G", | ||
2741 | " 2G", | ||
2742 | " 4G", | ||
2743 | " 8G", | ||
2744 | " 16G", | ||
2745 | " 32G", | ||
2746 | " 64G", | ||
2747 | "128G", | ||
2748 | "256G", | ||
2749 | "512G", | ||
2750 | " 1T", | ||
2751 | " 2T", | ||
2752 | }; | ||
2753 | |||
2754 | /* Gather some infos about the MMU */ | ||
2755 | mmucfg = mfspr(SPRN_MMUCFG); | ||
2756 | mmu_version = (mmucfg & 3) + 1; | ||
2757 | ntlbs = ((mmucfg >> 2) & 3) + 1; | ||
2758 | pidsz = ((mmucfg >> 6) & 0x1f) + 1; | ||
2759 | lpidsz = (mmucfg >> 24) & 0xf; | ||
2760 | rasz = (mmucfg >> 16) & 0x7f; | ||
2761 | if ((mmu_version > 1) && (mmucfg & 0x10000)) | ||
2762 | lrat = 1; | ||
2763 | printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n", | ||
2764 | mmu_version, ntlbs, pidsz, lpidsz, rasz); | ||
2765 | pidmask = (1ul << pidsz) - 1; | ||
2766 | lpidmask = (1ul << lpidsz) - 1; | ||
2767 | ramask = (1ull << rasz) - 1; | ||
2768 | |||
2769 | for (tlb = 0; tlb < ntlbs; tlb++) { | ||
2770 | u32 tlbcfg; | ||
2771 | int nent, assoc, new_cc = 1; | ||
2772 | printf("TLB %d:\n------\n", tlb); | ||
2773 | switch(tlb) { | ||
2774 | case 0: | ||
2775 | tlbcfg = mfspr(SPRN_TLB0CFG); | ||
2776 | break; | ||
2777 | case 1: | ||
2778 | tlbcfg = mfspr(SPRN_TLB1CFG); | ||
2779 | break; | ||
2780 | case 2: | ||
2781 | tlbcfg = mfspr(SPRN_TLB2CFG); | ||
2782 | break; | ||
2783 | case 3: | ||
2784 | tlbcfg = mfspr(SPRN_TLB3CFG); | ||
2785 | break; | ||
2786 | default: | ||
2787 | printf("Unsupported TLB number !\n"); | ||
2788 | continue; | ||
2789 | } | ||
2790 | nent = tlbcfg & 0xfff; | ||
2791 | assoc = (tlbcfg >> 24) & 0xff; | ||
2792 | for (i = 0; i < nent; i++) { | ||
2793 | u32 mas0 = MAS0_TLBSEL(tlb); | ||
2794 | u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K); | ||
2795 | u64 mas2 = 0; | ||
2796 | u64 mas7_mas3; | ||
2797 | int esel = i, cc = i; | ||
2798 | |||
2799 | if (assoc != 0) { | ||
2800 | cc = i / assoc; | ||
2801 | esel = i % assoc; | ||
2802 | mas2 = cc * 0x1000; | ||
2803 | } | ||
2804 | |||
2805 | mas0 |= MAS0_ESEL(esel); | ||
2806 | mtspr(SPRN_MAS0, mas0); | ||
2807 | mtspr(SPRN_MAS1, mas1); | ||
2808 | mtspr(SPRN_MAS2, mas2); | ||
2809 | asm volatile("tlbre 0,0,0" : : : "memory"); | ||
2810 | mas1 = mfspr(SPRN_MAS1); | ||
2811 | mas2 = mfspr(SPRN_MAS2); | ||
2812 | mas7_mas3 = mfspr(SPRN_MAS7_MAS3); | ||
2813 | if (assoc && (i % assoc) == 0) | ||
2814 | new_cc = 1; | ||
2815 | if (!(mas1 & MAS1_VALID)) | ||
2816 | continue; | ||
2817 | if (assoc == 0) | ||
2818 | printf("%04x- ", i); | ||
2819 | else if (new_cc) | ||
2820 | printf("%04x-%c", cc, 'A' + esel); | ||
2821 | else | ||
2822 | printf(" |%c", 'A' + esel); | ||
2823 | new_cc = 0; | ||
2824 | printf(" %016llx %04x %s %c%c AS%c", | ||
2825 | mas2 & ~0x3ffull, | ||
2826 | (mas1 >> 16) & 0x3fff, | ||
2827 | pgsz_names[(mas1 >> 7) & 0x1f], | ||
2828 | mas1 & MAS1_IND ? 'I' : ' ', | ||
2829 | mas1 & MAS1_IPROT ? 'P' : ' ', | ||
2830 | mas1 & MAS1_TS ? '1' : '0'); | ||
2831 | printf(" %c%c%c%c%c%c%c", | ||
2832 | mas2 & MAS2_X0 ? 'a' : ' ', | ||
2833 | mas2 & MAS2_X1 ? 'v' : ' ', | ||
2834 | mas2 & MAS2_W ? 'w' : ' ', | ||
2835 | mas2 & MAS2_I ? 'i' : ' ', | ||
2836 | mas2 & MAS2_M ? 'm' : ' ', | ||
2837 | mas2 & MAS2_G ? 'g' : ' ', | ||
2838 | mas2 & MAS2_E ? 'e' : ' '); | ||
2839 | printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull); | ||
2840 | if (mas1 & MAS1_IND) | ||
2841 | printf(" %s\n", | ||
2842 | pgsz_names[(mas7_mas3 >> 1) & 0x1f]); | ||
2843 | else | ||
2844 | printf(" U%c%c%c S%c%c%c\n", | ||
2845 | mas7_mas3 & MAS3_UX ? 'x' : ' ', | ||
2846 | mas7_mas3 & MAS3_UW ? 'w' : ' ', | ||
2847 | mas7_mas3 & MAS3_UR ? 'r' : ' ', | ||
2848 | mas7_mas3 & MAS3_SX ? 'x' : ' ', | ||
2849 | mas7_mas3 & MAS3_SW ? 'w' : ' ', | ||
2850 | mas7_mas3 & MAS3_SR ? 'r' : ' '); | ||
2851 | } | ||
2852 | } | ||
2853 | } | ||
2854 | #endif /* CONFIG_PPC_BOOK3E */ | ||
2855 | |||
2704 | static void xmon_init(int enable) | 2856 | static void xmon_init(int enable) |
2705 | { | 2857 | { |
2706 | #ifdef CONFIG_PPC_ISERIES | 2858 | #ifdef CONFIG_PPC_ISERIES |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 35cca4c7fb18..fa27d1676ee5 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -194,7 +194,7 @@ static int __init hvc_console_setup(struct console *co, char *options) | |||
194 | return 0; | 194 | return 0; |
195 | } | 195 | } |
196 | 196 | ||
197 | static struct console hvc_con_driver = { | 197 | static struct console hvc_console = { |
198 | .name = "hvc", | 198 | .name = "hvc", |
199 | .write = hvc_console_print, | 199 | .write = hvc_console_print, |
200 | .device = hvc_console_device, | 200 | .device = hvc_console_device, |
@@ -220,7 +220,7 @@ static struct console hvc_con_driver = { | |||
220 | */ | 220 | */ |
221 | static int __init hvc_console_init(void) | 221 | static int __init hvc_console_init(void) |
222 | { | 222 | { |
223 | register_console(&hvc_con_driver); | 223 | register_console(&hvc_console); |
224 | return 0; | 224 | return 0; |
225 | } | 225 | } |
226 | console_initcall(hvc_console_init); | 226 | console_initcall(hvc_console_init); |
@@ -276,8 +276,8 @@ int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops) | |||
276 | * now (setup won't fail at this point). It's ok to just | 276 | * now (setup won't fail at this point). It's ok to just |
277 | * call register again if previously .setup failed. | 277 | * call register again if previously .setup failed. |
278 | */ | 278 | */ |
279 | if (index == hvc_con_driver.index) | 279 | if (index == hvc_console.index) |
280 | register_console(&hvc_con_driver); | 280 | register_console(&hvc_console); |
281 | 281 | ||
282 | return 0; | 282 | return 0; |
283 | } | 283 | } |
@@ -641,7 +641,7 @@ int hvc_poll(struct hvc_struct *hp) | |||
641 | } | 641 | } |
642 | for (i = 0; i < n; ++i) { | 642 | for (i = 0; i < n; ++i) { |
643 | #ifdef CONFIG_MAGIC_SYSRQ | 643 | #ifdef CONFIG_MAGIC_SYSRQ |
644 | if (hp->index == hvc_con_driver.index) { | 644 | if (hp->index == hvc_console.index) { |
645 | /* Handle the SysRq Hack */ | 645 | /* Handle the SysRq Hack */ |
646 | /* XXX should support a sequence */ | 646 | /* XXX should support a sequence */ |
647 | if (buf[i] == '\x0f') { /* ^O */ | 647 | if (buf[i] == '\x0f') { /* ^O */ |
@@ -909,7 +909,7 @@ static void __exit hvc_exit(void) | |||
909 | tty_unregister_driver(hvc_driver); | 909 | tty_unregister_driver(hvc_driver); |
910 | /* return tty_struct instances allocated in hvc_init(). */ | 910 | /* return tty_struct instances allocated in hvc_init(). */ |
911 | put_tty_driver(hvc_driver); | 911 | put_tty_driver(hvc_driver); |
912 | unregister_console(&hvc_con_driver); | 912 | unregister_console(&hvc_console); |
913 | } | 913 | } |
914 | } | 914 | } |
915 | module_exit(hvc_exit); | 915 | module_exit(hvc_exit); |
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index d4b14ff1c4c1..1f4b6de65a2d 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c | |||
@@ -1255,7 +1255,7 @@ static int __init hvsi_console_setup(struct console *console, char *options) | |||
1255 | return 0; | 1255 | return 0; |
1256 | } | 1256 | } |
1257 | 1257 | ||
1258 | static struct console hvsi_con_driver = { | 1258 | static struct console hvsi_console = { |
1259 | .name = "hvsi", | 1259 | .name = "hvsi", |
1260 | .write = hvsi_console_print, | 1260 | .write = hvsi_console_print, |
1261 | .device = hvsi_console_device, | 1261 | .device = hvsi_console_device, |
@@ -1308,7 +1308,7 @@ static int __init hvsi_console_init(void) | |||
1308 | } | 1308 | } |
1309 | 1309 | ||
1310 | if (hvsi_count) | 1310 | if (hvsi_count) |
1311 | register_console(&hvsi_con_driver); | 1311 | register_console(&hvsi_console); |
1312 | return 0; | 1312 | return 0; |
1313 | } | 1313 | } |
1314 | console_initcall(hvsi_console_init); | 1314 | console_initcall(hvsi_console_init); |
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index df00eb1f11f9..54247d475fc3 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c | |||
@@ -63,6 +63,7 @@ struct mpc_i2c { | |||
63 | wait_queue_head_t queue; | 63 | wait_queue_head_t queue; |
64 | struct i2c_adapter adap; | 64 | struct i2c_adapter adap; |
65 | int irq; | 65 | int irq; |
66 | u32 real_clk; | ||
66 | }; | 67 | }; |
67 | 68 | ||
68 | struct mpc_i2c_divider { | 69 | struct mpc_i2c_divider { |
@@ -96,20 +97,23 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id) | |||
96 | /* Sometimes 9th clock pulse isn't generated, and slave doesn't release | 97 | /* Sometimes 9th clock pulse isn't generated, and slave doesn't release |
97 | * the bus, because it wants to send ACK. | 98 | * the bus, because it wants to send ACK. |
98 | * Following sequence of enabling/disabling and sending start/stop generates | 99 | * Following sequence of enabling/disabling and sending start/stop generates |
99 | * the pulse, so it's all OK. | 100 | * the 9 pulses, so it's all OK. |
100 | */ | 101 | */ |
101 | static void mpc_i2c_fixup(struct mpc_i2c *i2c) | 102 | static void mpc_i2c_fixup(struct mpc_i2c *i2c) |
102 | { | 103 | { |
103 | writeccr(i2c, 0); | 104 | int k; |
104 | udelay(30); | 105 | u32 delay_val = 1000000 / i2c->real_clk + 1; |
105 | writeccr(i2c, CCR_MEN); | 106 | |
106 | udelay(30); | 107 | if (delay_val < 2) |
107 | writeccr(i2c, CCR_MSTA | CCR_MTX); | 108 | delay_val = 2; |
108 | udelay(30); | 109 | |
109 | writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); | 110 | for (k = 9; k; k--) { |
110 | udelay(30); | 111 | writeccr(i2c, 0); |
111 | writeccr(i2c, CCR_MEN); | 112 | writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); |
112 | udelay(30); | 113 | udelay(delay_val); |
114 | writeccr(i2c, CCR_MEN); | ||
115 | udelay(delay_val << 1); | ||
116 | } | ||
113 | } | 117 | } |
114 | 118 | ||
115 | static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) | 119 | static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) |
@@ -190,15 +194,18 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] __devinitconst = { | |||
190 | }; | 194 | }; |
191 | 195 | ||
192 | static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, | 196 | static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, |
193 | int prescaler) | 197 | int prescaler, u32 *real_clk) |
194 | { | 198 | { |
195 | const struct mpc_i2c_divider *div = NULL; | 199 | const struct mpc_i2c_divider *div = NULL; |
196 | unsigned int pvr = mfspr(SPRN_PVR); | 200 | unsigned int pvr = mfspr(SPRN_PVR); |
197 | u32 divider; | 201 | u32 divider; |
198 | int i; | 202 | int i; |
199 | 203 | ||
200 | if (clock == MPC_I2C_CLOCK_LEGACY) | 204 | if (clock == MPC_I2C_CLOCK_LEGACY) { |
205 | /* see below - default fdr = 0x3f -> div = 2048 */ | ||
206 | *real_clk = mpc5xxx_get_bus_frequency(node) / 2048; | ||
201 | return -EINVAL; | 207 | return -EINVAL; |
208 | } | ||
202 | 209 | ||
203 | /* Determine divider value */ | 210 | /* Determine divider value */ |
204 | divider = mpc5xxx_get_bus_frequency(node) / clock; | 211 | divider = mpc5xxx_get_bus_frequency(node) / clock; |
@@ -216,7 +223,8 @@ static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, | |||
216 | break; | 223 | break; |
217 | } | 224 | } |
218 | 225 | ||
219 | return div ? (int)div->fdr : -EINVAL; | 226 | *real_clk = mpc5xxx_get_bus_frequency(node) / div->divider; |
227 | return (int)div->fdr; | ||
220 | } | 228 | } |
221 | 229 | ||
222 | static void __devinit mpc_i2c_setup_52xx(struct device_node *node, | 230 | static void __devinit mpc_i2c_setup_52xx(struct device_node *node, |
@@ -231,13 +239,14 @@ static void __devinit mpc_i2c_setup_52xx(struct device_node *node, | |||
231 | return; | 239 | return; |
232 | } | 240 | } |
233 | 241 | ||
234 | ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler); | 242 | ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler, &i2c->real_clk); |
235 | fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */ | 243 | fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */ |
236 | 244 | ||
237 | writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR); | 245 | writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR); |
238 | 246 | ||
239 | if (ret >= 0) | 247 | if (ret >= 0) |
240 | dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr); | 248 | dev_info(i2c->dev, "clock %u Hz (fdr=%d)\n", i2c->real_clk, |
249 | fdr); | ||
241 | } | 250 | } |
242 | #else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */ | 251 | #else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */ |
243 | static void __devinit mpc_i2c_setup_52xx(struct device_node *node, | 252 | static void __devinit mpc_i2c_setup_52xx(struct device_node *node, |
@@ -334,14 +343,17 @@ static u32 __devinit mpc_i2c_get_sec_cfg_8xxx(void) | |||
334 | } | 343 | } |
335 | 344 | ||
336 | static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, | 345 | static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, |
337 | u32 prescaler) | 346 | u32 prescaler, u32 *real_clk) |
338 | { | 347 | { |
339 | const struct mpc_i2c_divider *div = NULL; | 348 | const struct mpc_i2c_divider *div = NULL; |
340 | u32 divider; | 349 | u32 divider; |
341 | int i; | 350 | int i; |
342 | 351 | ||
343 | if (clock == MPC_I2C_CLOCK_LEGACY) | 352 | if (clock == MPC_I2C_CLOCK_LEGACY) { |
353 | /* see below - default fdr = 0x1031 -> div = 16 * 3072 */ | ||
354 | *real_clk = fsl_get_sys_freq() / prescaler / (16 * 3072); | ||
344 | return -EINVAL; | 355 | return -EINVAL; |
356 | } | ||
345 | 357 | ||
346 | /* Determine proper divider value */ | 358 | /* Determine proper divider value */ |
347 | if (of_device_is_compatible(node, "fsl,mpc8544-i2c")) | 359 | if (of_device_is_compatible(node, "fsl,mpc8544-i2c")) |
@@ -364,6 +376,7 @@ static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, | |||
364 | break; | 376 | break; |
365 | } | 377 | } |
366 | 378 | ||
379 | *real_clk = fsl_get_sys_freq() / prescaler / div->divider; | ||
367 | return div ? (int)div->fdr : -EINVAL; | 380 | return div ? (int)div->fdr : -EINVAL; |
368 | } | 381 | } |
369 | 382 | ||
@@ -380,7 +393,7 @@ static void __devinit mpc_i2c_setup_8xxx(struct device_node *node, | |||
380 | return; | 393 | return; |
381 | } | 394 | } |
382 | 395 | ||
383 | ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler); | 396 | ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler, &i2c->real_clk); |
384 | fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */ | 397 | fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */ |
385 | 398 | ||
386 | writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR); | 399 | writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR); |
@@ -388,7 +401,7 @@ static void __devinit mpc_i2c_setup_8xxx(struct device_node *node, | |||
388 | 401 | ||
389 | if (ret >= 0) | 402 | if (ret >= 0) |
390 | dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n", | 403 | dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n", |
391 | clock, fdr >> 8, fdr & 0xff); | 404 | i2c->real_clk, fdr >> 8, fdr & 0xff); |
392 | } | 405 | } |
393 | 406 | ||
394 | #else /* !CONFIG_FSL_SOC */ | 407 | #else /* !CONFIG_FSL_SOC */ |
@@ -500,10 +513,14 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
500 | return -EINTR; | 513 | return -EINTR; |
501 | } | 514 | } |
502 | if (time_after(jiffies, orig_jiffies + HZ)) { | 515 | if (time_after(jiffies, orig_jiffies + HZ)) { |
516 | u8 status = readb(i2c->base + MPC_I2C_SR); | ||
517 | |||
503 | dev_dbg(i2c->dev, "timeout\n"); | 518 | dev_dbg(i2c->dev, "timeout\n"); |
504 | if (readb(i2c->base + MPC_I2C_SR) == | 519 | if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) { |
505 | (CSR_MCF | CSR_MBB | CSR_RXAK)) | 520 | writeb(status & ~CSR_MAL, |
521 | i2c->base + MPC_I2C_SR); | ||
506 | mpc_i2c_fixup(i2c); | 522 | mpc_i2c_fixup(i2c); |
523 | } | ||
507 | return -EIO; | 524 | return -EIO; |
508 | } | 525 | } |
509 | schedule(); | 526 | schedule(); |
@@ -595,6 +612,14 @@ static int __devinit fsl_i2c_probe(struct of_device *op, | |||
595 | mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock, 0); | 612 | mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock, 0); |
596 | } | 613 | } |
597 | 614 | ||
615 | prop = of_get_property(op->dev.of_node, "fsl,timeout", &plen); | ||
616 | if (prop && plen == sizeof(u32)) { | ||
617 | mpc_ops.timeout = *prop * HZ / 1000000; | ||
618 | if (mpc_ops.timeout < 5) | ||
619 | mpc_ops.timeout = 5; | ||
620 | } | ||
621 | dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ); | ||
622 | |||
598 | dev_set_drvdata(&op->dev, i2c); | 623 | dev_set_drvdata(&op->dev, i2c); |
599 | 624 | ||
600 | i2c->adap = mpc_ops; | 625 | i2c->adap = mpc_ops; |
diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h index 847f4aad7ed5..5d48bb66aa73 100644 --- a/drivers/input/serio/i8042-io.h +++ b/drivers/input/serio/i8042-io.h | |||
@@ -27,6 +27,11 @@ | |||
27 | #include <asm/irq.h> | 27 | #include <asm/irq.h> |
28 | #elif defined(CONFIG_SH_CAYMAN) | 28 | #elif defined(CONFIG_SH_CAYMAN) |
29 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
30 | #elif defined(CONFIG_PPC) | ||
31 | extern int of_i8042_kbd_irq; | ||
32 | extern int of_i8042_aux_irq; | ||
33 | # define I8042_KBD_IRQ of_i8042_kbd_irq | ||
34 | # define I8042_AUX_IRQ of_i8042_aux_irq | ||
30 | #else | 35 | #else |
31 | # define I8042_KBD_IRQ 1 | 36 | # define I8042_KBD_IRQ 1 |
32 | # define I8042_AUX_IRQ 12 | 37 | # define I8042_AUX_IRQ 12 |
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index f22bc9f05ddb..6629d09f3b38 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
@@ -321,7 +321,7 @@ config MTD_CFI_FLAGADM | |||
321 | 321 | ||
322 | config MTD_REDWOOD | 322 | config MTD_REDWOOD |
323 | tristate "CFI Flash devices mapped on IBM Redwood" | 323 | tristate "CFI Flash devices mapped on IBM Redwood" |
324 | depends on MTD_CFI && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 ) | 324 | depends on MTD_CFI |
325 | help | 325 | help |
326 | This enables access routines for the flash chips on the IBM | 326 | This enables access routines for the flash chips on the IBM |
327 | Redwood board. If you have one of these boards and would like to | 327 | Redwood board. If you have one of these boards and would like to |
diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c index 933c0b63b016..d2c9db00db0c 100644 --- a/drivers/mtd/maps/redwood.c +++ b/drivers/mtd/maps/redwood.c | |||
@@ -22,8 +22,6 @@ | |||
22 | 22 | ||
23 | #include <asm/io.h> | 23 | #include <asm/io.h> |
24 | 24 | ||
25 | #if !defined (CONFIG_REDWOOD_6) | ||
26 | |||
27 | #define WINDOW_ADDR 0xffc00000 | 25 | #define WINDOW_ADDR 0xffc00000 |
28 | #define WINDOW_SIZE 0x00400000 | 26 | #define WINDOW_SIZE 0x00400000 |
29 | 27 | ||
@@ -69,47 +67,6 @@ static struct mtd_partition redwood_flash_partitions[] = { | |||
69 | } | 67 | } |
70 | }; | 68 | }; |
71 | 69 | ||
72 | #else /* CONFIG_REDWOOD_6 */ | ||
73 | /* FIXME: the window is bigger - armin */ | ||
74 | #define WINDOW_ADDR 0xff800000 | ||
75 | #define WINDOW_SIZE 0x00800000 | ||
76 | |||
77 | #define RW_PART0_OF 0 | ||
78 | #define RW_PART0_SZ 0x400000 /* 4 MiB data */ | ||
79 | #define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ | ||
80 | #define RW_PART1_SZ 0x10000 /* 64K VPD */ | ||
81 | #define RW_PART2_OF RW_PART1_OF + RW_PART1_SZ | ||
82 | #define RW_PART2_SZ 0x400000 - (0x10000 + 0x20000) | ||
83 | #define RW_PART3_OF RW_PART2_OF + RW_PART2_SZ | ||
84 | #define RW_PART3_SZ 0x20000 | ||
85 | |||
86 | static struct mtd_partition redwood_flash_partitions[] = { | ||
87 | { | ||
88 | .name = "Redwood filesystem", | ||
89 | .offset = RW_PART0_OF, | ||
90 | .size = RW_PART0_SZ | ||
91 | }, | ||
92 | { | ||
93 | .name = "Redwood OpenBIOS Vital Product Data", | ||
94 | .offset = RW_PART1_OF, | ||
95 | .size = RW_PART1_SZ, | ||
96 | .mask_flags = MTD_WRITEABLE /* force read-only */ | ||
97 | }, | ||
98 | { | ||
99 | .name = "Redwood kernel", | ||
100 | .offset = RW_PART2_OF, | ||
101 | .size = RW_PART2_SZ | ||
102 | }, | ||
103 | { | ||
104 | .name = "Redwood OpenBIOS", | ||
105 | .offset = RW_PART3_OF, | ||
106 | .size = RW_PART3_SZ, | ||
107 | .mask_flags = MTD_WRITEABLE /* force read-only */ | ||
108 | } | ||
109 | }; | ||
110 | |||
111 | #endif /* CONFIG_REDWOOD_6 */ | ||
112 | |||
113 | struct map_info redwood_flash_map = { | 70 | struct map_info redwood_flash_map = { |
114 | .name = "IBM Redwood", | 71 | .name = "IBM Redwood", |
115 | .size = WINDOW_SIZE, | 72 | .size = WINDOW_SIZE, |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 23c13180ff14..5a6895320b48 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -914,7 +914,7 @@ config SMC91X | |||
914 | tristate "SMC 91C9x/91C1xxx support" | 914 | tristate "SMC 91C9x/91C1xxx support" |
915 | select CRC32 | 915 | select CRC32 |
916 | select MII | 916 | select MII |
917 | depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \ | 917 | depends on ARM || M32R || SUPERH || \ |
918 | MIPS || BLACKFIN || MN10300 || COLDFIRE | 918 | MIPS || BLACKFIN || MN10300 || COLDFIRE |
919 | help | 919 | help |
920 | This is a driver for SMC's 91x series of Ethernet chipsets, | 920 | This is a driver for SMC's 91x series of Ethernet chipsets, |
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 8d2772cc42f2..ee747919a766 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h | |||
@@ -83,43 +83,6 @@ static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg) | |||
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ||
86 | #elif defined(CONFIG_REDWOOD_5) || defined(CONFIG_REDWOOD_6) | ||
87 | |||
88 | /* We can only do 16-bit reads and writes in the static memory space. */ | ||
89 | #define SMC_CAN_USE_8BIT 0 | ||
90 | #define SMC_CAN_USE_16BIT 1 | ||
91 | #define SMC_CAN_USE_32BIT 0 | ||
92 | #define SMC_NOWAIT 1 | ||
93 | |||
94 | #define SMC_IO_SHIFT 0 | ||
95 | |||
96 | #define SMC_inw(a, r) in_be16((volatile u16 *)((a) + (r))) | ||
97 | #define SMC_outw(v, a, r) out_be16((volatile u16 *)((a) + (r)), v) | ||
98 | #define SMC_insw(a, r, p, l) \ | ||
99 | do { \ | ||
100 | unsigned long __port = (a) + (r); \ | ||
101 | u16 *__p = (u16 *)(p); \ | ||
102 | int __l = (l); \ | ||
103 | insw(__port, __p, __l); \ | ||
104 | while (__l > 0) { \ | ||
105 | *__p = swab16(*__p); \ | ||
106 | __p++; \ | ||
107 | __l--; \ | ||
108 | } \ | ||
109 | } while (0) | ||
110 | #define SMC_outsw(a, r, p, l) \ | ||
111 | do { \ | ||
112 | unsigned long __port = (a) + (r); \ | ||
113 | u16 *__p = (u16 *)(p); \ | ||
114 | int __l = (l); \ | ||
115 | while (__l > 0) { \ | ||
116 | /* Believe it or not, the swab isn't needed. */ \ | ||
117 | outw( /* swab16 */ (*__p++), __port); \ | ||
118 | __l--; \ | ||
119 | } \ | ||
120 | } while (0) | ||
121 | #define SMC_IRQ_FLAGS (0) | ||
122 | |||
123 | #elif defined(CONFIG_SA1100_PLEB) | 86 | #elif defined(CONFIG_SA1100_PLEB) |
124 | /* We can only do 16-bit reads and writes in the static memory space. */ | 87 | /* We can only do 16-bit reads and writes in the static memory space. */ |
125 | #define SMC_CAN_USE_8BIT 1 | 88 | #define SMC_CAN_USE_8BIT 1 |
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 84a35f699016..1a88b363005c 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
@@ -113,7 +113,9 @@ struct psc_ops { | |||
113 | unsigned char (*read_char)(struct uart_port *port); | 113 | unsigned char (*read_char)(struct uart_port *port); |
114 | void (*cw_disable_ints)(struct uart_port *port); | 114 | void (*cw_disable_ints)(struct uart_port *port); |
115 | void (*cw_restore_ints)(struct uart_port *port); | 115 | void (*cw_restore_ints)(struct uart_port *port); |
116 | unsigned long (*getuartclk)(void *p); | 116 | unsigned int (*set_baudrate)(struct uart_port *port, |
117 | struct ktermios *new, | ||
118 | struct ktermios *old); | ||
117 | int (*clock)(struct uart_port *port, int enable); | 119 | int (*clock)(struct uart_port *port, int enable); |
118 | int (*fifoc_init)(void); | 120 | int (*fifoc_init)(void); |
119 | void (*fifoc_uninit)(void); | 121 | void (*fifoc_uninit)(void); |
@@ -121,6 +123,16 @@ struct psc_ops { | |||
121 | irqreturn_t (*handle_irq)(struct uart_port *port); | 123 | irqreturn_t (*handle_irq)(struct uart_port *port); |
122 | }; | 124 | }; |
123 | 125 | ||
126 | /* setting the prescaler and divisor reg is common for all chips */ | ||
127 | static inline void mpc52xx_set_divisor(struct mpc52xx_psc __iomem *psc, | ||
128 | u16 prescaler, unsigned int divisor) | ||
129 | { | ||
130 | /* select prescaler */ | ||
131 | out_be16(&psc->mpc52xx_psc_clock_select, prescaler); | ||
132 | out_8(&psc->ctur, divisor >> 8); | ||
133 | out_8(&psc->ctlr, divisor & 0xff); | ||
134 | } | ||
135 | |||
124 | #ifdef CONFIG_PPC_MPC52xx | 136 | #ifdef CONFIG_PPC_MPC52xx |
125 | #define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1)) | 137 | #define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1)) |
126 | static void mpc52xx_psc_fifo_init(struct uart_port *port) | 138 | static void mpc52xx_psc_fifo_init(struct uart_port *port) |
@@ -128,9 +140,6 @@ static void mpc52xx_psc_fifo_init(struct uart_port *port) | |||
128 | struct mpc52xx_psc __iomem *psc = PSC(port); | 140 | struct mpc52xx_psc __iomem *psc = PSC(port); |
129 | struct mpc52xx_psc_fifo __iomem *fifo = FIFO_52xx(port); | 141 | struct mpc52xx_psc_fifo __iomem *fifo = FIFO_52xx(port); |
130 | 142 | ||
131 | /* /32 prescaler */ | ||
132 | out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); | ||
133 | |||
134 | out_8(&fifo->rfcntl, 0x00); | 143 | out_8(&fifo->rfcntl, 0x00); |
135 | out_be16(&fifo->rfalarm, 0x1ff); | 144 | out_be16(&fifo->rfalarm, 0x1ff); |
136 | out_8(&fifo->tfcntl, 0x07); | 145 | out_8(&fifo->tfcntl, 0x07); |
@@ -219,15 +228,47 @@ static void mpc52xx_psc_cw_restore_ints(struct uart_port *port) | |||
219 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); | 228 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); |
220 | } | 229 | } |
221 | 230 | ||
222 | /* Search for bus-frequency property in this node or a parent */ | 231 | static unsigned int mpc5200_psc_set_baudrate(struct uart_port *port, |
223 | static unsigned long mpc52xx_getuartclk(void *p) | 232 | struct ktermios *new, |
233 | struct ktermios *old) | ||
224 | { | 234 | { |
225 | /* | 235 | unsigned int baud; |
226 | * 5200 UARTs have a / 32 prescaler | 236 | unsigned int divisor; |
227 | * but the generic serial code assumes 16 | 237 | |
228 | * so return ipb freq / 2 | 238 | /* The 5200 has a fixed /32 prescaler, uartclk contains the ipb freq */ |
229 | */ | 239 | baud = uart_get_baud_rate(port, new, old, |
230 | return mpc5xxx_get_bus_frequency(p) / 2; | 240 | port->uartclk / (32 * 0xffff) + 1, |
241 | port->uartclk / 32); | ||
242 | divisor = (port->uartclk + 16 * baud) / (32 * baud); | ||
243 | |||
244 | /* enable the /32 prescaler and set the divisor */ | ||
245 | mpc52xx_set_divisor(PSC(port), 0xdd00, divisor); | ||
246 | return baud; | ||
247 | } | ||
248 | |||
249 | static unsigned int mpc5200b_psc_set_baudrate(struct uart_port *port, | ||
250 | struct ktermios *new, | ||
251 | struct ktermios *old) | ||
252 | { | ||
253 | unsigned int baud; | ||
254 | unsigned int divisor; | ||
255 | u16 prescaler; | ||
256 | |||
257 | /* The 5200B has a selectable /4 or /32 prescaler, uartclk contains the | ||
258 | * ipb freq */ | ||
259 | baud = uart_get_baud_rate(port, new, old, | ||
260 | port->uartclk / (32 * 0xffff) + 1, | ||
261 | port->uartclk / 4); | ||
262 | divisor = (port->uartclk + 2 * baud) / (4 * baud); | ||
263 | |||
264 | /* select the proper prescaler and set the divisor */ | ||
265 | if (divisor > 0xffff) { | ||
266 | divisor = (divisor + 4) / 8; | ||
267 | prescaler = 0xdd00; /* /32 */ | ||
268 | } else | ||
269 | prescaler = 0xff00; /* /4 */ | ||
270 | mpc52xx_set_divisor(PSC(port), prescaler, divisor); | ||
271 | return baud; | ||
231 | } | 272 | } |
232 | 273 | ||
233 | static void mpc52xx_psc_get_irq(struct uart_port *port, struct device_node *np) | 274 | static void mpc52xx_psc_get_irq(struct uart_port *port, struct device_node *np) |
@@ -258,7 +299,28 @@ static struct psc_ops mpc52xx_psc_ops = { | |||
258 | .read_char = mpc52xx_psc_read_char, | 299 | .read_char = mpc52xx_psc_read_char, |
259 | .cw_disable_ints = mpc52xx_psc_cw_disable_ints, | 300 | .cw_disable_ints = mpc52xx_psc_cw_disable_ints, |
260 | .cw_restore_ints = mpc52xx_psc_cw_restore_ints, | 301 | .cw_restore_ints = mpc52xx_psc_cw_restore_ints, |
261 | .getuartclk = mpc52xx_getuartclk, | 302 | .set_baudrate = mpc5200_psc_set_baudrate, |
303 | .get_irq = mpc52xx_psc_get_irq, | ||
304 | .handle_irq = mpc52xx_psc_handle_irq, | ||
305 | }; | ||
306 | |||
307 | static struct psc_ops mpc5200b_psc_ops = { | ||
308 | .fifo_init = mpc52xx_psc_fifo_init, | ||
309 | .raw_rx_rdy = mpc52xx_psc_raw_rx_rdy, | ||
310 | .raw_tx_rdy = mpc52xx_psc_raw_tx_rdy, | ||
311 | .rx_rdy = mpc52xx_psc_rx_rdy, | ||
312 | .tx_rdy = mpc52xx_psc_tx_rdy, | ||
313 | .tx_empty = mpc52xx_psc_tx_empty, | ||
314 | .stop_rx = mpc52xx_psc_stop_rx, | ||
315 | .start_tx = mpc52xx_psc_start_tx, | ||
316 | .stop_tx = mpc52xx_psc_stop_tx, | ||
317 | .rx_clr_irq = mpc52xx_psc_rx_clr_irq, | ||
318 | .tx_clr_irq = mpc52xx_psc_tx_clr_irq, | ||
319 | .write_char = mpc52xx_psc_write_char, | ||
320 | .read_char = mpc52xx_psc_read_char, | ||
321 | .cw_disable_ints = mpc52xx_psc_cw_disable_ints, | ||
322 | .cw_restore_ints = mpc52xx_psc_cw_restore_ints, | ||
323 | .set_baudrate = mpc5200b_psc_set_baudrate, | ||
262 | .get_irq = mpc52xx_psc_get_irq, | 324 | .get_irq = mpc52xx_psc_get_irq, |
263 | .handle_irq = mpc52xx_psc_handle_irq, | 325 | .handle_irq = mpc52xx_psc_handle_irq, |
264 | }; | 326 | }; |
@@ -392,9 +454,35 @@ static void mpc512x_psc_cw_restore_ints(struct uart_port *port) | |||
392 | out_be32(&FIFO_512x(port)->rximr, port->read_status_mask & 0x7f); | 454 | out_be32(&FIFO_512x(port)->rximr, port->read_status_mask & 0x7f); |
393 | } | 455 | } |
394 | 456 | ||
395 | static unsigned long mpc512x_getuartclk(void *p) | 457 | static unsigned int mpc512x_psc_set_baudrate(struct uart_port *port, |
458 | struct ktermios *new, | ||
459 | struct ktermios *old) | ||
396 | { | 460 | { |
397 | return mpc5xxx_get_bus_frequency(p); | 461 | unsigned int baud; |
462 | unsigned int divisor; | ||
463 | |||
464 | /* | ||
465 | * The "MPC5121e Microcontroller Reference Manual, Rev. 3" says on | ||
466 | * pg. 30-10 that the chip supports a /32 and a /10 prescaler. | ||
467 | * Furthermore, it states that "After reset, the prescaler by 10 | ||
468 | * for the UART mode is selected", but the reset register value is | ||
469 | * 0x0000 which means a /32 prescaler. This is wrong. | ||
470 | * | ||
471 | * In reality using /32 prescaler doesn't work, as it is not supported! | ||
472 | * Use /16 or /10 prescaler, see "MPC5121e Hardware Design Guide", | ||
473 | * Chapter 4.1 PSC in UART Mode. | ||
474 | * Calculate with a /16 prescaler here. | ||
475 | */ | ||
476 | |||
477 | /* uartclk contains the ips freq */ | ||
478 | baud = uart_get_baud_rate(port, new, old, | ||
479 | port->uartclk / (16 * 0xffff) + 1, | ||
480 | port->uartclk / 16); | ||
481 | divisor = (port->uartclk + 8 * baud) / (16 * baud); | ||
482 | |||
483 | /* enable the /16 prescaler and set the divisor */ | ||
484 | mpc52xx_set_divisor(PSC(port), 0xdd00, divisor); | ||
485 | return baud; | ||
398 | } | 486 | } |
399 | 487 | ||
400 | /* Init PSC FIFO Controller */ | 488 | /* Init PSC FIFO Controller */ |
@@ -498,7 +586,7 @@ static struct psc_ops mpc512x_psc_ops = { | |||
498 | .read_char = mpc512x_psc_read_char, | 586 | .read_char = mpc512x_psc_read_char, |
499 | .cw_disable_ints = mpc512x_psc_cw_disable_ints, | 587 | .cw_disable_ints = mpc512x_psc_cw_disable_ints, |
500 | .cw_restore_ints = mpc512x_psc_cw_restore_ints, | 588 | .cw_restore_ints = mpc512x_psc_cw_restore_ints, |
501 | .getuartclk = mpc512x_getuartclk, | 589 | .set_baudrate = mpc512x_psc_set_baudrate, |
502 | .clock = mpc512x_psc_clock, | 590 | .clock = mpc512x_psc_clock, |
503 | .fifoc_init = mpc512x_psc_fifoc_init, | 591 | .fifoc_init = mpc512x_psc_fifoc_init, |
504 | .fifoc_uninit = mpc512x_psc_fifoc_uninit, | 592 | .fifoc_uninit = mpc512x_psc_fifoc_uninit, |
@@ -666,8 +754,8 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
666 | struct mpc52xx_psc __iomem *psc = PSC(port); | 754 | struct mpc52xx_psc __iomem *psc = PSC(port); |
667 | unsigned long flags; | 755 | unsigned long flags; |
668 | unsigned char mr1, mr2; | 756 | unsigned char mr1, mr2; |
669 | unsigned short ctr; | 757 | unsigned int j; |
670 | unsigned int j, baud, quot; | 758 | unsigned int baud; |
671 | 759 | ||
672 | /* Prepare what we're gonna write */ | 760 | /* Prepare what we're gonna write */ |
673 | mr1 = 0; | 761 | mr1 = 0; |
@@ -704,16 +792,9 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
704 | mr2 |= MPC52xx_PSC_MODE_TXCTS; | 792 | mr2 |= MPC52xx_PSC_MODE_TXCTS; |
705 | } | 793 | } |
706 | 794 | ||
707 | baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16); | ||
708 | quot = uart_get_divisor(port, baud); | ||
709 | ctr = quot & 0xffff; | ||
710 | |||
711 | /* Get the lock */ | 795 | /* Get the lock */ |
712 | spin_lock_irqsave(&port->lock, flags); | 796 | spin_lock_irqsave(&port->lock, flags); |
713 | 797 | ||
714 | /* Update the per-port timeout */ | ||
715 | uart_update_timeout(port, new->c_cflag, baud); | ||
716 | |||
717 | /* Do our best to flush TX & RX, so we don't lose anything */ | 798 | /* Do our best to flush TX & RX, so we don't lose anything */ |
718 | /* But we don't wait indefinitely ! */ | 799 | /* But we don't wait indefinitely ! */ |
719 | j = 5000000; /* Maximum wait */ | 800 | j = 5000000; /* Maximum wait */ |
@@ -737,8 +818,10 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
737 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); | 818 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); |
738 | out_8(&psc->mode, mr1); | 819 | out_8(&psc->mode, mr1); |
739 | out_8(&psc->mode, mr2); | 820 | out_8(&psc->mode, mr2); |
740 | out_8(&psc->ctur, ctr >> 8); | 821 | baud = psc_ops->set_baudrate(port, new, old); |
741 | out_8(&psc->ctlr, ctr & 0xff); | 822 | |
823 | /* Update the per-port timeout */ | ||
824 | uart_update_timeout(port, new->c_cflag, baud); | ||
742 | 825 | ||
743 | if (UART_ENABLE_MS(port, new->c_cflag)) | 826 | if (UART_ENABLE_MS(port, new->c_cflag)) |
744 | mpc52xx_uart_enable_ms(port); | 827 | mpc52xx_uart_enable_ms(port); |
@@ -1118,7 +1201,7 @@ mpc52xx_console_setup(struct console *co, char *options) | |||
1118 | return ret; | 1201 | return ret; |
1119 | } | 1202 | } |
1120 | 1203 | ||
1121 | uartclk = psc_ops->getuartclk(np); | 1204 | uartclk = mpc5xxx_get_bus_frequency(np); |
1122 | if (uartclk == 0) { | 1205 | if (uartclk == 0) { |
1123 | pr_debug("Could not find uart clock frequency!\n"); | 1206 | pr_debug("Could not find uart clock frequency!\n"); |
1124 | return -EINVAL; | 1207 | return -EINVAL; |
@@ -1201,6 +1284,7 @@ static struct uart_driver mpc52xx_uart_driver = { | |||
1201 | 1284 | ||
1202 | static struct of_device_id mpc52xx_uart_of_match[] = { | 1285 | static struct of_device_id mpc52xx_uart_of_match[] = { |
1203 | #ifdef CONFIG_PPC_MPC52xx | 1286 | #ifdef CONFIG_PPC_MPC52xx |
1287 | { .compatible = "fsl,mpc5200b-psc-uart", .data = &mpc5200b_psc_ops, }, | ||
1204 | { .compatible = "fsl,mpc5200-psc-uart", .data = &mpc52xx_psc_ops, }, | 1288 | { .compatible = "fsl,mpc5200-psc-uart", .data = &mpc52xx_psc_ops, }, |
1205 | /* binding used by old lite5200 device trees: */ | 1289 | /* binding used by old lite5200 device trees: */ |
1206 | { .compatible = "mpc5200-psc-uart", .data = &mpc52xx_psc_ops, }, | 1290 | { .compatible = "mpc5200-psc-uart", .data = &mpc52xx_psc_ops, }, |
@@ -1233,7 +1317,10 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
1233 | pr_debug("Found %s assigned to ttyPSC%x\n", | 1317 | pr_debug("Found %s assigned to ttyPSC%x\n", |
1234 | mpc52xx_uart_nodes[idx]->full_name, idx); | 1318 | mpc52xx_uart_nodes[idx]->full_name, idx); |
1235 | 1319 | ||
1236 | uartclk = psc_ops->getuartclk(op->dev.of_node); | 1320 | /* set the uart clock to the input clock of the psc, the different |
1321 | * prescalers are taken into account in the set_baudrate() methods | ||
1322 | * of the respective chip */ | ||
1323 | uartclk = mpc5xxx_get_bus_frequency(op->dev.of_node); | ||
1237 | if (uartclk == 0) { | 1324 | if (uartclk == 0) { |
1238 | dev_dbg(&op->dev, "Could not find uart clock frequency!\n"); | 1325 | dev_dbg(&op->dev, "Could not find uart clock frequency!\n"); |
1239 | return -EINVAL; | 1326 | return -EINVAL; |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 9e711a1d0d97..7b11ea68c80e 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -1871,6 +1871,7 @@ config FB_MBX_DEBUG | |||
1871 | config FB_FSL_DIU | 1871 | config FB_FSL_DIU |
1872 | tristate "Freescale DIU framebuffer support" | 1872 | tristate "Freescale DIU framebuffer support" |
1873 | depends on FB && FSL_SOC | 1873 | depends on FB && FSL_SOC |
1874 | select FB_MODE_HELPERS | ||
1874 | select FB_CFB_FILLRECT | 1875 | select FB_CFB_FILLRECT |
1875 | select FB_CFB_COPYAREA | 1876 | select FB_CFB_COPYAREA |
1876 | select FB_CFB_IMAGEBLIT | 1877 | select FB_CFB_IMAGEBLIT |
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 27455ce298b7..e38ad2224540 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c | |||
@@ -34,7 +34,8 @@ | |||
34 | #include <linux/of_platform.h> | 34 | #include <linux/of_platform.h> |
35 | 35 | ||
36 | #include <sysdev/fsl_soc.h> | 36 | #include <sysdev/fsl_soc.h> |
37 | #include "fsl-diu-fb.h" | 37 | #include <linux/fsl-diu-fb.h> |
38 | #include "edid.h" | ||
38 | 39 | ||
39 | /* | 40 | /* |
40 | * These parameters give default parameters | 41 | * These parameters give default parameters |
@@ -217,6 +218,7 @@ struct mfb_info { | |||
217 | int x_aoi_d; /* aoi display x offset to physical screen */ | 218 | int x_aoi_d; /* aoi display x offset to physical screen */ |
218 | int y_aoi_d; /* aoi display y offset to physical screen */ | 219 | int y_aoi_d; /* aoi display y offset to physical screen */ |
219 | struct fsl_diu_data *parent; | 220 | struct fsl_diu_data *parent; |
221 | u8 *edid_data; | ||
220 | }; | 222 | }; |
221 | 223 | ||
222 | 224 | ||
@@ -317,6 +319,17 @@ static void fsl_diu_free(void *virt, size_t size) | |||
317 | free_pages_exact(virt, size); | 319 | free_pages_exact(virt, size); |
318 | } | 320 | } |
319 | 321 | ||
322 | /* | ||
323 | * Workaround for failed writing desc register of planes. | ||
324 | * Needed with MPC5121 DIU rev 2.0 silicon. | ||
325 | */ | ||
326 | void wr_reg_wa(u32 *reg, u32 val) | ||
327 | { | ||
328 | do { | ||
329 | out_be32(reg, val); | ||
330 | } while (in_be32(reg) != val); | ||
331 | } | ||
332 | |||
320 | static int fsl_diu_enable_panel(struct fb_info *info) | 333 | static int fsl_diu_enable_panel(struct fb_info *info) |
321 | { | 334 | { |
322 | struct mfb_info *pmfbi, *cmfbi, *mfbi = info->par; | 335 | struct mfb_info *pmfbi, *cmfbi, *mfbi = info->par; |
@@ -330,7 +343,7 @@ static int fsl_diu_enable_panel(struct fb_info *info) | |||
330 | switch (mfbi->index) { | 343 | switch (mfbi->index) { |
331 | case 0: /* plane 0 */ | 344 | case 0: /* plane 0 */ |
332 | if (hw->desc[0] != ad->paddr) | 345 | if (hw->desc[0] != ad->paddr) |
333 | out_be32(&hw->desc[0], ad->paddr); | 346 | wr_reg_wa(&hw->desc[0], ad->paddr); |
334 | break; | 347 | break; |
335 | case 1: /* plane 1 AOI 0 */ | 348 | case 1: /* plane 1 AOI 0 */ |
336 | cmfbi = machine_data->fsl_diu_info[2]->par; | 349 | cmfbi = machine_data->fsl_diu_info[2]->par; |
@@ -340,7 +353,7 @@ static int fsl_diu_enable_panel(struct fb_info *info) | |||
340 | cpu_to_le32(cmfbi->ad->paddr); | 353 | cpu_to_le32(cmfbi->ad->paddr); |
341 | else | 354 | else |
342 | ad->next_ad = 0; | 355 | ad->next_ad = 0; |
343 | out_be32(&hw->desc[1], ad->paddr); | 356 | wr_reg_wa(&hw->desc[1], ad->paddr); |
344 | } | 357 | } |
345 | break; | 358 | break; |
346 | case 3: /* plane 2 AOI 0 */ | 359 | case 3: /* plane 2 AOI 0 */ |
@@ -351,14 +364,14 @@ static int fsl_diu_enable_panel(struct fb_info *info) | |||
351 | cpu_to_le32(cmfbi->ad->paddr); | 364 | cpu_to_le32(cmfbi->ad->paddr); |
352 | else | 365 | else |
353 | ad->next_ad = 0; | 366 | ad->next_ad = 0; |
354 | out_be32(&hw->desc[2], ad->paddr); | 367 | wr_reg_wa(&hw->desc[2], ad->paddr); |
355 | } | 368 | } |
356 | break; | 369 | break; |
357 | case 2: /* plane 1 AOI 1 */ | 370 | case 2: /* plane 1 AOI 1 */ |
358 | pmfbi = machine_data->fsl_diu_info[1]->par; | 371 | pmfbi = machine_data->fsl_diu_info[1]->par; |
359 | ad->next_ad = 0; | 372 | ad->next_ad = 0; |
360 | if (hw->desc[1] == machine_data->dummy_ad->paddr) | 373 | if (hw->desc[1] == machine_data->dummy_ad->paddr) |
361 | out_be32(&hw->desc[1], ad->paddr); | 374 | wr_reg_wa(&hw->desc[1], ad->paddr); |
362 | else /* AOI0 open */ | 375 | else /* AOI0 open */ |
363 | pmfbi->ad->next_ad = cpu_to_le32(ad->paddr); | 376 | pmfbi->ad->next_ad = cpu_to_le32(ad->paddr); |
364 | break; | 377 | break; |
@@ -366,7 +379,7 @@ static int fsl_diu_enable_panel(struct fb_info *info) | |||
366 | pmfbi = machine_data->fsl_diu_info[3]->par; | 379 | pmfbi = machine_data->fsl_diu_info[3]->par; |
367 | ad->next_ad = 0; | 380 | ad->next_ad = 0; |
368 | if (hw->desc[2] == machine_data->dummy_ad->paddr) | 381 | if (hw->desc[2] == machine_data->dummy_ad->paddr) |
369 | out_be32(&hw->desc[2], ad->paddr); | 382 | wr_reg_wa(&hw->desc[2], ad->paddr); |
370 | else /* AOI0 was open */ | 383 | else /* AOI0 was open */ |
371 | pmfbi->ad->next_ad = cpu_to_le32(ad->paddr); | 384 | pmfbi->ad->next_ad = cpu_to_le32(ad->paddr); |
372 | break; | 385 | break; |
@@ -390,27 +403,24 @@ static int fsl_diu_disable_panel(struct fb_info *info) | |||
390 | switch (mfbi->index) { | 403 | switch (mfbi->index) { |
391 | case 0: /* plane 0 */ | 404 | case 0: /* plane 0 */ |
392 | if (hw->desc[0] != machine_data->dummy_ad->paddr) | 405 | if (hw->desc[0] != machine_data->dummy_ad->paddr) |
393 | out_be32(&hw->desc[0], | 406 | wr_reg_wa(&hw->desc[0], machine_data->dummy_ad->paddr); |
394 | machine_data->dummy_ad->paddr); | ||
395 | break; | 407 | break; |
396 | case 1: /* plane 1 AOI 0 */ | 408 | case 1: /* plane 1 AOI 0 */ |
397 | cmfbi = machine_data->fsl_diu_info[2]->par; | 409 | cmfbi = machine_data->fsl_diu_info[2]->par; |
398 | if (cmfbi->count > 0) /* AOI1 is open */ | 410 | if (cmfbi->count > 0) /* AOI1 is open */ |
399 | out_be32(&hw->desc[1], cmfbi->ad->paddr); | 411 | wr_reg_wa(&hw->desc[1], cmfbi->ad->paddr); |
400 | /* move AOI1 to the first */ | 412 | /* move AOI1 to the first */ |
401 | else /* AOI1 was closed */ | 413 | else /* AOI1 was closed */ |
402 | out_be32(&hw->desc[1], | 414 | wr_reg_wa(&hw->desc[1], machine_data->dummy_ad->paddr); |
403 | machine_data->dummy_ad->paddr); | ||
404 | /* close AOI 0 */ | 415 | /* close AOI 0 */ |
405 | break; | 416 | break; |
406 | case 3: /* plane 2 AOI 0 */ | 417 | case 3: /* plane 2 AOI 0 */ |
407 | cmfbi = machine_data->fsl_diu_info[4]->par; | 418 | cmfbi = machine_data->fsl_diu_info[4]->par; |
408 | if (cmfbi->count > 0) /* AOI1 is open */ | 419 | if (cmfbi->count > 0) /* AOI1 is open */ |
409 | out_be32(&hw->desc[2], cmfbi->ad->paddr); | 420 | wr_reg_wa(&hw->desc[2], cmfbi->ad->paddr); |
410 | /* move AOI1 to the first */ | 421 | /* move AOI1 to the first */ |
411 | else /* AOI1 was closed */ | 422 | else /* AOI1 was closed */ |
412 | out_be32(&hw->desc[2], | 423 | wr_reg_wa(&hw->desc[2], machine_data->dummy_ad->paddr); |
413 | machine_data->dummy_ad->paddr); | ||
414 | /* close AOI 0 */ | 424 | /* close AOI 0 */ |
415 | break; | 425 | break; |
416 | case 2: /* plane 1 AOI 1 */ | 426 | case 2: /* plane 1 AOI 1 */ |
@@ -421,7 +431,7 @@ static int fsl_diu_disable_panel(struct fb_info *info) | |||
421 | /* AOI0 is open, must be the first */ | 431 | /* AOI0 is open, must be the first */ |
422 | pmfbi->ad->next_ad = 0; | 432 | pmfbi->ad->next_ad = 0; |
423 | } else /* AOI1 is the first in the chain */ | 433 | } else /* AOI1 is the first in the chain */ |
424 | out_be32(&hw->desc[1], machine_data->dummy_ad->paddr); | 434 | wr_reg_wa(&hw->desc[1], machine_data->dummy_ad->paddr); |
425 | /* close AOI 1 */ | 435 | /* close AOI 1 */ |
426 | break; | 436 | break; |
427 | case 4: /* plane 2 AOI 1 */ | 437 | case 4: /* plane 2 AOI 1 */ |
@@ -432,7 +442,7 @@ static int fsl_diu_disable_panel(struct fb_info *info) | |||
432 | /* AOI0 is open, must be the first */ | 442 | /* AOI0 is open, must be the first */ |
433 | pmfbi->ad->next_ad = 0; | 443 | pmfbi->ad->next_ad = 0; |
434 | } else /* AOI1 is the first in the chain */ | 444 | } else /* AOI1 is the first in the chain */ |
435 | out_be32(&hw->desc[2], machine_data->dummy_ad->paddr); | 445 | wr_reg_wa(&hw->desc[2], machine_data->dummy_ad->paddr); |
436 | /* close AOI 1 */ | 446 | /* close AOI 1 */ |
437 | break; | 447 | break; |
438 | default: | 448 | default: |
@@ -1100,6 +1110,10 @@ static int fsl_diu_open(struct fb_info *info, int user) | |||
1100 | struct mfb_info *mfbi = info->par; | 1110 | struct mfb_info *mfbi = info->par; |
1101 | int res = 0; | 1111 | int res = 0; |
1102 | 1112 | ||
1113 | /* free boot splash memory on first /dev/fb0 open */ | ||
1114 | if (!mfbi->index && diu_ops.release_bootmem) | ||
1115 | diu_ops.release_bootmem(); | ||
1116 | |||
1103 | spin_lock(&diu_lock); | 1117 | spin_lock(&diu_lock); |
1104 | mfbi->count++; | 1118 | mfbi->count++; |
1105 | if (mfbi->count == 1) { | 1119 | if (mfbi->count == 1) { |
@@ -1173,18 +1187,30 @@ static int __devinit install_fb(struct fb_info *info) | |||
1173 | int rc; | 1187 | int rc; |
1174 | struct mfb_info *mfbi = info->par; | 1188 | struct mfb_info *mfbi = info->par; |
1175 | const char *aoi_mode, *init_aoi_mode = "320x240"; | 1189 | const char *aoi_mode, *init_aoi_mode = "320x240"; |
1190 | struct fb_videomode *db = fsl_diu_mode_db; | ||
1191 | unsigned int dbsize = ARRAY_SIZE(fsl_diu_mode_db); | ||
1192 | int has_default_mode = 1; | ||
1176 | 1193 | ||
1177 | if (init_fbinfo(info)) | 1194 | if (init_fbinfo(info)) |
1178 | return -EINVAL; | 1195 | return -EINVAL; |
1179 | 1196 | ||
1180 | if (mfbi->index == 0) /* plane 0 */ | 1197 | if (mfbi->index == 0) { /* plane 0 */ |
1198 | if (mfbi->edid_data) { | ||
1199 | /* Now build modedb from EDID */ | ||
1200 | fb_edid_to_monspecs(mfbi->edid_data, &info->monspecs); | ||
1201 | fb_videomode_to_modelist(info->monspecs.modedb, | ||
1202 | info->monspecs.modedb_len, | ||
1203 | &info->modelist); | ||
1204 | db = info->monspecs.modedb; | ||
1205 | dbsize = info->monspecs.modedb_len; | ||
1206 | } | ||
1181 | aoi_mode = fb_mode; | 1207 | aoi_mode = fb_mode; |
1182 | else | 1208 | } else { |
1183 | aoi_mode = init_aoi_mode; | 1209 | aoi_mode = init_aoi_mode; |
1210 | } | ||
1184 | pr_debug("mode used = %s\n", aoi_mode); | 1211 | pr_debug("mode used = %s\n", aoi_mode); |
1185 | rc = fb_find_mode(&info->var, info, aoi_mode, fsl_diu_mode_db, | 1212 | rc = fb_find_mode(&info->var, info, aoi_mode, db, dbsize, |
1186 | ARRAY_SIZE(fsl_diu_mode_db), &fsl_diu_default_mode, default_bpp); | 1213 | &fsl_diu_default_mode, default_bpp); |
1187 | |||
1188 | switch (rc) { | 1214 | switch (rc) { |
1189 | case 1: | 1215 | case 1: |
1190 | pr_debug("using mode specified in @mode\n"); | 1216 | pr_debug("using mode specified in @mode\n"); |
@@ -1202,10 +1228,50 @@ static int __devinit install_fb(struct fb_info *info) | |||
1202 | default: | 1228 | default: |
1203 | pr_debug("rc = %d\n", rc); | 1229 | pr_debug("rc = %d\n", rc); |
1204 | pr_debug("failed to find mode\n"); | 1230 | pr_debug("failed to find mode\n"); |
1205 | return -EINVAL; | 1231 | /* |
1232 | * For plane 0 we continue and look into | ||
1233 | * driver's internal modedb. | ||
1234 | */ | ||
1235 | if (mfbi->index == 0 && mfbi->edid_data) | ||
1236 | has_default_mode = 0; | ||
1237 | else | ||
1238 | return -EINVAL; | ||
1206 | break; | 1239 | break; |
1207 | } | 1240 | } |
1208 | 1241 | ||
1242 | if (!has_default_mode) { | ||
1243 | rc = fb_find_mode(&info->var, info, aoi_mode, fsl_diu_mode_db, | ||
1244 | ARRAY_SIZE(fsl_diu_mode_db), | ||
1245 | &fsl_diu_default_mode, | ||
1246 | default_bpp); | ||
1247 | if (rc > 0 && rc < 5) | ||
1248 | has_default_mode = 1; | ||
1249 | } | ||
1250 | |||
1251 | /* Still not found, use preferred mode from database if any */ | ||
1252 | if (!has_default_mode && info->monspecs.modedb) { | ||
1253 | struct fb_monspecs *specs = &info->monspecs; | ||
1254 | struct fb_videomode *modedb = &specs->modedb[0]; | ||
1255 | |||
1256 | /* | ||
1257 | * Get preferred timing. If not found, | ||
1258 | * first mode in database will be used. | ||
1259 | */ | ||
1260 | if (specs->misc & FB_MISC_1ST_DETAIL) { | ||
1261 | int i; | ||
1262 | |||
1263 | for (i = 0; i < specs->modedb_len; i++) { | ||
1264 | if (specs->modedb[i].flag & FB_MODE_IS_FIRST) { | ||
1265 | modedb = &specs->modedb[i]; | ||
1266 | break; | ||
1267 | } | ||
1268 | } | ||
1269 | } | ||
1270 | |||
1271 | info->var.bits_per_pixel = default_bpp; | ||
1272 | fb_videomode_to_var(&info->var, modedb); | ||
1273 | } | ||
1274 | |||
1209 | pr_debug("xres_virtual %d\n", info->var.xres_virtual); | 1275 | pr_debug("xres_virtual %d\n", info->var.xres_virtual); |
1210 | pr_debug("bits_per_pixel %d\n", info->var.bits_per_pixel); | 1276 | pr_debug("bits_per_pixel %d\n", info->var.bits_per_pixel); |
1211 | 1277 | ||
@@ -1244,6 +1310,9 @@ static void uninstall_fb(struct fb_info *info) | |||
1244 | if (!mfbi->registered) | 1310 | if (!mfbi->registered) |
1245 | return; | 1311 | return; |
1246 | 1312 | ||
1313 | if (mfbi->index == 0) | ||
1314 | kfree(mfbi->edid_data); | ||
1315 | |||
1247 | unregister_framebuffer(info); | 1316 | unregister_framebuffer(info); |
1248 | unmap_video_memory(info); | 1317 | unmap_video_memory(info); |
1249 | if (&info->cmap) | 1318 | if (&info->cmap) |
@@ -1427,6 +1496,7 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev, | |||
1427 | int ret, i, error = 0; | 1496 | int ret, i, error = 0; |
1428 | struct resource res; | 1497 | struct resource res; |
1429 | struct fsl_diu_data *machine_data; | 1498 | struct fsl_diu_data *machine_data; |
1499 | int diu_mode; | ||
1430 | 1500 | ||
1431 | machine_data = kzalloc(sizeof(struct fsl_diu_data), GFP_KERNEL); | 1501 | machine_data = kzalloc(sizeof(struct fsl_diu_data), GFP_KERNEL); |
1432 | if (!machine_data) | 1502 | if (!machine_data) |
@@ -1443,6 +1513,17 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev, | |||
1443 | mfbi = machine_data->fsl_diu_info[i]->par; | 1513 | mfbi = machine_data->fsl_diu_info[i]->par; |
1444 | memcpy(mfbi, &mfb_template[i], sizeof(struct mfb_info)); | 1514 | memcpy(mfbi, &mfb_template[i], sizeof(struct mfb_info)); |
1445 | mfbi->parent = machine_data; | 1515 | mfbi->parent = machine_data; |
1516 | |||
1517 | if (mfbi->index == 0) { | ||
1518 | const u8 *prop; | ||
1519 | int len; | ||
1520 | |||
1521 | /* Get EDID */ | ||
1522 | prop = of_get_property(np, "edid", &len); | ||
1523 | if (prop && len == EDID_LENGTH) | ||
1524 | mfbi->edid_data = kmemdup(prop, EDID_LENGTH, | ||
1525 | GFP_KERNEL); | ||
1526 | } | ||
1446 | } | 1527 | } |
1447 | 1528 | ||
1448 | ret = of_address_to_resource(np, 0, &res); | 1529 | ret = of_address_to_resource(np, 0, &res); |
@@ -1463,7 +1544,9 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev, | |||
1463 | goto error2; | 1544 | goto error2; |
1464 | } | 1545 | } |
1465 | 1546 | ||
1466 | out_be32(&dr.diu_reg->diu_mode, 0); /* disable DIU anyway*/ | 1547 | diu_mode = in_be32(&dr.diu_reg->diu_mode); |
1548 | if (diu_mode != MFB_MODE1) | ||
1549 | out_be32(&dr.diu_reg->diu_mode, 0); /* disable DIU */ | ||
1467 | 1550 | ||
1468 | /* Get the IRQ of the DIU */ | 1551 | /* Get the IRQ of the DIU */ |
1469 | machine_data->irq = irq_of_parse_and_map(np, 0); | 1552 | machine_data->irq = irq_of_parse_and_map(np, 0); |
@@ -1511,7 +1594,13 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev, | |||
1511 | machine_data->dummy_ad->offset_xyd = 0; | 1594 | machine_data->dummy_ad->offset_xyd = 0; |
1512 | machine_data->dummy_ad->next_ad = 0; | 1595 | machine_data->dummy_ad->next_ad = 0; |
1513 | 1596 | ||
1514 | out_be32(&dr.diu_reg->desc[0], machine_data->dummy_ad->paddr); | 1597 | /* |
1598 | * Let DIU display splash screen if it was pre-initialized | ||
1599 | * by the bootloader, set dummy area descriptor otherwise. | ||
1600 | */ | ||
1601 | if (diu_mode != MFB_MODE1) | ||
1602 | out_be32(&dr.diu_reg->desc[0], machine_data->dummy_ad->paddr); | ||
1603 | |||
1515 | out_be32(&dr.diu_reg->desc[1], machine_data->dummy_ad->paddr); | 1604 | out_be32(&dr.diu_reg->desc[1], machine_data->dummy_ad->paddr); |
1516 | out_be32(&dr.diu_reg->desc[2], machine_data->dummy_ad->paddr); | 1605 | out_be32(&dr.diu_reg->desc[2], machine_data->dummy_ad->paddr); |
1517 | 1606 | ||
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 574dc54e12d4..29b5daacc217 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c | |||
@@ -485,6 +485,8 @@ static int __devexit xilinxfb_of_remove(struct of_device *op) | |||
485 | /* Match table for of_platform binding */ | 485 | /* Match table for of_platform binding */ |
486 | static struct of_device_id xilinxfb_of_match[] __devinitdata = { | 486 | static struct of_device_id xilinxfb_of_match[] __devinitdata = { |
487 | { .compatible = "xlnx,xps-tft-1.00.a", }, | 487 | { .compatible = "xlnx,xps-tft-1.00.a", }, |
488 | { .compatible = "xlnx,xps-tft-2.00.a", }, | ||
489 | { .compatible = "xlnx,xps-tft-2.01.a", }, | ||
488 | { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", }, | 490 | { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", }, |
489 | { .compatible = "xlnx,plb-dvi-cntlr-ref-1.00.c", }, | 491 | { .compatible = "xlnx,plb-dvi-cntlr-ref-1.00.c", }, |
490 | {}, | 492 | {}, |
diff --git a/drivers/video/fsl-diu-fb.h b/include/linux/fsl-diu-fb.h index fc295d7ea463..fc295d7ea463 100644 --- a/drivers/video/fsl-diu-fb.h +++ b/include/linux/fsl-diu-fb.h | |||
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index e69612cace61..33145408f045 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -2264,6 +2264,7 @@ | |||
2264 | #define PCI_DEVICE_ID_TDI_EHCI 0x0101 | 2264 | #define PCI_DEVICE_ID_TDI_EHCI 0x0101 |
2265 | 2265 | ||
2266 | #define PCI_VENDOR_ID_FREESCALE 0x1957 | 2266 | #define PCI_VENDOR_ID_FREESCALE 0x1957 |
2267 | #define PCI_DEVICE_ID_MPC8308 0xc006 | ||
2267 | #define PCI_DEVICE_ID_MPC8315E 0x00b4 | 2268 | #define PCI_DEVICE_ID_MPC8315E 0x00b4 |
2268 | #define PCI_DEVICE_ID_MPC8315 0x00b5 | 2269 | #define PCI_DEVICE_ID_MPC8315 0x00b5 |
2269 | #define PCI_DEVICE_ID_MPC8314E 0x00b6 | 2270 | #define PCI_DEVICE_ID_MPC8314E 0x00b6 |
diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c index 7a56b22e0602..71ed3ce29e12 100644 --- a/kernel/hw_breakpoint.c +++ b/kernel/hw_breakpoint.c | |||
@@ -242,6 +242,17 @@ toggle_bp_slot(struct perf_event *bp, bool enable, enum bp_type_idx type, | |||
242 | } | 242 | } |
243 | 243 | ||
244 | /* | 244 | /* |
245 | * Function to perform processor-specific cleanup during unregistration | ||
246 | */ | ||
247 | __weak void arch_unregister_hw_breakpoint(struct perf_event *bp) | ||
248 | { | ||
249 | /* | ||
250 | * A weak stub function here for those archs that don't define | ||
251 | * it inside arch/.../kernel/hw_breakpoint.c | ||
252 | */ | ||
253 | } | ||
254 | |||
255 | /* | ||
245 | * Contraints to check before allowing this new breakpoint counter: | 256 | * Contraints to check before allowing this new breakpoint counter: |
246 | * | 257 | * |
247 | * == Non-pinned counter == (Considered as pinned for now) | 258 | * == Non-pinned counter == (Considered as pinned for now) |
@@ -339,6 +350,7 @@ void release_bp_slot(struct perf_event *bp) | |||
339 | { | 350 | { |
340 | mutex_lock(&nr_bp_mutex); | 351 | mutex_lock(&nr_bp_mutex); |
341 | 352 | ||
353 | arch_unregister_hw_breakpoint(bp); | ||
342 | __release_bp_slot(bp); | 354 | __release_bp_slot(bp); |
343 | 355 | ||
344 | mutex_unlock(&nr_bp_mutex); | 356 | mutex_unlock(&nr_bp_mutex); |