diff options
Diffstat (limited to 'arch/powerpc')
187 files changed, 8509 insertions, 2978 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 2031a2846865..e2bf40a2ce5a 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -120,6 +120,8 @@ config ARCH_NO_VIRT_TO_BUS | |||
120 | config PPC | 120 | config PPC |
121 | bool | 121 | bool |
122 | default y | 122 | default y |
123 | select OF | ||
124 | select OF_FLATTREE | ||
123 | select HAVE_FTRACE_MCOUNT_RECORD | 125 | select HAVE_FTRACE_MCOUNT_RECORD |
124 | select HAVE_DYNAMIC_FTRACE | 126 | select HAVE_DYNAMIC_FTRACE |
125 | select HAVE_FUNCTION_TRACER | 127 | select HAVE_FUNCTION_TRACER |
@@ -141,6 +143,7 @@ config PPC | |||
141 | select GENERIC_ATOMIC64 if PPC32 | 143 | select GENERIC_ATOMIC64 if PPC32 |
142 | select HAVE_PERF_EVENTS | 144 | select HAVE_PERF_EVENTS |
143 | select HAVE_REGS_AND_STACK_ACCESS_API | 145 | select HAVE_REGS_AND_STACK_ACCESS_API |
146 | select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64 | ||
144 | 147 | ||
145 | config EARLY_PRINTK | 148 | config EARLY_PRINTK |
146 | bool | 149 | bool |
@@ -172,10 +175,6 @@ config ARCH_MAY_HAVE_PC_FDC | |||
172 | config PPC_OF | 175 | config PPC_OF |
173 | def_bool y | 176 | def_bool y |
174 | 177 | ||
175 | config OF | ||
176 | def_bool y | ||
177 | select OF_FLATTREE | ||
178 | |||
179 | config PPC_UDBG_16550 | 178 | config PPC_UDBG_16550 |
180 | bool | 179 | bool |
181 | default n | 180 | default n |
@@ -198,10 +197,6 @@ config SYS_SUPPORTS_APM_EMULATION | |||
198 | default y if PMAC_APM_EMU | 197 | default y if PMAC_APM_EMU |
199 | bool | 198 | bool |
200 | 199 | ||
201 | config DTC | ||
202 | bool | ||
203 | default y | ||
204 | |||
205 | config DEFAULT_UIMAGE | 200 | config DEFAULT_UIMAGE |
206 | bool | 201 | bool |
207 | help | 202 | help |
@@ -218,7 +213,7 @@ config ARCH_HIBERNATION_POSSIBLE | |||
218 | config ARCH_SUSPEND_POSSIBLE | 213 | config ARCH_SUSPEND_POSSIBLE |
219 | def_bool y | 214 | def_bool y |
220 | depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ | 215 | depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ |
221 | PPC_85xx || PPC_86xx | 216 | PPC_85xx || PPC_86xx || PPC_PSERIES |
222 | 217 | ||
223 | config PPC_DCR_NATIVE | 218 | config PPC_DCR_NATIVE |
224 | bool | 219 | bool |
@@ -351,7 +346,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE | |||
351 | 346 | ||
352 | config KEXEC | 347 | config KEXEC |
353 | bool "kexec system call (EXPERIMENTAL)" | 348 | bool "kexec system call (EXPERIMENTAL)" |
354 | depends on (PPC_BOOK3S || (FSL_BOOKE && !SMP)) && EXPERIMENTAL | 349 | depends on (PPC_BOOK3S || FSL_BOOKE) && EXPERIMENTAL |
355 | help | 350 | help |
356 | kexec is a system call that implements the ability to shutdown your | 351 | 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 | 352 | current kernel, and to start another kernel. It is like a reboot |
@@ -368,8 +363,8 @@ config KEXEC | |||
368 | 363 | ||
369 | config CRASH_DUMP | 364 | config CRASH_DUMP |
370 | bool "Build a kdump crash kernel" | 365 | bool "Build a kdump crash kernel" |
371 | depends on PPC64 || 6xx | 366 | depends on PPC64 || 6xx || FSL_BOOKE |
372 | select RELOCATABLE if PPC64 | 367 | select RELOCATABLE if PPC64 || FSL_BOOKE |
373 | help | 368 | help |
374 | Build a kernel suitable for use as a kdump capture kernel. | 369 | Build a kernel suitable for use as a kdump capture kernel. |
375 | The same kernel binary can be used as production kernel and dump | 370 | The same kernel binary can be used as production kernel and dump |
@@ -578,14 +573,6 @@ config SCHED_SMT | |||
578 | when dealing with POWER5 cpus at a cost of slightly increased | 573 | when dealing with POWER5 cpus at a cost of slightly increased |
579 | overhead in some places. If unsure say N here. | 574 | overhead in some places. If unsure say N here. |
580 | 575 | ||
581 | config PROC_DEVICETREE | ||
582 | bool "Support for device tree in /proc" | ||
583 | depends on PROC_FS | ||
584 | help | ||
585 | This option adds a device-tree directory under /proc which contains | ||
586 | an image of the device tree that the kernel copies from Open | ||
587 | Firmware or other boot firmware. If unsure, say Y here. | ||
588 | |||
589 | config CMDLINE_BOOL | 576 | config CMDLINE_BOOL |
590 | bool "Default bootloader kernel arguments" | 577 | bool "Default bootloader kernel arguments" |
591 | 578 | ||
@@ -668,7 +655,7 @@ config NEED_SG_DMA_LENGTH | |||
668 | 655 | ||
669 | config GENERIC_ISA_DMA | 656 | config GENERIC_ISA_DMA |
670 | bool | 657 | bool |
671 | depends on PPC64 || POWER4 || 6xx && !CPM2 | 658 | depends on ISA_DMA_API |
672 | default y | 659 | default y |
673 | 660 | ||
674 | config PPC_INDIRECT_PCI | 661 | config PPC_INDIRECT_PCI |
@@ -897,7 +884,7 @@ config KERNEL_START_BOOL | |||
897 | config KERNEL_START | 884 | config KERNEL_START |
898 | hex "Virtual address of kernel base" if KERNEL_START_BOOL | 885 | hex "Virtual address of kernel base" if KERNEL_START_BOOL |
899 | default PAGE_OFFSET if PAGE_OFFSET_BOOL | 886 | default PAGE_OFFSET if PAGE_OFFSET_BOOL |
900 | default "0xc2000000" if CRASH_DUMP | 887 | default "0xc2000000" if CRASH_DUMP && !RELOCATABLE |
901 | default "0xc0000000" | 888 | default "0xc0000000" |
902 | 889 | ||
903 | config PHYSICAL_START_BOOL | 890 | config PHYSICAL_START_BOOL |
@@ -910,7 +897,7 @@ config PHYSICAL_START_BOOL | |||
910 | 897 | ||
911 | config PHYSICAL_START | 898 | config PHYSICAL_START |
912 | hex "Physical address where the kernel is loaded" if PHYSICAL_START_BOOL | 899 | hex "Physical address where the kernel is loaded" if PHYSICAL_START_BOOL |
913 | default "0x02000000" if PPC_STD_MMU && CRASH_DUMP | 900 | default "0x02000000" if PPC_STD_MMU && CRASH_DUMP && !RELOCATABLE |
914 | default "0x00000000" | 901 | default "0x00000000" |
915 | 902 | ||
916 | config PHYSICAL_ALIGN | 903 | config PHYSICAL_ALIGN |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 77cfe7a29e25..5d42f5eae70f 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -94,7 +94,7 @@ else | |||
94 | endif | 94 | endif |
95 | endif | 95 | endif |
96 | 96 | ||
97 | LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o | 97 | KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o |
98 | 98 | ||
99 | ifeq ($(CONFIG_TUNE_CELL),y) | 99 | ifeq ($(CONFIG_TUNE_CELL),y) |
100 | KBUILD_CFLAGS += $(call cc-option,-mtune=cell) | 100 | KBUILD_CFLAGS += $(call cc-option,-mtune=cell) |
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/irq.h b/arch/powerpc/include/asm/irq.h index ecba37a91749..67ab5fb7d153 100644 --- a/arch/powerpc/include/asm/irq.h +++ b/arch/powerpc/include/asm/irq.h | |||
@@ -300,34 +300,6 @@ extern unsigned int irq_alloc_virt(struct irq_host *host, | |||
300 | */ | 300 | */ |
301 | extern void irq_free_virt(unsigned int virq, unsigned int count); | 301 | extern void irq_free_virt(unsigned int virq, unsigned int count); |
302 | 302 | ||
303 | |||
304 | /* -- OF helpers -- */ | ||
305 | |||
306 | /** | ||
307 | * irq_create_of_mapping - Map a hardware interrupt into linux virq space | ||
308 | * @controller: Device node of the interrupt controller | ||
309 | * @inspec: Interrupt specifier from the device-tree | ||
310 | * @intsize: Size of the interrupt specifier from the device-tree | ||
311 | * | ||
312 | * This function is identical to irq_create_mapping except that it takes | ||
313 | * as input informations straight from the device-tree (typically the results | ||
314 | * of the of_irq_map_*() functions. | ||
315 | */ | ||
316 | extern unsigned int irq_create_of_mapping(struct device_node *controller, | ||
317 | const u32 *intspec, unsigned int intsize); | ||
318 | |||
319 | /** | ||
320 | * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space | ||
321 | * @device: Device node of the device whose interrupt is to be mapped | ||
322 | * @index: Index of the interrupt to map | ||
323 | * | ||
324 | * This function is a wrapper that chains of_irq_map_one() and | ||
325 | * irq_create_of_mapping() to make things easier to callers | ||
326 | */ | ||
327 | extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index); | ||
328 | |||
329 | /* -- End OF helpers -- */ | ||
330 | |||
331 | /** | 303 | /** |
332 | * irq_early_init - Init irq remapping subsystem | 304 | * irq_early_init - Init irq remapping subsystem |
333 | */ | 305 | */ |
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 6f74d93725a0..8274a2d43925 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h | |||
@@ -115,7 +115,15 @@ extern void kvmppc_mmu_book3s_32_init(struct kvm_vcpu *vcpu); | |||
115 | extern int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte); | 115 | extern int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte); |
116 | extern int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr); | 116 | extern int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr); |
117 | extern void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu); | 117 | extern void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu); |
118 | extern struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, bool data); | 118 | |
119 | extern void kvmppc_mmu_hpte_cache_map(struct kvm_vcpu *vcpu, struct hpte_cache *pte); | ||
120 | extern struct hpte_cache *kvmppc_mmu_hpte_cache_next(struct kvm_vcpu *vcpu); | ||
121 | extern void kvmppc_mmu_hpte_destroy(struct kvm_vcpu *vcpu); | ||
122 | extern int kvmppc_mmu_hpte_init(struct kvm_vcpu *vcpu); | ||
123 | extern void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte); | ||
124 | extern int kvmppc_mmu_hpte_sysinit(void); | ||
125 | extern void kvmppc_mmu_hpte_sysexit(void); | ||
126 | |||
119 | extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); | 127 | extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); |
120 | extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); | 128 | extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); |
121 | extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec); | 129 | extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec); |
diff --git a/arch/powerpc/include/asm/kvm_fpu.h b/arch/powerpc/include/asm/kvm_fpu.h index 94f05de9ad04..c3d4f0518a67 100644 --- a/arch/powerpc/include/asm/kvm_fpu.h +++ b/arch/powerpc/include/asm/kvm_fpu.h | |||
@@ -22,24 +22,24 @@ | |||
22 | 22 | ||
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | 24 | ||
25 | extern void fps_fres(struct thread_struct *t, u32 *dst, u32 *src1); | 25 | extern void fps_fres(u64 *fpscr, u32 *dst, u32 *src1); |
26 | extern void fps_frsqrte(struct thread_struct *t, u32 *dst, u32 *src1); | 26 | extern void fps_frsqrte(u64 *fpscr, u32 *dst, u32 *src1); |
27 | extern void fps_fsqrts(struct thread_struct *t, u32 *dst, u32 *src1); | 27 | extern void fps_fsqrts(u64 *fpscr, u32 *dst, u32 *src1); |
28 | 28 | ||
29 | extern void fps_fadds(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2); | 29 | extern void fps_fadds(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2); |
30 | extern void fps_fdivs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2); | 30 | extern void fps_fdivs(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2); |
31 | extern void fps_fmuls(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2); | 31 | extern void fps_fmuls(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2); |
32 | extern void fps_fsubs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2); | 32 | extern void fps_fsubs(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2); |
33 | 33 | ||
34 | extern void fps_fmadds(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2, | 34 | extern void fps_fmadds(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2, |
35 | u32 *src3); | 35 | u32 *src3); |
36 | extern void fps_fmsubs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2, | 36 | extern void fps_fmsubs(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2, |
37 | u32 *src3); | 37 | u32 *src3); |
38 | extern void fps_fnmadds(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2, | 38 | extern void fps_fnmadds(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2, |
39 | u32 *src3); | 39 | u32 *src3); |
40 | extern void fps_fnmsubs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2, | 40 | extern void fps_fnmsubs(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2, |
41 | u32 *src3); | 41 | u32 *src3); |
42 | extern void fps_fsel(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2, | 42 | extern void fps_fsel(u64 *fpscr, u32 *dst, u32 *src1, u32 *src2, |
43 | u32 *src3); | 43 | u32 *src3); |
44 | 44 | ||
45 | #define FPD_ONE_IN(name) extern void fpd_ ## name(u64 *fpscr, u32 *cr, \ | 45 | #define FPD_ONE_IN(name) extern void fpd_ ## name(u64 *fpscr, u32 *cr, \ |
@@ -82,4 +82,7 @@ FPD_THREE_IN(fmadd) | |||
82 | FPD_THREE_IN(fnmsub) | 82 | FPD_THREE_IN(fnmsub) |
83 | FPD_THREE_IN(fnmadd) | 83 | FPD_THREE_IN(fnmadd) |
84 | 84 | ||
85 | extern void kvm_cvt_fd(u32 *from, u64 *to, u64 *fpscr); | ||
86 | extern void kvm_cvt_df(u64 *from, u32 *to, u64 *fpscr); | ||
87 | |||
85 | #endif | 88 | #endif |
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 0c9ad869decd..b0b23c007d6e 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h | |||
@@ -35,10 +35,17 @@ | |||
35 | #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 | 35 | #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 |
36 | 36 | ||
37 | /* We don't currently support large pages. */ | 37 | /* We don't currently support large pages. */ |
38 | #define KVM_HPAGE_GFN_SHIFT(x) 0 | ||
38 | #define KVM_NR_PAGE_SIZES 1 | 39 | #define KVM_NR_PAGE_SIZES 1 |
39 | #define KVM_PAGES_PER_HPAGE(x) (1UL<<31) | 40 | #define KVM_PAGES_PER_HPAGE(x) (1UL<<31) |
40 | 41 | ||
41 | #define HPTEG_CACHE_NUM 1024 | 42 | #define HPTEG_CACHE_NUM (1 << 15) |
43 | #define HPTEG_HASH_BITS_PTE 13 | ||
44 | #define HPTEG_HASH_BITS_VPTE 13 | ||
45 | #define HPTEG_HASH_BITS_VPTE_LONG 5 | ||
46 | #define HPTEG_HASH_NUM_PTE (1 << HPTEG_HASH_BITS_PTE) | ||
47 | #define HPTEG_HASH_NUM_VPTE (1 << HPTEG_HASH_BITS_VPTE) | ||
48 | #define HPTEG_HASH_NUM_VPTE_LONG (1 << HPTEG_HASH_BITS_VPTE_LONG) | ||
42 | 49 | ||
43 | struct kvm; | 50 | struct kvm; |
44 | struct kvm_run; | 51 | struct kvm_run; |
@@ -151,6 +158,9 @@ struct kvmppc_mmu { | |||
151 | }; | 158 | }; |
152 | 159 | ||
153 | struct hpte_cache { | 160 | struct hpte_cache { |
161 | struct hlist_node list_pte; | ||
162 | struct hlist_node list_vpte; | ||
163 | struct hlist_node list_vpte_long; | ||
154 | u64 host_va; | 164 | u64 host_va; |
155 | u64 pfn; | 165 | u64 pfn; |
156 | ulong slot; | 166 | ulong slot; |
@@ -282,8 +292,10 @@ struct kvm_vcpu_arch { | |||
282 | unsigned long pending_exceptions; | 292 | unsigned long pending_exceptions; |
283 | 293 | ||
284 | #ifdef CONFIG_PPC_BOOK3S | 294 | #ifdef CONFIG_PPC_BOOK3S |
285 | struct hpte_cache hpte_cache[HPTEG_CACHE_NUM]; | 295 | struct hlist_head hpte_hash_pte[HPTEG_HASH_NUM_PTE]; |
286 | int hpte_cache_offset; | 296 | struct hlist_head hpte_hash_vpte[HPTEG_HASH_NUM_VPTE]; |
297 | struct hlist_head hpte_hash_vpte_long[HPTEG_HASH_NUM_VPTE_LONG]; | ||
298 | int hpte_cache_count; | ||
287 | #endif | 299 | #endif |
288 | }; | 300 | }; |
289 | 301 | ||
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/macio.h b/arch/powerpc/include/asm/macio.h index 675e159b5ef4..7ab82c825a03 100644 --- a/arch/powerpc/include/asm/macio.h +++ b/arch/powerpc/include/asm/macio.h | |||
@@ -38,7 +38,7 @@ struct macio_dev | |||
38 | { | 38 | { |
39 | struct macio_bus *bus; /* macio bus this device is on */ | 39 | struct macio_bus *bus; /* macio bus this device is on */ |
40 | struct macio_dev *media_bay; /* Device is part of a media bay */ | 40 | struct macio_dev *media_bay; /* Device is part of a media bay */ |
41 | struct of_device ofdev; | 41 | struct platform_device ofdev; |
42 | struct device_dma_parameters dma_parms; /* ide needs that */ | 42 | struct device_dma_parameters dma_parms; /* ide needs that */ |
43 | int n_resources; | 43 | int n_resources; |
44 | struct resource resource[MACIO_DEV_COUNT_RESOURCES]; | 44 | struct resource resource[MACIO_DEV_COUNT_RESOURCES]; |
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/of_device.h b/arch/powerpc/include/asm/of_device.h deleted file mode 100644 index 444e97e2982e..000000000000 --- a/arch/powerpc/include/asm/of_device.h +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | #ifndef _ASM_POWERPC_OF_DEVICE_H | ||
2 | #define _ASM_POWERPC_OF_DEVICE_H | ||
3 | #ifdef __KERNEL__ | ||
4 | |||
5 | #include <linux/device.h> | ||
6 | #include <linux/of.h> | ||
7 | |||
8 | /* | ||
9 | * The of_device is a kind of "base class" that is a superset of | ||
10 | * struct device for use by devices attached to an OF node and | ||
11 | * probed using OF properties. | ||
12 | */ | ||
13 | struct of_device | ||
14 | { | ||
15 | struct device dev; /* Generic device interface */ | ||
16 | struct pdev_archdata archdata; | ||
17 | }; | ||
18 | |||
19 | extern struct of_device *of_device_alloc(struct device_node *np, | ||
20 | const char *bus_id, | ||
21 | struct device *parent); | ||
22 | |||
23 | extern int of_device_uevent(struct device *dev, | ||
24 | struct kobj_uevent_env *env); | ||
25 | |||
26 | #endif /* __KERNEL__ */ | ||
27 | #endif /* _ASM_POWERPC_OF_DEVICE_H */ | ||
diff --git a/arch/powerpc/include/asm/of_platform.h b/arch/powerpc/include/asm/of_platform.h deleted file mode 100644 index d4aaa3489440..000000000000 --- a/arch/powerpc/include/asm/of_platform.h +++ /dev/null | |||
@@ -1,29 +0,0 @@ | |||
1 | #ifndef _ASM_POWERPC_OF_PLATFORM_H | ||
2 | #define _ASM_POWERPC_OF_PLATFORM_H | ||
3 | /* | ||
4 | * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. | ||
5 | * <benh@kernel.crashing.org> | ||
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 | |||
14 | /* Platform devices and busses creation */ | ||
15 | extern struct of_device *of_platform_device_create(struct device_node *np, | ||
16 | const char *bus_id, | ||
17 | struct device *parent); | ||
18 | /* pseudo "matches" value to not do deep probe */ | ||
19 | #define OF_NO_DEEP_PROBE ((struct of_device_id *)-1) | ||
20 | |||
21 | extern int of_platform_bus_probe(struct device_node *root, | ||
22 | const struct of_device_id *matches, | ||
23 | struct device *parent); | ||
24 | |||
25 | extern struct of_device *of_find_device_by_phandle(phandle ph); | ||
26 | |||
27 | extern void of_instantiate_rtc(void); | ||
28 | |||
29 | #endif /* _ASM_POWERPC_OF_PLATFORM_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/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 76e1f313a58e..51e9e6f90d12 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h | |||
@@ -303,13 +303,8 @@ extern void pcibios_free_controller(struct pci_controller *phb); | |||
303 | extern void pcibios_setup_phb_resources(struct pci_controller *hose); | 303 | extern void pcibios_setup_phb_resources(struct pci_controller *hose); |
304 | 304 | ||
305 | #ifdef CONFIG_PCI | 305 | #ifdef CONFIG_PCI |
306 | extern unsigned long pci_address_to_pio(phys_addr_t address); | ||
307 | extern int pcibios_vaddr_is_ioport(void __iomem *address); | 306 | extern int pcibios_vaddr_is_ioport(void __iomem *address); |
308 | #else | 307 | #else |
309 | static inline unsigned long pci_address_to_pio(phys_addr_t address) | ||
310 | { | ||
311 | return (unsigned long)-1; | ||
312 | } | ||
313 | static inline int pcibios_vaddr_is_ioport(void __iomem *address) | 308 | static inline int pcibios_vaddr_is_ioport(void __iomem *address) |
314 | { | 309 | { |
315 | return 0; | 310 | return 0; |
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/prom.h b/arch/powerpc/include/asm/prom.h index ddd408a93b5a..ae26f2efd089 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h | |||
@@ -17,9 +17,6 @@ | |||
17 | * 2 of the License, or (at your option) any later version. | 17 | * 2 of the License, or (at your option) any later version. |
18 | */ | 18 | */ |
19 | #include <linux/types.h> | 19 | #include <linux/types.h> |
20 | #include <linux/of_fdt.h> | ||
21 | #include <linux/proc_fs.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <asm/irq.h> | 20 | #include <asm/irq.h> |
24 | #include <asm/atomic.h> | 21 | #include <asm/atomic.h> |
25 | 22 | ||
@@ -43,49 +40,14 @@ extern void pci_create_OF_bus_map(void); | |||
43 | * OF address retreival & translation | 40 | * OF address retreival & translation |
44 | */ | 41 | */ |
45 | 42 | ||
46 | /* Translate an OF address block into a CPU physical address | ||
47 | */ | ||
48 | extern u64 of_translate_address(struct device_node *np, const u32 *addr); | ||
49 | |||
50 | /* Translate a DMA address from device space to CPU space */ | 43 | /* Translate a DMA address from device space to CPU space */ |
51 | extern u64 of_translate_dma_address(struct device_node *dev, | 44 | extern u64 of_translate_dma_address(struct device_node *dev, |
52 | const u32 *in_addr); | 45 | const u32 *in_addr); |
53 | 46 | ||
54 | /* Extract an address from a device, returns the region size and | ||
55 | * the address space flags too. The PCI version uses a BAR number | ||
56 | * instead of an absolute index | ||
57 | */ | ||
58 | extern const u32 *of_get_address(struct device_node *dev, int index, | ||
59 | u64 *size, unsigned int *flags); | ||
60 | #ifdef CONFIG_PCI | 47 | #ifdef CONFIG_PCI |
61 | extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no, | 48 | extern unsigned long pci_address_to_pio(phys_addr_t address); |
62 | u64 *size, unsigned int *flags); | 49 | #define pci_address_to_pio pci_address_to_pio |
63 | #else | 50 | #endif /* CONFIG_PCI */ |
64 | static inline const u32 *of_get_pci_address(struct device_node *dev, | ||
65 | int bar_no, u64 *size, unsigned int *flags) | ||
66 | { | ||
67 | return NULL; | ||
68 | } | ||
69 | #endif /* CONFIG_PCI */ | ||
70 | |||
71 | /* Get an address as a resource. Note that if your address is | ||
72 | * a PIO address, the conversion will fail if the physical address | ||
73 | * can't be internally converted to an IO token with | ||
74 | * pci_address_to_pio(), that is because it's either called to early | ||
75 | * or it can't be matched to any host bridge IO space | ||
76 | */ | ||
77 | extern int of_address_to_resource(struct device_node *dev, int index, | ||
78 | struct resource *r); | ||
79 | #ifdef CONFIG_PCI | ||
80 | extern int of_pci_address_to_resource(struct device_node *dev, int bar, | ||
81 | struct resource *r); | ||
82 | #else | ||
83 | static inline int of_pci_address_to_resource(struct device_node *dev, int bar, | ||
84 | struct resource *r) | ||
85 | { | ||
86 | return -ENOSYS; | ||
87 | } | ||
88 | #endif /* CONFIG_PCI */ | ||
89 | 51 | ||
90 | /* Parse the ibm,dma-window property of an OF node into the busno, phys and | 52 | /* Parse the ibm,dma-window property of an OF node into the busno, phys and |
91 | * size parameters. | 53 | * size parameters. |
@@ -104,69 +66,12 @@ struct device_node *of_find_next_cache_node(struct device_node *np); | |||
104 | /* Get the MAC address */ | 66 | /* Get the MAC address */ |
105 | extern const void *of_get_mac_address(struct device_node *np); | 67 | extern const void *of_get_mac_address(struct device_node *np); |
106 | 68 | ||
107 | /* | 69 | #ifdef CONFIG_NUMA |
108 | * OF interrupt mapping | 70 | extern int of_node_to_nid(struct device_node *device); |
109 | */ | 71 | #else |
110 | 72 | static inline int of_node_to_nid(struct device_node *device) { return 0; } | |
111 | /* This structure is returned when an interrupt is mapped. The controller | 73 | #endif |
112 | * field needs to be put() after use | 74 | #define of_node_to_nid of_node_to_nid |
113 | */ | ||
114 | |||
115 | #define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */ | ||
116 | |||
117 | struct of_irq { | ||
118 | struct device_node *controller; /* Interrupt controller node */ | ||
119 | u32 size; /* Specifier size */ | ||
120 | u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */ | ||
121 | }; | ||
122 | |||
123 | /** | ||
124 | * of_irq_map_init - Initialize the irq remapper | ||
125 | * @flags: flags defining workarounds to enable | ||
126 | * | ||
127 | * Some machines have bugs in the device-tree which require certain workarounds | ||
128 | * to be applied. Call this before any interrupt mapping attempts to enable | ||
129 | * those workarounds. | ||
130 | */ | ||
131 | #define OF_IMAP_OLDWORLD_MAC 0x00000001 | ||
132 | #define OF_IMAP_NO_PHANDLE 0x00000002 | ||
133 | |||
134 | extern void of_irq_map_init(unsigned int flags); | ||
135 | |||
136 | /** | ||
137 | * of_irq_map_raw - Low level interrupt tree parsing | ||
138 | * @parent: the device interrupt parent | ||
139 | * @intspec: interrupt specifier ("interrupts" property of the device) | ||
140 | * @ointsize: size of the passed in interrupt specifier | ||
141 | * @addr: address specifier (start of "reg" property of the device) | ||
142 | * @out_irq: structure of_irq filled by this function | ||
143 | * | ||
144 | * Returns 0 on success and a negative number on error | ||
145 | * | ||
146 | * This function is a low-level interrupt tree walking function. It | ||
147 | * can be used to do a partial walk with synthetized reg and interrupts | ||
148 | * properties, for example when resolving PCI interrupts when no device | ||
149 | * node exist for the parent. | ||
150 | * | ||
151 | */ | ||
152 | |||
153 | extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec, | ||
154 | u32 ointsize, const u32 *addr, | ||
155 | struct of_irq *out_irq); | ||
156 | |||
157 | |||
158 | /** | ||
159 | * of_irq_map_one - Resolve an interrupt for a device | ||
160 | * @device: the device whose interrupt is to be resolved | ||
161 | * @index: index of the interrupt to resolve | ||
162 | * @out_irq: structure of_irq filled by this function | ||
163 | * | ||
164 | * This function resolves an interrupt, walking the tree, for a given | ||
165 | * device-tree node. It's the high level pendant to of_irq_map_raw(). | ||
166 | * It also implements the workarounds for OldWolrd Macs. | ||
167 | */ | ||
168 | extern int of_irq_map_one(struct device_node *device, int index, | ||
169 | struct of_irq *out_irq); | ||
170 | 75 | ||
171 | /** | 76 | /** |
172 | * of_irq_map_pci - Resolve the interrupt for a PCI device | 77 | * of_irq_map_pci - Resolve the interrupt for a PCI device |
@@ -180,19 +85,19 @@ extern int of_irq_map_one(struct device_node *device, int index, | |||
180 | * resolving using the OF tree walking. | 85 | * resolving using the OF tree walking. |
181 | */ | 86 | */ |
182 | struct pci_dev; | 87 | struct pci_dev; |
88 | struct of_irq; | ||
183 | extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); | 89 | extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); |
184 | 90 | ||
185 | extern int of_irq_to_resource(struct device_node *dev, int index, | 91 | extern void of_instantiate_rtc(void); |
186 | struct resource *r); | ||
187 | 92 | ||
188 | /** | 93 | /* These includes are put at the bottom because they may contain things |
189 | * of_iomap - Maps the memory mapped IO for a given device_node | 94 | * that are overridden by this file. Ideally they shouldn't be included |
190 | * @device: the device whose io range will be mapped | 95 | * by this file, but there are a bunch of .c files that currently depend |
191 | * @index: index of the io range | 96 | * on it. Eventually they will be cleaned up. */ |
192 | * | 97 | #include <linux/of_fdt.h> |
193 | * Returns a pointer to the mapped memory | 98 | #include <linux/of_address.h> |
194 | */ | 99 | #include <linux/of_irq.h> |
195 | extern void __iomem *of_iomap(struct device_node *device, int index); | 100 | #include <linux/platform_device.h> |
196 | 101 | ||
197 | #endif /* __KERNEL__ */ | 102 | #endif /* __KERNEL__ */ |
198 | #endif /* _POWERPC_PROM_H */ | 103 | #endif /* _POWERPC_PROM_H */ |
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/smu.h b/arch/powerpc/include/asm/smu.h index 7ae2753da565..e3bdada8c542 100644 --- a/arch/powerpc/include/asm/smu.h +++ b/arch/powerpc/include/asm/smu.h | |||
@@ -457,8 +457,8 @@ extern void smu_poll(void); | |||
457 | */ | 457 | */ |
458 | extern int smu_init(void); | 458 | extern int smu_init(void); |
459 | extern int smu_present(void); | 459 | extern int smu_present(void); |
460 | struct of_device; | 460 | struct platform_device; |
461 | extern struct of_device *smu_get_ofdev(void); | 461 | extern struct platform_device *smu_get_ofdev(void); |
462 | 462 | ||
463 | 463 | ||
464 | /* | 464 | /* |
diff --git a/arch/powerpc/include/asm/system.h b/arch/powerpc/include/asm/system.h index a6297c67c3d6..6c294acac848 100644 --- a/arch/powerpc/include/asm/system.h +++ b/arch/powerpc/include/asm/system.h | |||
@@ -515,11 +515,8 @@ __cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new, | |||
515 | * powers of 2 writes until it reaches sufficient alignment). | 515 | * powers of 2 writes until it reaches sufficient alignment). |
516 | * | 516 | * |
517 | * Based on this we disable the IP header alignment in network drivers. | 517 | * Based on this we disable the IP header alignment in network drivers. |
518 | * We also modify NET_SKB_PAD to be a cacheline in size, thus maintaining | ||
519 | * cacheline alignment of buffers. | ||
520 | */ | 518 | */ |
521 | #define NET_IP_ALIGN 0 | 519 | #define NET_IP_ALIGN 0 |
522 | #define NET_SKB_PAD L1_CACHE_BYTES | ||
523 | 520 | ||
524 | #define cmpxchg64(ptr, o, n) \ | 521 | #define cmpxchg64(ptr, o, n) \ |
525 | ({ \ | 522 | ({ \ |
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..afe4aaa65c3b 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h | |||
@@ -41,8 +41,6 @@ static inline int cpu_to_node(int cpu) | |||
41 | cpu_all_mask : \ | 41 | cpu_all_mask : \ |
42 | node_to_cpumask_map[node]) | 42 | node_to_cpumask_map[node]) |
43 | 43 | ||
44 | int of_node_to_nid(struct device_node *device); | ||
45 | |||
46 | struct pci_bus; | 44 | struct pci_bus; |
47 | #ifdef CONFIG_PCI | 45 | #ifdef CONFIG_PCI |
48 | extern int pcibus_to_node(struct pci_bus *bus); | 46 | extern int pcibus_to_node(struct pci_bus *bus); |
@@ -87,6 +85,9 @@ static inline int pcibus_to_node(struct pci_bus *bus) | |||
87 | .balance_interval = 1, \ | 85 | .balance_interval = 1, \ |
88 | } | 86 | } |
89 | 87 | ||
88 | extern int __node_distance(int, int); | ||
89 | #define node_distance(a, b) __node_distance(a, b) | ||
90 | |||
90 | extern void __init dump_numa_cpu_topology(void); | 91 | extern void __init dump_numa_cpu_topology(void); |
91 | 92 | ||
92 | extern int sysfs_add_device_to_node(struct sys_device *dev, int nid); | 93 | extern int sysfs_add_device_to_node(struct sys_device *dev, int nid); |
@@ -94,11 +95,6 @@ extern void sysfs_remove_device_from_node(struct sys_device *dev, int nid); | |||
94 | 95 | ||
95 | #else | 96 | #else |
96 | 97 | ||
97 | static inline int of_node_to_nid(struct device_node *device) | ||
98 | { | ||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static inline void dump_numa_cpu_topology(void) {} | 98 | static inline void dump_numa_cpu_topology(void) {} |
103 | 99 | ||
104 | static inline int sysfs_add_device_to_node(struct sys_device *dev, int nid) | 100 | static inline 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..1dda70129141 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -34,13 +34,14 @@ 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 |
43 | obj-$(CONFIG_PPC_OF) += of_device.o of_platform.o prom_parse.o | 44 | obj-$(CONFIG_PPC_OF) += of_platform.o prom_parse.o |
44 | obj-$(CONFIG_PPC_CLOCK) += clock.o | 45 | obj-$(CONFIG_PPC_CLOCK) += clock.o |
45 | procfs-y := proc_powerpc.o | 46 | procfs-y := proc_powerpc.o |
46 | obj-$(CONFIG_PROC_FS) += $(procfs-y) | 47 | obj-$(CONFIG_PROC_FS) += $(procfs-y) |
@@ -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/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c index 02f724f36753..4295e0b94b2d 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c | |||
@@ -82,17 +82,9 @@ static struct notifier_block ppc_swiotlb_plat_bus_notifier = { | |||
82 | .priority = 0, | 82 | .priority = 0, |
83 | }; | 83 | }; |
84 | 84 | ||
85 | static struct notifier_block ppc_swiotlb_of_bus_notifier = { | ||
86 | .notifier_call = ppc_swiotlb_bus_notify, | ||
87 | .priority = 0, | ||
88 | }; | ||
89 | |||
90 | int __init swiotlb_setup_bus_notifier(void) | 85 | int __init swiotlb_setup_bus_notifier(void) |
91 | { | 86 | { |
92 | bus_register_notifier(&platform_bus_type, | 87 | bus_register_notifier(&platform_bus_type, |
93 | &ppc_swiotlb_plat_bus_notifier); | 88 | &ppc_swiotlb_plat_bus_notifier); |
94 | bus_register_notifier(&of_platform_bus_type, | ||
95 | &ppc_swiotlb_of_bus_notifier); | ||
96 | |||
97 | return 0; | 89 | return 0; |
98 | } | 90 | } |
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/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 21266abfbda6..9b626cfffce1 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c | |||
@@ -140,19 +140,19 @@ static struct dma_map_ops ibmebus_dma_ops = { | |||
140 | 140 | ||
141 | static int ibmebus_match_path(struct device *dev, void *data) | 141 | static int ibmebus_match_path(struct device *dev, void *data) |
142 | { | 142 | { |
143 | struct device_node *dn = to_of_device(dev)->dev.of_node; | 143 | struct device_node *dn = to_platform_device(dev)->dev.of_node; |
144 | return (dn->full_name && | 144 | return (dn->full_name && |
145 | (strcasecmp((char *)data, dn->full_name) == 0)); | 145 | (strcasecmp((char *)data, dn->full_name) == 0)); |
146 | } | 146 | } |
147 | 147 | ||
148 | static int ibmebus_match_node(struct device *dev, void *data) | 148 | static int ibmebus_match_node(struct device *dev, void *data) |
149 | { | 149 | { |
150 | return to_of_device(dev)->dev.of_node == data; | 150 | return to_platform_device(dev)->dev.of_node == data; |
151 | } | 151 | } |
152 | 152 | ||
153 | static int ibmebus_create_device(struct device_node *dn) | 153 | static int ibmebus_create_device(struct device_node *dn) |
154 | { | 154 | { |
155 | struct of_device *dev; | 155 | struct platform_device *dev; |
156 | int ret; | 156 | int ret; |
157 | 157 | ||
158 | dev = of_device_alloc(dn, NULL, &ibmebus_bus_device); | 158 | dev = of_device_alloc(dn, NULL, &ibmebus_bus_device); |
@@ -298,7 +298,7 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus, | |||
298 | 298 | ||
299 | if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path, | 299 | if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path, |
300 | ibmebus_match_path))) { | 300 | ibmebus_match_path))) { |
301 | of_device_unregister(to_of_device(dev)); | 301 | of_device_unregister(to_platform_device(dev)); |
302 | 302 | ||
303 | kfree(path); | 303 | kfree(path); |
304 | return count; | 304 | return count; |
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..d3ce67cf03be 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -53,6 +53,8 @@ | |||
53 | #include <linux/bootmem.h> | 53 | #include <linux/bootmem.h> |
54 | #include <linux/pci.h> | 54 | #include <linux/pci.h> |
55 | #include <linux/debugfs.h> | 55 | #include <linux/debugfs.h> |
56 | #include <linux/of.h> | ||
57 | #include <linux/of_irq.h> | ||
56 | 58 | ||
57 | #include <asm/uaccess.h> | 59 | #include <asm/uaccess.h> |
58 | #include <asm/system.h> | 60 | #include <asm/system.h> |
@@ -64,6 +66,8 @@ | |||
64 | #include <asm/ptrace.h> | 66 | #include <asm/ptrace.h> |
65 | #include <asm/machdep.h> | 67 | #include <asm/machdep.h> |
66 | #include <asm/udbg.h> | 68 | #include <asm/udbg.h> |
69 | #include <asm/dbell.h> | ||
70 | |||
67 | #ifdef CONFIG_PPC64 | 71 | #ifdef CONFIG_PPC64 |
68 | #include <asm/paca.h> | 72 | #include <asm/paca.h> |
69 | #include <asm/firmware.h> | 73 | #include <asm/firmware.h> |
@@ -153,14 +157,28 @@ notrace void raw_local_irq_restore(unsigned long en) | |||
153 | if (get_hard_enabled()) | 157 | if (get_hard_enabled()) |
154 | return; | 158 | return; |
155 | 159 | ||
160 | #if defined(CONFIG_BOOKE) && defined(CONFIG_SMP) | ||
161 | /* Check for pending doorbell interrupts and resend to ourself */ | ||
162 | doorbell_check_self(); | ||
163 | #endif | ||
164 | |||
156 | /* | 165 | /* |
157 | * Need to hard-enable interrupts here. Since currently disabled, | 166 | * Need to hard-enable interrupts here. Since currently disabled, |
158 | * no need to take further asm precautions against preemption; but | 167 | * no need to take further asm precautions against preemption; but |
159 | * use local_paca instead of get_paca() to avoid preemption checking. | 168 | * use local_paca instead of get_paca() to avoid preemption checking. |
160 | */ | 169 | */ |
161 | local_paca->hard_enabled = en; | 170 | local_paca->hard_enabled = en; |
171 | |||
172 | #ifndef CONFIG_BOOKE | ||
173 | /* On server, re-trigger the decrementer if it went negative since | ||
174 | * some processors only trigger on edge transitions of the sign bit. | ||
175 | * | ||
176 | * BookE has a level sensitive decrementer (latches in TSR) so we | ||
177 | * don't need that | ||
178 | */ | ||
162 | if ((int)mfspr(SPRN_DEC) < 0) | 179 | if ((int)mfspr(SPRN_DEC) < 0) |
163 | mtspr(SPRN_DEC, 1); | 180 | mtspr(SPRN_DEC, 1); |
181 | #endif /* CONFIG_BOOKE */ | ||
164 | 182 | ||
165 | /* | 183 | /* |
166 | * Force the delivery of pending soft-disabled interrupts on PS3. | 184 | * Force the delivery of pending soft-disabled interrupts on PS3. |
@@ -804,18 +822,6 @@ unsigned int irq_create_of_mapping(struct device_node *controller, | |||
804 | } | 822 | } |
805 | EXPORT_SYMBOL_GPL(irq_create_of_mapping); | 823 | EXPORT_SYMBOL_GPL(irq_create_of_mapping); |
806 | 824 | ||
807 | unsigned int irq_of_parse_and_map(struct device_node *dev, int index) | ||
808 | { | ||
809 | struct of_irq oirq; | ||
810 | |||
811 | if (of_irq_map_one(dev, index, &oirq)) | ||
812 | return NO_IRQ; | ||
813 | |||
814 | return irq_create_of_mapping(oirq.controller, oirq.specifier, | ||
815 | oirq.size); | ||
816 | } | ||
817 | EXPORT_SYMBOL_GPL(irq_of_parse_and_map); | ||
818 | |||
819 | void irq_dispose_mapping(unsigned int virq) | 825 | void irq_dispose_mapping(unsigned int virq) |
820 | { | 826 | { |
821 | struct irq_host *host; | 827 | struct irq_host *host; |
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index 82a7b228c81a..7f61a3ac787c 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c | |||
@@ -129,7 +129,7 @@ static int kgdb_handle_breakpoint(struct pt_regs *regs) | |||
129 | return 0; | 129 | return 0; |
130 | 130 | ||
131 | if (*(u32 *) (regs->nip) == *(u32 *) (&arch_kgdb_ops.gdb_bpt_instr)) | 131 | if (*(u32 *) (regs->nip) == *(u32 *) (&arch_kgdb_ops.gdb_bpt_instr)) |
132 | regs->nip += 4; | 132 | regs->nip += BREAK_INSTR_SIZE; |
133 | 133 | ||
134 | return 1; | 134 | return 1; |
135 | } | 135 | } |
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 035ada5443ee..c1fd0f9658fd 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/serial_core.h> | 4 | #include <linux/serial_core.h> |
5 | #include <linux/console.h> | 5 | #include <linux/console.h> |
6 | #include <linux/pci.h> | 6 | #include <linux/pci.h> |
7 | #include <linux/of_address.h> | ||
7 | #include <linux/of_device.h> | 8 | #include <linux/of_device.h> |
8 | #include <asm/io.h> | 9 | #include <asm/io.h> |
9 | #include <asm/mmu.h> | 10 | #include <asm/mmu.h> |
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/of_device.c b/arch/powerpc/kernel/of_device.c deleted file mode 100644 index df78e0236a02..000000000000 --- a/arch/powerpc/kernel/of_device.c +++ /dev/null | |||
@@ -1,133 +0,0 @@ | |||
1 | #include <linux/string.h> | ||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/of.h> | ||
4 | #include <linux/init.h> | ||
5 | #include <linux/module.h> | ||
6 | #include <linux/mod_devicetable.h> | ||
7 | #include <linux/slab.h> | ||
8 | #include <linux/of_device.h> | ||
9 | |||
10 | #include <asm/errno.h> | ||
11 | #include <asm/dcr.h> | ||
12 | |||
13 | static void of_device_make_bus_id(struct of_device *dev) | ||
14 | { | ||
15 | static atomic_t bus_no_reg_magic; | ||
16 | struct device_node *node = dev->dev.of_node; | ||
17 | const u32 *reg; | ||
18 | u64 addr; | ||
19 | int magic; | ||
20 | |||
21 | /* | ||
22 | * If it's a DCR based device, use 'd' for native DCRs | ||
23 | * and 'D' for MMIO DCRs. | ||
24 | */ | ||
25 | #ifdef CONFIG_PPC_DCR | ||
26 | reg = of_get_property(node, "dcr-reg", NULL); | ||
27 | if (reg) { | ||
28 | #ifdef CONFIG_PPC_DCR_NATIVE | ||
29 | dev_set_name(&dev->dev, "d%x.%s", *reg, node->name); | ||
30 | #else /* CONFIG_PPC_DCR_NATIVE */ | ||
31 | addr = of_translate_dcr_address(node, *reg, NULL); | ||
32 | if (addr != OF_BAD_ADDR) { | ||
33 | dev_set_name(&dev->dev, "D%llx.%s", | ||
34 | (unsigned long long)addr, node->name); | ||
35 | return; | ||
36 | } | ||
37 | #endif /* !CONFIG_PPC_DCR_NATIVE */ | ||
38 | } | ||
39 | #endif /* CONFIG_PPC_DCR */ | ||
40 | |||
41 | /* | ||
42 | * For MMIO, get the physical address | ||
43 | */ | ||
44 | reg = of_get_property(node, "reg", NULL); | ||
45 | if (reg) { | ||
46 | addr = of_translate_address(node, reg); | ||
47 | if (addr != OF_BAD_ADDR) { | ||
48 | dev_set_name(&dev->dev, "%llx.%s", | ||
49 | (unsigned long long)addr, node->name); | ||
50 | return; | ||
51 | } | ||
52 | } | ||
53 | |||
54 | /* | ||
55 | * No BusID, use the node name and add a globally incremented | ||
56 | * counter (and pray...) | ||
57 | */ | ||
58 | magic = atomic_add_return(1, &bus_no_reg_magic); | ||
59 | dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1); | ||
60 | } | ||
61 | |||
62 | struct of_device *of_device_alloc(struct device_node *np, | ||
63 | const char *bus_id, | ||
64 | struct device *parent) | ||
65 | { | ||
66 | struct of_device *dev; | ||
67 | |||
68 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
69 | if (!dev) | ||
70 | return NULL; | ||
71 | |||
72 | dev->dev.of_node = of_node_get(np); | ||
73 | dev->dev.dma_mask = &dev->archdata.dma_mask; | ||
74 | dev->dev.parent = parent; | ||
75 | dev->dev.release = of_release_dev; | ||
76 | |||
77 | if (bus_id) | ||
78 | dev_set_name(&dev->dev, "%s", bus_id); | ||
79 | else | ||
80 | of_device_make_bus_id(dev); | ||
81 | |||
82 | return dev; | ||
83 | } | ||
84 | EXPORT_SYMBOL(of_device_alloc); | ||
85 | |||
86 | int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
87 | { | ||
88 | struct of_device *ofdev; | ||
89 | const char *compat; | ||
90 | int seen = 0, cplen, sl; | ||
91 | |||
92 | if (!dev) | ||
93 | return -ENODEV; | ||
94 | |||
95 | ofdev = to_of_device(dev); | ||
96 | |||
97 | if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name)) | ||
98 | return -ENOMEM; | ||
99 | |||
100 | if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type)) | ||
101 | return -ENOMEM; | ||
102 | |||
103 | /* Since the compatible field can contain pretty much anything | ||
104 | * it's not really legal to split it out with commas. We split it | ||
105 | * up using a number of environment variables instead. */ | ||
106 | |||
107 | compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen); | ||
108 | while (compat && *compat && cplen > 0) { | ||
109 | if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) | ||
110 | return -ENOMEM; | ||
111 | |||
112 | sl = strlen (compat) + 1; | ||
113 | compat += sl; | ||
114 | cplen -= sl; | ||
115 | seen++; | ||
116 | } | ||
117 | |||
118 | if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen)) | ||
119 | return -ENOMEM; | ||
120 | |||
121 | /* modalias is trickier, we add it in 2 steps */ | ||
122 | if (add_uevent_var(env, "MODALIAS=")) | ||
123 | return -ENOMEM; | ||
124 | sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1], | ||
125 | sizeof(env->buf) - env->buflen); | ||
126 | if (sl >= (sizeof(env->buf) - env->buflen)) | ||
127 | return -ENOMEM; | ||
128 | env->buflen += sl; | ||
129 | |||
130 | return 0; | ||
131 | } | ||
132 | EXPORT_SYMBOL(of_device_uevent); | ||
133 | EXPORT_SYMBOL(of_device_get_modalias); | ||
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 487a98851ba6..b2c363ef38ad 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c | |||
@@ -28,207 +28,6 @@ | |||
28 | #include <asm/ppc-pci.h> | 28 | #include <asm/ppc-pci.h> |
29 | #include <asm/atomic.h> | 29 | #include <asm/atomic.h> |
30 | 30 | ||
31 | /* | ||
32 | * The list of OF IDs below is used for matching bus types in the | ||
33 | * system whose devices are to be exposed as of_platform_devices. | ||
34 | * | ||
35 | * This is the default list valid for most platforms. This file provides | ||
36 | * functions who can take an explicit list if necessary though | ||
37 | * | ||
38 | * The search is always performed recursively looking for children of | ||
39 | * the provided device_node and recursively if such a children matches | ||
40 | * a bus type in the list | ||
41 | */ | ||
42 | |||
43 | static const struct of_device_id of_default_bus_ids[] = { | ||
44 | { .type = "soc", }, | ||
45 | { .compatible = "soc", }, | ||
46 | { .type = "spider", }, | ||
47 | { .type = "axon", }, | ||
48 | { .type = "plb5", }, | ||
49 | { .type = "plb4", }, | ||
50 | { .type = "opb", }, | ||
51 | { .type = "ebc", }, | ||
52 | {}, | ||
53 | }; | ||
54 | |||
55 | struct bus_type of_platform_bus_type = { | ||
56 | .uevent = of_device_uevent, | ||
57 | }; | ||
58 | EXPORT_SYMBOL(of_platform_bus_type); | ||
59 | |||
60 | static int __init of_bus_driver_init(void) | ||
61 | { | ||
62 | return of_bus_type_init(&of_platform_bus_type, "of_platform"); | ||
63 | } | ||
64 | |||
65 | postcore_initcall(of_bus_driver_init); | ||
66 | |||
67 | struct of_device* of_platform_device_create(struct device_node *np, | ||
68 | const char *bus_id, | ||
69 | struct device *parent) | ||
70 | { | ||
71 | struct of_device *dev; | ||
72 | |||
73 | dev = of_device_alloc(np, bus_id, parent); | ||
74 | if (!dev) | ||
75 | return NULL; | ||
76 | |||
77 | dev->archdata.dma_mask = 0xffffffffUL; | ||
78 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | ||
79 | |||
80 | dev->dev.bus = &of_platform_bus_type; | ||
81 | |||
82 | /* We do not fill the DMA ops for platform devices by default. | ||
83 | * This is currently the responsibility of the platform code | ||
84 | * to do such, possibly using a device notifier | ||
85 | */ | ||
86 | |||
87 | if (of_device_register(dev) != 0) { | ||
88 | of_device_free(dev); | ||
89 | return NULL; | ||
90 | } | ||
91 | |||
92 | return dev; | ||
93 | } | ||
94 | EXPORT_SYMBOL(of_platform_device_create); | ||
95 | |||
96 | |||
97 | |||
98 | /** | ||
99 | * of_platform_bus_create - Create an OF device for a bus node and all its | ||
100 | * children. Optionally recursively instanciate matching busses. | ||
101 | * @bus: device node of the bus to instanciate | ||
102 | * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to | ||
103 | * disallow recursive creation of child busses | ||
104 | */ | ||
105 | static int of_platform_bus_create(const struct device_node *bus, | ||
106 | const struct of_device_id *matches, | ||
107 | struct device *parent) | ||
108 | { | ||
109 | struct device_node *child; | ||
110 | struct of_device *dev; | ||
111 | int rc = 0; | ||
112 | |||
113 | for_each_child_of_node(bus, child) { | ||
114 | pr_debug(" create child: %s\n", child->full_name); | ||
115 | dev = of_platform_device_create(child, NULL, parent); | ||
116 | if (dev == NULL) | ||
117 | rc = -ENOMEM; | ||
118 | else if (!of_match_node(matches, child)) | ||
119 | continue; | ||
120 | if (rc == 0) { | ||
121 | pr_debug(" and sub busses\n"); | ||
122 | rc = of_platform_bus_create(child, matches, &dev->dev); | ||
123 | } if (rc) { | ||
124 | of_node_put(child); | ||
125 | break; | ||
126 | } | ||
127 | } | ||
128 | return rc; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * of_platform_bus_probe - Probe the device-tree for platform busses | ||
133 | * @root: parent of the first level to probe or NULL for the root of the tree | ||
134 | * @matches: match table, NULL to use the default | ||
135 | * @parent: parent to hook devices from, NULL for toplevel | ||
136 | * | ||
137 | * Note that children of the provided root are not instanciated as devices | ||
138 | * unless the specified root itself matches the bus list and is not NULL. | ||
139 | */ | ||
140 | |||
141 | int of_platform_bus_probe(struct device_node *root, | ||
142 | const struct of_device_id *matches, | ||
143 | struct device *parent) | ||
144 | { | ||
145 | struct device_node *child; | ||
146 | struct of_device *dev; | ||
147 | int rc = 0; | ||
148 | |||
149 | if (matches == NULL) | ||
150 | matches = of_default_bus_ids; | ||
151 | if (matches == OF_NO_DEEP_PROBE) | ||
152 | return -EINVAL; | ||
153 | if (root == NULL) | ||
154 | root = of_find_node_by_path("/"); | ||
155 | else | ||
156 | of_node_get(root); | ||
157 | |||
158 | pr_debug("of_platform_bus_probe()\n"); | ||
159 | pr_debug(" starting at: %s\n", root->full_name); | ||
160 | |||
161 | /* Do a self check of bus type, if there's a match, create | ||
162 | * children | ||
163 | */ | ||
164 | if (of_match_node(matches, root)) { | ||
165 | pr_debug(" root match, create all sub devices\n"); | ||
166 | dev = of_platform_device_create(root, NULL, parent); | ||
167 | if (dev == NULL) { | ||
168 | rc = -ENOMEM; | ||
169 | goto bail; | ||
170 | } | ||
171 | pr_debug(" create all sub busses\n"); | ||
172 | rc = of_platform_bus_create(root, matches, &dev->dev); | ||
173 | goto bail; | ||
174 | } | ||
175 | for_each_child_of_node(root, child) { | ||
176 | if (!of_match_node(matches, child)) | ||
177 | continue; | ||
178 | |||
179 | pr_debug(" match: %s\n", child->full_name); | ||
180 | dev = of_platform_device_create(child, NULL, parent); | ||
181 | if (dev == NULL) | ||
182 | rc = -ENOMEM; | ||
183 | else | ||
184 | rc = of_platform_bus_create(child, matches, &dev->dev); | ||
185 | if (rc) { | ||
186 | of_node_put(child); | ||
187 | break; | ||
188 | } | ||
189 | } | ||
190 | bail: | ||
191 | of_node_put(root); | ||
192 | return rc; | ||
193 | } | ||
194 | EXPORT_SYMBOL(of_platform_bus_probe); | ||
195 | |||
196 | static int of_dev_node_match(struct device *dev, void *data) | ||
197 | { | ||
198 | return to_of_device(dev)->dev.of_node == data; | ||
199 | } | ||
200 | |||
201 | struct of_device *of_find_device_by_node(struct device_node *np) | ||
202 | { | ||
203 | struct device *dev; | ||
204 | |||
205 | dev = bus_find_device(&of_platform_bus_type, | ||
206 | NULL, np, of_dev_node_match); | ||
207 | if (dev) | ||
208 | return to_of_device(dev); | ||
209 | return NULL; | ||
210 | } | ||
211 | EXPORT_SYMBOL(of_find_device_by_node); | ||
212 | |||
213 | static int of_dev_phandle_match(struct device *dev, void *data) | ||
214 | { | ||
215 | phandle *ph = data; | ||
216 | return to_of_device(dev)->dev.of_node->phandle == *ph; | ||
217 | } | ||
218 | |||
219 | struct of_device *of_find_device_by_phandle(phandle ph) | ||
220 | { | ||
221 | struct device *dev; | ||
222 | |||
223 | dev = bus_find_device(&of_platform_bus_type, | ||
224 | NULL, &ph, of_dev_phandle_match); | ||
225 | if (dev) | ||
226 | return to_of_device(dev); | ||
227 | return NULL; | ||
228 | } | ||
229 | EXPORT_SYMBOL(of_find_device_by_phandle); | ||
230 | |||
231 | |||
232 | #ifdef CONFIG_PPC_OF_PLATFORM_PCI | 31 | #ifdef CONFIG_PPC_OF_PLATFORM_PCI |
233 | 32 | ||
234 | /* The probing of PCI controllers from of_platform is currently | 33 | /* The probing of PCI controllers from of_platform is currently |
@@ -237,7 +36,7 @@ EXPORT_SYMBOL(of_find_device_by_phandle); | |||
237 | * lacking some bits needed here. | 36 | * lacking some bits needed here. |
238 | */ | 37 | */ |
239 | 38 | ||
240 | static int __devinit of_pci_phb_probe(struct of_device *dev, | 39 | static int __devinit of_pci_phb_probe(struct platform_device *dev, |
241 | const struct of_device_id *match) | 40 | const struct of_device_id *match) |
242 | { | 41 | { |
243 | struct pci_controller *phb; | 42 | struct pci_controller *phb; |
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/pci-common.c b/arch/powerpc/kernel/pci-common.c index 5b38f6ae2b29..9021c4ad4bbd 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/string.h> | 21 | #include <linux/string.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/bootmem.h> | 23 | #include <linux/bootmem.h> |
24 | #include <linux/of_address.h> | ||
24 | #include <linux/mm.h> | 25 | #include <linux/mm.h> |
25 | #include <linux/list.h> | 26 | #include <linux/list.h> |
26 | #include <linux/syscalls.h> | 27 | #include <linux/syscalls.h> |
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 3b4dcc82a4c1..ab3e392ac63c 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -101,10 +101,6 @@ EXPORT_SYMBOL(pci_dram_offset); | |||
101 | EXPORT_SYMBOL(start_thread); | 101 | EXPORT_SYMBOL(start_thread); |
102 | EXPORT_SYMBOL(kernel_thread); | 102 | EXPORT_SYMBOL(kernel_thread); |
103 | 103 | ||
104 | #ifdef CONFIG_PPC_FPU | ||
105 | EXPORT_SYMBOL_GPL(cvt_df); | ||
106 | EXPORT_SYMBOL_GPL(cvt_fd); | ||
107 | #endif | ||
108 | EXPORT_SYMBOL(giveup_fpu); | 104 | EXPORT_SYMBOL(giveup_fpu); |
109 | #ifdef CONFIG_ALTIVEC | 105 | #ifdef CONFIG_ALTIVEC |
110 | EXPORT_SYMBOL(giveup_altivec); | 106 | EXPORT_SYMBOL(giveup_altivec); |
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/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index 8362620c9e6f..88334af038e5 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c | |||
@@ -6,232 +6,11 @@ | |||
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/ioport.h> | 7 | #include <linux/ioport.h> |
8 | #include <linux/etherdevice.h> | 8 | #include <linux/etherdevice.h> |
9 | #include <linux/of_address.h> | ||
9 | #include <asm/prom.h> | 10 | #include <asm/prom.h> |
10 | #include <asm/pci-bridge.h> | 11 | #include <asm/pci-bridge.h> |
11 | 12 | ||
12 | #ifdef DEBUG | ||
13 | #define DBG(fmt...) do { printk(fmt); } while(0) | ||
14 | #else | ||
15 | #define DBG(fmt...) do { } while(0) | ||
16 | #endif | ||
17 | |||
18 | #ifdef CONFIG_PPC64 | ||
19 | #define PRu64 "%lx" | ||
20 | #else | ||
21 | #define PRu64 "%llx" | ||
22 | #endif | ||
23 | |||
24 | /* Max address size we deal with */ | ||
25 | #define OF_MAX_ADDR_CELLS 4 | ||
26 | #define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ | ||
27 | (ns) > 0) | ||
28 | |||
29 | static struct of_bus *of_match_bus(struct device_node *np); | ||
30 | static int __of_address_to_resource(struct device_node *dev, | ||
31 | const u32 *addrp, u64 size, unsigned int flags, | ||
32 | struct resource *r); | ||
33 | |||
34 | |||
35 | /* Debug utility */ | ||
36 | #ifdef DEBUG | ||
37 | static void of_dump_addr(const char *s, const u32 *addr, int na) | ||
38 | { | ||
39 | printk("%s", s); | ||
40 | while(na--) | ||
41 | printk(" %08x", *(addr++)); | ||
42 | printk("\n"); | ||
43 | } | ||
44 | #else | ||
45 | static void of_dump_addr(const char *s, const u32 *addr, int na) { } | ||
46 | #endif | ||
47 | |||
48 | |||
49 | /* Callbacks for bus specific translators */ | ||
50 | struct of_bus { | ||
51 | const char *name; | ||
52 | const char *addresses; | ||
53 | int (*match)(struct device_node *parent); | ||
54 | void (*count_cells)(struct device_node *child, | ||
55 | int *addrc, int *sizec); | ||
56 | u64 (*map)(u32 *addr, const u32 *range, | ||
57 | int na, int ns, int pna); | ||
58 | int (*translate)(u32 *addr, u64 offset, int na); | ||
59 | unsigned int (*get_flags)(const u32 *addr); | ||
60 | }; | ||
61 | |||
62 | |||
63 | /* | ||
64 | * Default translator (generic bus) | ||
65 | */ | ||
66 | |||
67 | static void of_bus_default_count_cells(struct device_node *dev, | ||
68 | int *addrc, int *sizec) | ||
69 | { | ||
70 | if (addrc) | ||
71 | *addrc = of_n_addr_cells(dev); | ||
72 | if (sizec) | ||
73 | *sizec = of_n_size_cells(dev); | ||
74 | } | ||
75 | |||
76 | static u64 of_bus_default_map(u32 *addr, const u32 *range, | ||
77 | int na, int ns, int pna) | ||
78 | { | ||
79 | u64 cp, s, da; | ||
80 | |||
81 | cp = of_read_number(range, na); | ||
82 | s = of_read_number(range + na + pna, ns); | ||
83 | da = of_read_number(addr, na); | ||
84 | |||
85 | DBG("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n", | ||
86 | cp, s, da); | ||
87 | |||
88 | if (da < cp || da >= (cp + s)) | ||
89 | return OF_BAD_ADDR; | ||
90 | return da - cp; | ||
91 | } | ||
92 | |||
93 | static int of_bus_default_translate(u32 *addr, u64 offset, int na) | ||
94 | { | ||
95 | u64 a = of_read_number(addr, na); | ||
96 | memset(addr, 0, na * 4); | ||
97 | a += offset; | ||
98 | if (na > 1) | ||
99 | addr[na - 2] = a >> 32; | ||
100 | addr[na - 1] = a & 0xffffffffu; | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static unsigned int of_bus_default_get_flags(const u32 *addr) | ||
106 | { | ||
107 | return IORESOURCE_MEM; | ||
108 | } | ||
109 | |||
110 | |||
111 | #ifdef CONFIG_PCI | 13 | #ifdef CONFIG_PCI |
112 | /* | ||
113 | * PCI bus specific translator | ||
114 | */ | ||
115 | |||
116 | static int of_bus_pci_match(struct device_node *np) | ||
117 | { | ||
118 | /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */ | ||
119 | return !strcmp(np->type, "pci") || !strcmp(np->type, "vci"); | ||
120 | } | ||
121 | |||
122 | static void of_bus_pci_count_cells(struct device_node *np, | ||
123 | int *addrc, int *sizec) | ||
124 | { | ||
125 | if (addrc) | ||
126 | *addrc = 3; | ||
127 | if (sizec) | ||
128 | *sizec = 2; | ||
129 | } | ||
130 | |||
131 | static unsigned int of_bus_pci_get_flags(const u32 *addr) | ||
132 | { | ||
133 | unsigned int flags = 0; | ||
134 | u32 w = addr[0]; | ||
135 | |||
136 | switch((w >> 24) & 0x03) { | ||
137 | case 0x01: | ||
138 | flags |= IORESOURCE_IO; | ||
139 | break; | ||
140 | case 0x02: /* 32 bits */ | ||
141 | case 0x03: /* 64 bits */ | ||
142 | flags |= IORESOURCE_MEM; | ||
143 | break; | ||
144 | } | ||
145 | if (w & 0x40000000) | ||
146 | flags |= IORESOURCE_PREFETCH; | ||
147 | return flags; | ||
148 | } | ||
149 | |||
150 | static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna) | ||
151 | { | ||
152 | u64 cp, s, da; | ||
153 | unsigned int af, rf; | ||
154 | |||
155 | af = of_bus_pci_get_flags(addr); | ||
156 | rf = of_bus_pci_get_flags(range); | ||
157 | |||
158 | /* Check address type match */ | ||
159 | if ((af ^ rf) & (IORESOURCE_MEM | IORESOURCE_IO)) | ||
160 | return OF_BAD_ADDR; | ||
161 | |||
162 | /* Read address values, skipping high cell */ | ||
163 | cp = of_read_number(range + 1, na - 1); | ||
164 | s = of_read_number(range + na + pna, ns); | ||
165 | da = of_read_number(addr + 1, na - 1); | ||
166 | |||
167 | DBG("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); | ||
168 | |||
169 | if (da < cp || da >= (cp + s)) | ||
170 | return OF_BAD_ADDR; | ||
171 | return da - cp; | ||
172 | } | ||
173 | |||
174 | static int of_bus_pci_translate(u32 *addr, u64 offset, int na) | ||
175 | { | ||
176 | return of_bus_default_translate(addr + 1, offset, na - 1); | ||
177 | } | ||
178 | |||
179 | const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, | ||
180 | unsigned int *flags) | ||
181 | { | ||
182 | const u32 *prop; | ||
183 | unsigned int psize; | ||
184 | struct device_node *parent; | ||
185 | struct of_bus *bus; | ||
186 | int onesize, i, na, ns; | ||
187 | |||
188 | /* Get parent & match bus type */ | ||
189 | parent = of_get_parent(dev); | ||
190 | if (parent == NULL) | ||
191 | return NULL; | ||
192 | bus = of_match_bus(parent); | ||
193 | if (strcmp(bus->name, "pci")) { | ||
194 | of_node_put(parent); | ||
195 | return NULL; | ||
196 | } | ||
197 | bus->count_cells(dev, &na, &ns); | ||
198 | of_node_put(parent); | ||
199 | if (!OF_CHECK_COUNTS(na, ns)) | ||
200 | return NULL; | ||
201 | |||
202 | /* Get "reg" or "assigned-addresses" property */ | ||
203 | prop = of_get_property(dev, bus->addresses, &psize); | ||
204 | if (prop == NULL) | ||
205 | return NULL; | ||
206 | psize /= 4; | ||
207 | |||
208 | onesize = na + ns; | ||
209 | for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) | ||
210 | if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) { | ||
211 | if (size) | ||
212 | *size = of_read_number(prop + na, ns); | ||
213 | if (flags) | ||
214 | *flags = bus->get_flags(prop); | ||
215 | return prop; | ||
216 | } | ||
217 | return NULL; | ||
218 | } | ||
219 | EXPORT_SYMBOL(of_get_pci_address); | ||
220 | |||
221 | int of_pci_address_to_resource(struct device_node *dev, int bar, | ||
222 | struct resource *r) | ||
223 | { | ||
224 | const u32 *addrp; | ||
225 | u64 size; | ||
226 | unsigned int flags; | ||
227 | |||
228 | addrp = of_get_pci_address(dev, bar, &size, &flags); | ||
229 | if (addrp == NULL) | ||
230 | return -EINVAL; | ||
231 | return __of_address_to_resource(dev, addrp, size, flags, r); | ||
232 | } | ||
233 | EXPORT_SYMBOL_GPL(of_pci_address_to_resource); | ||
234 | |||
235 | int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) | 14 | int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) |
236 | { | 15 | { |
237 | struct device_node *dn, *ppnode; | 16 | struct device_node *dn, *ppnode; |
@@ -313,345 +92,6 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) | |||
313 | EXPORT_SYMBOL_GPL(of_irq_map_pci); | 92 | EXPORT_SYMBOL_GPL(of_irq_map_pci); |
314 | #endif /* CONFIG_PCI */ | 93 | #endif /* CONFIG_PCI */ |
315 | 94 | ||
316 | /* | ||
317 | * ISA bus specific translator | ||
318 | */ | ||
319 | |||
320 | static int of_bus_isa_match(struct device_node *np) | ||
321 | { | ||
322 | return !strcmp(np->name, "isa"); | ||
323 | } | ||
324 | |||
325 | static void of_bus_isa_count_cells(struct device_node *child, | ||
326 | int *addrc, int *sizec) | ||
327 | { | ||
328 | if (addrc) | ||
329 | *addrc = 2; | ||
330 | if (sizec) | ||
331 | *sizec = 1; | ||
332 | } | ||
333 | |||
334 | static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna) | ||
335 | { | ||
336 | u64 cp, s, da; | ||
337 | |||
338 | /* Check address type match */ | ||
339 | if ((addr[0] ^ range[0]) & 0x00000001) | ||
340 | return OF_BAD_ADDR; | ||
341 | |||
342 | /* Read address values, skipping high cell */ | ||
343 | cp = of_read_number(range + 1, na - 1); | ||
344 | s = of_read_number(range + na + pna, ns); | ||
345 | da = of_read_number(addr + 1, na - 1); | ||
346 | |||
347 | DBG("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); | ||
348 | |||
349 | if (da < cp || da >= (cp + s)) | ||
350 | return OF_BAD_ADDR; | ||
351 | return da - cp; | ||
352 | } | ||
353 | |||
354 | static int of_bus_isa_translate(u32 *addr, u64 offset, int na) | ||
355 | { | ||
356 | return of_bus_default_translate(addr + 1, offset, na - 1); | ||
357 | } | ||
358 | |||
359 | static unsigned int of_bus_isa_get_flags(const u32 *addr) | ||
360 | { | ||
361 | unsigned int flags = 0; | ||
362 | u32 w = addr[0]; | ||
363 | |||
364 | if (w & 1) | ||
365 | flags |= IORESOURCE_IO; | ||
366 | else | ||
367 | flags |= IORESOURCE_MEM; | ||
368 | return flags; | ||
369 | } | ||
370 | |||
371 | |||
372 | /* | ||
373 | * Array of bus specific translators | ||
374 | */ | ||
375 | |||
376 | static struct of_bus of_busses[] = { | ||
377 | #ifdef CONFIG_PCI | ||
378 | /* PCI */ | ||
379 | { | ||
380 | .name = "pci", | ||
381 | .addresses = "assigned-addresses", | ||
382 | .match = of_bus_pci_match, | ||
383 | .count_cells = of_bus_pci_count_cells, | ||
384 | .map = of_bus_pci_map, | ||
385 | .translate = of_bus_pci_translate, | ||
386 | .get_flags = of_bus_pci_get_flags, | ||
387 | }, | ||
388 | #endif /* CONFIG_PCI */ | ||
389 | /* ISA */ | ||
390 | { | ||
391 | .name = "isa", | ||
392 | .addresses = "reg", | ||
393 | .match = of_bus_isa_match, | ||
394 | .count_cells = of_bus_isa_count_cells, | ||
395 | .map = of_bus_isa_map, | ||
396 | .translate = of_bus_isa_translate, | ||
397 | .get_flags = of_bus_isa_get_flags, | ||
398 | }, | ||
399 | /* Default */ | ||
400 | { | ||
401 | .name = "default", | ||
402 | .addresses = "reg", | ||
403 | .match = NULL, | ||
404 | .count_cells = of_bus_default_count_cells, | ||
405 | .map = of_bus_default_map, | ||
406 | .translate = of_bus_default_translate, | ||
407 | .get_flags = of_bus_default_get_flags, | ||
408 | }, | ||
409 | }; | ||
410 | |||
411 | static struct of_bus *of_match_bus(struct device_node *np) | ||
412 | { | ||
413 | int i; | ||
414 | |||
415 | for (i = 0; i < ARRAY_SIZE(of_busses); i ++) | ||
416 | if (!of_busses[i].match || of_busses[i].match(np)) | ||
417 | return &of_busses[i]; | ||
418 | BUG(); | ||
419 | return NULL; | ||
420 | } | ||
421 | |||
422 | static int of_translate_one(struct device_node *parent, struct of_bus *bus, | ||
423 | struct of_bus *pbus, u32 *addr, | ||
424 | int na, int ns, int pna, const char *rprop) | ||
425 | { | ||
426 | const u32 *ranges; | ||
427 | unsigned int rlen; | ||
428 | int rone; | ||
429 | u64 offset = OF_BAD_ADDR; | ||
430 | |||
431 | /* Normally, an absence of a "ranges" property means we are | ||
432 | * crossing a non-translatable boundary, and thus the addresses | ||
433 | * below the current not cannot be converted to CPU physical ones. | ||
434 | * Unfortunately, while this is very clear in the spec, it's not | ||
435 | * what Apple understood, and they do have things like /uni-n or | ||
436 | * /ht nodes with no "ranges" property and a lot of perfectly | ||
437 | * useable mapped devices below them. Thus we treat the absence of | ||
438 | * "ranges" as equivalent to an empty "ranges" property which means | ||
439 | * a 1:1 translation at that level. It's up to the caller not to try | ||
440 | * to translate addresses that aren't supposed to be translated in | ||
441 | * the first place. --BenH. | ||
442 | */ | ||
443 | ranges = of_get_property(parent, rprop, &rlen); | ||
444 | if (ranges == NULL || rlen == 0) { | ||
445 | offset = of_read_number(addr, na); | ||
446 | memset(addr, 0, pna * 4); | ||
447 | DBG("OF: no ranges, 1:1 translation\n"); | ||
448 | goto finish; | ||
449 | } | ||
450 | |||
451 | DBG("OF: walking ranges...\n"); | ||
452 | |||
453 | /* Now walk through the ranges */ | ||
454 | rlen /= 4; | ||
455 | rone = na + pna + ns; | ||
456 | for (; rlen >= rone; rlen -= rone, ranges += rone) { | ||
457 | offset = bus->map(addr, ranges, na, ns, pna); | ||
458 | if (offset != OF_BAD_ADDR) | ||
459 | break; | ||
460 | } | ||
461 | if (offset == OF_BAD_ADDR) { | ||
462 | DBG("OF: not found !\n"); | ||
463 | return 1; | ||
464 | } | ||
465 | memcpy(addr, ranges + na, 4 * pna); | ||
466 | |||
467 | finish: | ||
468 | of_dump_addr("OF: parent translation for:", addr, pna); | ||
469 | DBG("OF: with offset: "PRu64"\n", offset); | ||
470 | |||
471 | /* Translate it into parent bus space */ | ||
472 | return pbus->translate(addr, offset, pna); | ||
473 | } | ||
474 | |||
475 | |||
476 | /* | ||
477 | * Translate an address from the device-tree into a CPU physical address, | ||
478 | * this walks up the tree and applies the various bus mappings on the | ||
479 | * way. | ||
480 | * | ||
481 | * Note: We consider that crossing any level with #size-cells == 0 to mean | ||
482 | * that translation is impossible (that is we are not dealing with a value | ||
483 | * that can be mapped to a cpu physical address). This is not really specified | ||
484 | * that way, but this is traditionally the way IBM at least do things | ||
485 | */ | ||
486 | u64 __of_translate_address(struct device_node *dev, const u32 *in_addr, | ||
487 | const char *rprop) | ||
488 | { | ||
489 | struct device_node *parent = NULL; | ||
490 | struct of_bus *bus, *pbus; | ||
491 | u32 addr[OF_MAX_ADDR_CELLS]; | ||
492 | int na, ns, pna, pns; | ||
493 | u64 result = OF_BAD_ADDR; | ||
494 | |||
495 | DBG("OF: ** translation for device %s **\n", dev->full_name); | ||
496 | |||
497 | /* Increase refcount at current level */ | ||
498 | of_node_get(dev); | ||
499 | |||
500 | /* Get parent & match bus type */ | ||
501 | parent = of_get_parent(dev); | ||
502 | if (parent == NULL) | ||
503 | goto bail; | ||
504 | bus = of_match_bus(parent); | ||
505 | |||
506 | /* Cound address cells & copy address locally */ | ||
507 | bus->count_cells(dev, &na, &ns); | ||
508 | if (!OF_CHECK_COUNTS(na, ns)) { | ||
509 | printk(KERN_ERR "prom_parse: Bad cell count for %s\n", | ||
510 | dev->full_name); | ||
511 | goto bail; | ||
512 | } | ||
513 | memcpy(addr, in_addr, na * 4); | ||
514 | |||
515 | DBG("OF: bus is %s (na=%d, ns=%d) on %s\n", | ||
516 | bus->name, na, ns, parent->full_name); | ||
517 | of_dump_addr("OF: translating address:", addr, na); | ||
518 | |||
519 | /* Translate */ | ||
520 | for (;;) { | ||
521 | /* Switch to parent bus */ | ||
522 | of_node_put(dev); | ||
523 | dev = parent; | ||
524 | parent = of_get_parent(dev); | ||
525 | |||
526 | /* If root, we have finished */ | ||
527 | if (parent == NULL) { | ||
528 | DBG("OF: reached root node\n"); | ||
529 | result = of_read_number(addr, na); | ||
530 | break; | ||
531 | } | ||
532 | |||
533 | /* Get new parent bus and counts */ | ||
534 | pbus = of_match_bus(parent); | ||
535 | pbus->count_cells(dev, &pna, &pns); | ||
536 | if (!OF_CHECK_COUNTS(pna, pns)) { | ||
537 | printk(KERN_ERR "prom_parse: Bad cell count for %s\n", | ||
538 | dev->full_name); | ||
539 | break; | ||
540 | } | ||
541 | |||
542 | DBG("OF: parent bus is %s (na=%d, ns=%d) on %s\n", | ||
543 | pbus->name, pna, pns, parent->full_name); | ||
544 | |||
545 | /* Apply bus translation */ | ||
546 | if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop)) | ||
547 | break; | ||
548 | |||
549 | /* Complete the move up one level */ | ||
550 | na = pna; | ||
551 | ns = pns; | ||
552 | bus = pbus; | ||
553 | |||
554 | of_dump_addr("OF: one level translation:", addr, na); | ||
555 | } | ||
556 | bail: | ||
557 | of_node_put(parent); | ||
558 | of_node_put(dev); | ||
559 | |||
560 | return result; | ||
561 | } | ||
562 | |||
563 | u64 of_translate_address(struct device_node *dev, const u32 *in_addr) | ||
564 | { | ||
565 | return __of_translate_address(dev, in_addr, "ranges"); | ||
566 | } | ||
567 | EXPORT_SYMBOL(of_translate_address); | ||
568 | |||
569 | u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr) | ||
570 | { | ||
571 | return __of_translate_address(dev, in_addr, "dma-ranges"); | ||
572 | } | ||
573 | EXPORT_SYMBOL(of_translate_dma_address); | ||
574 | |||
575 | const u32 *of_get_address(struct device_node *dev, int index, u64 *size, | ||
576 | unsigned int *flags) | ||
577 | { | ||
578 | const u32 *prop; | ||
579 | unsigned int psize; | ||
580 | struct device_node *parent; | ||
581 | struct of_bus *bus; | ||
582 | int onesize, i, na, ns; | ||
583 | |||
584 | /* Get parent & match bus type */ | ||
585 | parent = of_get_parent(dev); | ||
586 | if (parent == NULL) | ||
587 | return NULL; | ||
588 | bus = of_match_bus(parent); | ||
589 | bus->count_cells(dev, &na, &ns); | ||
590 | of_node_put(parent); | ||
591 | if (!OF_CHECK_COUNTS(na, ns)) | ||
592 | return NULL; | ||
593 | |||
594 | /* Get "reg" or "assigned-addresses" property */ | ||
595 | prop = of_get_property(dev, bus->addresses, &psize); | ||
596 | if (prop == NULL) | ||
597 | return NULL; | ||
598 | psize /= 4; | ||
599 | |||
600 | onesize = na + ns; | ||
601 | for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) | ||
602 | if (i == index) { | ||
603 | if (size) | ||
604 | *size = of_read_number(prop + na, ns); | ||
605 | if (flags) | ||
606 | *flags = bus->get_flags(prop); | ||
607 | return prop; | ||
608 | } | ||
609 | return NULL; | ||
610 | } | ||
611 | EXPORT_SYMBOL(of_get_address); | ||
612 | |||
613 | static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, | ||
614 | u64 size, unsigned int flags, | ||
615 | struct resource *r) | ||
616 | { | ||
617 | u64 taddr; | ||
618 | |||
619 | if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0) | ||
620 | return -EINVAL; | ||
621 | taddr = of_translate_address(dev, addrp); | ||
622 | if (taddr == OF_BAD_ADDR) | ||
623 | return -EINVAL; | ||
624 | memset(r, 0, sizeof(struct resource)); | ||
625 | if (flags & IORESOURCE_IO) { | ||
626 | unsigned long port; | ||
627 | port = pci_address_to_pio(taddr); | ||
628 | if (port == (unsigned long)-1) | ||
629 | return -EINVAL; | ||
630 | r->start = port; | ||
631 | r->end = port + size - 1; | ||
632 | } else { | ||
633 | r->start = taddr; | ||
634 | r->end = taddr + size - 1; | ||
635 | } | ||
636 | r->flags = flags; | ||
637 | r->name = dev->name; | ||
638 | return 0; | ||
639 | } | ||
640 | |||
641 | int of_address_to_resource(struct device_node *dev, int index, | ||
642 | struct resource *r) | ||
643 | { | ||
644 | const u32 *addrp; | ||
645 | u64 size; | ||
646 | unsigned int flags; | ||
647 | |||
648 | addrp = of_get_address(dev, index, &size, &flags); | ||
649 | if (addrp == NULL) | ||
650 | return -EINVAL; | ||
651 | return __of_address_to_resource(dev, addrp, size, flags, r); | ||
652 | } | ||
653 | EXPORT_SYMBOL_GPL(of_address_to_resource); | ||
654 | |||
655 | void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, | 95 | void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, |
656 | unsigned long *busno, unsigned long *phys, unsigned long *size) | 96 | unsigned long *busno, unsigned long *phys, unsigned long *size) |
657 | { | 97 | { |
@@ -678,342 +118,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, | |||
678 | *size = of_read_number(dma_window, cells); | 118 | *size = of_read_number(dma_window, cells); |
679 | } | 119 | } |
680 | 120 | ||
681 | /* | ||
682 | * Interrupt remapper | ||
683 | */ | ||
684 | |||
685 | static unsigned int of_irq_workarounds; | ||
686 | static struct device_node *of_irq_dflt_pic; | ||
687 | |||
688 | static struct device_node *of_irq_find_parent(struct device_node *child) | ||
689 | { | ||
690 | struct device_node *p; | ||
691 | const phandle *parp; | ||
692 | |||
693 | if (!of_node_get(child)) | ||
694 | return NULL; | ||
695 | |||
696 | do { | ||
697 | parp = of_get_property(child, "interrupt-parent", NULL); | ||
698 | if (parp == NULL) | ||
699 | p = of_get_parent(child); | ||
700 | else { | ||
701 | if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) | ||
702 | p = of_node_get(of_irq_dflt_pic); | ||
703 | else | ||
704 | p = of_find_node_by_phandle(*parp); | ||
705 | } | ||
706 | of_node_put(child); | ||
707 | child = p; | ||
708 | } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); | ||
709 | |||
710 | return p; | ||
711 | } | ||
712 | |||
713 | /* This doesn't need to be called if you don't have any special workaround | ||
714 | * flags to pass | ||
715 | */ | ||
716 | void of_irq_map_init(unsigned int flags) | ||
717 | { | ||
718 | of_irq_workarounds = flags; | ||
719 | |||
720 | /* OldWorld, don't bother looking at other things */ | ||
721 | if (flags & OF_IMAP_OLDWORLD_MAC) | ||
722 | return; | ||
723 | |||
724 | /* If we don't have phandles, let's try to locate a default interrupt | ||
725 | * controller (happens when booting with BootX). We do a first match | ||
726 | * here, hopefully, that only ever happens on machines with one | ||
727 | * controller. | ||
728 | */ | ||
729 | if (flags & OF_IMAP_NO_PHANDLE) { | ||
730 | struct device_node *np; | ||
731 | |||
732 | for_each_node_with_property(np, "interrupt-controller") { | ||
733 | /* Skip /chosen/interrupt-controller */ | ||
734 | if (strcmp(np->name, "chosen") == 0) | ||
735 | continue; | ||
736 | /* It seems like at least one person on this planet wants | ||
737 | * to use BootX on a machine with an AppleKiwi controller | ||
738 | * which happens to pretend to be an interrupt | ||
739 | * controller too. | ||
740 | */ | ||
741 | if (strcmp(np->name, "AppleKiwi") == 0) | ||
742 | continue; | ||
743 | /* I think we found one ! */ | ||
744 | of_irq_dflt_pic = np; | ||
745 | break; | ||
746 | } | ||
747 | } | ||
748 | |||
749 | } | ||
750 | |||
751 | int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, | ||
752 | const u32 *addr, struct of_irq *out_irq) | ||
753 | { | ||
754 | struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; | ||
755 | const u32 *tmp, *imap, *imask; | ||
756 | u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; | ||
757 | int imaplen, match, i; | ||
758 | |||
759 | DBG("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n", | ||
760 | parent->full_name, intspec[0], intspec[1], ointsize); | ||
761 | |||
762 | ipar = of_node_get(parent); | ||
763 | |||
764 | /* First get the #interrupt-cells property of the current cursor | ||
765 | * that tells us how to interpret the passed-in intspec. If there | ||
766 | * is none, we are nice and just walk up the tree | ||
767 | */ | ||
768 | do { | ||
769 | tmp = of_get_property(ipar, "#interrupt-cells", NULL); | ||
770 | if (tmp != NULL) { | ||
771 | intsize = *tmp; | ||
772 | break; | ||
773 | } | ||
774 | tnode = ipar; | ||
775 | ipar = of_irq_find_parent(ipar); | ||
776 | of_node_put(tnode); | ||
777 | } while (ipar); | ||
778 | if (ipar == NULL) { | ||
779 | DBG(" -> no parent found !\n"); | ||
780 | goto fail; | ||
781 | } | ||
782 | |||
783 | DBG("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize); | ||
784 | |||
785 | if (ointsize != intsize) | ||
786 | return -EINVAL; | ||
787 | |||
788 | /* Look for this #address-cells. We have to implement the old linux | ||
789 | * trick of looking for the parent here as some device-trees rely on it | ||
790 | */ | ||
791 | old = of_node_get(ipar); | ||
792 | do { | ||
793 | tmp = of_get_property(old, "#address-cells", NULL); | ||
794 | tnode = of_get_parent(old); | ||
795 | of_node_put(old); | ||
796 | old = tnode; | ||
797 | } while(old && tmp == NULL); | ||
798 | of_node_put(old); | ||
799 | old = NULL; | ||
800 | addrsize = (tmp == NULL) ? 2 : *tmp; | ||
801 | |||
802 | DBG(" -> addrsize=%d\n", addrsize); | ||
803 | |||
804 | /* Now start the actual "proper" walk of the interrupt tree */ | ||
805 | while (ipar != NULL) { | ||
806 | /* Now check if cursor is an interrupt-controller and if it is | ||
807 | * then we are done | ||
808 | */ | ||
809 | if (of_get_property(ipar, "interrupt-controller", NULL) != | ||
810 | NULL) { | ||
811 | DBG(" -> got it !\n"); | ||
812 | memcpy(out_irq->specifier, intspec, | ||
813 | intsize * sizeof(u32)); | ||
814 | out_irq->size = intsize; | ||
815 | out_irq->controller = ipar; | ||
816 | of_node_put(old); | ||
817 | return 0; | ||
818 | } | ||
819 | |||
820 | /* Now look for an interrupt-map */ | ||
821 | imap = of_get_property(ipar, "interrupt-map", &imaplen); | ||
822 | /* No interrupt map, check for an interrupt parent */ | ||
823 | if (imap == NULL) { | ||
824 | DBG(" -> no map, getting parent\n"); | ||
825 | newpar = of_irq_find_parent(ipar); | ||
826 | goto skiplevel; | ||
827 | } | ||
828 | imaplen /= sizeof(u32); | ||
829 | |||
830 | /* Look for a mask */ | ||
831 | imask = of_get_property(ipar, "interrupt-map-mask", NULL); | ||
832 | |||
833 | /* If we were passed no "reg" property and we attempt to parse | ||
834 | * an interrupt-map, then #address-cells must be 0. | ||
835 | * Fail if it's not. | ||
836 | */ | ||
837 | if (addr == NULL && addrsize != 0) { | ||
838 | DBG(" -> no reg passed in when needed !\n"); | ||
839 | goto fail; | ||
840 | } | ||
841 | |||
842 | /* Parse interrupt-map */ | ||
843 | match = 0; | ||
844 | while (imaplen > (addrsize + intsize + 1) && !match) { | ||
845 | /* Compare specifiers */ | ||
846 | match = 1; | ||
847 | for (i = 0; i < addrsize && match; ++i) { | ||
848 | u32 mask = imask ? imask[i] : 0xffffffffu; | ||
849 | match = ((addr[i] ^ imap[i]) & mask) == 0; | ||
850 | } | ||
851 | for (; i < (addrsize + intsize) && match; ++i) { | ||
852 | u32 mask = imask ? imask[i] : 0xffffffffu; | ||
853 | match = | ||
854 | ((intspec[i-addrsize] ^ imap[i]) & mask) == 0; | ||
855 | } | ||
856 | imap += addrsize + intsize; | ||
857 | imaplen -= addrsize + intsize; | ||
858 | |||
859 | DBG(" -> match=%d (imaplen=%d)\n", match, imaplen); | ||
860 | |||
861 | /* Get the interrupt parent */ | ||
862 | if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) | ||
863 | newpar = of_node_get(of_irq_dflt_pic); | ||
864 | else | ||
865 | newpar = of_find_node_by_phandle((phandle)*imap); | ||
866 | imap++; | ||
867 | --imaplen; | ||
868 | |||
869 | /* Check if not found */ | ||
870 | if (newpar == NULL) { | ||
871 | DBG(" -> imap parent not found !\n"); | ||
872 | goto fail; | ||
873 | } | ||
874 | |||
875 | /* Get #interrupt-cells and #address-cells of new | ||
876 | * parent | ||
877 | */ | ||
878 | tmp = of_get_property(newpar, "#interrupt-cells", NULL); | ||
879 | if (tmp == NULL) { | ||
880 | DBG(" -> parent lacks #interrupt-cells !\n"); | ||
881 | goto fail; | ||
882 | } | ||
883 | newintsize = *tmp; | ||
884 | tmp = of_get_property(newpar, "#address-cells", NULL); | ||
885 | newaddrsize = (tmp == NULL) ? 0 : *tmp; | ||
886 | |||
887 | DBG(" -> newintsize=%d, newaddrsize=%d\n", | ||
888 | newintsize, newaddrsize); | ||
889 | |||
890 | /* Check for malformed properties */ | ||
891 | if (imaplen < (newaddrsize + newintsize)) | ||
892 | goto fail; | ||
893 | |||
894 | imap += newaddrsize + newintsize; | ||
895 | imaplen -= newaddrsize + newintsize; | ||
896 | |||
897 | DBG(" -> imaplen=%d\n", imaplen); | ||
898 | } | ||
899 | if (!match) | ||
900 | goto fail; | ||
901 | |||
902 | of_node_put(old); | ||
903 | old = of_node_get(newpar); | ||
904 | addrsize = newaddrsize; | ||
905 | intsize = newintsize; | ||
906 | intspec = imap - intsize; | ||
907 | addr = intspec - addrsize; | ||
908 | |||
909 | skiplevel: | ||
910 | /* Iterate again with new parent */ | ||
911 | DBG(" -> new parent: %s\n", newpar ? newpar->full_name : "<>"); | ||
912 | of_node_put(ipar); | ||
913 | ipar = newpar; | ||
914 | newpar = NULL; | ||
915 | } | ||
916 | fail: | ||
917 | of_node_put(ipar); | ||
918 | of_node_put(old); | ||
919 | of_node_put(newpar); | ||
920 | |||
921 | return -EINVAL; | ||
922 | } | ||
923 | EXPORT_SYMBOL_GPL(of_irq_map_raw); | ||
924 | |||
925 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) | ||
926 | static int of_irq_map_oldworld(struct device_node *device, int index, | ||
927 | struct of_irq *out_irq) | ||
928 | { | ||
929 | const u32 *ints = NULL; | ||
930 | int intlen; | ||
931 | |||
932 | /* | ||
933 | * Old machines just have a list of interrupt numbers | ||
934 | * and no interrupt-controller nodes. We also have dodgy | ||
935 | * cases where the APPL,interrupts property is completely | ||
936 | * missing behind pci-pci bridges and we have to get it | ||
937 | * from the parent (the bridge itself, as apple just wired | ||
938 | * everything together on these) | ||
939 | */ | ||
940 | while (device) { | ||
941 | ints = of_get_property(device, "AAPL,interrupts", &intlen); | ||
942 | if (ints != NULL) | ||
943 | break; | ||
944 | device = device->parent; | ||
945 | if (device && strcmp(device->type, "pci") != 0) | ||
946 | break; | ||
947 | } | ||
948 | if (ints == NULL) | ||
949 | return -EINVAL; | ||
950 | intlen /= sizeof(u32); | ||
951 | |||
952 | if (index >= intlen) | ||
953 | return -EINVAL; | ||
954 | |||
955 | out_irq->controller = NULL; | ||
956 | out_irq->specifier[0] = ints[index]; | ||
957 | out_irq->size = 1; | ||
958 | |||
959 | return 0; | ||
960 | } | ||
961 | #else /* defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) */ | ||
962 | static int of_irq_map_oldworld(struct device_node *device, int index, | ||
963 | struct of_irq *out_irq) | ||
964 | { | ||
965 | return -EINVAL; | ||
966 | } | ||
967 | #endif /* !(defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)) */ | ||
968 | |||
969 | int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq) | ||
970 | { | ||
971 | struct device_node *p; | ||
972 | const u32 *intspec, *tmp, *addr; | ||
973 | u32 intsize, intlen; | ||
974 | int res = -EINVAL; | ||
975 | |||
976 | DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index); | ||
977 | |||
978 | /* OldWorld mac stuff is "special", handle out of line */ | ||
979 | if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC) | ||
980 | return of_irq_map_oldworld(device, index, out_irq); | ||
981 | |||
982 | /* Get the interrupts property */ | ||
983 | intspec = of_get_property(device, "interrupts", &intlen); | ||
984 | if (intspec == NULL) | ||
985 | return -EINVAL; | ||
986 | intlen /= sizeof(u32); | ||
987 | |||
988 | /* Get the reg property (if any) */ | ||
989 | addr = of_get_property(device, "reg", NULL); | ||
990 | |||
991 | /* Look for the interrupt parent. */ | ||
992 | p = of_irq_find_parent(device); | ||
993 | if (p == NULL) | ||
994 | return -EINVAL; | ||
995 | |||
996 | /* Get size of interrupt specifier */ | ||
997 | tmp = of_get_property(p, "#interrupt-cells", NULL); | ||
998 | if (tmp == NULL) | ||
999 | goto out; | ||
1000 | intsize = *tmp; | ||
1001 | |||
1002 | DBG(" intsize=%d intlen=%d\n", intsize, intlen); | ||
1003 | |||
1004 | /* Check index */ | ||
1005 | if ((index + 1) * intsize > intlen) | ||
1006 | goto out; | ||
1007 | |||
1008 | /* Get new specifier and map it */ | ||
1009 | res = of_irq_map_raw(p, intspec + index * intsize, intsize, | ||
1010 | addr, out_irq); | ||
1011 | out: | ||
1012 | of_node_put(p); | ||
1013 | return res; | ||
1014 | } | ||
1015 | EXPORT_SYMBOL_GPL(of_irq_map_one); | ||
1016 | |||
1017 | /** | 121 | /** |
1018 | * Search the device tree for the best MAC address to use. 'mac-address' is | 122 | * Search the device tree for the best MAC address to use. 'mac-address' is |
1019 | * checked first, because that is supposed to contain to "most recent" MAC | 123 | * checked first, because that is supposed to contain to "most recent" MAC |
@@ -1051,29 +155,3 @@ const void *of_get_mac_address(struct device_node *np) | |||
1051 | return NULL; | 155 | return NULL; |
1052 | } | 156 | } |
1053 | EXPORT_SYMBOL(of_get_mac_address); | 157 | EXPORT_SYMBOL(of_get_mac_address); |
1054 | |||
1055 | int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) | ||
1056 | { | ||
1057 | int irq = irq_of_parse_and_map(dev, index); | ||
1058 | |||
1059 | /* Only dereference the resource if both the | ||
1060 | * resource and the irq are valid. */ | ||
1061 | if (r && irq != NO_IRQ) { | ||
1062 | r->start = r->end = irq; | ||
1063 | r->flags = IORESOURCE_IRQ; | ||
1064 | } | ||
1065 | |||
1066 | return irq; | ||
1067 | } | ||
1068 | EXPORT_SYMBOL_GPL(of_irq_to_resource); | ||
1069 | |||
1070 | void __iomem *of_iomap(struct device_node *np, int index) | ||
1071 | { | ||
1072 | struct resource res; | ||
1073 | |||
1074 | if (of_address_to_resource(np, index, &res)) | ||
1075 | return NULL; | ||
1076 | |||
1077 | return ioremap(res.start, 1 + res.end - res.start); | ||
1078 | } | ||
1079 | EXPORT_SYMBOL(of_iomap); | ||
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..15ade0d7bbb2 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; |
@@ -701,16 +714,9 @@ static struct notifier_block ppc_dflt_plat_bus_notifier = { | |||
701 | .priority = INT_MAX, | 714 | .priority = INT_MAX, |
702 | }; | 715 | }; |
703 | 716 | ||
704 | static struct notifier_block ppc_dflt_of_bus_notifier = { | ||
705 | .notifier_call = ppc_dflt_bus_notify, | ||
706 | .priority = INT_MAX, | ||
707 | }; | ||
708 | |||
709 | static int __init setup_bus_notifier(void) | 717 | static int __init setup_bus_notifier(void) |
710 | { | 718 | { |
711 | bus_register_notifier(&platform_bus_type, &ppc_dflt_plat_bus_notifier); | 719 | bus_register_notifier(&platform_bus_type, &ppc_dflt_plat_bus_notifier); |
712 | bus_register_notifier(&of_platform_bus_type, &ppc_dflt_of_bus_notifier); | ||
713 | |||
714 | return 0; | 720 | return 0; |
715 | } | 721 | } |
716 | 722 | ||
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/suspend.c b/arch/powerpc/kernel/suspend.c index 6fc6328dc626..0167d53da30c 100644 --- a/arch/powerpc/kernel/suspend.c +++ b/arch/powerpc/kernel/suspend.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Distribute under GPLv2 | 4 | * Distribute under GPLv2 |
5 | * | 5 | * |
6 | * Copyright (c) 2002 Pavel Machek <pavel@suse.cz> | 6 | * Copyright (c) 2002 Pavel Machek <pavel@ucw.cz> |
7 | * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org> | 7 | * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org> |
8 | */ | 8 | */ |
9 | 9 | ||
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/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c index 812312542e50..9b9b5cdea840 100644 --- a/arch/powerpc/kvm/44x_tlb.c +++ b/arch/powerpc/kvm/44x_tlb.c | |||
@@ -316,7 +316,8 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr, | |||
316 | gfn = gpaddr >> PAGE_SHIFT; | 316 | gfn = gpaddr >> PAGE_SHIFT; |
317 | new_page = gfn_to_page(vcpu->kvm, gfn); | 317 | new_page = gfn_to_page(vcpu->kvm, gfn); |
318 | if (is_error_page(new_page)) { | 318 | if (is_error_page(new_page)) { |
319 | printk(KERN_ERR "Couldn't get guest page for gfn %lx!\n", gfn); | 319 | printk(KERN_ERR "Couldn't get guest page for gfn %llx!\n", |
320 | (unsigned long long)gfn); | ||
320 | kvm_release_page_clean(new_page); | 321 | kvm_release_page_clean(new_page); |
321 | return; | 322 | return; |
322 | } | 323 | } |
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index ff436066bf77..d45c818a384c 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile | |||
@@ -45,6 +45,7 @@ kvm-book3s_64-objs := \ | |||
45 | book3s.o \ | 45 | book3s.o \ |
46 | book3s_emulate.o \ | 46 | book3s_emulate.o \ |
47 | book3s_interrupts.o \ | 47 | book3s_interrupts.o \ |
48 | book3s_mmu_hpte.o \ | ||
48 | book3s_64_mmu_host.o \ | 49 | book3s_64_mmu_host.o \ |
49 | book3s_64_mmu.o \ | 50 | book3s_64_mmu.o \ |
50 | book3s_32_mmu.o | 51 | book3s_32_mmu.o |
@@ -57,6 +58,7 @@ kvm-book3s_32-objs := \ | |||
57 | book3s.o \ | 58 | book3s.o \ |
58 | book3s_emulate.o \ | 59 | book3s_emulate.o \ |
59 | book3s_interrupts.o \ | 60 | book3s_interrupts.o \ |
61 | book3s_mmu_hpte.o \ | ||
60 | book3s_32_mmu_host.o \ | 62 | book3s_32_mmu_host.o \ |
61 | book3s_32_mmu.o | 63 | book3s_32_mmu.o |
62 | kvm-objs-$(CONFIG_KVM_BOOK3S_32) := $(kvm-book3s_32-objs) | 64 | kvm-objs-$(CONFIG_KVM_BOOK3S_32) := $(kvm-book3s_32-objs) |
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index b998abf1a63d..a3cef30d1d42 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c | |||
@@ -1047,8 +1047,6 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
1047 | { | 1047 | { |
1048 | int i; | 1048 | int i; |
1049 | 1049 | ||
1050 | vcpu_load(vcpu); | ||
1051 | |||
1052 | regs->pc = kvmppc_get_pc(vcpu); | 1050 | regs->pc = kvmppc_get_pc(vcpu); |
1053 | regs->cr = kvmppc_get_cr(vcpu); | 1051 | regs->cr = kvmppc_get_cr(vcpu); |
1054 | regs->ctr = kvmppc_get_ctr(vcpu); | 1052 | regs->ctr = kvmppc_get_ctr(vcpu); |
@@ -1069,8 +1067,6 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
1069 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) | 1067 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) |
1070 | regs->gpr[i] = kvmppc_get_gpr(vcpu, i); | 1068 | regs->gpr[i] = kvmppc_get_gpr(vcpu, i); |
1071 | 1069 | ||
1072 | vcpu_put(vcpu); | ||
1073 | |||
1074 | return 0; | 1070 | return 0; |
1075 | } | 1071 | } |
1076 | 1072 | ||
@@ -1078,8 +1074,6 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
1078 | { | 1074 | { |
1079 | int i; | 1075 | int i; |
1080 | 1076 | ||
1081 | vcpu_load(vcpu); | ||
1082 | |||
1083 | kvmppc_set_pc(vcpu, regs->pc); | 1077 | kvmppc_set_pc(vcpu, regs->pc); |
1084 | kvmppc_set_cr(vcpu, regs->cr); | 1078 | kvmppc_set_cr(vcpu, regs->cr); |
1085 | kvmppc_set_ctr(vcpu, regs->ctr); | 1079 | kvmppc_set_ctr(vcpu, regs->ctr); |
@@ -1099,8 +1093,6 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
1099 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) | 1093 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) |
1100 | kvmppc_set_gpr(vcpu, i, regs->gpr[i]); | 1094 | kvmppc_set_gpr(vcpu, i, regs->gpr[i]); |
1101 | 1095 | ||
1102 | vcpu_put(vcpu); | ||
1103 | |||
1104 | return 0; | 1096 | return 0; |
1105 | } | 1097 | } |
1106 | 1098 | ||
@@ -1110,8 +1102,6 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, | |||
1110 | struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu); | 1102 | struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu); |
1111 | int i; | 1103 | int i; |
1112 | 1104 | ||
1113 | vcpu_load(vcpu); | ||
1114 | |||
1115 | sregs->pvr = vcpu->arch.pvr; | 1105 | sregs->pvr = vcpu->arch.pvr; |
1116 | 1106 | ||
1117 | sregs->u.s.sdr1 = to_book3s(vcpu)->sdr1; | 1107 | sregs->u.s.sdr1 = to_book3s(vcpu)->sdr1; |
@@ -1131,8 +1121,6 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, | |||
1131 | } | 1121 | } |
1132 | } | 1122 | } |
1133 | 1123 | ||
1134 | vcpu_put(vcpu); | ||
1135 | |||
1136 | return 0; | 1124 | return 0; |
1137 | } | 1125 | } |
1138 | 1126 | ||
@@ -1142,8 +1130,6 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | |||
1142 | struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu); | 1130 | struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu); |
1143 | int i; | 1131 | int i; |
1144 | 1132 | ||
1145 | vcpu_load(vcpu); | ||
1146 | |||
1147 | kvmppc_set_pvr(vcpu, sregs->pvr); | 1133 | kvmppc_set_pvr(vcpu, sregs->pvr); |
1148 | 1134 | ||
1149 | vcpu3s->sdr1 = sregs->u.s.sdr1; | 1135 | vcpu3s->sdr1 = sregs->u.s.sdr1; |
@@ -1171,8 +1157,6 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | |||
1171 | /* Flush the MMU after messing with the segments */ | 1157 | /* Flush the MMU after messing with the segments */ |
1172 | kvmppc_mmu_pte_flush(vcpu, 0, 0); | 1158 | kvmppc_mmu_pte_flush(vcpu, 0, 0); |
1173 | 1159 | ||
1174 | vcpu_put(vcpu); | ||
1175 | |||
1176 | return 0; | 1160 | return 0; |
1177 | } | 1161 | } |
1178 | 1162 | ||
@@ -1309,12 +1293,17 @@ extern int __kvmppc_vcpu_entry(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); | |||
1309 | int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | 1293 | int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) |
1310 | { | 1294 | { |
1311 | int ret; | 1295 | int ret; |
1312 | struct thread_struct ext_bkp; | 1296 | double fpr[32][TS_FPRWIDTH]; |
1297 | unsigned int fpscr; | ||
1298 | int fpexc_mode; | ||
1313 | #ifdef CONFIG_ALTIVEC | 1299 | #ifdef CONFIG_ALTIVEC |
1314 | bool save_vec = current->thread.used_vr; | 1300 | vector128 vr[32]; |
1301 | vector128 vscr; | ||
1302 | unsigned long uninitialized_var(vrsave); | ||
1303 | int used_vr; | ||
1315 | #endif | 1304 | #endif |
1316 | #ifdef CONFIG_VSX | 1305 | #ifdef CONFIG_VSX |
1317 | bool save_vsx = current->thread.used_vsr; | 1306 | int used_vsr; |
1318 | #endif | 1307 | #endif |
1319 | ulong ext_msr; | 1308 | ulong ext_msr; |
1320 | 1309 | ||
@@ -1327,27 +1316,27 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
1327 | /* Save FPU state in stack */ | 1316 | /* Save FPU state in stack */ |
1328 | if (current->thread.regs->msr & MSR_FP) | 1317 | if (current->thread.regs->msr & MSR_FP) |
1329 | giveup_fpu(current); | 1318 | giveup_fpu(current); |
1330 | memcpy(ext_bkp.fpr, current->thread.fpr, sizeof(current->thread.fpr)); | 1319 | memcpy(fpr, current->thread.fpr, sizeof(current->thread.fpr)); |
1331 | ext_bkp.fpscr = current->thread.fpscr; | 1320 | fpscr = current->thread.fpscr.val; |
1332 | ext_bkp.fpexc_mode = current->thread.fpexc_mode; | 1321 | fpexc_mode = current->thread.fpexc_mode; |
1333 | 1322 | ||
1334 | #ifdef CONFIG_ALTIVEC | 1323 | #ifdef CONFIG_ALTIVEC |
1335 | /* Save Altivec state in stack */ | 1324 | /* Save Altivec state in stack */ |
1336 | if (save_vec) { | 1325 | used_vr = current->thread.used_vr; |
1326 | if (used_vr) { | ||
1337 | if (current->thread.regs->msr & MSR_VEC) | 1327 | if (current->thread.regs->msr & MSR_VEC) |
1338 | giveup_altivec(current); | 1328 | giveup_altivec(current); |
1339 | memcpy(ext_bkp.vr, current->thread.vr, sizeof(ext_bkp.vr)); | 1329 | memcpy(vr, current->thread.vr, sizeof(current->thread.vr)); |
1340 | ext_bkp.vscr = current->thread.vscr; | 1330 | vscr = current->thread.vscr; |
1341 | ext_bkp.vrsave = current->thread.vrsave; | 1331 | vrsave = current->thread.vrsave; |
1342 | } | 1332 | } |
1343 | ext_bkp.used_vr = current->thread.used_vr; | ||
1344 | #endif | 1333 | #endif |
1345 | 1334 | ||
1346 | #ifdef CONFIG_VSX | 1335 | #ifdef CONFIG_VSX |
1347 | /* Save VSX state in stack */ | 1336 | /* Save VSX state in stack */ |
1348 | if (save_vsx && (current->thread.regs->msr & MSR_VSX)) | 1337 | used_vsr = current->thread.used_vsr; |
1338 | if (used_vsr && (current->thread.regs->msr & MSR_VSX)) | ||
1349 | __giveup_vsx(current); | 1339 | __giveup_vsx(current); |
1350 | ext_bkp.used_vsr = current->thread.used_vsr; | ||
1351 | #endif | 1340 | #endif |
1352 | 1341 | ||
1353 | /* Remember the MSR with disabled extensions */ | 1342 | /* Remember the MSR with disabled extensions */ |
@@ -1372,22 +1361,22 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
1372 | kvmppc_giveup_ext(vcpu, MSR_VSX); | 1361 | kvmppc_giveup_ext(vcpu, MSR_VSX); |
1373 | 1362 | ||
1374 | /* Restore FPU state from stack */ | 1363 | /* Restore FPU state from stack */ |
1375 | memcpy(current->thread.fpr, ext_bkp.fpr, sizeof(ext_bkp.fpr)); | 1364 | memcpy(current->thread.fpr, fpr, sizeof(current->thread.fpr)); |
1376 | current->thread.fpscr = ext_bkp.fpscr; | 1365 | current->thread.fpscr.val = fpscr; |
1377 | current->thread.fpexc_mode = ext_bkp.fpexc_mode; | 1366 | current->thread.fpexc_mode = fpexc_mode; |
1378 | 1367 | ||
1379 | #ifdef CONFIG_ALTIVEC | 1368 | #ifdef CONFIG_ALTIVEC |
1380 | /* Restore Altivec state from stack */ | 1369 | /* Restore Altivec state from stack */ |
1381 | if (save_vec && current->thread.used_vr) { | 1370 | if (used_vr && current->thread.used_vr) { |
1382 | memcpy(current->thread.vr, ext_bkp.vr, sizeof(ext_bkp.vr)); | 1371 | memcpy(current->thread.vr, vr, sizeof(current->thread.vr)); |
1383 | current->thread.vscr = ext_bkp.vscr; | 1372 | current->thread.vscr = vscr; |
1384 | current->thread.vrsave= ext_bkp.vrsave; | 1373 | current->thread.vrsave = vrsave; |
1385 | } | 1374 | } |
1386 | current->thread.used_vr = ext_bkp.used_vr; | 1375 | current->thread.used_vr = used_vr; |
1387 | #endif | 1376 | #endif |
1388 | 1377 | ||
1389 | #ifdef CONFIG_VSX | 1378 | #ifdef CONFIG_VSX |
1390 | current->thread.used_vsr = ext_bkp.used_vsr; | 1379 | current->thread.used_vsr = used_vsr; |
1391 | #endif | 1380 | #endif |
1392 | 1381 | ||
1393 | return ret; | 1382 | return ret; |
@@ -1395,12 +1384,22 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
1395 | 1384 | ||
1396 | static int kvmppc_book3s_init(void) | 1385 | static int kvmppc_book3s_init(void) |
1397 | { | 1386 | { |
1398 | return kvm_init(NULL, sizeof(struct kvmppc_vcpu_book3s), 0, | 1387 | int r; |
1399 | THIS_MODULE); | 1388 | |
1389 | r = kvm_init(NULL, sizeof(struct kvmppc_vcpu_book3s), 0, | ||
1390 | THIS_MODULE); | ||
1391 | |||
1392 | if (r) | ||
1393 | return r; | ||
1394 | |||
1395 | r = kvmppc_mmu_hpte_sysinit(); | ||
1396 | |||
1397 | return r; | ||
1400 | } | 1398 | } |
1401 | 1399 | ||
1402 | static void kvmppc_book3s_exit(void) | 1400 | static void kvmppc_book3s_exit(void) |
1403 | { | 1401 | { |
1402 | kvmppc_mmu_hpte_sysexit(); | ||
1404 | kvm_exit(); | 1403 | kvm_exit(); |
1405 | } | 1404 | } |
1406 | 1405 | ||
diff --git a/arch/powerpc/kvm/book3s_32_mmu.c b/arch/powerpc/kvm/book3s_32_mmu.c index 0b10503c8a4a..3292d76101d2 100644 --- a/arch/powerpc/kvm/book3s_32_mmu.c +++ b/arch/powerpc/kvm/book3s_32_mmu.c | |||
@@ -354,10 +354,10 @@ static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid, | |||
354 | *vsid = VSID_REAL_DR | gvsid; | 354 | *vsid = VSID_REAL_DR | gvsid; |
355 | break; | 355 | break; |
356 | case MSR_DR|MSR_IR: | 356 | case MSR_DR|MSR_IR: |
357 | if (!sr->valid) | 357 | if (sr->valid) |
358 | return -1; | 358 | *vsid = sr->vsid; |
359 | 359 | else | |
360 | *vsid = sr->vsid; | 360 | *vsid = VSID_BAT | gvsid; |
361 | break; | 361 | break; |
362 | default: | 362 | default: |
363 | BUG(); | 363 | BUG(); |
diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c index 0bb66005338f..0b51ef872c1e 100644 --- a/arch/powerpc/kvm/book3s_32_mmu_host.c +++ b/arch/powerpc/kvm/book3s_32_mmu_host.c | |||
@@ -19,6 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/kvm_host.h> | 21 | #include <linux/kvm_host.h> |
22 | #include <linux/hash.h> | ||
22 | 23 | ||
23 | #include <asm/kvm_ppc.h> | 24 | #include <asm/kvm_ppc.h> |
24 | #include <asm/kvm_book3s.h> | 25 | #include <asm/kvm_book3s.h> |
@@ -57,139 +58,26 @@ | |||
57 | static ulong htab; | 58 | static ulong htab; |
58 | static u32 htabmask; | 59 | static u32 htabmask; |
59 | 60 | ||
60 | static void invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte) | 61 | void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte) |
61 | { | 62 | { |
62 | volatile u32 *pteg; | 63 | volatile u32 *pteg; |
63 | 64 | ||
64 | dprintk_mmu("KVM: Flushing SPTE: 0x%llx (0x%llx) -> 0x%llx\n", | 65 | /* Remove from host HTAB */ |
65 | pte->pte.eaddr, pte->pte.vpage, pte->host_va); | ||
66 | |||
67 | pteg = (u32*)pte->slot; | 66 | pteg = (u32*)pte->slot; |
68 | |||
69 | pteg[0] = 0; | 67 | pteg[0] = 0; |
68 | |||
69 | /* And make sure it's gone from the TLB too */ | ||
70 | asm volatile ("sync"); | 70 | asm volatile ("sync"); |
71 | asm volatile ("tlbie %0" : : "r" (pte->pte.eaddr) : "memory"); | 71 | asm volatile ("tlbie %0" : : "r" (pte->pte.eaddr) : "memory"); |
72 | asm volatile ("sync"); | 72 | asm volatile ("sync"); |
73 | asm volatile ("tlbsync"); | 73 | asm volatile ("tlbsync"); |
74 | |||
75 | pte->host_va = 0; | ||
76 | |||
77 | if (pte->pte.may_write) | ||
78 | kvm_release_pfn_dirty(pte->pfn); | ||
79 | else | ||
80 | kvm_release_pfn_clean(pte->pfn); | ||
81 | } | ||
82 | |||
83 | void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, ulong guest_ea, ulong ea_mask) | ||
84 | { | ||
85 | int i; | ||
86 | |||
87 | dprintk_mmu("KVM: Flushing %d Shadow PTEs: 0x%x & 0x%x\n", | ||
88 | vcpu->arch.hpte_cache_offset, guest_ea, ea_mask); | ||
89 | BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM); | ||
90 | |||
91 | guest_ea &= ea_mask; | ||
92 | for (i = 0; i < vcpu->arch.hpte_cache_offset; i++) { | ||
93 | struct hpte_cache *pte; | ||
94 | |||
95 | pte = &vcpu->arch.hpte_cache[i]; | ||
96 | if (!pte->host_va) | ||
97 | continue; | ||
98 | |||
99 | if ((pte->pte.eaddr & ea_mask) == guest_ea) { | ||
100 | invalidate_pte(vcpu, pte); | ||
101 | } | ||
102 | } | ||
103 | |||
104 | /* Doing a complete flush -> start from scratch */ | ||
105 | if (!ea_mask) | ||
106 | vcpu->arch.hpte_cache_offset = 0; | ||
107 | } | ||
108 | |||
109 | void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 guest_vp, u64 vp_mask) | ||
110 | { | ||
111 | int i; | ||
112 | |||
113 | dprintk_mmu("KVM: Flushing %d Shadow vPTEs: 0x%llx & 0x%llx\n", | ||
114 | vcpu->arch.hpte_cache_offset, guest_vp, vp_mask); | ||
115 | BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM); | ||
116 | |||
117 | guest_vp &= vp_mask; | ||
118 | for (i = 0; i < vcpu->arch.hpte_cache_offset; i++) { | ||
119 | struct hpte_cache *pte; | ||
120 | |||
121 | pte = &vcpu->arch.hpte_cache[i]; | ||
122 | if (!pte->host_va) | ||
123 | continue; | ||
124 | |||
125 | if ((pte->pte.vpage & vp_mask) == guest_vp) { | ||
126 | invalidate_pte(vcpu, pte); | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, ulong pa_start, ulong pa_end) | ||
132 | { | ||
133 | int i; | ||
134 | |||
135 | dprintk_mmu("KVM: Flushing %d Shadow pPTEs: 0x%llx & 0x%llx\n", | ||
136 | vcpu->arch.hpte_cache_offset, pa_start, pa_end); | ||
137 | BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM); | ||
138 | |||
139 | for (i = 0; i < vcpu->arch.hpte_cache_offset; i++) { | ||
140 | struct hpte_cache *pte; | ||
141 | |||
142 | pte = &vcpu->arch.hpte_cache[i]; | ||
143 | if (!pte->host_va) | ||
144 | continue; | ||
145 | |||
146 | if ((pte->pte.raddr >= pa_start) && | ||
147 | (pte->pte.raddr < pa_end)) { | ||
148 | invalidate_pte(vcpu, pte); | ||
149 | } | ||
150 | } | ||
151 | } | ||
152 | |||
153 | struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, bool data) | ||
154 | { | ||
155 | int i; | ||
156 | u64 guest_vp; | ||
157 | |||
158 | guest_vp = vcpu->arch.mmu.ea_to_vp(vcpu, ea, false); | ||
159 | for (i=0; i<vcpu->arch.hpte_cache_offset; i++) { | ||
160 | struct hpte_cache *pte; | ||
161 | |||
162 | pte = &vcpu->arch.hpte_cache[i]; | ||
163 | if (!pte->host_va) | ||
164 | continue; | ||
165 | |||
166 | if (pte->pte.vpage == guest_vp) | ||
167 | return &pte->pte; | ||
168 | } | ||
169 | |||
170 | return NULL; | ||
171 | } | ||
172 | |||
173 | static int kvmppc_mmu_hpte_cache_next(struct kvm_vcpu *vcpu) | ||
174 | { | ||
175 | if (vcpu->arch.hpte_cache_offset == HPTEG_CACHE_NUM) | ||
176 | kvmppc_mmu_pte_flush(vcpu, 0, 0); | ||
177 | |||
178 | return vcpu->arch.hpte_cache_offset++; | ||
179 | } | 74 | } |
180 | 75 | ||
181 | /* We keep 512 gvsid->hvsid entries, mapping the guest ones to the array using | 76 | /* We keep 512 gvsid->hvsid entries, mapping the guest ones to the array using |
182 | * a hash, so we don't waste cycles on looping */ | 77 | * a hash, so we don't waste cycles on looping */ |
183 | static u16 kvmppc_sid_hash(struct kvm_vcpu *vcpu, u64 gvsid) | 78 | static u16 kvmppc_sid_hash(struct kvm_vcpu *vcpu, u64 gvsid) |
184 | { | 79 | { |
185 | return (u16)(((gvsid >> (SID_MAP_BITS * 7)) & SID_MAP_MASK) ^ | 80 | return hash_64(gvsid, SID_MAP_BITS); |
186 | ((gvsid >> (SID_MAP_BITS * 6)) & SID_MAP_MASK) ^ | ||
187 | ((gvsid >> (SID_MAP_BITS * 5)) & SID_MAP_MASK) ^ | ||
188 | ((gvsid >> (SID_MAP_BITS * 4)) & SID_MAP_MASK) ^ | ||
189 | ((gvsid >> (SID_MAP_BITS * 3)) & SID_MAP_MASK) ^ | ||
190 | ((gvsid >> (SID_MAP_BITS * 2)) & SID_MAP_MASK) ^ | ||
191 | ((gvsid >> (SID_MAP_BITS * 1)) & SID_MAP_MASK) ^ | ||
192 | ((gvsid >> (SID_MAP_BITS * 0)) & SID_MAP_MASK)); | ||
193 | } | 81 | } |
194 | 82 | ||
195 | 83 | ||
@@ -256,7 +144,6 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) | |||
256 | register int rr = 0; | 144 | register int rr = 0; |
257 | bool primary = false; | 145 | bool primary = false; |
258 | bool evict = false; | 146 | bool evict = false; |
259 | int hpte_id; | ||
260 | struct hpte_cache *pte; | 147 | struct hpte_cache *pte; |
261 | 148 | ||
262 | /* Get host physical address for gpa */ | 149 | /* Get host physical address for gpa */ |
@@ -341,8 +228,7 @@ next_pteg: | |||
341 | 228 | ||
342 | /* Now tell our Shadow PTE code about the new page */ | 229 | /* Now tell our Shadow PTE code about the new page */ |
343 | 230 | ||
344 | hpte_id = kvmppc_mmu_hpte_cache_next(vcpu); | 231 | pte = kvmppc_mmu_hpte_cache_next(vcpu); |
345 | pte = &vcpu->arch.hpte_cache[hpte_id]; | ||
346 | 232 | ||
347 | dprintk_mmu("KVM: %c%c Map 0x%llx: [%lx] 0x%llx (0x%llx) -> %lx\n", | 233 | dprintk_mmu("KVM: %c%c Map 0x%llx: [%lx] 0x%llx (0x%llx) -> %lx\n", |
348 | orig_pte->may_write ? 'w' : '-', | 234 | orig_pte->may_write ? 'w' : '-', |
@@ -355,6 +241,8 @@ next_pteg: | |||
355 | pte->pte = *orig_pte; | 241 | pte->pte = *orig_pte; |
356 | pte->pfn = hpaddr >> PAGE_SHIFT; | 242 | pte->pfn = hpaddr >> PAGE_SHIFT; |
357 | 243 | ||
244 | kvmppc_mmu_hpte_cache_map(vcpu, pte); | ||
245 | |||
358 | return 0; | 246 | return 0; |
359 | } | 247 | } |
360 | 248 | ||
@@ -439,7 +327,7 @@ void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu) | |||
439 | 327 | ||
440 | void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) | 328 | void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) |
441 | { | 329 | { |
442 | kvmppc_mmu_pte_flush(vcpu, 0, 0); | 330 | kvmppc_mmu_hpte_destroy(vcpu); |
443 | preempt_disable(); | 331 | preempt_disable(); |
444 | __destroy_context(to_book3s(vcpu)->context_id); | 332 | __destroy_context(to_book3s(vcpu)->context_id); |
445 | preempt_enable(); | 333 | preempt_enable(); |
@@ -479,5 +367,7 @@ int kvmppc_mmu_init(struct kvm_vcpu *vcpu) | |||
479 | htabmask = ((sdr1 & 0x1FF) << 16) | 0xFFC0; | 367 | htabmask = ((sdr1 & 0x1FF) << 16) | 0xFFC0; |
480 | htab = (ulong)__va(sdr1 & 0xffff0000); | 368 | htab = (ulong)__va(sdr1 & 0xffff0000); |
481 | 369 | ||
370 | kvmppc_mmu_hpte_init(vcpu); | ||
371 | |||
482 | return 0; | 372 | return 0; |
483 | } | 373 | } |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index e4b5744977f6..384179a5002b 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c | |||
@@ -20,6 +20,7 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/kvm_host.h> | 22 | #include <linux/kvm_host.h> |
23 | #include <linux/hash.h> | ||
23 | 24 | ||
24 | #include <asm/kvm_ppc.h> | 25 | #include <asm/kvm_ppc.h> |
25 | #include <asm/kvm_book3s.h> | 26 | #include <asm/kvm_book3s.h> |
@@ -46,135 +47,20 @@ | |||
46 | #define dprintk_slb(a, ...) do { } while(0) | 47 | #define dprintk_slb(a, ...) do { } while(0) |
47 | #endif | 48 | #endif |
48 | 49 | ||
49 | static void invalidate_pte(struct hpte_cache *pte) | 50 | void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte) |
50 | { | 51 | { |
51 | dprintk_mmu("KVM: Flushing SPT: 0x%lx (0x%llx) -> 0x%llx\n", | ||
52 | pte->pte.eaddr, pte->pte.vpage, pte->host_va); | ||
53 | |||
54 | ppc_md.hpte_invalidate(pte->slot, pte->host_va, | 52 | ppc_md.hpte_invalidate(pte->slot, pte->host_va, |
55 | MMU_PAGE_4K, MMU_SEGSIZE_256M, | 53 | MMU_PAGE_4K, MMU_SEGSIZE_256M, |
56 | false); | 54 | false); |
57 | pte->host_va = 0; | ||
58 | |||
59 | if (pte->pte.may_write) | ||
60 | kvm_release_pfn_dirty(pte->pfn); | ||
61 | else | ||
62 | kvm_release_pfn_clean(pte->pfn); | ||
63 | } | ||
64 | |||
65 | void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, ulong guest_ea, ulong ea_mask) | ||
66 | { | ||
67 | int i; | ||
68 | |||
69 | dprintk_mmu("KVM: Flushing %d Shadow PTEs: 0x%lx & 0x%lx\n", | ||
70 | vcpu->arch.hpte_cache_offset, guest_ea, ea_mask); | ||
71 | BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM); | ||
72 | |||
73 | guest_ea &= ea_mask; | ||
74 | for (i = 0; i < vcpu->arch.hpte_cache_offset; i++) { | ||
75 | struct hpte_cache *pte; | ||
76 | |||
77 | pte = &vcpu->arch.hpte_cache[i]; | ||
78 | if (!pte->host_va) | ||
79 | continue; | ||
80 | |||
81 | if ((pte->pte.eaddr & ea_mask) == guest_ea) { | ||
82 | invalidate_pte(pte); | ||
83 | } | ||
84 | } | ||
85 | |||
86 | /* Doing a complete flush -> start from scratch */ | ||
87 | if (!ea_mask) | ||
88 | vcpu->arch.hpte_cache_offset = 0; | ||
89 | } | ||
90 | |||
91 | void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 guest_vp, u64 vp_mask) | ||
92 | { | ||
93 | int i; | ||
94 | |||
95 | dprintk_mmu("KVM: Flushing %d Shadow vPTEs: 0x%llx & 0x%llx\n", | ||
96 | vcpu->arch.hpte_cache_offset, guest_vp, vp_mask); | ||
97 | BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM); | ||
98 | |||
99 | guest_vp &= vp_mask; | ||
100 | for (i = 0; i < vcpu->arch.hpte_cache_offset; i++) { | ||
101 | struct hpte_cache *pte; | ||
102 | |||
103 | pte = &vcpu->arch.hpte_cache[i]; | ||
104 | if (!pte->host_va) | ||
105 | continue; | ||
106 | |||
107 | if ((pte->pte.vpage & vp_mask) == guest_vp) { | ||
108 | invalidate_pte(pte); | ||
109 | } | ||
110 | } | ||
111 | } | ||
112 | |||
113 | void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, ulong pa_start, ulong pa_end) | ||
114 | { | ||
115 | int i; | ||
116 | |||
117 | dprintk_mmu("KVM: Flushing %d Shadow pPTEs: 0x%lx & 0x%lx\n", | ||
118 | vcpu->arch.hpte_cache_offset, pa_start, pa_end); | ||
119 | BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM); | ||
120 | |||
121 | for (i = 0; i < vcpu->arch.hpte_cache_offset; i++) { | ||
122 | struct hpte_cache *pte; | ||
123 | |||
124 | pte = &vcpu->arch.hpte_cache[i]; | ||
125 | if (!pte->host_va) | ||
126 | continue; | ||
127 | |||
128 | if ((pte->pte.raddr >= pa_start) && | ||
129 | (pte->pte.raddr < pa_end)) { | ||
130 | invalidate_pte(pte); | ||
131 | } | ||
132 | } | ||
133 | } | ||
134 | |||
135 | struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, bool data) | ||
136 | { | ||
137 | int i; | ||
138 | u64 guest_vp; | ||
139 | |||
140 | guest_vp = vcpu->arch.mmu.ea_to_vp(vcpu, ea, false); | ||
141 | for (i=0; i<vcpu->arch.hpte_cache_offset; i++) { | ||
142 | struct hpte_cache *pte; | ||
143 | |||
144 | pte = &vcpu->arch.hpte_cache[i]; | ||
145 | if (!pte->host_va) | ||
146 | continue; | ||
147 | |||
148 | if (pte->pte.vpage == guest_vp) | ||
149 | return &pte->pte; | ||
150 | } | ||
151 | |||
152 | return NULL; | ||
153 | } | ||
154 | |||
155 | static int kvmppc_mmu_hpte_cache_next(struct kvm_vcpu *vcpu) | ||
156 | { | ||
157 | if (vcpu->arch.hpte_cache_offset == HPTEG_CACHE_NUM) | ||
158 | kvmppc_mmu_pte_flush(vcpu, 0, 0); | ||
159 | |||
160 | return vcpu->arch.hpte_cache_offset++; | ||
161 | } | 55 | } |
162 | 56 | ||
163 | /* We keep 512 gvsid->hvsid entries, mapping the guest ones to the array using | 57 | /* We keep 512 gvsid->hvsid entries, mapping the guest ones to the array using |
164 | * a hash, so we don't waste cycles on looping */ | 58 | * a hash, so we don't waste cycles on looping */ |
165 | static u16 kvmppc_sid_hash(struct kvm_vcpu *vcpu, u64 gvsid) | 59 | static u16 kvmppc_sid_hash(struct kvm_vcpu *vcpu, u64 gvsid) |
166 | { | 60 | { |
167 | return (u16)(((gvsid >> (SID_MAP_BITS * 7)) & SID_MAP_MASK) ^ | 61 | return hash_64(gvsid, SID_MAP_BITS); |
168 | ((gvsid >> (SID_MAP_BITS * 6)) & SID_MAP_MASK) ^ | ||
169 | ((gvsid >> (SID_MAP_BITS * 5)) & SID_MAP_MASK) ^ | ||
170 | ((gvsid >> (SID_MAP_BITS * 4)) & SID_MAP_MASK) ^ | ||
171 | ((gvsid >> (SID_MAP_BITS * 3)) & SID_MAP_MASK) ^ | ||
172 | ((gvsid >> (SID_MAP_BITS * 2)) & SID_MAP_MASK) ^ | ||
173 | ((gvsid >> (SID_MAP_BITS * 1)) & SID_MAP_MASK) ^ | ||
174 | ((gvsid >> (SID_MAP_BITS * 0)) & SID_MAP_MASK)); | ||
175 | } | 62 | } |
176 | 63 | ||
177 | |||
178 | static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid) | 64 | static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid) |
179 | { | 65 | { |
180 | struct kvmppc_sid_map *map; | 66 | struct kvmppc_sid_map *map; |
@@ -273,8 +159,7 @@ map_again: | |||
273 | attempt++; | 159 | attempt++; |
274 | goto map_again; | 160 | goto map_again; |
275 | } else { | 161 | } else { |
276 | int hpte_id = kvmppc_mmu_hpte_cache_next(vcpu); | 162 | struct hpte_cache *pte = kvmppc_mmu_hpte_cache_next(vcpu); |
277 | struct hpte_cache *pte = &vcpu->arch.hpte_cache[hpte_id]; | ||
278 | 163 | ||
279 | dprintk_mmu("KVM: %c%c Map 0x%lx: [%lx] 0x%lx (0x%llx) -> %lx\n", | 164 | dprintk_mmu("KVM: %c%c Map 0x%lx: [%lx] 0x%lx (0x%llx) -> %lx\n", |
280 | ((rflags & HPTE_R_PP) == 3) ? '-' : 'w', | 165 | ((rflags & HPTE_R_PP) == 3) ? '-' : 'w', |
@@ -292,6 +177,8 @@ map_again: | |||
292 | pte->host_va = va; | 177 | pte->host_va = va; |
293 | pte->pte = *orig_pte; | 178 | pte->pte = *orig_pte; |
294 | pte->pfn = hpaddr >> PAGE_SHIFT; | 179 | pte->pfn = hpaddr >> PAGE_SHIFT; |
180 | |||
181 | kvmppc_mmu_hpte_cache_map(vcpu, pte); | ||
295 | } | 182 | } |
296 | 183 | ||
297 | return 0; | 184 | return 0; |
@@ -418,7 +305,7 @@ void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu) | |||
418 | 305 | ||
419 | void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) | 306 | void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) |
420 | { | 307 | { |
421 | kvmppc_mmu_pte_flush(vcpu, 0, 0); | 308 | kvmppc_mmu_hpte_destroy(vcpu); |
422 | __destroy_context(to_book3s(vcpu)->context_id); | 309 | __destroy_context(to_book3s(vcpu)->context_id); |
423 | } | 310 | } |
424 | 311 | ||
@@ -436,5 +323,7 @@ int kvmppc_mmu_init(struct kvm_vcpu *vcpu) | |||
436 | vcpu3s->vsid_first = vcpu3s->context_id << USER_ESID_BITS; | 323 | vcpu3s->vsid_first = vcpu3s->context_id << USER_ESID_BITS; |
437 | vcpu3s->vsid_next = vcpu3s->vsid_first; | 324 | vcpu3s->vsid_next = vcpu3s->vsid_first; |
438 | 325 | ||
326 | kvmppc_mmu_hpte_init(vcpu); | ||
327 | |||
439 | return 0; | 328 | return 0; |
440 | } | 329 | } |
diff --git a/arch/powerpc/kvm/book3s_mmu_hpte.c b/arch/powerpc/kvm/book3s_mmu_hpte.c new file mode 100644 index 000000000000..4868d4a7ebc5 --- /dev/null +++ b/arch/powerpc/kvm/book3s_mmu_hpte.c | |||
@@ -0,0 +1,277 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 SUSE Linux Products GmbH. All rights reserved. | ||
3 | * | ||
4 | * Authors: | ||
5 | * Alexander Graf <agraf@suse.de> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License, version 2, as | ||
9 | * published by the Free Software Foundation. | ||
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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kvm_host.h> | ||
22 | #include <linux/hash.h> | ||
23 | #include <linux/slab.h> | ||
24 | |||
25 | #include <asm/kvm_ppc.h> | ||
26 | #include <asm/kvm_book3s.h> | ||
27 | #include <asm/machdep.h> | ||
28 | #include <asm/mmu_context.h> | ||
29 | #include <asm/hw_irq.h> | ||
30 | |||
31 | #define PTE_SIZE 12 | ||
32 | |||
33 | /* #define DEBUG_MMU */ | ||
34 | |||
35 | #ifdef DEBUG_MMU | ||
36 | #define dprintk_mmu(a, ...) printk(KERN_INFO a, __VA_ARGS__) | ||
37 | #else | ||
38 | #define dprintk_mmu(a, ...) do { } while(0) | ||
39 | #endif | ||
40 | |||
41 | static struct kmem_cache *hpte_cache; | ||
42 | |||
43 | static inline u64 kvmppc_mmu_hash_pte(u64 eaddr) | ||
44 | { | ||
45 | return hash_64(eaddr >> PTE_SIZE, HPTEG_HASH_BITS_PTE); | ||
46 | } | ||
47 | |||
48 | static inline u64 kvmppc_mmu_hash_vpte(u64 vpage) | ||
49 | { | ||
50 | return hash_64(vpage & 0xfffffffffULL, HPTEG_HASH_BITS_VPTE); | ||
51 | } | ||
52 | |||
53 | static inline u64 kvmppc_mmu_hash_vpte_long(u64 vpage) | ||
54 | { | ||
55 | return hash_64((vpage & 0xffffff000ULL) >> 12, | ||
56 | HPTEG_HASH_BITS_VPTE_LONG); | ||
57 | } | ||
58 | |||
59 | void kvmppc_mmu_hpte_cache_map(struct kvm_vcpu *vcpu, struct hpte_cache *pte) | ||
60 | { | ||
61 | u64 index; | ||
62 | |||
63 | /* Add to ePTE list */ | ||
64 | index = kvmppc_mmu_hash_pte(pte->pte.eaddr); | ||
65 | hlist_add_head(&pte->list_pte, &vcpu->arch.hpte_hash_pte[index]); | ||
66 | |||
67 | /* Add to vPTE list */ | ||
68 | index = kvmppc_mmu_hash_vpte(pte->pte.vpage); | ||
69 | hlist_add_head(&pte->list_vpte, &vcpu->arch.hpte_hash_vpte[index]); | ||
70 | |||
71 | /* Add to vPTE_long list */ | ||
72 | index = kvmppc_mmu_hash_vpte_long(pte->pte.vpage); | ||
73 | hlist_add_head(&pte->list_vpte_long, | ||
74 | &vcpu->arch.hpte_hash_vpte_long[index]); | ||
75 | } | ||
76 | |||
77 | static void invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte) | ||
78 | { | ||
79 | dprintk_mmu("KVM: Flushing SPT: 0x%lx (0x%llx) -> 0x%llx\n", | ||
80 | pte->pte.eaddr, pte->pte.vpage, pte->host_va); | ||
81 | |||
82 | /* Different for 32 and 64 bit */ | ||
83 | kvmppc_mmu_invalidate_pte(vcpu, pte); | ||
84 | |||
85 | if (pte->pte.may_write) | ||
86 | kvm_release_pfn_dirty(pte->pfn); | ||
87 | else | ||
88 | kvm_release_pfn_clean(pte->pfn); | ||
89 | |||
90 | hlist_del(&pte->list_pte); | ||
91 | hlist_del(&pte->list_vpte); | ||
92 | hlist_del(&pte->list_vpte_long); | ||
93 | |||
94 | vcpu->arch.hpte_cache_count--; | ||
95 | kmem_cache_free(hpte_cache, pte); | ||
96 | } | ||
97 | |||
98 | static void kvmppc_mmu_pte_flush_all(struct kvm_vcpu *vcpu) | ||
99 | { | ||
100 | struct hpte_cache *pte; | ||
101 | struct hlist_node *node, *tmp; | ||
102 | int i; | ||
103 | |||
104 | for (i = 0; i < HPTEG_HASH_NUM_VPTE_LONG; i++) { | ||
105 | struct hlist_head *list = &vcpu->arch.hpte_hash_vpte_long[i]; | ||
106 | |||
107 | hlist_for_each_entry_safe(pte, node, tmp, list, list_vpte_long) | ||
108 | invalidate_pte(vcpu, pte); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | static void kvmppc_mmu_pte_flush_page(struct kvm_vcpu *vcpu, ulong guest_ea) | ||
113 | { | ||
114 | struct hlist_head *list; | ||
115 | struct hlist_node *node, *tmp; | ||
116 | struct hpte_cache *pte; | ||
117 | |||
118 | /* Find the list of entries in the map */ | ||
119 | list = &vcpu->arch.hpte_hash_pte[kvmppc_mmu_hash_pte(guest_ea)]; | ||
120 | |||
121 | /* Check the list for matching entries and invalidate */ | ||
122 | hlist_for_each_entry_safe(pte, node, tmp, list, list_pte) | ||
123 | if ((pte->pte.eaddr & ~0xfffUL) == guest_ea) | ||
124 | invalidate_pte(vcpu, pte); | ||
125 | } | ||
126 | |||
127 | void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, ulong guest_ea, ulong ea_mask) | ||
128 | { | ||
129 | u64 i; | ||
130 | |||
131 | dprintk_mmu("KVM: Flushing %d Shadow PTEs: 0x%lx & 0x%lx\n", | ||
132 | vcpu->arch.hpte_cache_count, guest_ea, ea_mask); | ||
133 | |||
134 | guest_ea &= ea_mask; | ||
135 | |||
136 | switch (ea_mask) { | ||
137 | case ~0xfffUL: | ||
138 | kvmppc_mmu_pte_flush_page(vcpu, guest_ea); | ||
139 | break; | ||
140 | case 0x0ffff000: | ||
141 | /* 32-bit flush w/o segment, go through all possible segments */ | ||
142 | for (i = 0; i < 0x100000000ULL; i += 0x10000000ULL) | ||
143 | kvmppc_mmu_pte_flush(vcpu, guest_ea | i, ~0xfffUL); | ||
144 | break; | ||
145 | case 0: | ||
146 | /* Doing a complete flush -> start from scratch */ | ||
147 | kvmppc_mmu_pte_flush_all(vcpu); | ||
148 | break; | ||
149 | default: | ||
150 | WARN_ON(1); | ||
151 | break; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | /* Flush with mask 0xfffffffff */ | ||
156 | static void kvmppc_mmu_pte_vflush_short(struct kvm_vcpu *vcpu, u64 guest_vp) | ||
157 | { | ||
158 | struct hlist_head *list; | ||
159 | struct hlist_node *node, *tmp; | ||
160 | struct hpte_cache *pte; | ||
161 | u64 vp_mask = 0xfffffffffULL; | ||
162 | |||
163 | list = &vcpu->arch.hpte_hash_vpte[kvmppc_mmu_hash_vpte(guest_vp)]; | ||
164 | |||
165 | /* Check the list for matching entries and invalidate */ | ||
166 | hlist_for_each_entry_safe(pte, node, tmp, list, list_vpte) | ||
167 | if ((pte->pte.vpage & vp_mask) == guest_vp) | ||
168 | invalidate_pte(vcpu, pte); | ||
169 | } | ||
170 | |||
171 | /* Flush with mask 0xffffff000 */ | ||
172 | static void kvmppc_mmu_pte_vflush_long(struct kvm_vcpu *vcpu, u64 guest_vp) | ||
173 | { | ||
174 | struct hlist_head *list; | ||
175 | struct hlist_node *node, *tmp; | ||
176 | struct hpte_cache *pte; | ||
177 | u64 vp_mask = 0xffffff000ULL; | ||
178 | |||
179 | list = &vcpu->arch.hpte_hash_vpte_long[ | ||
180 | kvmppc_mmu_hash_vpte_long(guest_vp)]; | ||
181 | |||
182 | /* Check the list for matching entries and invalidate */ | ||
183 | hlist_for_each_entry_safe(pte, node, tmp, list, list_vpte_long) | ||
184 | if ((pte->pte.vpage & vp_mask) == guest_vp) | ||
185 | invalidate_pte(vcpu, pte); | ||
186 | } | ||
187 | |||
188 | void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 guest_vp, u64 vp_mask) | ||
189 | { | ||
190 | dprintk_mmu("KVM: Flushing %d Shadow vPTEs: 0x%llx & 0x%llx\n", | ||
191 | vcpu->arch.hpte_cache_count, guest_vp, vp_mask); | ||
192 | guest_vp &= vp_mask; | ||
193 | |||
194 | switch(vp_mask) { | ||
195 | case 0xfffffffffULL: | ||
196 | kvmppc_mmu_pte_vflush_short(vcpu, guest_vp); | ||
197 | break; | ||
198 | case 0xffffff000ULL: | ||
199 | kvmppc_mmu_pte_vflush_long(vcpu, guest_vp); | ||
200 | break; | ||
201 | default: | ||
202 | WARN_ON(1); | ||
203 | return; | ||
204 | } | ||
205 | } | ||
206 | |||
207 | void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, ulong pa_start, ulong pa_end) | ||
208 | { | ||
209 | struct hlist_node *node, *tmp; | ||
210 | struct hpte_cache *pte; | ||
211 | int i; | ||
212 | |||
213 | dprintk_mmu("KVM: Flushing %d Shadow pPTEs: 0x%lx - 0x%lx\n", | ||
214 | vcpu->arch.hpte_cache_count, pa_start, pa_end); | ||
215 | |||
216 | for (i = 0; i < HPTEG_HASH_NUM_VPTE_LONG; i++) { | ||
217 | struct hlist_head *list = &vcpu->arch.hpte_hash_vpte_long[i]; | ||
218 | |||
219 | hlist_for_each_entry_safe(pte, node, tmp, list, list_vpte_long) | ||
220 | if ((pte->pte.raddr >= pa_start) && | ||
221 | (pte->pte.raddr < pa_end)) | ||
222 | invalidate_pte(vcpu, pte); | ||
223 | } | ||
224 | } | ||
225 | |||
226 | struct hpte_cache *kvmppc_mmu_hpte_cache_next(struct kvm_vcpu *vcpu) | ||
227 | { | ||
228 | struct hpte_cache *pte; | ||
229 | |||
230 | pte = kmem_cache_zalloc(hpte_cache, GFP_KERNEL); | ||
231 | vcpu->arch.hpte_cache_count++; | ||
232 | |||
233 | if (vcpu->arch.hpte_cache_count == HPTEG_CACHE_NUM) | ||
234 | kvmppc_mmu_pte_flush_all(vcpu); | ||
235 | |||
236 | return pte; | ||
237 | } | ||
238 | |||
239 | void kvmppc_mmu_hpte_destroy(struct kvm_vcpu *vcpu) | ||
240 | { | ||
241 | kvmppc_mmu_pte_flush(vcpu, 0, 0); | ||
242 | } | ||
243 | |||
244 | static void kvmppc_mmu_hpte_init_hash(struct hlist_head *hash_list, int len) | ||
245 | { | ||
246 | int i; | ||
247 | |||
248 | for (i = 0; i < len; i++) | ||
249 | INIT_HLIST_HEAD(&hash_list[i]); | ||
250 | } | ||
251 | |||
252 | int kvmppc_mmu_hpte_init(struct kvm_vcpu *vcpu) | ||
253 | { | ||
254 | /* init hpte lookup hashes */ | ||
255 | kvmppc_mmu_hpte_init_hash(vcpu->arch.hpte_hash_pte, | ||
256 | ARRAY_SIZE(vcpu->arch.hpte_hash_pte)); | ||
257 | kvmppc_mmu_hpte_init_hash(vcpu->arch.hpte_hash_vpte, | ||
258 | ARRAY_SIZE(vcpu->arch.hpte_hash_vpte)); | ||
259 | kvmppc_mmu_hpte_init_hash(vcpu->arch.hpte_hash_vpte_long, | ||
260 | ARRAY_SIZE(vcpu->arch.hpte_hash_vpte_long)); | ||
261 | |||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | int kvmppc_mmu_hpte_sysinit(void) | ||
266 | { | ||
267 | /* init hpte slab cache */ | ||
268 | hpte_cache = kmem_cache_create("kvm-spt", sizeof(struct hpte_cache), | ||
269 | sizeof(struct hpte_cache), 0, NULL); | ||
270 | |||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | void kvmppc_mmu_hpte_sysexit(void) | ||
275 | { | ||
276 | kmem_cache_destroy(hpte_cache); | ||
277 | } | ||
diff --git a/arch/powerpc/kvm/book3s_paired_singles.c b/arch/powerpc/kvm/book3s_paired_singles.c index a9f66abafcb3..474f2e24050a 100644 --- a/arch/powerpc/kvm/book3s_paired_singles.c +++ b/arch/powerpc/kvm/book3s_paired_singles.c | |||
@@ -159,10 +159,7 @@ | |||
159 | 159 | ||
160 | static inline void kvmppc_sync_qpr(struct kvm_vcpu *vcpu, int rt) | 160 | static inline void kvmppc_sync_qpr(struct kvm_vcpu *vcpu, int rt) |
161 | { | 161 | { |
162 | struct thread_struct t; | 162 | kvm_cvt_df(&vcpu->arch.fpr[rt], &vcpu->arch.qpr[rt], &vcpu->arch.fpscr); |
163 | |||
164 | t.fpscr.val = vcpu->arch.fpscr; | ||
165 | cvt_df((double*)&vcpu->arch.fpr[rt], (float*)&vcpu->arch.qpr[rt], &t); | ||
166 | } | 163 | } |
167 | 164 | ||
168 | static void kvmppc_inject_pf(struct kvm_vcpu *vcpu, ulong eaddr, bool is_store) | 165 | static void kvmppc_inject_pf(struct kvm_vcpu *vcpu, ulong eaddr, bool is_store) |
@@ -183,7 +180,6 @@ static int kvmppc_emulate_fpr_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
183 | int rs, ulong addr, int ls_type) | 180 | int rs, ulong addr, int ls_type) |
184 | { | 181 | { |
185 | int emulated = EMULATE_FAIL; | 182 | int emulated = EMULATE_FAIL; |
186 | struct thread_struct t; | ||
187 | int r; | 183 | int r; |
188 | char tmp[8]; | 184 | char tmp[8]; |
189 | int len = sizeof(u32); | 185 | int len = sizeof(u32); |
@@ -191,8 +187,6 @@ static int kvmppc_emulate_fpr_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
191 | if (ls_type == FPU_LS_DOUBLE) | 187 | if (ls_type == FPU_LS_DOUBLE) |
192 | len = sizeof(u64); | 188 | len = sizeof(u64); |
193 | 189 | ||
194 | t.fpscr.val = vcpu->arch.fpscr; | ||
195 | |||
196 | /* read from memory */ | 190 | /* read from memory */ |
197 | r = kvmppc_ld(vcpu, &addr, len, tmp, true); | 191 | r = kvmppc_ld(vcpu, &addr, len, tmp, true); |
198 | vcpu->arch.paddr_accessed = addr; | 192 | vcpu->arch.paddr_accessed = addr; |
@@ -210,7 +204,7 @@ static int kvmppc_emulate_fpr_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
210 | /* put in registers */ | 204 | /* put in registers */ |
211 | switch (ls_type) { | 205 | switch (ls_type) { |
212 | case FPU_LS_SINGLE: | 206 | case FPU_LS_SINGLE: |
213 | cvt_fd((float*)tmp, (double*)&vcpu->arch.fpr[rs], &t); | 207 | kvm_cvt_fd((u32*)tmp, &vcpu->arch.fpr[rs], &vcpu->arch.fpscr); |
214 | vcpu->arch.qpr[rs] = *((u32*)tmp); | 208 | vcpu->arch.qpr[rs] = *((u32*)tmp); |
215 | break; | 209 | break; |
216 | case FPU_LS_DOUBLE: | 210 | case FPU_LS_DOUBLE: |
@@ -229,17 +223,14 @@ static int kvmppc_emulate_fpr_store(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
229 | int rs, ulong addr, int ls_type) | 223 | int rs, ulong addr, int ls_type) |
230 | { | 224 | { |
231 | int emulated = EMULATE_FAIL; | 225 | int emulated = EMULATE_FAIL; |
232 | struct thread_struct t; | ||
233 | int r; | 226 | int r; |
234 | char tmp[8]; | 227 | char tmp[8]; |
235 | u64 val; | 228 | u64 val; |
236 | int len; | 229 | int len; |
237 | 230 | ||
238 | t.fpscr.val = vcpu->arch.fpscr; | ||
239 | |||
240 | switch (ls_type) { | 231 | switch (ls_type) { |
241 | case FPU_LS_SINGLE: | 232 | case FPU_LS_SINGLE: |
242 | cvt_df((double*)&vcpu->arch.fpr[rs], (float*)tmp, &t); | 233 | kvm_cvt_df(&vcpu->arch.fpr[rs], (u32*)tmp, &vcpu->arch.fpscr); |
243 | val = *((u32*)tmp); | 234 | val = *((u32*)tmp); |
244 | len = sizeof(u32); | 235 | len = sizeof(u32); |
245 | break; | 236 | break; |
@@ -278,13 +269,10 @@ static int kvmppc_emulate_psq_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
278 | int rs, ulong addr, bool w, int i) | 269 | int rs, ulong addr, bool w, int i) |
279 | { | 270 | { |
280 | int emulated = EMULATE_FAIL; | 271 | int emulated = EMULATE_FAIL; |
281 | struct thread_struct t; | ||
282 | int r; | 272 | int r; |
283 | float one = 1.0; | 273 | float one = 1.0; |
284 | u32 tmp[2]; | 274 | u32 tmp[2]; |
285 | 275 | ||
286 | t.fpscr.val = vcpu->arch.fpscr; | ||
287 | |||
288 | /* read from memory */ | 276 | /* read from memory */ |
289 | if (w) { | 277 | if (w) { |
290 | r = kvmppc_ld(vcpu, &addr, sizeof(u32), tmp, true); | 278 | r = kvmppc_ld(vcpu, &addr, sizeof(u32), tmp, true); |
@@ -308,7 +296,7 @@ static int kvmppc_emulate_psq_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
308 | emulated = EMULATE_DONE; | 296 | emulated = EMULATE_DONE; |
309 | 297 | ||
310 | /* put in registers */ | 298 | /* put in registers */ |
311 | cvt_fd((float*)&tmp[0], (double*)&vcpu->arch.fpr[rs], &t); | 299 | kvm_cvt_fd(&tmp[0], &vcpu->arch.fpr[rs], &vcpu->arch.fpscr); |
312 | vcpu->arch.qpr[rs] = tmp[1]; | 300 | vcpu->arch.qpr[rs] = tmp[1]; |
313 | 301 | ||
314 | dprintk(KERN_INFO "KVM: PSQ_LD [0x%x, 0x%x] at 0x%lx (%d)\n", tmp[0], | 302 | dprintk(KERN_INFO "KVM: PSQ_LD [0x%x, 0x%x] at 0x%lx (%d)\n", tmp[0], |
@@ -322,14 +310,11 @@ static int kvmppc_emulate_psq_store(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
322 | int rs, ulong addr, bool w, int i) | 310 | int rs, ulong addr, bool w, int i) |
323 | { | 311 | { |
324 | int emulated = EMULATE_FAIL; | 312 | int emulated = EMULATE_FAIL; |
325 | struct thread_struct t; | ||
326 | int r; | 313 | int r; |
327 | u32 tmp[2]; | 314 | u32 tmp[2]; |
328 | int len = w ? sizeof(u32) : sizeof(u64); | 315 | int len = w ? sizeof(u32) : sizeof(u64); |
329 | 316 | ||
330 | t.fpscr.val = vcpu->arch.fpscr; | 317 | kvm_cvt_df(&vcpu->arch.fpr[rs], &tmp[0], &vcpu->arch.fpscr); |
331 | |||
332 | cvt_df((double*)&vcpu->arch.fpr[rs], (float*)&tmp[0], &t); | ||
333 | tmp[1] = vcpu->arch.qpr[rs]; | 318 | tmp[1] = vcpu->arch.qpr[rs]; |
334 | 319 | ||
335 | r = kvmppc_st(vcpu, &addr, len, tmp, true); | 320 | r = kvmppc_st(vcpu, &addr, len, tmp, true); |
@@ -517,7 +502,7 @@ static int get_d_signext(u32 inst) | |||
517 | static int kvmppc_ps_three_in(struct kvm_vcpu *vcpu, bool rc, | 502 | static int kvmppc_ps_three_in(struct kvm_vcpu *vcpu, bool rc, |
518 | int reg_out, int reg_in1, int reg_in2, | 503 | int reg_out, int reg_in1, int reg_in2, |
519 | int reg_in3, int scalar, | 504 | int reg_in3, int scalar, |
520 | void (*func)(struct thread_struct *t, | 505 | void (*func)(u64 *fpscr, |
521 | u32 *dst, u32 *src1, | 506 | u32 *dst, u32 *src1, |
522 | u32 *src2, u32 *src3)) | 507 | u32 *src2, u32 *src3)) |
523 | { | 508 | { |
@@ -526,27 +511,25 @@ static int kvmppc_ps_three_in(struct kvm_vcpu *vcpu, bool rc, | |||
526 | u32 ps0_out; | 511 | u32 ps0_out; |
527 | u32 ps0_in1, ps0_in2, ps0_in3; | 512 | u32 ps0_in1, ps0_in2, ps0_in3; |
528 | u32 ps1_in1, ps1_in2, ps1_in3; | 513 | u32 ps1_in1, ps1_in2, ps1_in3; |
529 | struct thread_struct t; | ||
530 | t.fpscr.val = vcpu->arch.fpscr; | ||
531 | 514 | ||
532 | /* RC */ | 515 | /* RC */ |
533 | WARN_ON(rc); | 516 | WARN_ON(rc); |
534 | 517 | ||
535 | /* PS0 */ | 518 | /* PS0 */ |
536 | cvt_df((double*)&fpr[reg_in1], (float*)&ps0_in1, &t); | 519 | kvm_cvt_df(&fpr[reg_in1], &ps0_in1, &vcpu->arch.fpscr); |
537 | cvt_df((double*)&fpr[reg_in2], (float*)&ps0_in2, &t); | 520 | kvm_cvt_df(&fpr[reg_in2], &ps0_in2, &vcpu->arch.fpscr); |
538 | cvt_df((double*)&fpr[reg_in3], (float*)&ps0_in3, &t); | 521 | kvm_cvt_df(&fpr[reg_in3], &ps0_in3, &vcpu->arch.fpscr); |
539 | 522 | ||
540 | if (scalar & SCALAR_LOW) | 523 | if (scalar & SCALAR_LOW) |
541 | ps0_in2 = qpr[reg_in2]; | 524 | ps0_in2 = qpr[reg_in2]; |
542 | 525 | ||
543 | func(&t, &ps0_out, &ps0_in1, &ps0_in2, &ps0_in3); | 526 | func(&vcpu->arch.fpscr, &ps0_out, &ps0_in1, &ps0_in2, &ps0_in3); |
544 | 527 | ||
545 | dprintk(KERN_INFO "PS3 ps0 -> f(0x%x, 0x%x, 0x%x) = 0x%x\n", | 528 | dprintk(KERN_INFO "PS3 ps0 -> f(0x%x, 0x%x, 0x%x) = 0x%x\n", |
546 | ps0_in1, ps0_in2, ps0_in3, ps0_out); | 529 | ps0_in1, ps0_in2, ps0_in3, ps0_out); |
547 | 530 | ||
548 | if (!(scalar & SCALAR_NO_PS0)) | 531 | if (!(scalar & SCALAR_NO_PS0)) |
549 | cvt_fd((float*)&ps0_out, (double*)&fpr[reg_out], &t); | 532 | kvm_cvt_fd(&ps0_out, &fpr[reg_out], &vcpu->arch.fpscr); |
550 | 533 | ||
551 | /* PS1 */ | 534 | /* PS1 */ |
552 | ps1_in1 = qpr[reg_in1]; | 535 | ps1_in1 = qpr[reg_in1]; |
@@ -557,7 +540,7 @@ static int kvmppc_ps_three_in(struct kvm_vcpu *vcpu, bool rc, | |||
557 | ps1_in2 = ps0_in2; | 540 | ps1_in2 = ps0_in2; |
558 | 541 | ||
559 | if (!(scalar & SCALAR_NO_PS1)) | 542 | if (!(scalar & SCALAR_NO_PS1)) |
560 | func(&t, &qpr[reg_out], &ps1_in1, &ps1_in2, &ps1_in3); | 543 | func(&vcpu->arch.fpscr, &qpr[reg_out], &ps1_in1, &ps1_in2, &ps1_in3); |
561 | 544 | ||
562 | dprintk(KERN_INFO "PS3 ps1 -> f(0x%x, 0x%x, 0x%x) = 0x%x\n", | 545 | dprintk(KERN_INFO "PS3 ps1 -> f(0x%x, 0x%x, 0x%x) = 0x%x\n", |
563 | ps1_in1, ps1_in2, ps1_in3, qpr[reg_out]); | 546 | ps1_in1, ps1_in2, ps1_in3, qpr[reg_out]); |
@@ -568,7 +551,7 @@ static int kvmppc_ps_three_in(struct kvm_vcpu *vcpu, bool rc, | |||
568 | static int kvmppc_ps_two_in(struct kvm_vcpu *vcpu, bool rc, | 551 | static int kvmppc_ps_two_in(struct kvm_vcpu *vcpu, bool rc, |
569 | int reg_out, int reg_in1, int reg_in2, | 552 | int reg_out, int reg_in1, int reg_in2, |
570 | int scalar, | 553 | int scalar, |
571 | void (*func)(struct thread_struct *t, | 554 | void (*func)(u64 *fpscr, |
572 | u32 *dst, u32 *src1, | 555 | u32 *dst, u32 *src1, |
573 | u32 *src2)) | 556 | u32 *src2)) |
574 | { | 557 | { |
@@ -578,27 +561,25 @@ static int kvmppc_ps_two_in(struct kvm_vcpu *vcpu, bool rc, | |||
578 | u32 ps0_in1, ps0_in2; | 561 | u32 ps0_in1, ps0_in2; |
579 | u32 ps1_out; | 562 | u32 ps1_out; |
580 | u32 ps1_in1, ps1_in2; | 563 | u32 ps1_in1, ps1_in2; |
581 | struct thread_struct t; | ||
582 | t.fpscr.val = vcpu->arch.fpscr; | ||
583 | 564 | ||
584 | /* RC */ | 565 | /* RC */ |
585 | WARN_ON(rc); | 566 | WARN_ON(rc); |
586 | 567 | ||
587 | /* PS0 */ | 568 | /* PS0 */ |
588 | cvt_df((double*)&fpr[reg_in1], (float*)&ps0_in1, &t); | 569 | kvm_cvt_df(&fpr[reg_in1], &ps0_in1, &vcpu->arch.fpscr); |
589 | 570 | ||
590 | if (scalar & SCALAR_LOW) | 571 | if (scalar & SCALAR_LOW) |
591 | ps0_in2 = qpr[reg_in2]; | 572 | ps0_in2 = qpr[reg_in2]; |
592 | else | 573 | else |
593 | cvt_df((double*)&fpr[reg_in2], (float*)&ps0_in2, &t); | 574 | kvm_cvt_df(&fpr[reg_in2], &ps0_in2, &vcpu->arch.fpscr); |
594 | 575 | ||
595 | func(&t, &ps0_out, &ps0_in1, &ps0_in2); | 576 | func(&vcpu->arch.fpscr, &ps0_out, &ps0_in1, &ps0_in2); |
596 | 577 | ||
597 | if (!(scalar & SCALAR_NO_PS0)) { | 578 | if (!(scalar & SCALAR_NO_PS0)) { |
598 | dprintk(KERN_INFO "PS2 ps0 -> f(0x%x, 0x%x) = 0x%x\n", | 579 | dprintk(KERN_INFO "PS2 ps0 -> f(0x%x, 0x%x) = 0x%x\n", |
599 | ps0_in1, ps0_in2, ps0_out); | 580 | ps0_in1, ps0_in2, ps0_out); |
600 | 581 | ||
601 | cvt_fd((float*)&ps0_out, (double*)&fpr[reg_out], &t); | 582 | kvm_cvt_fd(&ps0_out, &fpr[reg_out], &vcpu->arch.fpscr); |
602 | } | 583 | } |
603 | 584 | ||
604 | /* PS1 */ | 585 | /* PS1 */ |
@@ -608,7 +589,7 @@ static int kvmppc_ps_two_in(struct kvm_vcpu *vcpu, bool rc, | |||
608 | if (scalar & SCALAR_HIGH) | 589 | if (scalar & SCALAR_HIGH) |
609 | ps1_in2 = ps0_in2; | 590 | ps1_in2 = ps0_in2; |
610 | 591 | ||
611 | func(&t, &ps1_out, &ps1_in1, &ps1_in2); | 592 | func(&vcpu->arch.fpscr, &ps1_out, &ps1_in1, &ps1_in2); |
612 | 593 | ||
613 | if (!(scalar & SCALAR_NO_PS1)) { | 594 | if (!(scalar & SCALAR_NO_PS1)) { |
614 | qpr[reg_out] = ps1_out; | 595 | qpr[reg_out] = ps1_out; |
@@ -622,31 +603,29 @@ static int kvmppc_ps_two_in(struct kvm_vcpu *vcpu, bool rc, | |||
622 | 603 | ||
623 | static int kvmppc_ps_one_in(struct kvm_vcpu *vcpu, bool rc, | 604 | static int kvmppc_ps_one_in(struct kvm_vcpu *vcpu, bool rc, |
624 | int reg_out, int reg_in, | 605 | int reg_out, int reg_in, |
625 | void (*func)(struct thread_struct *t, | 606 | void (*func)(u64 *t, |
626 | u32 *dst, u32 *src1)) | 607 | u32 *dst, u32 *src1)) |
627 | { | 608 | { |
628 | u32 *qpr = vcpu->arch.qpr; | 609 | u32 *qpr = vcpu->arch.qpr; |
629 | u64 *fpr = vcpu->arch.fpr; | 610 | u64 *fpr = vcpu->arch.fpr; |
630 | u32 ps0_out, ps0_in; | 611 | u32 ps0_out, ps0_in; |
631 | u32 ps1_in; | 612 | u32 ps1_in; |
632 | struct thread_struct t; | ||
633 | t.fpscr.val = vcpu->arch.fpscr; | ||
634 | 613 | ||
635 | /* RC */ | 614 | /* RC */ |
636 | WARN_ON(rc); | 615 | WARN_ON(rc); |
637 | 616 | ||
638 | /* PS0 */ | 617 | /* PS0 */ |
639 | cvt_df((double*)&fpr[reg_in], (float*)&ps0_in, &t); | 618 | kvm_cvt_df(&fpr[reg_in], &ps0_in, &vcpu->arch.fpscr); |
640 | func(&t, &ps0_out, &ps0_in); | 619 | func(&vcpu->arch.fpscr, &ps0_out, &ps0_in); |
641 | 620 | ||
642 | dprintk(KERN_INFO "PS1 ps0 -> f(0x%x) = 0x%x\n", | 621 | dprintk(KERN_INFO "PS1 ps0 -> f(0x%x) = 0x%x\n", |
643 | ps0_in, ps0_out); | 622 | ps0_in, ps0_out); |
644 | 623 | ||
645 | cvt_fd((float*)&ps0_out, (double*)&fpr[reg_out], &t); | 624 | kvm_cvt_fd(&ps0_out, &fpr[reg_out], &vcpu->arch.fpscr); |
646 | 625 | ||
647 | /* PS1 */ | 626 | /* PS1 */ |
648 | ps1_in = qpr[reg_in]; | 627 | ps1_in = qpr[reg_in]; |
649 | func(&t, &qpr[reg_out], &ps1_in); | 628 | func(&vcpu->arch.fpscr, &qpr[reg_out], &ps1_in); |
650 | 629 | ||
651 | dprintk(KERN_INFO "PS1 ps1 -> f(0x%x) = 0x%x\n", | 630 | dprintk(KERN_INFO "PS1 ps1 -> f(0x%x) = 0x%x\n", |
652 | ps1_in, qpr[reg_out]); | 631 | ps1_in, qpr[reg_out]); |
@@ -672,13 +651,10 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
672 | 651 | ||
673 | bool rcomp = (inst & 1) ? true : false; | 652 | bool rcomp = (inst & 1) ? true : false; |
674 | u32 cr = kvmppc_get_cr(vcpu); | 653 | u32 cr = kvmppc_get_cr(vcpu); |
675 | struct thread_struct t; | ||
676 | #ifdef DEBUG | 654 | #ifdef DEBUG |
677 | int i; | 655 | int i; |
678 | #endif | 656 | #endif |
679 | 657 | ||
680 | t.fpscr.val = vcpu->arch.fpscr; | ||
681 | |||
682 | if (!kvmppc_inst_is_paired_single(vcpu, inst)) | 658 | if (!kvmppc_inst_is_paired_single(vcpu, inst)) |
683 | return EMULATE_FAIL; | 659 | return EMULATE_FAIL; |
684 | 660 | ||
@@ -695,7 +671,7 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
695 | #ifdef DEBUG | 671 | #ifdef DEBUG |
696 | for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) { | 672 | for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) { |
697 | u32 f; | 673 | u32 f; |
698 | cvt_df((double*)&vcpu->arch.fpr[i], (float*)&f, &t); | 674 | kvm_cvt_df(&vcpu->arch.fpr[i], &f, &vcpu->arch.fpscr); |
699 | dprintk(KERN_INFO "FPR[%d] = 0x%x / 0x%llx QPR[%d] = 0x%x\n", | 675 | dprintk(KERN_INFO "FPR[%d] = 0x%x / 0x%llx QPR[%d] = 0x%x\n", |
700 | i, f, vcpu->arch.fpr[i], i, vcpu->arch.qpr[i]); | 676 | i, f, vcpu->arch.fpr[i], i, vcpu->arch.qpr[i]); |
701 | } | 677 | } |
@@ -819,8 +795,9 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
819 | WARN_ON(rcomp); | 795 | WARN_ON(rcomp); |
820 | vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_ra]; | 796 | vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_ra]; |
821 | /* vcpu->arch.qpr[ax_rd] = vcpu->arch.fpr[ax_rb]; */ | 797 | /* vcpu->arch.qpr[ax_rd] = vcpu->arch.fpr[ax_rb]; */ |
822 | cvt_df((double*)&vcpu->arch.fpr[ax_rb], | 798 | kvm_cvt_df(&vcpu->arch.fpr[ax_rb], |
823 | (float*)&vcpu->arch.qpr[ax_rd], &t); | 799 | &vcpu->arch.qpr[ax_rd], |
800 | &vcpu->arch.fpscr); | ||
824 | break; | 801 | break; |
825 | case OP_4X_PS_MERGE01: | 802 | case OP_4X_PS_MERGE01: |
826 | WARN_ON(rcomp); | 803 | WARN_ON(rcomp); |
@@ -830,17 +807,20 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
830 | case OP_4X_PS_MERGE10: | 807 | case OP_4X_PS_MERGE10: |
831 | WARN_ON(rcomp); | 808 | WARN_ON(rcomp); |
832 | /* vcpu->arch.fpr[ax_rd] = vcpu->arch.qpr[ax_ra]; */ | 809 | /* vcpu->arch.fpr[ax_rd] = vcpu->arch.qpr[ax_ra]; */ |
833 | cvt_fd((float*)&vcpu->arch.qpr[ax_ra], | 810 | kvm_cvt_fd(&vcpu->arch.qpr[ax_ra], |
834 | (double*)&vcpu->arch.fpr[ax_rd], &t); | 811 | &vcpu->arch.fpr[ax_rd], |
812 | &vcpu->arch.fpscr); | ||
835 | /* vcpu->arch.qpr[ax_rd] = vcpu->arch.fpr[ax_rb]; */ | 813 | /* vcpu->arch.qpr[ax_rd] = vcpu->arch.fpr[ax_rb]; */ |
836 | cvt_df((double*)&vcpu->arch.fpr[ax_rb], | 814 | kvm_cvt_df(&vcpu->arch.fpr[ax_rb], |
837 | (float*)&vcpu->arch.qpr[ax_rd], &t); | 815 | &vcpu->arch.qpr[ax_rd], |
816 | &vcpu->arch.fpscr); | ||
838 | break; | 817 | break; |
839 | case OP_4X_PS_MERGE11: | 818 | case OP_4X_PS_MERGE11: |
840 | WARN_ON(rcomp); | 819 | WARN_ON(rcomp); |
841 | /* vcpu->arch.fpr[ax_rd] = vcpu->arch.qpr[ax_ra]; */ | 820 | /* vcpu->arch.fpr[ax_rd] = vcpu->arch.qpr[ax_ra]; */ |
842 | cvt_fd((float*)&vcpu->arch.qpr[ax_ra], | 821 | kvm_cvt_fd(&vcpu->arch.qpr[ax_ra], |
843 | (double*)&vcpu->arch.fpr[ax_rd], &t); | 822 | &vcpu->arch.fpr[ax_rd], |
823 | &vcpu->arch.fpscr); | ||
844 | vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb]; | 824 | vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb]; |
845 | break; | 825 | break; |
846 | } | 826 | } |
@@ -1275,7 +1255,7 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
1275 | #ifdef DEBUG | 1255 | #ifdef DEBUG |
1276 | for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) { | 1256 | for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) { |
1277 | u32 f; | 1257 | u32 f; |
1278 | cvt_df((double*)&vcpu->arch.fpr[i], (float*)&f, &t); | 1258 | kvm_cvt_df(&vcpu->arch.fpr[i], &f, &vcpu->arch.fpscr); |
1279 | dprintk(KERN_INFO "FPR[%d] = 0x%x\n", i, f); | 1259 | dprintk(KERN_INFO "FPR[%d] = 0x%x\n", i, f); |
1280 | } | 1260 | } |
1281 | #endif | 1261 | #endif |
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index a33ab8cc2ccc..8d4e35f5372c 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c | |||
@@ -144,7 +144,7 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, | |||
144 | unsigned int priority) | 144 | unsigned int priority) |
145 | { | 145 | { |
146 | int allowed = 0; | 146 | int allowed = 0; |
147 | ulong msr_mask; | 147 | ulong uninitialized_var(msr_mask); |
148 | bool update_esr = false, update_dear = false; | 148 | bool update_esr = false, update_dear = false; |
149 | 149 | ||
150 | switch (priority) { | 150 | switch (priority) { |
@@ -485,8 +485,6 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
485 | { | 485 | { |
486 | int i; | 486 | int i; |
487 | 487 | ||
488 | vcpu_load(vcpu); | ||
489 | |||
490 | regs->pc = vcpu->arch.pc; | 488 | regs->pc = vcpu->arch.pc; |
491 | regs->cr = kvmppc_get_cr(vcpu); | 489 | regs->cr = kvmppc_get_cr(vcpu); |
492 | regs->ctr = vcpu->arch.ctr; | 490 | regs->ctr = vcpu->arch.ctr; |
@@ -507,8 +505,6 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
507 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) | 505 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) |
508 | regs->gpr[i] = kvmppc_get_gpr(vcpu, i); | 506 | regs->gpr[i] = kvmppc_get_gpr(vcpu, i); |
509 | 507 | ||
510 | vcpu_put(vcpu); | ||
511 | |||
512 | return 0; | 508 | return 0; |
513 | } | 509 | } |
514 | 510 | ||
@@ -516,8 +512,6 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
516 | { | 512 | { |
517 | int i; | 513 | int i; |
518 | 514 | ||
519 | vcpu_load(vcpu); | ||
520 | |||
521 | vcpu->arch.pc = regs->pc; | 515 | vcpu->arch.pc = regs->pc; |
522 | kvmppc_set_cr(vcpu, regs->cr); | 516 | kvmppc_set_cr(vcpu, regs->cr); |
523 | vcpu->arch.ctr = regs->ctr; | 517 | vcpu->arch.ctr = regs->ctr; |
@@ -537,8 +531,6 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
537 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) | 531 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) |
538 | kvmppc_set_gpr(vcpu, i, regs->gpr[i]); | 532 | kvmppc_set_gpr(vcpu, i, regs->gpr[i]); |
539 | 533 | ||
540 | vcpu_put(vcpu); | ||
541 | |||
542 | return 0; | 534 | return 0; |
543 | } | 535 | } |
544 | 536 | ||
@@ -569,9 +561,7 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, | |||
569 | { | 561 | { |
570 | int r; | 562 | int r; |
571 | 563 | ||
572 | vcpu_load(vcpu); | ||
573 | r = kvmppc_core_vcpu_translate(vcpu, tr); | 564 | r = kvmppc_core_vcpu_translate(vcpu, tr); |
574 | vcpu_put(vcpu); | ||
575 | return r; | 565 | return r; |
576 | } | 566 | } |
577 | 567 | ||
diff --git a/arch/powerpc/kvm/fpu.S b/arch/powerpc/kvm/fpu.S index 2b340a3eee90..cb34bbe16113 100644 --- a/arch/powerpc/kvm/fpu.S +++ b/arch/powerpc/kvm/fpu.S | |||
@@ -271,3 +271,21 @@ FPD_THREE_IN(fmsub) | |||
271 | FPD_THREE_IN(fmadd) | 271 | FPD_THREE_IN(fmadd) |
272 | FPD_THREE_IN(fnmsub) | 272 | FPD_THREE_IN(fnmsub) |
273 | FPD_THREE_IN(fnmadd) | 273 | FPD_THREE_IN(fnmadd) |
274 | |||
275 | _GLOBAL(kvm_cvt_fd) | ||
276 | lfd 0,0(r5) /* load up fpscr value */ | ||
277 | MTFSF_L(0) | ||
278 | lfs 0,0(r3) | ||
279 | stfd 0,0(r4) | ||
280 | mffs 0 | ||
281 | stfd 0,0(r5) /* save new fpscr value */ | ||
282 | blr | ||
283 | |||
284 | _GLOBAL(kvm_cvt_df) | ||
285 | lfd 0,0(r5) /* load up fpscr value */ | ||
286 | MTFSF_L(0) | ||
287 | lfd 0,0(r3) | ||
288 | stfs 0,0(r4) | ||
289 | mffs 0 | ||
290 | stfd 0,0(r5) /* save new fpscr value */ | ||
291 | blr | ||
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 9b8683f39e05..72a4ad86ee91 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -36,11 +36,6 @@ | |||
36 | #define CREATE_TRACE_POINTS | 36 | #define CREATE_TRACE_POINTS |
37 | #include "trace.h" | 37 | #include "trace.h" |
38 | 38 | ||
39 | gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) | ||
40 | { | ||
41 | return gfn; | ||
42 | } | ||
43 | |||
44 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) | 39 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) |
45 | { | 40 | { |
46 | return !(v->arch.msr & MSR_WE) || !!(v->arch.pending_exceptions); | 41 | return !(v->arch.msr & MSR_WE) || !!(v->arch.pending_exceptions); |
@@ -287,7 +282,7 @@ static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu, | |||
287 | static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, | 282 | static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, |
288 | struct kvm_run *run) | 283 | struct kvm_run *run) |
289 | { | 284 | { |
290 | u64 gpr; | 285 | u64 uninitialized_var(gpr); |
291 | 286 | ||
292 | if (run->mmio.len > sizeof(gpr)) { | 287 | if (run->mmio.len > sizeof(gpr)) { |
293 | printk(KERN_ERR "bad MMIO length: %d\n", run->mmio.len); | 288 | printk(KERN_ERR "bad MMIO length: %d\n", run->mmio.len); |
@@ -423,8 +418,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
423 | int r; | 418 | int r; |
424 | sigset_t sigsaved; | 419 | sigset_t sigsaved; |
425 | 420 | ||
426 | vcpu_load(vcpu); | ||
427 | |||
428 | if (vcpu->sigset_active) | 421 | if (vcpu->sigset_active) |
429 | sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); | 422 | sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); |
430 | 423 | ||
@@ -456,8 +449,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
456 | if (vcpu->sigset_active) | 449 | if (vcpu->sigset_active) |
457 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); | 450 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); |
458 | 451 | ||
459 | vcpu_put(vcpu); | ||
460 | |||
461 | return r; | 452 | return r; |
462 | } | 453 | } |
463 | 454 | ||
@@ -523,8 +514,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
523 | if (copy_from_user(&irq, argp, sizeof(irq))) | 514 | if (copy_from_user(&irq, argp, sizeof(irq))) |
524 | goto out; | 515 | goto out; |
525 | r = kvm_vcpu_ioctl_interrupt(vcpu, &irq); | 516 | r = kvm_vcpu_ioctl_interrupt(vcpu, &irq); |
526 | break; | 517 | goto out; |
527 | } | 518 | } |
519 | |||
528 | case KVM_ENABLE_CAP: | 520 | case KVM_ENABLE_CAP: |
529 | { | 521 | { |
530 | struct kvm_enable_cap cap; | 522 | struct kvm_enable_cap cap; |
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..5b243bd3eb3b 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, |
@@ -660,7 +678,7 @@ static void psc_clks_init(void) | |||
660 | { | 678 | { |
661 | struct device_node *np; | 679 | struct device_node *np; |
662 | const u32 *cell_index; | 680 | const u32 *cell_index; |
663 | struct of_device *ofdev; | 681 | struct platform_device *ofdev; |
664 | 682 | ||
665 | for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { | 683 | for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { |
666 | cell_index = of_get_property(np, "cell-index", NULL); | 684 | cell_index = of_get_property(np, "cell-index", NULL); |
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.c b/arch/powerpc/platforms/52xx/lite5200.c index 6d584f4e3c9a..de55bc0584b5 100644 --- a/arch/powerpc/platforms/52xx/lite5200.c +++ b/arch/powerpc/platforms/52xx/lite5200.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
21 | #include <linux/of_address.h> | ||
21 | #include <linux/root_dev.h> | 22 | #include <linux/root_dev.h> |
22 | #include <linux/initrd.h> | 23 | #include <linux/initrd.h> |
23 | #include <asm/time.h> | 24 | #include <asm/time.h> |
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_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index ca5305a5bd61..0dad9a935eb5 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c | |||
@@ -147,26 +147,25 @@ mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | |||
147 | return 0; | 147 | return 0; |
148 | } | 148 | } |
149 | 149 | ||
150 | static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev, | 150 | static int __devinit mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev, |
151 | const struct of_device_id *match) | 151 | const struct of_device_id *match) |
152 | { | 152 | { |
153 | struct mpc52xx_gpiochip *chip; | 153 | struct mpc52xx_gpiochip *chip; |
154 | struct mpc52xx_gpio_wkup __iomem *regs; | 154 | struct mpc52xx_gpio_wkup __iomem *regs; |
155 | struct of_gpio_chip *ofchip; | 155 | struct gpio_chip *gc; |
156 | int ret; | 156 | int ret; |
157 | 157 | ||
158 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 158 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
159 | if (!chip) | 159 | if (!chip) |
160 | return -ENOMEM; | 160 | return -ENOMEM; |
161 | 161 | ||
162 | ofchip = &chip->mmchip.of_gc; | 162 | gc = &chip->mmchip.gc; |
163 | 163 | ||
164 | ofchip->gpio_cells = 2; | 164 | gc->ngpio = 8; |
165 | ofchip->gc.ngpio = 8; | 165 | gc->direction_input = mpc52xx_wkup_gpio_dir_in; |
166 | ofchip->gc.direction_input = mpc52xx_wkup_gpio_dir_in; | 166 | gc->direction_output = mpc52xx_wkup_gpio_dir_out; |
167 | ofchip->gc.direction_output = mpc52xx_wkup_gpio_dir_out; | 167 | gc->get = mpc52xx_wkup_gpio_get; |
168 | ofchip->gc.get = mpc52xx_wkup_gpio_get; | 168 | gc->set = mpc52xx_wkup_gpio_set; |
169 | ofchip->gc.set = mpc52xx_wkup_gpio_set; | ||
170 | 169 | ||
171 | ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); | 170 | ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); |
172 | if (ret) | 171 | if (ret) |
@@ -180,7 +179,7 @@ static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev, | |||
180 | return 0; | 179 | return 0; |
181 | } | 180 | } |
182 | 181 | ||
183 | static int mpc52xx_gpiochip_remove(struct of_device *ofdev) | 182 | static int mpc52xx_gpiochip_remove(struct platform_device *ofdev) |
184 | { | 183 | { |
185 | return -EBUSY; | 184 | return -EBUSY; |
186 | } | 185 | } |
@@ -311,11 +310,11 @@ mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | |||
311 | return 0; | 310 | return 0; |
312 | } | 311 | } |
313 | 312 | ||
314 | static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev, | 313 | static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev, |
315 | const struct of_device_id *match) | 314 | const struct of_device_id *match) |
316 | { | 315 | { |
317 | struct mpc52xx_gpiochip *chip; | 316 | struct mpc52xx_gpiochip *chip; |
318 | struct of_gpio_chip *ofchip; | 317 | struct gpio_chip *gc; |
319 | struct mpc52xx_gpio __iomem *regs; | 318 | struct mpc52xx_gpio __iomem *regs; |
320 | int ret; | 319 | int ret; |
321 | 320 | ||
@@ -323,14 +322,13 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev, | |||
323 | if (!chip) | 322 | if (!chip) |
324 | return -ENOMEM; | 323 | return -ENOMEM; |
325 | 324 | ||
326 | ofchip = &chip->mmchip.of_gc; | 325 | gc = &chip->mmchip.gc; |
327 | 326 | ||
328 | ofchip->gpio_cells = 2; | 327 | gc->ngpio = 32; |
329 | ofchip->gc.ngpio = 32; | 328 | gc->direction_input = mpc52xx_simple_gpio_dir_in; |
330 | ofchip->gc.direction_input = mpc52xx_simple_gpio_dir_in; | 329 | gc->direction_output = mpc52xx_simple_gpio_dir_out; |
331 | ofchip->gc.direction_output = mpc52xx_simple_gpio_dir_out; | 330 | gc->get = mpc52xx_simple_gpio_get; |
332 | ofchip->gc.get = mpc52xx_simple_gpio_get; | 331 | gc->set = mpc52xx_simple_gpio_set; |
333 | ofchip->gc.set = mpc52xx_simple_gpio_set; | ||
334 | 332 | ||
335 | ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); | 333 | ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); |
336 | if (ret) | 334 | if (ret) |
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 46c93578cbf0..fea833e18ad5 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c | |||
@@ -78,7 +78,7 @@ MODULE_LICENSE("GPL"); | |||
78 | * @dev: pointer to device structure | 78 | * @dev: pointer to device structure |
79 | * @regs: virtual address of GPT registers | 79 | * @regs: virtual address of GPT registers |
80 | * @lock: spinlock to coordinate between different functions. | 80 | * @lock: spinlock to coordinate between different functions. |
81 | * @of_gc: of_gpio_chip instance structure; used when GPIO is enabled | 81 | * @gc: gpio_chip instance structure; used when GPIO is enabled |
82 | * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported | 82 | * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported |
83 | * @wdt_mode: only relevant for gpt0: bit 0 (MPC52xx_GPT_CAN_WDT) indicates | 83 | * @wdt_mode: only relevant for gpt0: bit 0 (MPC52xx_GPT_CAN_WDT) indicates |
84 | * if the gpt may be used as wdt, bit 1 (MPC52xx_GPT_IS_WDT) indicates | 84 | * if the gpt may be used as wdt, bit 1 (MPC52xx_GPT_IS_WDT) indicates |
@@ -94,7 +94,7 @@ struct mpc52xx_gpt_priv { | |||
94 | u8 wdt_mode; | 94 | u8 wdt_mode; |
95 | 95 | ||
96 | #if defined(CONFIG_GPIOLIB) | 96 | #if defined(CONFIG_GPIOLIB) |
97 | struct of_gpio_chip of_gc; | 97 | struct gpio_chip gc; |
98 | #endif | 98 | #endif |
99 | }; | 99 | }; |
100 | 100 | ||
@@ -280,7 +280,7 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) | |||
280 | #if defined(CONFIG_GPIOLIB) | 280 | #if defined(CONFIG_GPIOLIB) |
281 | static inline struct mpc52xx_gpt_priv *gc_to_mpc52xx_gpt(struct gpio_chip *gc) | 281 | static inline struct mpc52xx_gpt_priv *gc_to_mpc52xx_gpt(struct gpio_chip *gc) |
282 | { | 282 | { |
283 | return container_of(to_of_gpio_chip(gc), struct mpc52xx_gpt_priv,of_gc); | 283 | return container_of(gc, struct mpc52xx_gpt_priv, gc); |
284 | } | 284 | } |
285 | 285 | ||
286 | static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio) | 286 | static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio) |
@@ -336,28 +336,25 @@ mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) | |||
336 | if (!of_find_property(node, "gpio-controller", NULL)) | 336 | if (!of_find_property(node, "gpio-controller", NULL)) |
337 | return; | 337 | return; |
338 | 338 | ||
339 | gpt->of_gc.gc.label = kstrdup(node->full_name, GFP_KERNEL); | 339 | gpt->gc.label = kstrdup(node->full_name, GFP_KERNEL); |
340 | if (!gpt->of_gc.gc.label) { | 340 | if (!gpt->gc.label) { |
341 | dev_err(gpt->dev, "out of memory\n"); | 341 | dev_err(gpt->dev, "out of memory\n"); |
342 | return; | 342 | return; |
343 | } | 343 | } |
344 | 344 | ||
345 | gpt->of_gc.gpio_cells = 2; | 345 | gpt->gc.ngpio = 1; |
346 | gpt->of_gc.gc.ngpio = 1; | 346 | gpt->gc.direction_input = mpc52xx_gpt_gpio_dir_in; |
347 | gpt->of_gc.gc.direction_input = mpc52xx_gpt_gpio_dir_in; | 347 | gpt->gc.direction_output = mpc52xx_gpt_gpio_dir_out; |
348 | gpt->of_gc.gc.direction_output = mpc52xx_gpt_gpio_dir_out; | 348 | gpt->gc.get = mpc52xx_gpt_gpio_get; |
349 | gpt->of_gc.gc.get = mpc52xx_gpt_gpio_get; | 349 | gpt->gc.set = mpc52xx_gpt_gpio_set; |
350 | gpt->of_gc.gc.set = mpc52xx_gpt_gpio_set; | 350 | gpt->gc.base = -1; |
351 | gpt->of_gc.gc.base = -1; | 351 | gpt->gc.of_node = node; |
352 | gpt->of_gc.xlate = of_gpio_simple_xlate; | ||
353 | node->data = &gpt->of_gc; | ||
354 | of_node_get(node); | ||
355 | 352 | ||
356 | /* Setup external pin in GPIO mode */ | 353 | /* Setup external pin in GPIO mode */ |
357 | clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK, | 354 | clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK, |
358 | MPC52xx_GPT_MODE_MS_GPIO); | 355 | MPC52xx_GPT_MODE_MS_GPIO); |
359 | 356 | ||
360 | rc = gpiochip_add(&gpt->of_gc.gc); | 357 | rc = gpiochip_add(&gpt->gc); |
361 | if (rc) | 358 | if (rc) |
362 | dev_err(gpt->dev, "gpiochip_add() failed; rc=%i\n", rc); | 359 | dev_err(gpt->dev, "gpiochip_add() failed; rc=%i\n", rc); |
363 | 360 | ||
@@ -723,7 +720,7 @@ static inline int mpc52xx_gpt_wdt_setup(struct mpc52xx_gpt_priv *gpt, | |||
723 | /* --------------------------------------------------------------------- | 720 | /* --------------------------------------------------------------------- |
724 | * of_platform bus binding code | 721 | * of_platform bus binding code |
725 | */ | 722 | */ |
726 | static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev, | 723 | static int __devinit mpc52xx_gpt_probe(struct platform_device *ofdev, |
727 | const struct of_device_id *match) | 724 | const struct of_device_id *match) |
728 | { | 725 | { |
729 | struct mpc52xx_gpt_priv *gpt; | 726 | struct mpc52xx_gpt_priv *gpt; |
@@ -769,7 +766,7 @@ static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev, | |||
769 | return 0; | 766 | return 0; |
770 | } | 767 | } |
771 | 768 | ||
772 | static int mpc52xx_gpt_remove(struct of_device *ofdev) | 769 | static int mpc52xx_gpt_remove(struct platform_device *ofdev) |
773 | { | 770 | { |
774 | return -EBUSY; | 771 | return -EBUSY; |
775 | } | 772 | } |
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c index e86aec644501..f4ac213c89c0 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c | |||
@@ -436,8 +436,8 @@ void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req) | |||
436 | } | 436 | } |
437 | EXPORT_SYMBOL(mpc52xx_lpbfifo_abort); | 437 | EXPORT_SYMBOL(mpc52xx_lpbfifo_abort); |
438 | 438 | ||
439 | static int __devinit | 439 | static int __devinit mpc52xx_lpbfifo_probe(struct platform_device *op, |
440 | mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match) | 440 | const struct of_device_id *match) |
441 | { | 441 | { |
442 | struct resource res; | 442 | struct resource res; |
443 | int rc = -ENOMEM; | 443 | int rc = -ENOMEM; |
@@ -507,7 +507,7 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match) | |||
507 | } | 507 | } |
508 | 508 | ||
509 | 509 | ||
510 | static int __devexit mpc52xx_lpbfifo_remove(struct of_device *op) | 510 | static int __devexit mpc52xx_lpbfifo_remove(struct platform_device *op) |
511 | { | 511 | { |
512 | if (lpbfifo.dev != &op->dev) | 512 | if (lpbfifo.dev != &op->dev) |
513 | return 0; | 513 | return 0; |
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/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index 9f2e52b36f91..1565e0446dc8 100644 --- a/arch/powerpc/platforms/82xx/ep8248e.c +++ b/arch/powerpc/platforms/82xx/ep8248e.c | |||
@@ -111,7 +111,7 @@ static struct mdiobb_ctrl ep8248e_mdio_ctrl = { | |||
111 | .ops = &ep8248e_mdio_ops, | 111 | .ops = &ep8248e_mdio_ops, |
112 | }; | 112 | }; |
113 | 113 | ||
114 | static int __devinit ep8248e_mdio_probe(struct of_device *ofdev, | 114 | static int __devinit ep8248e_mdio_probe(struct platform_device *ofdev, |
115 | const struct of_device_id *match) | 115 | const struct of_device_id *match) |
116 | { | 116 | { |
117 | struct mii_bus *bus; | 117 | struct mii_bus *bus; |
@@ -154,7 +154,7 @@ err_free_bus: | |||
154 | return ret; | 154 | return ret; |
155 | } | 155 | } |
156 | 156 | ||
157 | static int ep8248e_mdio_remove(struct of_device *ofdev) | 157 | static int ep8248e_mdio_remove(struct platform_device *ofdev) |
158 | { | 158 | { |
159 | BUG(); | 159 | BUG(); |
160 | return 0; | 160 | return 0; |
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/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index d119a7c1c17a..70798ac911ef 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c | |||
@@ -35,9 +35,8 @@ | |||
35 | 35 | ||
36 | struct mcu { | 36 | struct mcu { |
37 | struct mutex lock; | 37 | struct mutex lock; |
38 | struct device_node *np; | ||
39 | struct i2c_client *client; | 38 | struct i2c_client *client; |
40 | struct of_gpio_chip of_gc; | 39 | struct gpio_chip gc; |
41 | u8 reg_ctrl; | 40 | u8 reg_ctrl; |
42 | }; | 41 | }; |
43 | 42 | ||
@@ -56,8 +55,7 @@ static void mcu_power_off(void) | |||
56 | 55 | ||
57 | static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | 56 | static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) |
58 | { | 57 | { |
59 | struct of_gpio_chip *of_gc = to_of_gpio_chip(gc); | 58 | struct mcu *mcu = container_of(gc, struct mcu, gc); |
60 | struct mcu *mcu = container_of(of_gc, struct mcu, of_gc); | ||
61 | u8 bit = 1 << (4 + gpio); | 59 | u8 bit = 1 << (4 + gpio); |
62 | 60 | ||
63 | mutex_lock(&mcu->lock); | 61 | mutex_lock(&mcu->lock); |
@@ -79,9 +77,7 @@ static int mcu_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | |||
79 | static int mcu_gpiochip_add(struct mcu *mcu) | 77 | static int mcu_gpiochip_add(struct mcu *mcu) |
80 | { | 78 | { |
81 | struct device_node *np; | 79 | struct device_node *np; |
82 | struct of_gpio_chip *of_gc = &mcu->of_gc; | 80 | struct gpio_chip *gc = &mcu->gc; |
83 | struct gpio_chip *gc = &of_gc->gc; | ||
84 | int ret; | ||
85 | 81 | ||
86 | np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx"); | 82 | np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx"); |
87 | if (!np) | 83 | if (!np) |
@@ -94,32 +90,14 @@ static int mcu_gpiochip_add(struct mcu *mcu) | |||
94 | gc->base = -1; | 90 | gc->base = -1; |
95 | gc->set = mcu_gpio_set; | 91 | gc->set = mcu_gpio_set; |
96 | gc->direction_output = mcu_gpio_dir_out; | 92 | gc->direction_output = mcu_gpio_dir_out; |
97 | of_gc->gpio_cells = 2; | 93 | gc->of_node = np; |
98 | of_gc->xlate = of_gpio_simple_xlate; | ||
99 | 94 | ||
100 | np->data = of_gc; | 95 | return gpiochip_add(gc); |
101 | mcu->np = np; | ||
102 | |||
103 | /* | ||
104 | * We don't want to lose the node, its ->data and ->full_name... | ||
105 | * So, if succeeded, we don't put the node here. | ||
106 | */ | ||
107 | ret = gpiochip_add(gc); | ||
108 | if (ret) | ||
109 | of_node_put(np); | ||
110 | return ret; | ||
111 | } | 96 | } |
112 | 97 | ||
113 | static int mcu_gpiochip_remove(struct mcu *mcu) | 98 | static int mcu_gpiochip_remove(struct mcu *mcu) |
114 | { | 99 | { |
115 | int ret; | 100 | return gpiochip_remove(&mcu->gc); |
116 | |||
117 | ret = gpiochip_remove(&mcu->of_gc.gc); | ||
118 | if (ret) | ||
119 | return ret; | ||
120 | of_node_put(mcu->np); | ||
121 | |||
122 | return 0; | ||
123 | } | 101 | } |
124 | 102 | ||
125 | static int __devinit mcu_probe(struct i2c_client *client, | 103 | static int __devinit mcu_probe(struct i2c_client *client, |
@@ -182,10 +160,16 @@ static const struct i2c_device_id mcu_ids[] = { | |||
182 | }; | 160 | }; |
183 | MODULE_DEVICE_TABLE(i2c, mcu_ids); | 161 | MODULE_DEVICE_TABLE(i2c, mcu_ids); |
184 | 162 | ||
163 | static struct of_device_id mcu_of_match_table[] __devinitdata = { | ||
164 | { .compatible = "fsl,mcu-mpc8349emitx", }, | ||
165 | { }, | ||
166 | }; | ||
167 | |||
185 | static struct i2c_driver mcu_driver = { | 168 | static struct i2c_driver mcu_driver = { |
186 | .driver = { | 169 | .driver = { |
187 | .name = "mcu-mpc8349emitx", | 170 | .name = "mcu-mpc8349emitx", |
188 | .owner = THIS_MODULE, | 171 | .owner = THIS_MODULE, |
172 | .of_match_table = mcu_of_match_table, | ||
189 | }, | 173 | }, |
190 | .probe = mcu_probe, | 174 | .probe = mcu_probe, |
191 | .remove = __devexit_p(mcu_remove), | 175 | .remove = __devexit_p(mcu_remove), |
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/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index ebe6c3537209..75ae77f1af6a 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c | |||
@@ -99,7 +99,7 @@ struct pmc_type { | |||
99 | int has_deep_sleep; | 99 | int has_deep_sleep; |
100 | }; | 100 | }; |
101 | 101 | ||
102 | static struct of_device *pmc_dev; | 102 | static struct platform_device *pmc_dev; |
103 | static int has_deep_sleep, deep_sleeping; | 103 | static int has_deep_sleep, deep_sleeping; |
104 | static int pmc_irq; | 104 | static int pmc_irq; |
105 | static struct mpc83xx_pmc __iomem *pmc_regs; | 105 | static struct mpc83xx_pmc __iomem *pmc_regs; |
@@ -318,7 +318,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = { | |||
318 | .end = mpc83xx_suspend_end, | 318 | .end = mpc83xx_suspend_end, |
319 | }; | 319 | }; |
320 | 320 | ||
321 | static int pmc_probe(struct of_device *ofdev, | 321 | static int pmc_probe(struct platform_device *ofdev, |
322 | const struct of_device_id *match) | 322 | const struct of_device_id *match) |
323 | { | 323 | { |
324 | struct device_node *np = ofdev->dev.of_node; | 324 | struct device_node *np = ofdev->dev.of_node; |
@@ -396,7 +396,7 @@ out: | |||
396 | return ret; | 396 | return ret; |
397 | } | 397 | } |
398 | 398 | ||
399 | static int pmc_remove(struct of_device *ofdev) | 399 | static int pmc_remove(struct platform_device *ofdev) |
400 | { | 400 | { |
401 | return -EPERM; | 401 | return -EPERM; |
402 | }; | 402 | }; |
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/86xx/gef_gpio.c b/arch/powerpc/platforms/86xx/gef_gpio.c index b8cb08dbd89c..4ff7b1e7bbad 100644 --- a/arch/powerpc/platforms/86xx/gef_gpio.c +++ b/arch/powerpc/platforms/86xx/gef_gpio.c | |||
@@ -118,12 +118,12 @@ static int __init gef_gpio_init(void) | |||
118 | } | 118 | } |
119 | 119 | ||
120 | /* Setup pointers to chip functions */ | 120 | /* Setup pointers to chip functions */ |
121 | gef_gpio_chip->of_gc.gpio_cells = 2; | 121 | gef_gpio_chip->gc.of_gpio_n_cells = 2; |
122 | gef_gpio_chip->of_gc.gc.ngpio = 19; | 122 | gef_gpio_chip->gc.ngpio = 19; |
123 | gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in; | 123 | gef_gpio_chip->gc.direction_input = gef_gpio_dir_in; |
124 | gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out; | 124 | gef_gpio_chip->gc.direction_output = gef_gpio_dir_out; |
125 | gef_gpio_chip->of_gc.gc.get = gef_gpio_get; | 125 | gef_gpio_chip->gc.get = gef_gpio_get; |
126 | gef_gpio_chip->of_gc.gc.set = gef_gpio_set; | 126 | gef_gpio_chip->gc.set = gef_gpio_set; |
127 | 127 | ||
128 | /* This function adds a memory mapped GPIO chip */ | 128 | /* This function adds a memory mapped GPIO chip */ |
129 | retval = of_mm_gpiochip_add(np, gef_gpio_chip); | 129 | retval = of_mm_gpiochip_add(np, gef_gpio_chip); |
@@ -146,12 +146,12 @@ static int __init gef_gpio_init(void) | |||
146 | } | 146 | } |
147 | 147 | ||
148 | /* Setup pointers to chip functions */ | 148 | /* Setup pointers to chip functions */ |
149 | gef_gpio_chip->of_gc.gpio_cells = 2; | 149 | gef_gpio_chip->gc.of_gpio_n_cells = 2; |
150 | gef_gpio_chip->of_gc.gc.ngpio = 6; | 150 | gef_gpio_chip->gc.ngpio = 6; |
151 | gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in; | 151 | gef_gpio_chip->gc.direction_input = gef_gpio_dir_in; |
152 | gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out; | 152 | gef_gpio_chip->gc.direction_output = gef_gpio_dir_out; |
153 | gef_gpio_chip->of_gc.gc.get = gef_gpio_get; | 153 | gef_gpio_chip->gc.get = gef_gpio_get; |
154 | gef_gpio_chip->of_gc.gc.set = gef_gpio_set; | 154 | gef_gpio_chip->gc.set = gef_gpio_set; |
155 | 155 | ||
156 | /* This function adds a memory mapped GPIO chip */ | 156 | /* This function adds a memory mapped GPIO chip */ |
157 | retval = of_mm_gpiochip_add(np, gef_gpio_chip); | 157 | retval = of_mm_gpiochip_add(np, gef_gpio_chip); |
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/amigaone/setup.c b/arch/powerpc/platforms/amigaone/setup.c index fb4eb0df054c..03aabc0e16ac 100644 --- a/arch/powerpc/platforms/amigaone/setup.c +++ b/arch/powerpc/platforms/amigaone/setup.c | |||
@@ -13,12 +13,13 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/of.h> | ||
17 | #include <linux/of_address.h> | ||
16 | #include <linux/seq_file.h> | 18 | #include <linux/seq_file.h> |
17 | #include <generated/utsrelease.h> | 19 | #include <generated/utsrelease.h> |
18 | 20 | ||
19 | #include <asm/machdep.h> | 21 | #include <asm/machdep.h> |
20 | #include <asm/cputable.h> | 22 | #include <asm/cputable.h> |
21 | #include <asm/prom.h> | ||
22 | #include <asm/pci-bridge.h> | 23 | #include <asm/pci-bridge.h> |
23 | #include <asm/i8259.h> | 24 | #include <asm/i8259.h> |
24 | #include <asm/time.h> | 25 | #include <asm/time.h> |
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 6257e5378615..97085530aa63 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c | |||
@@ -328,7 +328,7 @@ static struct irq_host_ops msic_host_ops = { | |||
328 | .map = msic_host_map, | 328 | .map = msic_host_map, |
329 | }; | 329 | }; |
330 | 330 | ||
331 | static int axon_msi_shutdown(struct of_device *device) | 331 | static int axon_msi_shutdown(struct platform_device *device) |
332 | { | 332 | { |
333 | struct axon_msic *msic = dev_get_drvdata(&device->dev); | 333 | struct axon_msic *msic = dev_get_drvdata(&device->dev); |
334 | u32 tmp; | 334 | u32 tmp; |
@@ -342,7 +342,7 @@ static int axon_msi_shutdown(struct of_device *device) | |||
342 | return 0; | 342 | return 0; |
343 | } | 343 | } |
344 | 344 | ||
345 | static int axon_msi_probe(struct of_device *device, | 345 | static int axon_msi_probe(struct platform_device *device, |
346 | const struct of_device_id *device_id) | 346 | const struct of_device_id *device_id) |
347 | { | 347 | { |
348 | struct device_node *dn = device->dev.of_node; | 348 | struct device_node *dn = device->dev.of_node; |
diff --git a/arch/powerpc/platforms/cell/beat_iommu.c b/arch/powerpc/platforms/cell/beat_iommu.c index 39d361c5c6d2..beec405eb6f8 100644 --- a/arch/powerpc/platforms/cell/beat_iommu.c +++ b/arch/powerpc/platforms/cell/beat_iommu.c | |||
@@ -108,7 +108,7 @@ static int __init celleb_init_iommu(void) | |||
108 | celleb_init_direct_mapping(); | 108 | celleb_init_direct_mapping(); |
109 | set_pci_dma_ops(&dma_direct_ops); | 109 | set_pci_dma_ops(&dma_direct_ops); |
110 | ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup; | 110 | ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup; |
111 | bus_register_notifier(&of_platform_bus_type, &celleb_of_bus_notifier); | 111 | bus_register_notifier(&platform_bus_type, &celleb_of_bus_notifier); |
112 | 112 | ||
113 | return 0; | 113 | return 0; |
114 | } | 114 | } |
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 3712900471ba..58b13ce3847e 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
@@ -1204,7 +1204,7 @@ static int __init cell_iommu_init(void) | |||
1204 | /* Register callbacks on OF platform device addition/removal | 1204 | /* Register callbacks on OF platform device addition/removal |
1205 | * to handle linking them to the right DMA operations | 1205 | * to handle linking them to the right DMA operations |
1206 | */ | 1206 | */ |
1207 | bus_register_notifier(&of_platform_bus_type, &cell_of_bus_notifier); | 1207 | bus_register_notifier(&platform_bus_type, &cell_of_bus_notifier); |
1208 | 1208 | ||
1209 | return 0; | 1209 | return 0; |
1210 | } | 1210 | } |
diff --git a/arch/powerpc/platforms/cell/qpace_setup.c b/arch/powerpc/platforms/cell/qpace_setup.c index c5ce02e84c8e..1b5749042756 100644 --- a/arch/powerpc/platforms/cell/qpace_setup.c +++ b/arch/powerpc/platforms/cell/qpace_setup.c | |||
@@ -61,12 +61,24 @@ static void qpace_progress(char *s, unsigned short hex) | |||
61 | printk("*** %04x : %s\n", hex, s ? s : ""); | 61 | printk("*** %04x : %s\n", hex, s ? s : ""); |
62 | } | 62 | } |
63 | 63 | ||
64 | static const struct of_device_id qpace_bus_ids[] __initdata = { | ||
65 | { .type = "soc", }, | ||
66 | { .compatible = "soc", }, | ||
67 | { .type = "spider", }, | ||
68 | { .type = "axon", }, | ||
69 | { .type = "plb5", }, | ||
70 | { .type = "plb4", }, | ||
71 | { .type = "opb", }, | ||
72 | { .type = "ebc", }, | ||
73 | {}, | ||
74 | }; | ||
75 | |||
64 | static int __init qpace_publish_devices(void) | 76 | static int __init qpace_publish_devices(void) |
65 | { | 77 | { |
66 | int node; | 78 | int node; |
67 | 79 | ||
68 | /* Publish OF platform devices for southbridge IOs */ | 80 | /* Publish OF platform devices for southbridge IOs */ |
69 | of_platform_bus_probe(NULL, NULL, NULL); | 81 | of_platform_bus_probe(NULL, qpace_bus_ids, NULL); |
70 | 82 | ||
71 | /* There is no device for the MIC memory controller, thus we create | 83 | /* There is no device for the MIC memory controller, thus we create |
72 | * a platform device for it to attach the EDAC driver to. | 84 | * a platform device for it to attach the EDAC driver to. |
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 50385db586bd..691995761b3d 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c | |||
@@ -141,6 +141,18 @@ static int __devinit cell_setup_phb(struct pci_controller *phb) | |||
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
143 | 143 | ||
144 | static const struct of_device_id cell_bus_ids[] __initdata = { | ||
145 | { .type = "soc", }, | ||
146 | { .compatible = "soc", }, | ||
147 | { .type = "spider", }, | ||
148 | { .type = "axon", }, | ||
149 | { .type = "plb5", }, | ||
150 | { .type = "plb4", }, | ||
151 | { .type = "opb", }, | ||
152 | { .type = "ebc", }, | ||
153 | {}, | ||
154 | }; | ||
155 | |||
144 | static int __init cell_publish_devices(void) | 156 | static int __init cell_publish_devices(void) |
145 | { | 157 | { |
146 | struct device_node *root = of_find_node_by_path("/"); | 158 | struct device_node *root = of_find_node_by_path("/"); |
@@ -148,7 +160,7 @@ static int __init cell_publish_devices(void) | |||
148 | int node; | 160 | int node; |
149 | 161 | ||
150 | /* Publish OF platform devices for southbridge IOs */ | 162 | /* Publish OF platform devices for southbridge IOs */ |
151 | of_platform_bus_probe(NULL, NULL, NULL); | 163 | of_platform_bus_probe(NULL, cell_bus_ids, NULL); |
152 | 164 | ||
153 | /* On spider based blades, we need to manually create the OF | 165 | /* On spider based blades, we need to manually create the OF |
154 | * platform devices for the PCI host bridges | 166 | * platform devices for the PCI host bridges |
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index d2c1d497846e..33e5fc7334fc 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/completion.h> | 31 | #include <linux/completion.h> |
32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | #include <linux/proc_fs.h> | ||
33 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
34 | #include <linux/bcd.h> | 35 | #include <linux/bcd.h> |
35 | #include <linux/rtc.h> | 36 | #include <linux/rtc.h> |
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/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index 627ee089e75d..a5d907b5a4c2 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c | |||
@@ -216,7 +216,7 @@ static int gpio_mdio_reset(struct mii_bus *bus) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | 218 | ||
219 | static int __devinit gpio_mdio_probe(struct of_device *ofdev, | 219 | static int __devinit gpio_mdio_probe(struct platform_device *ofdev, |
220 | const struct of_device_id *match) | 220 | const struct of_device_id *match) |
221 | { | 221 | { |
222 | struct device *dev = &ofdev->dev; | 222 | struct device *dev = &ofdev->dev; |
@@ -275,7 +275,7 @@ out: | |||
275 | } | 275 | } |
276 | 276 | ||
277 | 277 | ||
278 | static int gpio_mdio_remove(struct of_device *dev) | 278 | static int gpio_mdio_remove(struct platform_device *dev) |
279 | { | 279 | { |
280 | struct mii_bus *bus = dev_get_drvdata(&dev->dev); | 280 | struct mii_bus *bus = dev_get_drvdata(&dev->dev); |
281 | 281 | ||
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..39df6ab1735a 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
24 | #include <linux/of.h> | ||
25 | #include <linux/of_address.h> | ||
24 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
25 | #include <linux/adb.h> | 27 | #include <linux/adb.h> |
26 | #include <linux/pmu.h> | 28 | #include <linux/pmu.h> |
@@ -2191,7 +2193,11 @@ static struct pmac_mb_def pmac_mb_defs[] = { | |||
2191 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | 2193 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, |
2192 | PMAC_MB_MAY_SLEEP, | 2194 | PMAC_MB_MAY_SLEEP, |
2193 | }, | 2195 | }, |
2194 | { "iMac,1", "iMac (first generation)", | 2196 | { "PowerMac10,2", "Mac mini (Late 2005)", |
2197 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
2198 | PMAC_MB_MAY_SLEEP, | ||
2199 | }, | ||
2200 | { "iMac,1", "iMac (first generation)", | ||
2195 | PMAC_TYPE_ORIG_IMAC, paddington_features, | 2201 | PMAC_TYPE_ORIG_IMAC, paddington_features, |
2196 | 0 | 2202 | 0 |
2197 | }, | 2203 | }, |
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 630a533d0e59..890d5f72b198 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c | |||
@@ -46,6 +46,10 @@ struct pmac_irq_hw { | |||
46 | unsigned int level; | 46 | unsigned int level; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | /* Workaround flags for 32bit powermac machines */ | ||
50 | unsigned int of_irq_workarounds; | ||
51 | struct device_node *of_irq_dflt_pic; | ||
52 | |||
49 | /* Default addresses */ | 53 | /* Default addresses */ |
50 | static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4]; | 54 | static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4]; |
51 | 55 | ||
@@ -428,6 +432,42 @@ static void __init pmac_pic_probe_oldstyle(void) | |||
428 | setup_irq(irq_create_mapping(NULL, 20), &xmon_action); | 432 | setup_irq(irq_create_mapping(NULL, 20), &xmon_action); |
429 | #endif | 433 | #endif |
430 | } | 434 | } |
435 | |||
436 | int of_irq_map_oldworld(struct device_node *device, int index, | ||
437 | struct of_irq *out_irq) | ||
438 | { | ||
439 | const u32 *ints = NULL; | ||
440 | int intlen; | ||
441 | |||
442 | /* | ||
443 | * Old machines just have a list of interrupt numbers | ||
444 | * and no interrupt-controller nodes. We also have dodgy | ||
445 | * cases where the APPL,interrupts property is completely | ||
446 | * missing behind pci-pci bridges and we have to get it | ||
447 | * from the parent (the bridge itself, as apple just wired | ||
448 | * everything together on these) | ||
449 | */ | ||
450 | while (device) { | ||
451 | ints = of_get_property(device, "AAPL,interrupts", &intlen); | ||
452 | if (ints != NULL) | ||
453 | break; | ||
454 | device = device->parent; | ||
455 | if (device && strcmp(device->type, "pci") != 0) | ||
456 | break; | ||
457 | } | ||
458 | if (ints == NULL) | ||
459 | return -EINVAL; | ||
460 | intlen /= sizeof(u32); | ||
461 | |||
462 | if (index >= intlen) | ||
463 | return -EINVAL; | ||
464 | |||
465 | out_irq->controller = NULL; | ||
466 | out_irq->specifier[0] = ints[index]; | ||
467 | out_irq->size = 1; | ||
468 | |||
469 | return 0; | ||
470 | } | ||
431 | #endif /* CONFIG_PPC32 */ | 471 | #endif /* CONFIG_PPC32 */ |
432 | 472 | ||
433 | static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc) | 473 | static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc) |
@@ -559,19 +599,39 @@ static int __init pmac_pic_probe_mpic(void) | |||
559 | 599 | ||
560 | void __init pmac_pic_init(void) | 600 | void __init pmac_pic_init(void) |
561 | { | 601 | { |
562 | unsigned int flags = 0; | ||
563 | |||
564 | /* We configure the OF parsing based on our oldworld vs. newworld | 602 | /* We configure the OF parsing based on our oldworld vs. newworld |
565 | * platform type and wether we were booted by BootX. | 603 | * platform type and wether we were booted by BootX. |
566 | */ | 604 | */ |
567 | #ifdef CONFIG_PPC32 | 605 | #ifdef CONFIG_PPC32 |
568 | if (!pmac_newworld) | 606 | if (!pmac_newworld) |
569 | flags |= OF_IMAP_OLDWORLD_MAC; | 607 | of_irq_workarounds |= OF_IMAP_OLDWORLD_MAC; |
570 | if (of_get_property(of_chosen, "linux,bootx", NULL) != NULL) | 608 | if (of_get_property(of_chosen, "linux,bootx", NULL) != NULL) |
571 | flags |= OF_IMAP_NO_PHANDLE; | 609 | of_irq_workarounds |= OF_IMAP_NO_PHANDLE; |
572 | #endif /* CONFIG_PPC_32 */ | ||
573 | 610 | ||
574 | of_irq_map_init(flags); | 611 | /* If we don't have phandles on a newworld, then try to locate a |
612 | * default interrupt controller (happens when booting with BootX). | ||
613 | * We do a first match here, hopefully, that only ever happens on | ||
614 | * machines with one controller. | ||
615 | */ | ||
616 | if (pmac_newworld && (of_irq_workarounds & OF_IMAP_NO_PHANDLE)) { | ||
617 | struct device_node *np; | ||
618 | |||
619 | for_each_node_with_property(np, "interrupt-controller") { | ||
620 | /* Skip /chosen/interrupt-controller */ | ||
621 | if (strcmp(np->name, "chosen") == 0) | ||
622 | continue; | ||
623 | /* It seems like at least one person wants | ||
624 | * to use BootX on a machine with an AppleKiwi | ||
625 | * controller which happens to pretend to be an | ||
626 | * interrupt controller too. */ | ||
627 | if (strcmp(np->name, "AppleKiwi") == 0) | ||
628 | continue; | ||
629 | /* I think we found one ! */ | ||
630 | of_irq_dflt_pic = np; | ||
631 | break; | ||
632 | } | ||
633 | } | ||
634 | #endif /* CONFIG_PPC32 */ | ||
575 | 635 | ||
576 | /* We first try to detect Apple's new Core99 chipset, since mac-io | 636 | /* We first try to detect Apple's new Core99 chipset, since mac-io |
577 | * is quite different on those machines and contains an IBM MPIC2. | 637 | * is quite different on those machines and contains an IBM MPIC2. |
diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c index 2c0ed87f2024..3124cf791ebb 100644 --- a/arch/powerpc/platforms/ps3/htab.c +++ b/arch/powerpc/platforms/ps3/htab.c | |||
@@ -136,7 +136,7 @@ static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp, | |||
136 | * As lv1_read_htab_entries() does not give us the RPN, we can | 136 | * As lv1_read_htab_entries() does not give us the RPN, we can |
137 | * not synthesize the new hpte_r value here, and therefore can | 137 | * not synthesize the new hpte_r value here, and therefore can |
138 | * not update the hpte with lv1_insert_htab_entry(), so we | 138 | * not update the hpte with lv1_insert_htab_entry(), so we |
139 | * insted invalidate it and ask the caller to update it via | 139 | * instead invalidate it and ask the caller to update it via |
140 | * ps3_hpte_insert() by returning a -1 value. | 140 | * ps3_hpte_insert() by returning a -1 value. |
141 | */ | 141 | */ |
142 | if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) { | 142 | if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) { |
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/axonram.c b/arch/powerpc/sysdev/axonram.c index 402d2212162f..2659a60bd7b8 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c | |||
@@ -60,7 +60,7 @@ | |||
60 | static int azfs_major, azfs_minor; | 60 | static int azfs_major, azfs_minor; |
61 | 61 | ||
62 | struct axon_ram_bank { | 62 | struct axon_ram_bank { |
63 | struct of_device *device; | 63 | struct platform_device *device; |
64 | struct gendisk *disk; | 64 | struct gendisk *disk; |
65 | unsigned int irq_id; | 65 | unsigned int irq_id; |
66 | unsigned long ph_addr; | 66 | unsigned long ph_addr; |
@@ -72,7 +72,7 @@ struct axon_ram_bank { | |||
72 | static ssize_t | 72 | static ssize_t |
73 | axon_ram_sysfs_ecc(struct device *dev, struct device_attribute *attr, char *buf) | 73 | axon_ram_sysfs_ecc(struct device *dev, struct device_attribute *attr, char *buf) |
74 | { | 74 | { |
75 | struct of_device *device = to_of_device(dev); | 75 | struct platform_device *device = to_platform_device(dev); |
76 | struct axon_ram_bank *bank = device->dev.platform_data; | 76 | struct axon_ram_bank *bank = device->dev.platform_data; |
77 | 77 | ||
78 | BUG_ON(!bank); | 78 | BUG_ON(!bank); |
@@ -90,7 +90,7 @@ static DEVICE_ATTR(ecc, S_IRUGO, axon_ram_sysfs_ecc, NULL); | |||
90 | static irqreturn_t | 90 | static irqreturn_t |
91 | axon_ram_irq_handler(int irq, void *dev) | 91 | axon_ram_irq_handler(int irq, void *dev) |
92 | { | 92 | { |
93 | struct of_device *device = dev; | 93 | struct platform_device *device = dev; |
94 | struct axon_ram_bank *bank = device->dev.platform_data; | 94 | struct axon_ram_bank *bank = device->dev.platform_data; |
95 | 95 | ||
96 | BUG_ON(!bank); | 96 | BUG_ON(!bank); |
@@ -174,8 +174,8 @@ static const struct block_device_operations axon_ram_devops = { | |||
174 | * axon_ram_probe - probe() method for platform driver | 174 | * axon_ram_probe - probe() method for platform driver |
175 | * @device, @device_id: see of_platform_driver method | 175 | * @device, @device_id: see of_platform_driver method |
176 | */ | 176 | */ |
177 | static int | 177 | static int axon_ram_probe(struct platform_device *device, |
178 | axon_ram_probe(struct of_device *device, const struct of_device_id *device_id) | 178 | const struct of_device_id *device_id) |
179 | { | 179 | { |
180 | static int axon_ram_bank_id = -1; | 180 | static int axon_ram_bank_id = -1; |
181 | struct axon_ram_bank *bank; | 181 | struct axon_ram_bank *bank; |
@@ -304,7 +304,7 @@ failed: | |||
304 | * @device: see of_platform_driver method | 304 | * @device: see of_platform_driver method |
305 | */ | 305 | */ |
306 | static int | 306 | static int |
307 | axon_ram_remove(struct of_device *device) | 307 | axon_ram_remove(struct platform_device *device) |
308 | { | 308 | { |
309 | struct axon_ram_bank *bank = device->dev.platform_data; | 309 | struct axon_ram_bank *bank = device->dev.platform_data; |
310 | 310 | ||
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c index a7c5c470af14..650256115064 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.c +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c | |||
@@ -365,8 +365,8 @@ bcom_engine_cleanup(void) | |||
365 | /* OF platform driver */ | 365 | /* OF platform driver */ |
366 | /* ======================================================================== */ | 366 | /* ======================================================================== */ |
367 | 367 | ||
368 | static int __devinit | 368 | static int __devinit mpc52xx_bcom_probe(struct platform_device *op, |
369 | mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match) | 369 | const struct of_device_id *match) |
370 | { | 370 | { |
371 | struct device_node *ofn_sram; | 371 | struct device_node *ofn_sram; |
372 | struct resource res_bcom; | 372 | struct resource res_bcom; |
@@ -461,8 +461,7 @@ error_ofput: | |||
461 | } | 461 | } |
462 | 462 | ||
463 | 463 | ||
464 | static int | 464 | static int mpc52xx_bcom_remove(struct platform_device *op) |
465 | mpc52xx_bcom_remove(struct of_device *op) | ||
466 | { | 465 | { |
467 | /* Clean up the engine */ | 466 | /* Clean up the engine */ |
468 | bcom_engine_cleanup(); | 467 | bcom_engine_cleanup(); |
diff --git a/arch/powerpc/sysdev/bestcomm/sram.c b/arch/powerpc/sysdev/bestcomm/sram.c index 5d74ef7a651f..1225012a681a 100644 --- a/arch/powerpc/sysdev/bestcomm/sram.c +++ b/arch/powerpc/sysdev/bestcomm/sram.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * kind, whether express or implied. | 11 | * kind, whether express or implied. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/err.h> | ||
14 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
16 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index 8d103ca6d6ab..00852124ff4a 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c | |||
@@ -621,7 +621,6 @@ int cpm1_gpiochip_add16(struct device_node *np) | |||
621 | { | 621 | { |
622 | struct cpm1_gpio16_chip *cpm1_gc; | 622 | struct cpm1_gpio16_chip *cpm1_gc; |
623 | struct of_mm_gpio_chip *mm_gc; | 623 | struct of_mm_gpio_chip *mm_gc; |
624 | struct of_gpio_chip *of_gc; | ||
625 | struct gpio_chip *gc; | 624 | struct gpio_chip *gc; |
626 | 625 | ||
627 | cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL); | 626 | cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL); |
@@ -631,11 +630,9 @@ int cpm1_gpiochip_add16(struct device_node *np) | |||
631 | spin_lock_init(&cpm1_gc->lock); | 630 | spin_lock_init(&cpm1_gc->lock); |
632 | 631 | ||
633 | mm_gc = &cpm1_gc->mm_gc; | 632 | mm_gc = &cpm1_gc->mm_gc; |
634 | of_gc = &mm_gc->of_gc; | 633 | gc = &mm_gc->gc; |
635 | gc = &of_gc->gc; | ||
636 | 634 | ||
637 | mm_gc->save_regs = cpm1_gpio16_save_regs; | 635 | mm_gc->save_regs = cpm1_gpio16_save_regs; |
638 | of_gc->gpio_cells = 2; | ||
639 | gc->ngpio = 16; | 636 | gc->ngpio = 16; |
640 | gc->direction_input = cpm1_gpio16_dir_in; | 637 | gc->direction_input = cpm1_gpio16_dir_in; |
641 | gc->direction_output = cpm1_gpio16_dir_out; | 638 | gc->direction_output = cpm1_gpio16_dir_out; |
@@ -745,7 +742,6 @@ int cpm1_gpiochip_add32(struct device_node *np) | |||
745 | { | 742 | { |
746 | struct cpm1_gpio32_chip *cpm1_gc; | 743 | struct cpm1_gpio32_chip *cpm1_gc; |
747 | struct of_mm_gpio_chip *mm_gc; | 744 | struct of_mm_gpio_chip *mm_gc; |
748 | struct of_gpio_chip *of_gc; | ||
749 | struct gpio_chip *gc; | 745 | struct gpio_chip *gc; |
750 | 746 | ||
751 | cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL); | 747 | cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL); |
@@ -755,11 +751,9 @@ int cpm1_gpiochip_add32(struct device_node *np) | |||
755 | spin_lock_init(&cpm1_gc->lock); | 751 | spin_lock_init(&cpm1_gc->lock); |
756 | 752 | ||
757 | mm_gc = &cpm1_gc->mm_gc; | 753 | mm_gc = &cpm1_gc->mm_gc; |
758 | of_gc = &mm_gc->of_gc; | 754 | gc = &mm_gc->gc; |
759 | gc = &of_gc->gc; | ||
760 | 755 | ||
761 | mm_gc->save_regs = cpm1_gpio32_save_regs; | 756 | mm_gc->save_regs = cpm1_gpio32_save_regs; |
762 | of_gc->gpio_cells = 2; | ||
763 | gc->ngpio = 32; | 757 | gc->ngpio = 32; |
764 | gc->direction_input = cpm1_gpio32_dir_in; | 758 | gc->direction_input = cpm1_gpio32_dir_in; |
765 | gc->direction_output = cpm1_gpio32_dir_out; | 759 | gc->direction_output = cpm1_gpio32_dir_out; |
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 88b9812c854f..2b69aa0315b3 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c | |||
@@ -325,7 +325,6 @@ int cpm2_gpiochip_add32(struct device_node *np) | |||
325 | { | 325 | { |
326 | struct cpm2_gpio32_chip *cpm2_gc; | 326 | struct cpm2_gpio32_chip *cpm2_gc; |
327 | struct of_mm_gpio_chip *mm_gc; | 327 | struct of_mm_gpio_chip *mm_gc; |
328 | struct of_gpio_chip *of_gc; | ||
329 | struct gpio_chip *gc; | 328 | struct gpio_chip *gc; |
330 | 329 | ||
331 | cpm2_gc = kzalloc(sizeof(*cpm2_gc), GFP_KERNEL); | 330 | cpm2_gc = kzalloc(sizeof(*cpm2_gc), GFP_KERNEL); |
@@ -335,11 +334,9 @@ int cpm2_gpiochip_add32(struct device_node *np) | |||
335 | spin_lock_init(&cpm2_gc->lock); | 334 | spin_lock_init(&cpm2_gc->lock); |
336 | 335 | ||
337 | mm_gc = &cpm2_gc->mm_gc; | 336 | mm_gc = &cpm2_gc->mm_gc; |
338 | of_gc = &mm_gc->of_gc; | 337 | gc = &mm_gc->gc; |
339 | gc = &of_gc->gc; | ||
340 | 338 | ||
341 | mm_gc->save_regs = cpm2_gpio32_save_regs; | 339 | mm_gc->save_regs = cpm2_gpio32_save_regs; |
342 | of_gc->gpio_cells = 2; | ||
343 | gc->ngpio = 32; | 340 | gc->ngpio = 32; |
344 | gc->direction_input = cpm2_gpio32_dir_in; | 341 | gc->direction_input = cpm2_gpio32_dir_in; |
345 | gc->direction_output = cpm2_gpio32_dir_out; | 342 | gc->direction_output = cpm2_gpio32_dir_out; |
diff --git a/arch/powerpc/sysdev/fsl_gtm.c b/arch/powerpc/sysdev/fsl_gtm.c index eca4545dd52e..7dd2885321ad 100644 --- a/arch/powerpc/sysdev/fsl_gtm.c +++ b/arch/powerpc/sysdev/fsl_gtm.c | |||
@@ -14,6 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/err.h> | ||
17 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
18 | #include <linux/list.h> | 19 | #include <linux/list.h> |
19 | #include <linux/io.h> | 20 | #include <linux/io.h> |
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 962c2d8dd8d9..87991d3abbab 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c | |||
@@ -250,7 +250,7 @@ unlock: | |||
250 | raw_spin_unlock(&desc->lock); | 250 | raw_spin_unlock(&desc->lock); |
251 | } | 251 | } |
252 | 252 | ||
253 | static int fsl_of_msi_remove(struct of_device *ofdev) | 253 | static int fsl_of_msi_remove(struct platform_device *ofdev) |
254 | { | 254 | { |
255 | struct fsl_msi *msi = ofdev->dev.platform_data; | 255 | struct fsl_msi *msi = ofdev->dev.platform_data; |
256 | int virq, i; | 256 | int virq, i; |
@@ -274,7 +274,7 @@ static int fsl_of_msi_remove(struct of_device *ofdev) | |||
274 | return 0; | 274 | return 0; |
275 | } | 275 | } |
276 | 276 | ||
277 | static int __devinit fsl_of_msi_probe(struct of_device *dev, | 277 | static int __devinit fsl_of_msi_probe(struct platform_device *dev, |
278 | const struct of_device_id *match) | 278 | const struct of_device_id *match) |
279 | { | 279 | { |
280 | struct fsl_msi *msi; | 280 | struct fsl_msi *msi; |
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_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index 9082eb921ad9..44de8559c975 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c | |||
@@ -58,7 +58,8 @@ static struct platform_suspend_ops pmc_suspend_ops = { | |||
58 | .enter = pmc_suspend_enter, | 58 | .enter = pmc_suspend_enter, |
59 | }; | 59 | }; |
60 | 60 | ||
61 | static int pmc_probe(struct of_device *ofdev, const struct of_device_id *id) | 61 | static int pmc_probe(struct platform_device *ofdev, |
62 | const struct of_device_id *id) | ||
62 | { | 63 | { |
63 | pmc_regs = of_iomap(ofdev->dev.of_node, 0); | 64 | pmc_regs = of_iomap(ofdev->dev.of_node, 0); |
64 | if (!pmc_regs) | 65 | if (!pmc_regs) |
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 30e1626b2e85..8bd86530ee25 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c | |||
@@ -1338,7 +1338,7 @@ static inline void fsl_rio_info(struct device *dev, u32 ccsr) | |||
1338 | * master port with system-specific info, and registers the | 1338 | * master port with system-specific info, and registers the |
1339 | * master port with the RapidIO subsystem. | 1339 | * master port with the RapidIO subsystem. |
1340 | */ | 1340 | */ |
1341 | int fsl_rio_setup(struct of_device *dev) | 1341 | int fsl_rio_setup(struct platform_device *dev) |
1342 | { | 1342 | { |
1343 | struct rio_ops *ops; | 1343 | struct rio_ops *ops; |
1344 | struct rio_mport *port; | 1344 | struct rio_mport *port; |
@@ -1536,7 +1536,7 @@ err_ops: | |||
1536 | 1536 | ||
1537 | /* The probe function for RapidIO peer-to-peer network. | 1537 | /* The probe function for RapidIO peer-to-peer network. |
1538 | */ | 1538 | */ |
1539 | static int __devinit fsl_of_rio_rpn_probe(struct of_device *dev, | 1539 | static int __devinit fsl_of_rio_rpn_probe(struct platform_device *dev, |
1540 | const struct of_device_id *match) | 1540 | const struct of_device_id *match) |
1541 | { | 1541 | { |
1542 | int rc; | 1542 | int rc; |
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/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c index 83f519655fac..2b69084d0f0c 100644 --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c | |||
@@ -257,7 +257,6 @@ static void __init mpc8xxx_add_controller(struct device_node *np) | |||
257 | { | 257 | { |
258 | struct mpc8xxx_gpio_chip *mpc8xxx_gc; | 258 | struct mpc8xxx_gpio_chip *mpc8xxx_gc; |
259 | struct of_mm_gpio_chip *mm_gc; | 259 | struct of_mm_gpio_chip *mm_gc; |
260 | struct of_gpio_chip *of_gc; | ||
261 | struct gpio_chip *gc; | 260 | struct gpio_chip *gc; |
262 | unsigned hwirq; | 261 | unsigned hwirq; |
263 | int ret; | 262 | int ret; |
@@ -271,11 +270,9 @@ static void __init mpc8xxx_add_controller(struct device_node *np) | |||
271 | spin_lock_init(&mpc8xxx_gc->lock); | 270 | spin_lock_init(&mpc8xxx_gc->lock); |
272 | 271 | ||
273 | mm_gc = &mpc8xxx_gc->mm_gc; | 272 | mm_gc = &mpc8xxx_gc->mm_gc; |
274 | of_gc = &mm_gc->of_gc; | 273 | gc = &mm_gc->gc; |
275 | gc = &of_gc->gc; | ||
276 | 274 | ||
277 | mm_gc->save_regs = mpc8xxx_gpio_save_regs; | 275 | mm_gc->save_regs = mpc8xxx_gpio_save_regs; |
278 | of_gc->gpio_cells = 2; | ||
279 | gc->ngpio = MPC8XXX_GPIO_PINS; | 276 | gc->ngpio = MPC8XXX_GPIO_PINS; |
280 | gc->direction_input = mpc8xxx_gpio_dir_in; | 277 | gc->direction_input = mpc8xxx_gpio_dir_in; |
281 | gc->direction_output = mpc8xxx_gpio_dir_out; | 278 | gc->direction_output = mpc8xxx_gpio_dir_out; |
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/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index 31acd3b1718b..1398bc454999 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c | |||
@@ -20,12 +20,7 @@ | |||
20 | 20 | ||
21 | #include <asm/prom.h> | 21 | #include <asm/prom.h> |
22 | 22 | ||
23 | /* | 23 | /* These functions provide the necessary setup for the mv64x60 drivers. */ |
24 | * These functions provide the necessary setup for the mv64x60 drivers. | ||
25 | * These drivers are unusual in that they work on both the MIPS and PowerPC | ||
26 | * architectures. Because of that, the drivers do not support the normal | ||
27 | * PowerPC of_platform_bus_type. They support platform_bus_type instead. | ||
28 | */ | ||
29 | 24 | ||
30 | static struct of_device_id __initdata of_mv64x60_devices[] = { | 25 | static struct of_device_id __initdata of_mv64x60_devices[] = { |
31 | { .compatible = "marvell,mv64306-devctrl", }, | 26 | { .compatible = "marvell,mv64306-devctrl", }, |
diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index d07137a07d75..24a0bb955b18 100644 --- a/arch/powerpc/sysdev/pmi.c +++ b/arch/powerpc/sysdev/pmi.c | |||
@@ -43,7 +43,7 @@ struct pmi_data { | |||
43 | struct mutex msg_mutex; | 43 | struct mutex msg_mutex; |
44 | pmi_message_t msg; | 44 | pmi_message_t msg; |
45 | struct completion *completion; | 45 | struct completion *completion; |
46 | struct of_device *dev; | 46 | struct platform_device *dev; |
47 | int irq; | 47 | int irq; |
48 | u8 __iomem *pmi_reg; | 48 | u8 __iomem *pmi_reg; |
49 | struct work_struct work; | 49 | struct work_struct work; |
@@ -121,7 +121,7 @@ static void pmi_notify_handlers(struct work_struct *work) | |||
121 | spin_unlock(&data->handler_spinlock); | 121 | spin_unlock(&data->handler_spinlock); |
122 | } | 122 | } |
123 | 123 | ||
124 | static int pmi_of_probe(struct of_device *dev, | 124 | static int pmi_of_probe(struct platform_device *dev, |
125 | const struct of_device_id *match) | 125 | const struct of_device_id *match) |
126 | { | 126 | { |
127 | struct device_node *np = dev->dev.of_node; | 127 | struct device_node *np = dev->dev.of_node; |
@@ -185,7 +185,7 @@ out: | |||
185 | return rc; | 185 | return rc; |
186 | } | 186 | } |
187 | 187 | ||
188 | static int pmi_of_remove(struct of_device *dev) | 188 | static int pmi_of_remove(struct platform_device *dev) |
189 | { | 189 | { |
190 | struct pmi_handler *handler, *tmp; | 190 | struct pmi_handler *handler, *tmp; |
191 | 191 | ||
diff --git a/arch/powerpc/sysdev/ppc4xx_gpio.c b/arch/powerpc/sysdev/ppc4xx_gpio.c index 3812fc366bec..fc65ad1b3293 100644 --- a/arch/powerpc/sysdev/ppc4xx_gpio.c +++ b/arch/powerpc/sysdev/ppc4xx_gpio.c | |||
@@ -181,7 +181,6 @@ static int __init ppc4xx_add_gpiochips(void) | |||
181 | int ret; | 181 | int ret; |
182 | struct ppc4xx_gpio_chip *ppc4xx_gc; | 182 | struct ppc4xx_gpio_chip *ppc4xx_gc; |
183 | struct of_mm_gpio_chip *mm_gc; | 183 | struct of_mm_gpio_chip *mm_gc; |
184 | struct of_gpio_chip *of_gc; | ||
185 | struct gpio_chip *gc; | 184 | struct gpio_chip *gc; |
186 | 185 | ||
187 | ppc4xx_gc = kzalloc(sizeof(*ppc4xx_gc), GFP_KERNEL); | 186 | ppc4xx_gc = kzalloc(sizeof(*ppc4xx_gc), GFP_KERNEL); |
@@ -193,10 +192,8 @@ static int __init ppc4xx_add_gpiochips(void) | |||
193 | spin_lock_init(&ppc4xx_gc->lock); | 192 | spin_lock_init(&ppc4xx_gc->lock); |
194 | 193 | ||
195 | mm_gc = &ppc4xx_gc->mm_gc; | 194 | mm_gc = &ppc4xx_gc->mm_gc; |
196 | of_gc = &mm_gc->of_gc; | 195 | gc = &mm_gc->gc; |
197 | gc = &of_gc->gc; | ||
198 | 196 | ||
199 | of_gc->gpio_cells = 2; | ||
200 | gc->ngpio = 32; | 197 | gc->ngpio = 32; |
201 | gc->direction_input = ppc4xx_gpio_dir_in; | 198 | gc->direction_input = ppc4xx_gpio_dir_in; |
202 | gc->direction_output = ppc4xx_gpio_dir_out; | 199 | gc->direction_output = ppc4xx_gpio_dir_out; |
diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c index dc8f8d618074..36bf845df127 100644 --- a/arch/powerpc/sysdev/qe_lib/gpio.c +++ b/arch/powerpc/sysdev/qe_lib/gpio.c | |||
@@ -138,8 +138,8 @@ struct qe_pin { | |||
138 | struct qe_pin *qe_pin_request(struct device_node *np, int index) | 138 | struct qe_pin *qe_pin_request(struct device_node *np, int index) |
139 | { | 139 | { |
140 | struct qe_pin *qe_pin; | 140 | struct qe_pin *qe_pin; |
141 | struct device_node *gc; | 141 | struct device_node *gpio_np; |
142 | struct of_gpio_chip *of_gc = NULL; | 142 | struct gpio_chip *gc; |
143 | struct of_mm_gpio_chip *mm_gc; | 143 | struct of_mm_gpio_chip *mm_gc; |
144 | struct qe_gpio_chip *qe_gc; | 144 | struct qe_gpio_chip *qe_gc; |
145 | int err; | 145 | int err; |
@@ -155,40 +155,40 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index) | |||
155 | } | 155 | } |
156 | 156 | ||
157 | err = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index, | 157 | err = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index, |
158 | &gc, &gpio_spec); | 158 | &gpio_np, &gpio_spec); |
159 | if (err) { | 159 | if (err) { |
160 | pr_debug("%s: can't parse gpios property\n", __func__); | 160 | pr_debug("%s: can't parse gpios property\n", __func__); |
161 | goto err0; | 161 | goto err0; |
162 | } | 162 | } |
163 | 163 | ||
164 | if (!of_device_is_compatible(gc, "fsl,mpc8323-qe-pario-bank")) { | 164 | if (!of_device_is_compatible(gpio_np, "fsl,mpc8323-qe-pario-bank")) { |
165 | pr_debug("%s: tried to get a non-qe pin\n", __func__); | 165 | pr_debug("%s: tried to get a non-qe pin\n", __func__); |
166 | err = -EINVAL; | 166 | err = -EINVAL; |
167 | goto err1; | 167 | goto err1; |
168 | } | 168 | } |
169 | 169 | ||
170 | of_gc = gc->data; | 170 | gc = of_node_to_gpiochip(gpio_np); |
171 | if (!of_gc) { | 171 | if (!gc) { |
172 | pr_debug("%s: gpio controller %s isn't registered\n", | 172 | pr_debug("%s: gpio controller %s isn't registered\n", |
173 | np->full_name, gc->full_name); | 173 | np->full_name, gpio_np->full_name); |
174 | err = -ENODEV; | 174 | err = -ENODEV; |
175 | goto err1; | 175 | goto err1; |
176 | } | 176 | } |
177 | 177 | ||
178 | gpio_cells = of_get_property(gc, "#gpio-cells", &size); | 178 | gpio_cells = of_get_property(gpio_np, "#gpio-cells", &size); |
179 | if (!gpio_cells || size != sizeof(*gpio_cells) || | 179 | if (!gpio_cells || size != sizeof(*gpio_cells) || |
180 | *gpio_cells != of_gc->gpio_cells) { | 180 | *gpio_cells != gc->of_gpio_n_cells) { |
181 | pr_debug("%s: wrong #gpio-cells for %s\n", | 181 | pr_debug("%s: wrong #gpio-cells for %s\n", |
182 | np->full_name, gc->full_name); | 182 | np->full_name, gpio_np->full_name); |
183 | err = -EINVAL; | 183 | err = -EINVAL; |
184 | goto err1; | 184 | goto err1; |
185 | } | 185 | } |
186 | 186 | ||
187 | err = of_gc->xlate(of_gc, np, gpio_spec, NULL); | 187 | err = gc->of_xlate(gc, np, gpio_spec, NULL); |
188 | if (err < 0) | 188 | if (err < 0) |
189 | goto err1; | 189 | goto err1; |
190 | 190 | ||
191 | mm_gc = to_of_mm_gpio_chip(&of_gc->gc); | 191 | mm_gc = to_of_mm_gpio_chip(gc); |
192 | qe_gc = to_qe_gpio_chip(mm_gc); | 192 | qe_gc = to_qe_gpio_chip(mm_gc); |
193 | 193 | ||
194 | spin_lock_irqsave(&qe_gc->lock, flags); | 194 | spin_lock_irqsave(&qe_gc->lock, flags); |
@@ -206,7 +206,7 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index) | |||
206 | if (!err) | 206 | if (!err) |
207 | return qe_pin; | 207 | return qe_pin; |
208 | err1: | 208 | err1: |
209 | of_node_put(gc); | 209 | of_node_put(gpio_np); |
210 | err0: | 210 | err0: |
211 | kfree(qe_pin); | 211 | kfree(qe_pin); |
212 | pr_debug("%s failed with status %d\n", __func__, err); | 212 | pr_debug("%s failed with status %d\n", __func__, err); |
@@ -307,7 +307,6 @@ static int __init qe_add_gpiochips(void) | |||
307 | int ret; | 307 | int ret; |
308 | struct qe_gpio_chip *qe_gc; | 308 | struct qe_gpio_chip *qe_gc; |
309 | struct of_mm_gpio_chip *mm_gc; | 309 | struct of_mm_gpio_chip *mm_gc; |
310 | struct of_gpio_chip *of_gc; | ||
311 | struct gpio_chip *gc; | 310 | struct gpio_chip *gc; |
312 | 311 | ||
313 | qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL); | 312 | qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL); |
@@ -319,11 +318,9 @@ static int __init qe_add_gpiochips(void) | |||
319 | spin_lock_init(&qe_gc->lock); | 318 | spin_lock_init(&qe_gc->lock); |
320 | 319 | ||
321 | mm_gc = &qe_gc->mm_gc; | 320 | mm_gc = &qe_gc->mm_gc; |
322 | of_gc = &mm_gc->of_gc; | 321 | gc = &mm_gc->gc; |
323 | gc = &of_gc->gc; | ||
324 | 322 | ||
325 | mm_gc->save_regs = qe_gpio_save_regs; | 323 | mm_gc->save_regs = qe_gpio_save_regs; |
326 | of_gc->gpio_cells = 2; | ||
327 | gc->ngpio = QE_PIO_PINS; | 324 | gc->ngpio = QE_PIO_PINS; |
328 | gc->direction_input = qe_gpio_dir_in; | 325 | gc->direction_input = qe_gpio_dir_in; |
329 | gc->direction_output = qe_gpio_dir_out; | 326 | gc->direction_output = qe_gpio_dir_out; |
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 093e0ae1a941..3da8014931c9 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c | |||
@@ -651,14 +651,15 @@ unsigned int qe_get_num_of_snums(void) | |||
651 | EXPORT_SYMBOL(qe_get_num_of_snums); | 651 | EXPORT_SYMBOL(qe_get_num_of_snums); |
652 | 652 | ||
653 | #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) | 653 | #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) |
654 | static int qe_resume(struct of_device *ofdev) | 654 | static int qe_resume(struct platform_device *ofdev) |
655 | { | 655 | { |
656 | if (!qe_alive_during_sleep()) | 656 | if (!qe_alive_during_sleep()) |
657 | qe_reset(); | 657 | qe_reset(); |
658 | return 0; | 658 | return 0; |
659 | } | 659 | } |
660 | 660 | ||
661 | static int qe_probe(struct of_device *ofdev, const struct of_device_id *id) | 661 | static int qe_probe(struct platform_device *ofdev, |
662 | const struct of_device_id *id) | ||
662 | { | 663 | { |
663 | return 0; | 664 | return 0; |
664 | } | 665 | } |
diff --git a/arch/powerpc/sysdev/simple_gpio.c b/arch/powerpc/sysdev/simple_gpio.c index d5fb173e588c..b6defda5ccc9 100644 --- a/arch/powerpc/sysdev/simple_gpio.c +++ b/arch/powerpc/sysdev/simple_gpio.c | |||
@@ -91,7 +91,6 @@ static int __init u8_simple_gpiochip_add(struct device_node *np) | |||
91 | int ret; | 91 | int ret; |
92 | struct u8_gpio_chip *u8_gc; | 92 | struct u8_gpio_chip *u8_gc; |
93 | struct of_mm_gpio_chip *mm_gc; | 93 | struct of_mm_gpio_chip *mm_gc; |
94 | struct of_gpio_chip *of_gc; | ||
95 | struct gpio_chip *gc; | 94 | struct gpio_chip *gc; |
96 | 95 | ||
97 | u8_gc = kzalloc(sizeof(*u8_gc), GFP_KERNEL); | 96 | u8_gc = kzalloc(sizeof(*u8_gc), GFP_KERNEL); |
@@ -101,11 +100,9 @@ static int __init u8_simple_gpiochip_add(struct device_node *np) | |||
101 | spin_lock_init(&u8_gc->lock); | 100 | spin_lock_init(&u8_gc->lock); |
102 | 101 | ||
103 | mm_gc = &u8_gc->mm_gc; | 102 | mm_gc = &u8_gc->mm_gc; |
104 | of_gc = &mm_gc->of_gc; | 103 | gc = &mm_gc->gc; |
105 | gc = &of_gc->gc; | ||
106 | 104 | ||
107 | mm_gc->save_regs = u8_gpio_save_regs; | 105 | mm_gc->save_regs = u8_gpio_save_regs; |
108 | of_gc->gpio_cells = 2; | ||
109 | gc->ngpio = 8; | 106 | gc->ngpio = 8; |
110 | gc->direction_input = u8_gpio_dir_in; | 107 | gc->direction_input = u8_gpio_dir_in; |
111 | gc->direction_output = u8_gpio_dir_out; | 108 | gc->direction_output = u8_gpio_dir_out; |
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 |