diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-06 20:12:03 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-06 20:12:03 -0500 |
commit | 1197ab2942f920f261952de0c392ac749a35796b (patch) | |
tree | 4922ccc8a6061e5ece6ac7420001f3bf4524ea92 /arch | |
parent | ec773e99ab4abce07b1ae23117179c2861831964 (diff) | |
parent | 96cc017c5b7ec095ef047d3c1952b6b6bbf98943 (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (106 commits)
powerpc/p3060qds: Add support for P3060QDS board
powerpc/83xx: Add shutdown request support to MCU handling on MPC8349 MITX
powerpc/85xx: Make kexec to interate over online cpus
powerpc/fsl_booke: Fix comment in head_fsl_booke.S
powerpc/85xx: issue 15 EOI after core reset for FSL CoreNet devices
powerpc/8xxx: Fix interrupt handling in MPC8xxx GPIO driver
powerpc/85xx: Add 'fsl,pq3-gpio' compatiable for GPIO driver
powerpc/86xx: Correct Gianfar support for GE boards
powerpc/cpm: Clear muram before it is in use.
drivers/virt: add ioctl for 32-bit compat on 64-bit to fsl-hv-manager
powerpc/fsl_msi: add support for "msi-address-64" property
powerpc/85xx: Setup secondary cores PIR with hard SMP id
powerpc/fsl-booke: Fix settlbcam for 64-bit
powerpc/85xx: Adding DCSR node to dtsi device trees
powerpc/85xx: clean up FPGA device tree nodes for Freecsale QorIQ boards
powerpc/85xx: fix PHYS_64BIT selection for P1022DS
powerpc/fsl-booke: Fix setup_initial_memory_limit to not blindly map
powerpc: respect mem= setting for early memory limit setup
powerpc: Update corenet64_smp_defconfig
powerpc: Update mpc85xx/corenet 32-bit defconfigs
...
Fix up trivial conflicts in:
- arch/powerpc/configs/40x/hcu4_defconfig
removed stale file, edited elsewhere
- arch/powerpc/include/asm/udbg.h, arch/powerpc/kernel/udbg.c:
added opal and gelic drivers vs added ePAPR driver
- drivers/tty/serial/8250.c
moved UPIO_TSI to powerpc vs removed UPIO_DWAPB support
Diffstat (limited to 'arch')
169 files changed, 8416 insertions, 1327 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 47682b67fd36..85195e48a9e6 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -323,7 +323,7 @@ config SWIOTLB | |||
323 | 323 | ||
324 | config HOTPLUG_CPU | 324 | config HOTPLUG_CPU |
325 | bool "Support for enabling/disabling CPUs" | 325 | bool "Support for enabling/disabling CPUs" |
326 | depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC) | 326 | depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC || PPC_POWERNV) |
327 | ---help--- | 327 | ---help--- |
328 | Say Y here to be able to disable and re-enable individual | 328 | Say Y here to be able to disable and re-enable individual |
329 | CPUs at runtime on SMP machines. | 329 | CPUs at runtime on SMP machines. |
@@ -345,7 +345,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE | |||
345 | 345 | ||
346 | config KEXEC | 346 | config KEXEC |
347 | bool "kexec system call (EXPERIMENTAL)" | 347 | bool "kexec system call (EXPERIMENTAL)" |
348 | depends on (PPC_BOOK3S || FSL_BOOKE) && EXPERIMENTAL | 348 | depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP && !47x)) && EXPERIMENTAL |
349 | help | 349 | help |
350 | kexec is a system call that implements the ability to shutdown your | 350 | kexec is a system call that implements the ability to shutdown your |
351 | current kernel, and to start another kernel. It is like a reboot | 351 | current kernel, and to start another kernel. It is like a reboot |
@@ -429,8 +429,7 @@ config ARCH_POPULATES_NODE_MAP | |||
429 | def_bool y | 429 | def_bool y |
430 | 430 | ||
431 | config SYS_SUPPORTS_HUGETLBFS | 431 | config SYS_SUPPORTS_HUGETLBFS |
432 | def_bool y | 432 | bool |
433 | depends on PPC_BOOK3S_64 | ||
434 | 433 | ||
435 | source "mm/Kconfig" | 434 | source "mm/Kconfig" |
436 | 435 | ||
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index 067cb8480747..1b8a9c905cf7 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug | |||
@@ -141,9 +141,6 @@ config BOOTX_TEXT | |||
141 | 141 | ||
142 | config PPC_EARLY_DEBUG | 142 | config PPC_EARLY_DEBUG |
143 | bool "Early debugging (dangerous)" | 143 | bool "Early debugging (dangerous)" |
144 | # PPC_EARLY_DEBUG on 440 leaves AS=1 mappings above the TLB high water | ||
145 | # mark, which doesn't work with current 440 KVM. | ||
146 | depends on !KVM | ||
147 | help | 144 | help |
148 | Say Y to enable some early debugging facilities that may be available | 145 | Say Y to enable some early debugging facilities that may be available |
149 | for your processor/board combination. Those facilities are hacks | 146 | for your processor/board combination. Those facilities are hacks |
@@ -222,7 +219,9 @@ config PPC_EARLY_DEBUG_BEAT | |||
222 | 219 | ||
223 | config PPC_EARLY_DEBUG_44x | 220 | config PPC_EARLY_DEBUG_44x |
224 | bool "Early serial debugging for IBM/AMCC 44x CPUs" | 221 | bool "Early serial debugging for IBM/AMCC 44x CPUs" |
225 | depends on 44x | 222 | # PPC_EARLY_DEBUG on 440 leaves AS=1 mappings above the TLB high water |
223 | # mark, which doesn't work with current 440 KVM. | ||
224 | depends on 44x && !KVM | ||
226 | help | 225 | help |
227 | Select this to enable early debugging for IBM 44x chips via the | 226 | Select this to enable early debugging for IBM 44x chips via the |
228 | inbuilt serial port. If you enable this, ensure you set | 227 | inbuilt serial port. If you enable this, ensure you set |
@@ -258,8 +257,35 @@ config PPC_EARLY_DEBUG_WSP | |||
258 | depends on PPC_WSP | 257 | depends on PPC_WSP |
259 | select PPC_UDBG_16550 | 258 | select PPC_UDBG_16550 |
260 | 259 | ||
260 | config PPC_EARLY_DEBUG_PS3GELIC | ||
261 | bool "Early debugging through the PS3 Ethernet port" | ||
262 | depends on PPC_PS3 | ||
263 | select PS3GELIC_UDBG | ||
264 | help | ||
265 | Select this to enable early debugging for the PlayStation3 via | ||
266 | UDP broadcasts sent out through the Ethernet port. | ||
267 | |||
268 | config PPC_EARLY_DEBUG_OPAL_RAW | ||
269 | bool "OPAL raw console" | ||
270 | depends on HVC_OPAL | ||
271 | help | ||
272 | Select this to enable early debugging for the PowerNV platform | ||
273 | using a "raw" console | ||
274 | |||
275 | config PPC_EARLY_DEBUG_OPAL_HVSI | ||
276 | bool "OPAL hvsi console" | ||
277 | depends on HVC_OPAL | ||
278 | help | ||
279 | Select this to enable early debugging for the PowerNV platform | ||
280 | using an "hvsi" console | ||
281 | |||
261 | endchoice | 282 | endchoice |
262 | 283 | ||
284 | config PPC_EARLY_DEBUG_OPAL | ||
285 | def_bool y | ||
286 | depends on PPC_EARLY_DEBUG_OPAL_RAW || PPC_EARLY_DEBUG_OPAL_HVSI | ||
287 | |||
288 | |||
263 | config PPC_EARLY_DEBUG_HVSI_VTERMNO | 289 | config PPC_EARLY_DEBUG_HVSI_VTERMNO |
264 | hex "vterm number to use with early debug HVSI" | 290 | hex "vterm number to use with early debug HVSI" |
265 | depends on PPC_EARLY_DEBUG_LPAR_HVSI | 291 | depends on PPC_EARLY_DEBUG_LPAR_HVSI |
@@ -268,6 +294,18 @@ config PPC_EARLY_DEBUG_HVSI_VTERMNO | |||
268 | You probably want 0x30000000 for your first serial port and | 294 | You probably want 0x30000000 for your first serial port and |
269 | 0x30000001 for your second one | 295 | 0x30000001 for your second one |
270 | 296 | ||
297 | config PPC_EARLY_DEBUG_OPAL_VTERMNO | ||
298 | hex "vterm number to use with OPAL early debug" | ||
299 | depends on PPC_EARLY_DEBUG_OPAL | ||
300 | default "0" | ||
301 | help | ||
302 | This correspond to which /dev/hvcN you want to use for early | ||
303 | debug. | ||
304 | |||
305 | On OPAL v1 (takeover) this should always be 0 | ||
306 | On OPAL v2, this will be 0 for network console and 1 or 2 for | ||
307 | the machine built-in serial ports. | ||
308 | |||
271 | config PPC_EARLY_DEBUG_44x_PHYSLOW | 309 | config PPC_EARLY_DEBUG_44x_PHYSLOW |
272 | hex "Low 32 bits of early debug UART physical address" | 310 | hex "Low 32 bits of early debug UART physical address" |
273 | depends on PPC_EARLY_DEBUG_44x | 311 | depends on PPC_EARLY_DEBUG_44x |
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index c26200b40a47..72ee8c1fba48 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile | |||
@@ -58,7 +58,7 @@ $(addprefix $(obj)/,$(zlib) cuboot-c2k.o gunzip_util.o main.o prpmc2800.o): \ | |||
58 | libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c | 58 | libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c |
59 | libfdtheader := fdt.h libfdt.h libfdt_internal.h | 59 | libfdtheader := fdt.h libfdt.h libfdt_internal.h |
60 | 60 | ||
61 | $(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o): \ | 61 | $(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o epapr.o): \ |
62 | $(addprefix $(obj)/,$(libfdtheader)) | 62 | $(addprefix $(obj)/,$(libfdtheader)) |
63 | 63 | ||
64 | src-wlib := string.S crt0.S crtsavres.S stdio.c main.c \ | 64 | src-wlib := string.S crt0.S crtsavres.S stdio.c main.c \ |
@@ -171,6 +171,7 @@ quiet_cmd_wrap = WRAP $@ | |||
171 | $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) vmlinux | 171 | $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) vmlinux |
172 | 172 | ||
173 | image-$(CONFIG_PPC_PSERIES) += zImage.pseries | 173 | image-$(CONFIG_PPC_PSERIES) += zImage.pseries |
174 | image-$(CONFIG_PPC_POWERNV) += zImage.pseries | ||
174 | image-$(CONFIG_PPC_MAPLE) += zImage.maple | 175 | image-$(CONFIG_PPC_MAPLE) += zImage.maple |
175 | image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries | 176 | image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries |
176 | image-$(CONFIG_PPC_PS3) += dtbImage.ps3 | 177 | image-$(CONFIG_PPC_PS3) += dtbImage.ps3 |
diff --git a/arch/powerpc/boot/dts/digsy_mtc.dts b/arch/powerpc/boot/dts/digsy_mtc.dts index 27bd267d631c..a7511f2d844d 100644 --- a/arch/powerpc/boot/dts/digsy_mtc.dts +++ b/arch/powerpc/boot/dts/digsy_mtc.dts | |||
@@ -23,19 +23,26 @@ | |||
23 | 23 | ||
24 | soc5200@f0000000 { | 24 | soc5200@f0000000 { |
25 | timer@600 { // General Purpose Timer | 25 | timer@600 { // General Purpose Timer |
26 | #gpio-cells = <2>; | ||
26 | fsl,has-wdt; | 27 | fsl,has-wdt; |
28 | gpio-controller; | ||
27 | }; | 29 | }; |
28 | 30 | ||
29 | rtc@800 { | 31 | timer@610 { |
30 | status = "disabled"; | 32 | #gpio-cells = <2>; |
33 | gpio-controller; | ||
31 | }; | 34 | }; |
32 | 35 | ||
33 | can@900 { | 36 | rtc@800 { |
34 | status = "disabled"; | 37 | status = "disabled"; |
35 | }; | 38 | }; |
36 | 39 | ||
37 | can@980 { | 40 | spi@f00 { |
38 | status = "disabled"; | 41 | msp430@0 { |
42 | compatible = "spidev"; | ||
43 | spi-max-frequency = <32000>; | ||
44 | reg = <0>; | ||
45 | }; | ||
39 | }; | 46 | }; |
40 | 47 | ||
41 | psc@2000 { // PSC1 | 48 | psc@2000 { // PSC1 |
@@ -73,11 +80,16 @@ | |||
73 | }; | 80 | }; |
74 | 81 | ||
75 | i2c@3d00 { | 82 | i2c@3d00 { |
76 | rtc@50 { | 83 | eeprom@50 { |
77 | compatible = "at,24c08"; | 84 | compatible = "at,24c08"; |
78 | reg = <0x50>; | 85 | reg = <0x50>; |
79 | }; | 86 | }; |
80 | 87 | ||
88 | rtc@56 { | ||
89 | compatible = "mc,rv3029c2"; | ||
90 | reg = <0x56>; | ||
91 | }; | ||
92 | |||
81 | rtc@68 { | 93 | rtc@68 { |
82 | compatible = "dallas,ds1339"; | 94 | compatible = "dallas,ds1339"; |
83 | reg = <0x68>; | 95 | reg = <0x68>; |
@@ -90,11 +102,22 @@ | |||
90 | }; | 102 | }; |
91 | 103 | ||
92 | pci@f0000d00 { | 104 | pci@f0000d00 { |
93 | status = "disabled"; | 105 | interrupt-map-mask = <0xf800 0 0 7>; |
106 | interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3 | ||
107 | 0xc000 0 0 2 &mpc5200_pic 0 0 3 | ||
108 | 0xc000 0 0 3 &mpc5200_pic 0 0 3 | ||
109 | 0xc000 0 0 4 &mpc5200_pic 0 0 3>; | ||
110 | clock-frequency = <0>; // From boot loader | ||
111 | interrupts = <2 8 0 2 9 0 2 10 0>; | ||
112 | bus-range = <0 0>; | ||
113 | ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000 | ||
114 | 0x02000000 0 0x90000000 0x90000000 0 0x10000000 | ||
115 | 0x01000000 0 0x00000000 0xa0000000 0 0x01000000>; | ||
94 | }; | 116 | }; |
95 | 117 | ||
96 | localbus { | 118 | localbus { |
97 | ranges = <0 0 0xff000000 0x1000000>; | 119 | ranges = <0 0 0xff000000 0x1000000 |
120 | 4 0 0x60000000 0x0001000>; | ||
98 | 121 | ||
99 | // 16-bit flash device at LocalPlus Bus CS0 | 122 | // 16-bit flash device at LocalPlus Bus CS0 |
100 | flash@0,0 { | 123 | flash@0,0 { |
@@ -122,5 +145,25 @@ | |||
122 | reg = <0x00f00000 0x100000>; | 145 | reg = <0x00f00000 0x100000>; |
123 | }; | 146 | }; |
124 | }; | 147 | }; |
148 | |||
149 | can@4,0 { | ||
150 | compatible = "nxp,sja1000"; | ||
151 | reg = <4 0x000 0x80>; | ||
152 | nxp,external-clock-frequency = <24000000>; | ||
153 | interrupts = <1 2 3>; // Level-low | ||
154 | }; | ||
155 | |||
156 | can@4,100 { | ||
157 | compatible = "nxp,sja1000"; | ||
158 | reg = <4 0x100 0x80>; | ||
159 | nxp,external-clock-frequency = <24000000>; | ||
160 | interrupts = <1 2 3>; // Level-low | ||
161 | }; | ||
162 | |||
163 | serial@4,200 { | ||
164 | compatible = "nxp,sc28l92"; | ||
165 | reg = <4 0x200 0x10>; | ||
166 | interrupts = <1 3 3>; | ||
167 | }; | ||
125 | }; | 168 | }; |
126 | }; | 169 | }; |
diff --git a/arch/powerpc/boot/dts/gef_ppc9a.dts b/arch/powerpc/boot/dts/gef_ppc9a.dts index 83f4b79dff85..2266bbb303d0 100644 --- a/arch/powerpc/boot/dts/gef_ppc9a.dts +++ b/arch/powerpc/boot/dts/gef_ppc9a.dts | |||
@@ -269,14 +269,16 @@ | |||
269 | enet0: ethernet@24000 { | 269 | enet0: ethernet@24000 { |
270 | #address-cells = <1>; | 270 | #address-cells = <1>; |
271 | #size-cells = <1>; | 271 | #size-cells = <1>; |
272 | cell-index = <0>; | ||
272 | device_type = "network"; | 273 | device_type = "network"; |
273 | model = "eTSEC"; | 274 | model = "TSEC"; |
274 | compatible = "gianfar"; | 275 | compatible = "gianfar"; |
275 | reg = <0x24000 0x1000>; | 276 | reg = <0x24000 0x1000>; |
276 | ranges = <0x0 0x24000 0x1000>; | 277 | ranges = <0x0 0x24000 0x1000>; |
277 | local-mac-address = [ 00 00 00 00 00 00 ]; | 278 | local-mac-address = [ 00 00 00 00 00 00 ]; |
278 | interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>; | 279 | interrupts = <29 2 30 2 34 2>; |
279 | interrupt-parent = <&mpic>; | 280 | interrupt-parent = <&mpic>; |
281 | tbi-handle = <&tbi0>; | ||
280 | phy-handle = <&phy0>; | 282 | phy-handle = <&phy0>; |
281 | phy-connection-type = "gmii"; | 283 | phy-connection-type = "gmii"; |
282 | 284 | ||
@@ -290,25 +292,48 @@ | |||
290 | interrupt-parent = <&gef_pic>; | 292 | interrupt-parent = <&gef_pic>; |
291 | interrupts = <0x9 0x4>; | 293 | interrupts = <0x9 0x4>; |
292 | reg = <1>; | 294 | reg = <1>; |
295 | device_type = "ethernet-phy"; | ||
293 | }; | 296 | }; |
294 | phy2: ethernet-phy@2 { | 297 | phy2: ethernet-phy@2 { |
295 | interrupt-parent = <&gef_pic>; | 298 | interrupt-parent = <&gef_pic>; |
296 | interrupts = <0x8 0x4>; | 299 | interrupts = <0x8 0x4>; |
297 | reg = <3>; | 300 | reg = <3>; |
301 | device_type = "ethernet-phy"; | ||
302 | }; | ||
303 | tbi0: tbi-phy@11 { | ||
304 | reg = <0x11>; | ||
305 | device_type = "tbi-phy"; | ||
298 | }; | 306 | }; |
299 | }; | 307 | }; |
300 | }; | 308 | }; |
301 | 309 | ||
302 | enet1: ethernet@26000 { | 310 | enet1: ethernet@26000 { |
311 | #address-cells = <1>; | ||
312 | #size-cells = <1>; | ||
313 | cell-index = <2>; | ||
303 | device_type = "network"; | 314 | device_type = "network"; |
304 | model = "eTSEC"; | 315 | model = "TSEC"; |
305 | compatible = "gianfar"; | 316 | compatible = "gianfar"; |
306 | reg = <0x26000 0x1000>; | 317 | reg = <0x26000 0x1000>; |
318 | ranges = <0x0 0x26000 0x1000>; | ||
307 | local-mac-address = [ 00 00 00 00 00 00 ]; | 319 | local-mac-address = [ 00 00 00 00 00 00 ]; |
308 | interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>; | 320 | interrupts = <31 2 32 2 33 2>; |
309 | interrupt-parent = <&mpic>; | 321 | interrupt-parent = <&mpic>; |
322 | tbi-handle = <&tbi2>; | ||
310 | phy-handle = <&phy2>; | 323 | phy-handle = <&phy2>; |
311 | phy-connection-type = "gmii"; | 324 | phy-connection-type = "gmii"; |
325 | |||
326 | mdio@520 { | ||
327 | #address-cells = <1>; | ||
328 | #size-cells = <0>; | ||
329 | compatible = "fsl,gianfar-tbi"; | ||
330 | reg = <0x520 0x20>; | ||
331 | |||
332 | tbi2: tbi-phy@11 { | ||
333 | reg = <0x11>; | ||
334 | device_type = "tbi-phy"; | ||
335 | }; | ||
336 | }; | ||
312 | }; | 337 | }; |
313 | 338 | ||
314 | serial0: serial@4500 { | 339 | serial0: serial@4500 { |
diff --git a/arch/powerpc/boot/dts/gef_sbc310.dts b/arch/powerpc/boot/dts/gef_sbc310.dts index fc3a331dd392..429e87d9acef 100644 --- a/arch/powerpc/boot/dts/gef_sbc310.dts +++ b/arch/powerpc/boot/dts/gef_sbc310.dts | |||
@@ -267,14 +267,16 @@ | |||
267 | enet0: ethernet@24000 { | 267 | enet0: ethernet@24000 { |
268 | #address-cells = <1>; | 268 | #address-cells = <1>; |
269 | #size-cells = <1>; | 269 | #size-cells = <1>; |
270 | cell-index = <0>; | ||
270 | device_type = "network"; | 271 | device_type = "network"; |
271 | model = "eTSEC"; | 272 | model = "TSEC"; |
272 | compatible = "gianfar"; | 273 | compatible = "gianfar"; |
273 | reg = <0x24000 0x1000>; | 274 | reg = <0x24000 0x1000>; |
274 | ranges = <0x0 0x24000 0x1000>; | 275 | ranges = <0x0 0x24000 0x1000>; |
275 | local-mac-address = [ 00 00 00 00 00 00 ]; | 276 | local-mac-address = [ 00 00 00 00 00 00 ]; |
276 | interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>; | 277 | interrupts = <29 2 30 2 34 2>; |
277 | interrupt-parent = <&mpic>; | 278 | interrupt-parent = <&mpic>; |
279 | tbi-handle = <&tbi0>; | ||
278 | phy-handle = <&phy0>; | 280 | phy-handle = <&phy0>; |
279 | phy-connection-type = "gmii"; | 281 | phy-connection-type = "gmii"; |
280 | 282 | ||
@@ -288,25 +290,48 @@ | |||
288 | interrupt-parent = <&gef_pic>; | 290 | interrupt-parent = <&gef_pic>; |
289 | interrupts = <0x9 0x4>; | 291 | interrupts = <0x9 0x4>; |
290 | reg = <1>; | 292 | reg = <1>; |
293 | device_type = "ethernet-phy"; | ||
291 | }; | 294 | }; |
292 | phy2: ethernet-phy@2 { | 295 | phy2: ethernet-phy@2 { |
293 | interrupt-parent = <&gef_pic>; | 296 | interrupt-parent = <&gef_pic>; |
294 | interrupts = <0x8 0x4>; | 297 | interrupts = <0x8 0x4>; |
295 | reg = <3>; | 298 | reg = <3>; |
299 | device_type = "ethernet-phy"; | ||
300 | }; | ||
301 | tbi0: tbi-phy@11 { | ||
302 | reg = <0x11>; | ||
303 | device_type = "tbi-phy"; | ||
296 | }; | 304 | }; |
297 | }; | 305 | }; |
298 | }; | 306 | }; |
299 | 307 | ||
300 | enet1: ethernet@26000 { | 308 | enet1: ethernet@26000 { |
309 | #address-cells = <1>; | ||
310 | #size-cells = <1>; | ||
311 | cell-index = <2>; | ||
301 | device_type = "network"; | 312 | device_type = "network"; |
302 | model = "eTSEC"; | 313 | model = "TSEC"; |
303 | compatible = "gianfar"; | 314 | compatible = "gianfar"; |
304 | reg = <0x26000 0x1000>; | 315 | reg = <0x26000 0x1000>; |
316 | ranges = <0x0 0x26000 0x1000>; | ||
305 | local-mac-address = [ 00 00 00 00 00 00 ]; | 317 | local-mac-address = [ 00 00 00 00 00 00 ]; |
306 | interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>; | 318 | interrupts = <31 2 32 2 33 2>; |
307 | interrupt-parent = <&mpic>; | 319 | interrupt-parent = <&mpic>; |
320 | tbi-handle = <&tbi2>; | ||
308 | phy-handle = <&phy2>; | 321 | phy-handle = <&phy2>; |
309 | phy-connection-type = "gmii"; | 322 | phy-connection-type = "gmii"; |
323 | |||
324 | mdio@520 { | ||
325 | #address-cells = <1>; | ||
326 | #size-cells = <0>; | ||
327 | compatible = "fsl,gianfar-tbi"; | ||
328 | reg = <0x520 0x20>; | ||
329 | |||
330 | tbi2: tbi-phy@11 { | ||
331 | reg = <0x11>; | ||
332 | device_type = "tbi-phy"; | ||
333 | }; | ||
334 | }; | ||
310 | }; | 335 | }; |
311 | 336 | ||
312 | serial0: serial@4500 { | 337 | serial0: serial@4500 { |
diff --git a/arch/powerpc/boot/dts/gef_sbc610.dts b/arch/powerpc/boot/dts/gef_sbc610.dts index c0671cc98125..d81201ac2cad 100644 --- a/arch/powerpc/boot/dts/gef_sbc610.dts +++ b/arch/powerpc/boot/dts/gef_sbc610.dts | |||
@@ -267,14 +267,16 @@ | |||
267 | enet0: ethernet@24000 { | 267 | enet0: ethernet@24000 { |
268 | #address-cells = <1>; | 268 | #address-cells = <1>; |
269 | #size-cells = <1>; | 269 | #size-cells = <1>; |
270 | cell-index = <0>; | ||
270 | device_type = "network"; | 271 | device_type = "network"; |
271 | model = "eTSEC"; | 272 | model = "TSEC"; |
272 | compatible = "gianfar"; | 273 | compatible = "gianfar"; |
273 | reg = <0x24000 0x1000>; | 274 | reg = <0x24000 0x1000>; |
274 | ranges = <0x0 0x24000 0x1000>; | 275 | ranges = <0x0 0x24000 0x1000>; |
275 | local-mac-address = [ 00 00 00 00 00 00 ]; | 276 | local-mac-address = [ 00 00 00 00 00 00 ]; |
276 | interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>; | 277 | interrupts = <29 2 30 2 34 2>; |
277 | interrupt-parent = <&mpic>; | 278 | interrupt-parent = <&mpic>; |
279 | tbi-handle = <&tbi0>; | ||
278 | phy-handle = <&phy0>; | 280 | phy-handle = <&phy0>; |
279 | phy-connection-type = "gmii"; | 281 | phy-connection-type = "gmii"; |
280 | 282 | ||
@@ -288,25 +290,48 @@ | |||
288 | interrupt-parent = <&gef_pic>; | 290 | interrupt-parent = <&gef_pic>; |
289 | interrupts = <0x9 0x4>; | 291 | interrupts = <0x9 0x4>; |
290 | reg = <1>; | 292 | reg = <1>; |
293 | device_type = "ethernet-phy"; | ||
291 | }; | 294 | }; |
292 | phy2: ethernet-phy@2 { | 295 | phy2: ethernet-phy@2 { |
293 | interrupt-parent = <&gef_pic>; | 296 | interrupt-parent = <&gef_pic>; |
294 | interrupts = <0x8 0x4>; | 297 | interrupts = <0x8 0x4>; |
295 | reg = <3>; | 298 | reg = <3>; |
299 | device_type = "ethernet-phy"; | ||
300 | }; | ||
301 | tbi0: tbi-phy@11 { | ||
302 | reg = <0x11>; | ||
303 | device_type = "tbi-phy"; | ||
296 | }; | 304 | }; |
297 | }; | 305 | }; |
298 | }; | 306 | }; |
299 | 307 | ||
300 | enet1: ethernet@26000 { | 308 | enet1: ethernet@26000 { |
309 | #address-cells = <1>; | ||
310 | #size-cells = <1>; | ||
311 | cell-index = <2>; | ||
301 | device_type = "network"; | 312 | device_type = "network"; |
302 | model = "eTSEC"; | 313 | model = "TSEC"; |
303 | compatible = "gianfar"; | 314 | compatible = "gianfar"; |
304 | reg = <0x26000 0x1000>; | 315 | reg = <0x26000 0x1000>; |
316 | ranges = <0x0 0x26000 0x1000>; | ||
305 | local-mac-address = [ 00 00 00 00 00 00 ]; | 317 | local-mac-address = [ 00 00 00 00 00 00 ]; |
306 | interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>; | 318 | interrupts = <31 2 32 2 33 2>; |
307 | interrupt-parent = <&mpic>; | 319 | interrupt-parent = <&mpic>; |
320 | tbi-handle = <&tbi2>; | ||
308 | phy-handle = <&phy2>; | 321 | phy-handle = <&phy2>; |
309 | phy-connection-type = "gmii"; | 322 | phy-connection-type = "gmii"; |
323 | |||
324 | mdio@520 { | ||
325 | #address-cells = <1>; | ||
326 | #size-cells = <0>; | ||
327 | compatible = "fsl,gianfar-tbi"; | ||
328 | reg = <0x520 0x20>; | ||
329 | |||
330 | tbi2: tbi-phy@11 { | ||
331 | reg = <0x11>; | ||
332 | device_type = "tbi-phy"; | ||
333 | }; | ||
334 | }; | ||
310 | }; | 335 | }; |
311 | 336 | ||
312 | serial0: serial@4500 { | 337 | serial0: serial@4500 { |
diff --git a/arch/powerpc/boot/dts/hcu4.dts b/arch/powerpc/boot/dts/hcu4.dts deleted file mode 100644 index 7988598da4c9..000000000000 --- a/arch/powerpc/boot/dts/hcu4.dts +++ /dev/null | |||
@@ -1,168 +0,0 @@ | |||
1 | /* | ||
2 | * Device Tree Source for Netstal Maschinen HCU4 | ||
3 | * based on the IBM Walnut | ||
4 | * | ||
5 | * Copyright 2008 | ||
6 | * Niklaus Giger <niklaus.giger@member.fsf.org> | ||
7 | * | ||
8 | * Copyright 2007 IBM Corp. | ||
9 | * Josh Boyer <jwboyer@linux.vnet.ibm.com> | ||
10 | * | ||
11 | * This file is licensed under the terms of the GNU General Public | ||
12 | * License version 2. This program is licensed "as is" without | ||
13 | * any warranty of any kind, whether express or implied. | ||
14 | */ | ||
15 | |||
16 | /dts-v1/; | ||
17 | |||
18 | / { | ||
19 | #address-cells = <0x1>; | ||
20 | #size-cells = <0x1>; | ||
21 | model = "netstal,hcu4"; | ||
22 | compatible = "netstal,hcu4"; | ||
23 | dcr-parent = <0x1>; | ||
24 | |||
25 | aliases { | ||
26 | ethernet0 = "/plb/opb/ethernet@ef600800"; | ||
27 | serial0 = "/plb/opb/serial@ef600300"; | ||
28 | }; | ||
29 | |||
30 | cpus { | ||
31 | #address-cells = <0x1>; | ||
32 | #size-cells = <0x0>; | ||
33 | |||
34 | cpu@0 { | ||
35 | device_type = "cpu"; | ||
36 | model = "PowerPC,405GPr"; | ||
37 | reg = <0x0>; | ||
38 | clock-frequency = <0>; /* Filled in by U-Boot */ | ||
39 | timebase-frequency = <0x0>; /* Filled in by U-Boot */ | ||
40 | i-cache-line-size = <0x20>; | ||
41 | d-cache-line-size = <0x20>; | ||
42 | i-cache-size = <0x4000>; | ||
43 | d-cache-size = <0x4000>; | ||
44 | dcr-controller; | ||
45 | dcr-access-method = "native"; | ||
46 | linux,phandle = <0x1>; | ||
47 | }; | ||
48 | }; | ||
49 | |||
50 | memory { | ||
51 | device_type = "memory"; | ||
52 | reg = <0x0 0x0>; /* Filled in by U-Boot */ | ||
53 | }; | ||
54 | |||
55 | UIC0: interrupt-controller { | ||
56 | compatible = "ibm,uic"; | ||
57 | interrupt-controller; | ||
58 | cell-index = <0x0>; | ||
59 | dcr-reg = <0xc0 0x9>; | ||
60 | #address-cells = <0x0>; | ||
61 | #size-cells = <0x0>; | ||
62 | #interrupt-cells = <0x2>; | ||
63 | linux,phandle = <0x2>; | ||
64 | }; | ||
65 | |||
66 | plb { | ||
67 | compatible = "ibm,plb3"; | ||
68 | #address-cells = <0x1>; | ||
69 | #size-cells = <0x1>; | ||
70 | ranges; | ||
71 | clock-frequency = <0x0>; /* Filled in by U-Boot */ | ||
72 | |||
73 | SDRAM0: memory-controller { | ||
74 | compatible = "ibm,sdram-405gp"; | ||
75 | dcr-reg = <0x10 0x2>; | ||
76 | }; | ||
77 | |||
78 | MAL: mcmal { | ||
79 | compatible = "ibm,mcmal-405gp", "ibm,mcmal"; | ||
80 | dcr-reg = <0x180 0x62>; | ||
81 | num-tx-chans = <0x1>; | ||
82 | num-rx-chans = <0x1>; | ||
83 | interrupt-parent = <0x2>; | ||
84 | interrupts = <0xb 0x4 0xc 0x4 0xa 0x4 0xd 0x4 0xe 0x4>; | ||
85 | linux,phandle = <0x3>; | ||
86 | }; | ||
87 | |||
88 | POB0: opb { | ||
89 | compatible = "ibm,opb-405gp", "ibm,opb"; | ||
90 | #address-cells = <0x1>; | ||
91 | #size-cells = <0x1>; | ||
92 | ranges = <0xef600000 0xef600000 0xa00000>; | ||
93 | dcr-reg = <0xa0 0x5>; | ||
94 | clock-frequency = <0x0>; /* Filled in by U-Boot */ | ||
95 | |||
96 | UART0: serial@ef600300 { | ||
97 | device_type = "serial"; | ||
98 | compatible = "ns16550"; | ||
99 | reg = <0xef600300 0x8>; | ||
100 | virtual-reg = <0xef600300>; | ||
101 | clock-frequency = <0x0>;/* Filled in by U-Boot */ | ||
102 | current-speed = <0>; /* Filled in by U-Boot */ | ||
103 | interrupt-parent = <0x2>; | ||
104 | interrupts = <0x0 0x4>; | ||
105 | }; | ||
106 | |||
107 | IIC: i2c@ef600500 { | ||
108 | compatible = "ibm,iic-405gp", "ibm,iic"; | ||
109 | reg = <0xef600500 0x11>; | ||
110 | interrupt-parent = <0x2>; | ||
111 | interrupts = <0x2 0x4>; | ||
112 | }; | ||
113 | |||
114 | GPIO: gpio@ef600700 { | ||
115 | compatible = "ibm,gpio-405gp"; | ||
116 | reg = <0xef600700 0x20>; | ||
117 | }; | ||
118 | |||
119 | EMAC: ethernet@ef600800 { | ||
120 | device_type = "network"; | ||
121 | compatible = "ibm,emac-405gp", "ibm,emac"; | ||
122 | interrupt-parent = <0x2>; | ||
123 | interrupts = <0xf 0x4 0x9 0x4>; | ||
124 | local-mac-address = [00 00 00 00 00 00]; | ||
125 | reg = <0xef600800 0x70>; | ||
126 | mal-device = <0x3>; | ||
127 | mal-tx-channel = <0x0>; | ||
128 | mal-rx-channel = <0x0>; | ||
129 | cell-index = <0x0>; | ||
130 | max-frame-size = <0x5dc>; | ||
131 | rx-fifo-size = <0x1000>; | ||
132 | tx-fifo-size = <0x800>; | ||
133 | phy-mode = "rmii"; | ||
134 | phy-map = <0x1>; | ||
135 | }; | ||
136 | }; | ||
137 | |||
138 | EBC0: ebc { | ||
139 | compatible = "ibm,ebc-405gp", "ibm,ebc"; | ||
140 | dcr-reg = <0x12 0x2>; | ||
141 | #address-cells = <0x2>; | ||
142 | #size-cells = <0x1>; | ||
143 | clock-frequency = <0x0>; /* Filled in by U-Boot */ | ||
144 | |||
145 | sram@0,0 { | ||
146 | reg = <0x0 0x0 0x80000>; | ||
147 | }; | ||
148 | |||
149 | flash@0,80000 { | ||
150 | compatible = "jedec-flash"; | ||
151 | bank-width = <0x1>; | ||
152 | reg = <0x0 0x80000 0x80000>; | ||
153 | #address-cells = <0x1>; | ||
154 | #size-cells = <0x1>; | ||
155 | |||
156 | partition@0 { | ||
157 | label = "OpenBIOS"; | ||
158 | reg = <0x0 0x80000>; | ||
159 | read-only; | ||
160 | }; | ||
161 | }; | ||
162 | }; | ||
163 | }; | ||
164 | |||
165 | chosen { | ||
166 | linux,stdout-path = "/plb/opb/serial@ef600300"; | ||
167 | }; | ||
168 | }; | ||
diff --git a/arch/powerpc/boot/dts/ksi8560.dts b/arch/powerpc/boot/dts/ksi8560.dts index bdb7fc0fa332..296c572ea605 100644 --- a/arch/powerpc/boot/dts/ksi8560.dts +++ b/arch/powerpc/boot/dts/ksi8560.dts | |||
@@ -306,7 +306,7 @@ | |||
306 | localbus@fdf05000 { | 306 | localbus@fdf05000 { |
307 | #address-cells = <2>; | 307 | #address-cells = <2>; |
308 | #size-cells = <1>; | 308 | #size-cells = <1>; |
309 | compatible = "fsl,mpc8560-localbus"; | 309 | compatible = "fsl,mpc8560-localbus", "simple-bus"; |
310 | reg = <0xfdf05000 0x68>; | 310 | reg = <0xfdf05000 0x68>; |
311 | 311 | ||
312 | ranges = <0x0 0x0 0xe0000000 0x00800000 | 312 | ranges = <0x0 0x0 0xe0000000 0x00800000 |
diff --git a/arch/powerpc/boot/dts/mgcoge.dts b/arch/powerpc/boot/dts/mgcoge.dts index 1360d2f69024..ededaf5ac015 100644 --- a/arch/powerpc/boot/dts/mgcoge.dts +++ b/arch/powerpc/boot/dts/mgcoge.dts | |||
@@ -213,6 +213,15 @@ | |||
213 | linux,network-index = <2>; | 213 | linux,network-index = <2>; |
214 | fsl,cpm-command = <0x16200300>; | 214 | fsl,cpm-command = <0x16200300>; |
215 | }; | 215 | }; |
216 | |||
217 | usb@11b60 { | ||
218 | compatible = "fsl,mpc8272-cpm-usb"; | ||
219 | mode = "peripheral"; | ||
220 | reg = <0x11b60 0x40 0x8b00 0x100>; | ||
221 | interrupts = <11 8>; | ||
222 | interrupt-parent = <&PIC>; | ||
223 | usb-clock = <5>; | ||
224 | }; | ||
216 | }; | 225 | }; |
217 | 226 | ||
218 | cpm2_pio_c: gpio-controller@10d40 { | 227 | cpm2_pio_c: gpio-controller@10d40 { |
diff --git a/arch/powerpc/boot/dts/mpc5200b.dtsi b/arch/powerpc/boot/dts/mpc5200b.dtsi index bc27548e895d..7ab286ab5300 100644 --- a/arch/powerpc/boot/dts/mpc5200b.dtsi +++ b/arch/powerpc/boot/dts/mpc5200b.dtsi | |||
@@ -147,6 +147,8 @@ | |||
147 | }; | 147 | }; |
148 | 148 | ||
149 | spi@f00 { | 149 | spi@f00 { |
150 | #address-cells = <1>; | ||
151 | #size-cells = <0>; | ||
150 | compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; | 152 | compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; |
151 | reg = <0xf00 0x20>; | 153 | reg = <0xf00 0x20>; |
152 | interrupts = <2 13 0 2 14 0>; | 154 | interrupts = <2 13 0 2 14 0>; |
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index b53d1df11e2d..505dc842d808 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts | |||
@@ -390,7 +390,8 @@ | |||
390 | #address-cells = <2>; | 390 | #address-cells = <2>; |
391 | #size-cells = <1>; | 391 | #size-cells = <1>; |
392 | compatible = "fsl,mpc8349e-localbus", | 392 | compatible = "fsl,mpc8349e-localbus", |
393 | "fsl,pq2pro-localbus"; | 393 | "fsl,pq2pro-localbus", |
394 | "simple-bus"; | ||
394 | reg = <0xe0005000 0xd8>; | 395 | reg = <0xe0005000 0xd8>; |
395 | ranges = <0x0 0x0 0xfe000000 0x1000000 /* flash */ | 396 | ranges = <0x0 0x0 0xfe000000 0x1000000 /* flash */ |
396 | 0x1 0x0 0xf8000000 0x20000 /* VSC 7385 */ | 397 | 0x1 0x0 0xf8000000 0x20000 /* VSC 7385 */ |
diff --git a/arch/powerpc/boot/dts/p1022ds.dts b/arch/powerpc/boot/dts/p1022ds.dts index 1be9743ab5e0..b9b8719a6204 100644 --- a/arch/powerpc/boot/dts/p1022ds.dts +++ b/arch/powerpc/boot/dts/p1022ds.dts | |||
@@ -150,7 +150,7 @@ | |||
150 | }; | 150 | }; |
151 | 151 | ||
152 | board-control@3,0 { | 152 | board-control@3,0 { |
153 | compatible = "fsl,p1022ds-pixis"; | 153 | compatible = "fsl,p1022ds-fpga", "fsl,fpga-ngpixis"; |
154 | reg = <3 0 0x30>; | 154 | reg = <3 0 0x30>; |
155 | interrupt-parent = <&mpic>; | 155 | interrupt-parent = <&mpic>; |
156 | /* | 156 | /* |
diff --git a/arch/powerpc/boot/dts/p2020ds.dts b/arch/powerpc/boot/dts/p2020ds.dts index dae403100f2f..66f03d6477b2 100644 --- a/arch/powerpc/boot/dts/p2020ds.dts +++ b/arch/powerpc/boot/dts/p2020ds.dts | |||
@@ -118,6 +118,11 @@ | |||
118 | }; | 118 | }; |
119 | }; | 119 | }; |
120 | 120 | ||
121 | board-control@3,0 { | ||
122 | compatible = "fsl,p2020ds-fpga", "fsl,fpga-ngpixis"; | ||
123 | reg = <0x3 0x0 0x30>; | ||
124 | }; | ||
125 | |||
121 | nand@4,0 { | 126 | nand@4,0 { |
122 | compatible = "fsl,elbc-fcm-nand"; | 127 | compatible = "fsl,elbc-fcm-nand"; |
123 | reg = <0x4 0x0 0x40000>; | 128 | reg = <0x4 0x0 0x40000>; |
diff --git a/arch/powerpc/boot/dts/p2040rdb.dts b/arch/powerpc/boot/dts/p2041rdb.dts index 7d84e391c632..79b6895027c0 100644 --- a/arch/powerpc/boot/dts/p2040rdb.dts +++ b/arch/powerpc/boot/dts/p2041rdb.dts | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * P2040RDB Device Tree Source | 2 | * P2041RDB Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2011 Freescale Semiconductor Inc. | 4 | * Copyright 2011 Freescale Semiconductor Inc. |
5 | * | 5 | * |
@@ -32,11 +32,11 @@ | |||
32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 | */ | 33 | */ |
34 | 34 | ||
35 | /include/ "p2040si.dtsi" | 35 | /include/ "p2041si.dtsi" |
36 | 36 | ||
37 | / { | 37 | / { |
38 | model = "fsl,P2040RDB"; | 38 | model = "fsl,P2041RDB"; |
39 | compatible = "fsl,P2040RDB"; | 39 | compatible = "fsl,P2041RDB"; |
40 | #address-cells = <2>; | 40 | #address-cells = <2>; |
41 | #size-cells = <2>; | 41 | #size-cells = <2>; |
42 | interrupt-parent = <&mpic>; | 42 | interrupt-parent = <&mpic>; |
@@ -45,6 +45,10 @@ | |||
45 | device_type = "memory"; | 45 | device_type = "memory"; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | dcsr: dcsr@f00000000 { | ||
49 | ranges = <0x00000000 0xf 0x00000000 0x01008000>; | ||
50 | }; | ||
51 | |||
48 | soc: soc@ffe000000 { | 52 | soc: soc@ffe000000 { |
49 | spi@110000 { | 53 | spi@110000 { |
50 | flash@0 { | 54 | flash@0 { |
@@ -97,13 +101,8 @@ | |||
97 | }; | 101 | }; |
98 | }; | 102 | }; |
99 | 103 | ||
100 | usb0: usb@210000 { | ||
101 | phy_type = "utmi"; | ||
102 | }; | ||
103 | |||
104 | usb1: usb@211000 { | 104 | usb1: usb@211000 { |
105 | dr_mode = "host"; | 105 | dr_mode = "host"; |
106 | phy_type = "utmi"; | ||
107 | }; | 106 | }; |
108 | }; | 107 | }; |
109 | 108 | ||
diff --git a/arch/powerpc/boot/dts/p2040si.dtsi b/arch/powerpc/boot/dts/p2041si.dtsi index 5fdbb24c0763..f7492edd0dfd 100644 --- a/arch/powerpc/boot/dts/p2040si.dtsi +++ b/arch/powerpc/boot/dts/p2041si.dtsi | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * P2040 Silicon Device Tree Source | 2 | * P2041 Silicon Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2011 Freescale Semiconductor Inc. | 4 | * Copyright 2011 Freescale Semiconductor Inc. |
5 | * | 5 | * |
@@ -35,13 +35,14 @@ | |||
35 | /dts-v1/; | 35 | /dts-v1/; |
36 | 36 | ||
37 | / { | 37 | / { |
38 | compatible = "fsl,P2040"; | 38 | compatible = "fsl,P2041"; |
39 | #address-cells = <2>; | 39 | #address-cells = <2>; |
40 | #size-cells = <2>; | 40 | #size-cells = <2>; |
41 | interrupt-parent = <&mpic>; | 41 | interrupt-parent = <&mpic>; |
42 | 42 | ||
43 | aliases { | 43 | aliases { |
44 | ccsr = &soc; | 44 | ccsr = &soc; |
45 | dcsr = &dcsr; | ||
45 | 46 | ||
46 | serial0 = &serial0; | 47 | serial0 = &serial0; |
47 | serial1 = &serial1; | 48 | serial1 = &serial1; |
@@ -109,6 +110,74 @@ | |||
109 | }; | 110 | }; |
110 | }; | 111 | }; |
111 | 112 | ||
113 | dcsr: dcsr@f00000000 { | ||
114 | #address-cells = <1>; | ||
115 | #size-cells = <1>; | ||
116 | compatible = "fsl,dcsr", "simple-bus"; | ||
117 | |||
118 | dcsr-epu@0 { | ||
119 | compatible = "fsl,dcsr-epu"; | ||
120 | interrupts = <52 2 0 0 | ||
121 | 84 2 0 0 | ||
122 | 85 2 0 0>; | ||
123 | interrupt-parent = <&mpic>; | ||
124 | reg = <0x0 0x1000>; | ||
125 | }; | ||
126 | dcsr-npc { | ||
127 | compatible = "fsl,dcsr-npc"; | ||
128 | reg = <0x1000 0x1000 0x1000000 0x8000>; | ||
129 | }; | ||
130 | dcsr-nxc@2000 { | ||
131 | compatible = "fsl,dcsr-nxc"; | ||
132 | reg = <0x2000 0x1000>; | ||
133 | }; | ||
134 | dcsr-corenet { | ||
135 | compatible = "fsl,dcsr-corenet"; | ||
136 | reg = <0x8000 0x1000 0xB0000 0x1000>; | ||
137 | }; | ||
138 | dcsr-dpaa@9000 { | ||
139 | compatible = "fsl,p2041-dcsr-dpaa", "fsl,dcsr-dpaa"; | ||
140 | reg = <0x9000 0x1000>; | ||
141 | }; | ||
142 | dcsr-ocn@11000 { | ||
143 | compatible = "fsl,p2041-dcsr-ocn", "fsl,dcsr-ocn"; | ||
144 | reg = <0x11000 0x1000>; | ||
145 | }; | ||
146 | dcsr-ddr@12000 { | ||
147 | compatible = "fsl,dcsr-ddr"; | ||
148 | dev-handle = <&ddr>; | ||
149 | reg = <0x12000 0x1000>; | ||
150 | }; | ||
151 | dcsr-nal@18000 { | ||
152 | compatible = "fsl,p2041-dcsr-nal", "fsl,dcsr-nal"; | ||
153 | reg = <0x18000 0x1000>; | ||
154 | }; | ||
155 | dcsr-rcpm@22000 { | ||
156 | compatible = "fsl,p2041-dcsr-rcpm", "fsl,dcsr-rcpm"; | ||
157 | reg = <0x22000 0x1000>; | ||
158 | }; | ||
159 | dcsr-cpu-sb-proxy@40000 { | ||
160 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
161 | cpu-handle = <&cpu0>; | ||
162 | reg = <0x40000 0x1000>; | ||
163 | }; | ||
164 | dcsr-cpu-sb-proxy@41000 { | ||
165 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
166 | cpu-handle = <&cpu1>; | ||
167 | reg = <0x41000 0x1000>; | ||
168 | }; | ||
169 | dcsr-cpu-sb-proxy@42000 { | ||
170 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
171 | cpu-handle = <&cpu2>; | ||
172 | reg = <0x42000 0x1000>; | ||
173 | }; | ||
174 | dcsr-cpu-sb-proxy@43000 { | ||
175 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
176 | cpu-handle = <&cpu3>; | ||
177 | reg = <0x43000 0x1000>; | ||
178 | }; | ||
179 | }; | ||
180 | |||
112 | soc: soc@ffe000000 { | 181 | soc: soc@ffe000000 { |
113 | #address-cells = <1>; | 182 | #address-cells = <1>; |
114 | #size-cells = <1>; | 183 | #size-cells = <1>; |
@@ -128,14 +197,14 @@ | |||
128 | fsl,num-laws = <32>; | 197 | fsl,num-laws = <32>; |
129 | }; | 198 | }; |
130 | 199 | ||
131 | memory-controller@8000 { | 200 | ddr: memory-controller@8000 { |
132 | compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; | 201 | compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; |
133 | reg = <0x8000 0x1000>; | 202 | reg = <0x8000 0x1000>; |
134 | interrupts = <16 2 1 23>; | 203 | interrupts = <16 2 1 23>; |
135 | }; | 204 | }; |
136 | 205 | ||
137 | cpc: l3-cache-controller@10000 { | 206 | cpc: l3-cache-controller@10000 { |
138 | compatible = "fsl,p2040-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache"; | 207 | compatible = "fsl,p2041-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache"; |
139 | reg = <0x10000 0x1000>; | 208 | reg = <0x10000 0x1000>; |
140 | interrupts = <16 2 1 27>; | 209 | interrupts = <16 2 1 27>; |
141 | }; | 210 | }; |
@@ -226,7 +295,7 @@ | |||
226 | }; | 295 | }; |
227 | 296 | ||
228 | clockgen: global-utilities@e1000 { | 297 | clockgen: global-utilities@e1000 { |
229 | compatible = "fsl,p2040-clockgen", "fsl,qoriq-clockgen-1.0"; | 298 | compatible = "fsl,p2041-clockgen", "fsl,qoriq-clockgen-1.0"; |
230 | reg = <0xe1000 0x1000>; | 299 | reg = <0xe1000 0x1000>; |
231 | clock-frequency = <0>; | 300 | clock-frequency = <0>; |
232 | }; | 301 | }; |
@@ -238,45 +307,45 @@ | |||
238 | }; | 307 | }; |
239 | 308 | ||
240 | sfp: sfp@e8000 { | 309 | sfp: sfp@e8000 { |
241 | compatible = "fsl,p2040-sfp", "fsl,qoriq-sfp-1.0"; | 310 | compatible = "fsl,p2041-sfp", "fsl,qoriq-sfp-1.0"; |
242 | reg = <0xe8000 0x1000>; | 311 | reg = <0xe8000 0x1000>; |
243 | }; | 312 | }; |
244 | 313 | ||
245 | serdes: serdes@ea000 { | 314 | serdes: serdes@ea000 { |
246 | compatible = "fsl,p2040-serdes"; | 315 | compatible = "fsl,p2041-serdes"; |
247 | reg = <0xea000 0x1000>; | 316 | reg = <0xea000 0x1000>; |
248 | }; | 317 | }; |
249 | 318 | ||
250 | dma0: dma@100300 { | 319 | dma0: dma@100300 { |
251 | #address-cells = <1>; | 320 | #address-cells = <1>; |
252 | #size-cells = <1>; | 321 | #size-cells = <1>; |
253 | compatible = "fsl,p2040-dma", "fsl,eloplus-dma"; | 322 | compatible = "fsl,p2041-dma", "fsl,eloplus-dma"; |
254 | reg = <0x100300 0x4>; | 323 | reg = <0x100300 0x4>; |
255 | ranges = <0x0 0x100100 0x200>; | 324 | ranges = <0x0 0x100100 0x200>; |
256 | cell-index = <0>; | 325 | cell-index = <0>; |
257 | dma-channel@0 { | 326 | dma-channel@0 { |
258 | compatible = "fsl,p2040-dma-channel", | 327 | compatible = "fsl,p2041-dma-channel", |
259 | "fsl,eloplus-dma-channel"; | 328 | "fsl,eloplus-dma-channel"; |
260 | reg = <0x0 0x80>; | 329 | reg = <0x0 0x80>; |
261 | cell-index = <0>; | 330 | cell-index = <0>; |
262 | interrupts = <28 2 0 0>; | 331 | interrupts = <28 2 0 0>; |
263 | }; | 332 | }; |
264 | dma-channel@80 { | 333 | dma-channel@80 { |
265 | compatible = "fsl,p2040-dma-channel", | 334 | compatible = "fsl,p2041-dma-channel", |
266 | "fsl,eloplus-dma-channel"; | 335 | "fsl,eloplus-dma-channel"; |
267 | reg = <0x80 0x80>; | 336 | reg = <0x80 0x80>; |
268 | cell-index = <1>; | 337 | cell-index = <1>; |
269 | interrupts = <29 2 0 0>; | 338 | interrupts = <29 2 0 0>; |
270 | }; | 339 | }; |
271 | dma-channel@100 { | 340 | dma-channel@100 { |
272 | compatible = "fsl,p2040-dma-channel", | 341 | compatible = "fsl,p2041-dma-channel", |
273 | "fsl,eloplus-dma-channel"; | 342 | "fsl,eloplus-dma-channel"; |
274 | reg = <0x100 0x80>; | 343 | reg = <0x100 0x80>; |
275 | cell-index = <2>; | 344 | cell-index = <2>; |
276 | interrupts = <30 2 0 0>; | 345 | interrupts = <30 2 0 0>; |
277 | }; | 346 | }; |
278 | dma-channel@180 { | 347 | dma-channel@180 { |
279 | compatible = "fsl,p2040-dma-channel", | 348 | compatible = "fsl,p2041-dma-channel", |
280 | "fsl,eloplus-dma-channel"; | 349 | "fsl,eloplus-dma-channel"; |
281 | reg = <0x180 0x80>; | 350 | reg = <0x180 0x80>; |
282 | cell-index = <3>; | 351 | cell-index = <3>; |
@@ -287,33 +356,33 @@ | |||
287 | dma1: dma@101300 { | 356 | dma1: dma@101300 { |
288 | #address-cells = <1>; | 357 | #address-cells = <1>; |
289 | #size-cells = <1>; | 358 | #size-cells = <1>; |
290 | compatible = "fsl,p2040-dma", "fsl,eloplus-dma"; | 359 | compatible = "fsl,p2041-dma", "fsl,eloplus-dma"; |
291 | reg = <0x101300 0x4>; | 360 | reg = <0x101300 0x4>; |
292 | ranges = <0x0 0x101100 0x200>; | 361 | ranges = <0x0 0x101100 0x200>; |
293 | cell-index = <1>; | 362 | cell-index = <1>; |
294 | dma-channel@0 { | 363 | dma-channel@0 { |
295 | compatible = "fsl,p2040-dma-channel", | 364 | compatible = "fsl,p2041-dma-channel", |
296 | "fsl,eloplus-dma-channel"; | 365 | "fsl,eloplus-dma-channel"; |
297 | reg = <0x0 0x80>; | 366 | reg = <0x0 0x80>; |
298 | cell-index = <0>; | 367 | cell-index = <0>; |
299 | interrupts = <32 2 0 0>; | 368 | interrupts = <32 2 0 0>; |
300 | }; | 369 | }; |
301 | dma-channel@80 { | 370 | dma-channel@80 { |
302 | compatible = "fsl,p2040-dma-channel", | 371 | compatible = "fsl,p2041-dma-channel", |
303 | "fsl,eloplus-dma-channel"; | 372 | "fsl,eloplus-dma-channel"; |
304 | reg = <0x80 0x80>; | 373 | reg = <0x80 0x80>; |
305 | cell-index = <1>; | 374 | cell-index = <1>; |
306 | interrupts = <33 2 0 0>; | 375 | interrupts = <33 2 0 0>; |
307 | }; | 376 | }; |
308 | dma-channel@100 { | 377 | dma-channel@100 { |
309 | compatible = "fsl,p2040-dma-channel", | 378 | compatible = "fsl,p2041-dma-channel", |
310 | "fsl,eloplus-dma-channel"; | 379 | "fsl,eloplus-dma-channel"; |
311 | reg = <0x100 0x80>; | 380 | reg = <0x100 0x80>; |
312 | cell-index = <2>; | 381 | cell-index = <2>; |
313 | interrupts = <34 2 0 0>; | 382 | interrupts = <34 2 0 0>; |
314 | }; | 383 | }; |
315 | dma-channel@180 { | 384 | dma-channel@180 { |
316 | compatible = "fsl,p2040-dma-channel", | 385 | compatible = "fsl,p2041-dma-channel", |
317 | "fsl,eloplus-dma-channel"; | 386 | "fsl,eloplus-dma-channel"; |
318 | reg = <0x180 0x80>; | 387 | reg = <0x180 0x80>; |
319 | cell-index = <3>; | 388 | cell-index = <3>; |
@@ -324,22 +393,20 @@ | |||
324 | spi@110000 { | 393 | spi@110000 { |
325 | #address-cells = <1>; | 394 | #address-cells = <1>; |
326 | #size-cells = <0>; | 395 | #size-cells = <0>; |
327 | compatible = "fsl,p2040-espi", "fsl,mpc8536-espi"; | 396 | compatible = "fsl,p2041-espi", "fsl,mpc8536-espi"; |
328 | reg = <0x110000 0x1000>; | 397 | reg = <0x110000 0x1000>; |
329 | interrupts = <53 0x2 0 0>; | 398 | interrupts = <53 0x2 0 0>; |
330 | fsl,espi-num-chipselects = <4>; | 399 | fsl,espi-num-chipselects = <4>; |
331 | |||
332 | }; | 400 | }; |
333 | 401 | ||
334 | sdhc: sdhc@114000 { | 402 | sdhc: sdhc@114000 { |
335 | compatible = "fsl,p2040-esdhc", "fsl,esdhc"; | 403 | compatible = "fsl,p2041-esdhc", "fsl,esdhc"; |
336 | reg = <0x114000 0x1000>; | 404 | reg = <0x114000 0x1000>; |
337 | interrupts = <48 2 0 0>; | 405 | interrupts = <48 2 0 0>; |
338 | sdhci,auto-cmd12; | 406 | sdhci,auto-cmd12; |
339 | clock-frequency = <0>; | 407 | clock-frequency = <0>; |
340 | }; | 408 | }; |
341 | 409 | ||
342 | |||
343 | i2c@118000 { | 410 | i2c@118000 { |
344 | #address-cells = <1>; | 411 | #address-cells = <1>; |
345 | #size-cells = <0>; | 412 | #size-cells = <0>; |
@@ -417,7 +484,7 @@ | |||
417 | }; | 484 | }; |
418 | 485 | ||
419 | gpio0: gpio@130000 { | 486 | gpio0: gpio@130000 { |
420 | compatible = "fsl,p2040-gpio", "fsl,qoriq-gpio"; | 487 | compatible = "fsl,p2041-gpio", "fsl,qoriq-gpio"; |
421 | reg = <0x130000 0x1000>; | 488 | reg = <0x130000 0x1000>; |
422 | interrupts = <55 2 0 0>; | 489 | interrupts = <55 2 0 0>; |
423 | #gpio-cells = <2>; | 490 | #gpio-cells = <2>; |
@@ -425,32 +492,34 @@ | |||
425 | }; | 492 | }; |
426 | 493 | ||
427 | usb0: usb@210000 { | 494 | usb0: usb@210000 { |
428 | compatible = "fsl,p2040-usb2-mph", | 495 | compatible = "fsl,p2041-usb2-mph", |
429 | "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph"; | 496 | "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph"; |
430 | reg = <0x210000 0x1000>; | 497 | reg = <0x210000 0x1000>; |
431 | #address-cells = <1>; | 498 | #address-cells = <1>; |
432 | #size-cells = <0>; | 499 | #size-cells = <0>; |
433 | interrupts = <44 0x2 0 0>; | 500 | interrupts = <44 0x2 0 0>; |
501 | phy_type = "utmi"; | ||
434 | port0; | 502 | port0; |
435 | }; | 503 | }; |
436 | 504 | ||
437 | usb1: usb@211000 { | 505 | usb1: usb@211000 { |
438 | compatible = "fsl,p2040-usb2-dr", | 506 | compatible = "fsl,p2041-usb2-dr", |
439 | "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr"; | 507 | "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr"; |
440 | reg = <0x211000 0x1000>; | 508 | reg = <0x211000 0x1000>; |
441 | #address-cells = <1>; | 509 | #address-cells = <1>; |
442 | #size-cells = <0>; | 510 | #size-cells = <0>; |
443 | interrupts = <45 0x2 0 0>; | 511 | interrupts = <45 0x2 0 0>; |
512 | phy_type = "utmi"; | ||
444 | }; | 513 | }; |
445 | 514 | ||
446 | sata@220000 { | 515 | sata@220000 { |
447 | compatible = "fsl,p2040-sata", "fsl,pq-sata-v2"; | 516 | compatible = "fsl,p2041-sata", "fsl,pq-sata-v2"; |
448 | reg = <0x220000 0x1000>; | 517 | reg = <0x220000 0x1000>; |
449 | interrupts = <68 0x2 0 0>; | 518 | interrupts = <68 0x2 0 0>; |
450 | }; | 519 | }; |
451 | 520 | ||
452 | sata@221000 { | 521 | sata@221000 { |
453 | compatible = "fsl,p2040-sata", "fsl,pq-sata-v2"; | 522 | compatible = "fsl,p2041-sata", "fsl,pq-sata-v2"; |
454 | reg = <0x221000 0x1000>; | 523 | reg = <0x221000 0x1000>; |
455 | interrupts = <69 0x2 0 0>; | 524 | interrupts = <69 0x2 0 0>; |
456 | }; | 525 | }; |
@@ -534,19 +603,19 @@ | |||
534 | }; | 603 | }; |
535 | 604 | ||
536 | localbus@ffe124000 { | 605 | localbus@ffe124000 { |
537 | compatible = "fsl,p2040-elbc", "fsl,elbc", "simple-bus"; | 606 | compatible = "fsl,p2041-elbc", "fsl,elbc", "simple-bus"; |
538 | interrupts = <25 2 0 0>; | 607 | interrupts = <25 2 0 0>; |
539 | #address-cells = <2>; | 608 | #address-cells = <2>; |
540 | #size-cells = <1>; | 609 | #size-cells = <1>; |
541 | }; | 610 | }; |
542 | 611 | ||
543 | pci0: pcie@ffe200000 { | 612 | pci0: pcie@ffe200000 { |
544 | compatible = "fsl,p2040-pcie", "fsl,qoriq-pcie-v2.2"; | 613 | compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2"; |
545 | device_type = "pci"; | 614 | device_type = "pci"; |
546 | #size-cells = <2>; | 615 | #size-cells = <2>; |
547 | #address-cells = <3>; | 616 | #address-cells = <3>; |
548 | bus-range = <0x0 0xff>; | 617 | bus-range = <0x0 0xff>; |
549 | clock-frequency = <0x1fca055>; | 618 | clock-frequency = <33333333>; |
550 | fsl,msi = <&msi0>; | 619 | fsl,msi = <&msi0>; |
551 | interrupts = <16 2 1 15>; | 620 | interrupts = <16 2 1 15>; |
552 | pcie@0 { | 621 | pcie@0 { |
@@ -568,12 +637,12 @@ | |||
568 | }; | 637 | }; |
569 | 638 | ||
570 | pci1: pcie@ffe201000 { | 639 | pci1: pcie@ffe201000 { |
571 | compatible = "fsl,p2040-pcie", "fsl,qoriq-pcie-v2.2"; | 640 | compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2"; |
572 | device_type = "pci"; | 641 | device_type = "pci"; |
573 | #size-cells = <2>; | 642 | #size-cells = <2>; |
574 | #address-cells = <3>; | 643 | #address-cells = <3>; |
575 | bus-range = <0 0xff>; | 644 | bus-range = <0 0xff>; |
576 | clock-frequency = <0x1fca055>; | 645 | clock-frequency = <33333333>; |
577 | fsl,msi = <&msi1>; | 646 | fsl,msi = <&msi1>; |
578 | interrupts = <16 2 1 14>; | 647 | interrupts = <16 2 1 14>; |
579 | pcie@0 { | 648 | pcie@0 { |
@@ -595,12 +664,12 @@ | |||
595 | }; | 664 | }; |
596 | 665 | ||
597 | pci2: pcie@ffe202000 { | 666 | pci2: pcie@ffe202000 { |
598 | compatible = "fsl,p2040-pcie", "fsl,qoriq-pcie-v2.2"; | 667 | compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2"; |
599 | device_type = "pci"; | 668 | device_type = "pci"; |
600 | #size-cells = <2>; | 669 | #size-cells = <2>; |
601 | #address-cells = <3>; | 670 | #address-cells = <3>; |
602 | bus-range = <0x0 0xff>; | 671 | bus-range = <0x0 0xff>; |
603 | clock-frequency = <0x1fca055>; | 672 | clock-frequency = <33333333>; |
604 | fsl,msi = <&msi2>; | 673 | fsl,msi = <&msi2>; |
605 | interrupts = <16 2 1 13>; | 674 | interrupts = <16 2 1 13>; |
606 | pcie@0 { | 675 | pcie@0 { |
diff --git a/arch/powerpc/boot/dts/p3041ds.dts b/arch/powerpc/boot/dts/p3041ds.dts index 69cae674f396..bbd113b49a8f 100644 --- a/arch/powerpc/boot/dts/p3041ds.dts +++ b/arch/powerpc/boot/dts/p3041ds.dts | |||
@@ -45,6 +45,10 @@ | |||
45 | device_type = "memory"; | 45 | device_type = "memory"; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | dcsr: dcsr@f00000000 { | ||
49 | ranges = <0x00000000 0xf 0x00000000 0x01008000>; | ||
50 | }; | ||
51 | |||
48 | soc: soc@ffe000000 { | 52 | soc: soc@ffe000000 { |
49 | spi@110000 { | 53 | spi@110000 { |
50 | flash@0 { | 54 | flash@0 { |
@@ -147,8 +151,8 @@ | |||
147 | }; | 151 | }; |
148 | 152 | ||
149 | board-control@3,0 { | 153 | board-control@3,0 { |
150 | compatible = "fsl,p3041ds-pixis"; | 154 | compatible = "fsl,p3041ds-fpga", "fsl,fpga-ngpixis"; |
151 | reg = <3 0 0x20>; | 155 | reg = <3 0 0x30>; |
152 | }; | 156 | }; |
153 | }; | 157 | }; |
154 | 158 | ||
diff --git a/arch/powerpc/boot/dts/p3041si.dtsi b/arch/powerpc/boot/dts/p3041si.dtsi index 8b695801f505..87130b732bc7 100644 --- a/arch/powerpc/boot/dts/p3041si.dtsi +++ b/arch/powerpc/boot/dts/p3041si.dtsi | |||
@@ -42,6 +42,7 @@ | |||
42 | 42 | ||
43 | aliases { | 43 | aliases { |
44 | ccsr = &soc; | 44 | ccsr = &soc; |
45 | dcsr = &dcsr; | ||
45 | 46 | ||
46 | serial0 = &serial0; | 47 | serial0 = &serial0; |
47 | serial1 = &serial1; | 48 | serial1 = &serial1; |
@@ -114,6 +115,74 @@ | |||
114 | }; | 115 | }; |
115 | }; | 116 | }; |
116 | 117 | ||
118 | dcsr: dcsr@f00000000 { | ||
119 | #address-cells = <1>; | ||
120 | #size-cells = <1>; | ||
121 | compatible = "fsl,dcsr", "simple-bus"; | ||
122 | |||
123 | dcsr-epu@0 { | ||
124 | compatible = "fsl,dcsr-epu"; | ||
125 | interrupts = <52 2 0 0 | ||
126 | 84 2 0 0 | ||
127 | 85 2 0 0>; | ||
128 | interrupt-parent = <&mpic>; | ||
129 | reg = <0x0 0x1000>; | ||
130 | }; | ||
131 | dcsr-npc { | ||
132 | compatible = "fsl,dcsr-npc"; | ||
133 | reg = <0x1000 0x1000 0x1000000 0x8000>; | ||
134 | }; | ||
135 | dcsr-nxc@2000 { | ||
136 | compatible = "fsl,dcsr-nxc"; | ||
137 | reg = <0x2000 0x1000>; | ||
138 | }; | ||
139 | dcsr-corenet { | ||
140 | compatible = "fsl,dcsr-corenet"; | ||
141 | reg = <0x8000 0x1000 0xB0000 0x1000>; | ||
142 | }; | ||
143 | dcsr-dpaa@9000 { | ||
144 | compatible = "fsl,p43041-dcsr-dpaa", "fsl,dcsr-dpaa"; | ||
145 | reg = <0x9000 0x1000>; | ||
146 | }; | ||
147 | dcsr-ocn@11000 { | ||
148 | compatible = "fsl,p43041-dcsr-ocn", "fsl,dcsr-ocn"; | ||
149 | reg = <0x11000 0x1000>; | ||
150 | }; | ||
151 | dcsr-ddr@12000 { | ||
152 | compatible = "fsl,dcsr-ddr"; | ||
153 | dev-handle = <&ddr>; | ||
154 | reg = <0x12000 0x1000>; | ||
155 | }; | ||
156 | dcsr-nal@18000 { | ||
157 | compatible = "fsl,p43041-dcsr-nal", "fsl,dcsr-nal"; | ||
158 | reg = <0x18000 0x1000>; | ||
159 | }; | ||
160 | dcsr-rcpm@22000 { | ||
161 | compatible = "fsl,p43041-dcsr-rcpm", "fsl,dcsr-rcpm"; | ||
162 | reg = <0x22000 0x1000>; | ||
163 | }; | ||
164 | dcsr-cpu-sb-proxy@40000 { | ||
165 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
166 | cpu-handle = <&cpu0>; | ||
167 | reg = <0x40000 0x1000>; | ||
168 | }; | ||
169 | dcsr-cpu-sb-proxy@41000 { | ||
170 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
171 | cpu-handle = <&cpu1>; | ||
172 | reg = <0x41000 0x1000>; | ||
173 | }; | ||
174 | dcsr-cpu-sb-proxy@42000 { | ||
175 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
176 | cpu-handle = <&cpu2>; | ||
177 | reg = <0x42000 0x1000>; | ||
178 | }; | ||
179 | dcsr-cpu-sb-proxy@43000 { | ||
180 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
181 | cpu-handle = <&cpu3>; | ||
182 | reg = <0x43000 0x1000>; | ||
183 | }; | ||
184 | }; | ||
185 | |||
117 | soc: soc@ffe000000 { | 186 | soc: soc@ffe000000 { |
118 | #address-cells = <1>; | 187 | #address-cells = <1>; |
119 | #size-cells = <1>; | 188 | #size-cells = <1>; |
@@ -133,7 +202,7 @@ | |||
133 | fsl,num-laws = <32>; | 202 | fsl,num-laws = <32>; |
134 | }; | 203 | }; |
135 | 204 | ||
136 | memory-controller@8000 { | 205 | ddr: memory-controller@8000 { |
137 | compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; | 206 | compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; |
138 | reg = <0x8000 0x1000>; | 207 | reg = <0x8000 0x1000>; |
139 | interrupts = <16 2 1 23>; | 208 | interrupts = <16 2 1 23>; |
diff --git a/arch/powerpc/boot/dts/p3060qds.dts b/arch/powerpc/boot/dts/p3060qds.dts new file mode 100644 index 000000000000..08b9193213e7 --- /dev/null +++ b/arch/powerpc/boot/dts/p3060qds.dts | |||
@@ -0,0 +1,238 @@ | |||
1 | /* | ||
2 | * P3060QDS Device Tree Source | ||
3 | * | ||
4 | * Copyright 2011 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are met: | ||
8 | * * Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * * Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * * Neither the name of Freescale Semiconductor nor the | ||
14 | * names of its contributors may be used to endorse or promote products | ||
15 | * derived from this software without specific prior written permission. | ||
16 | * | ||
17 | * | ||
18 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
19 | * GNU General Public License ("GPL") as published by the Free Software | ||
20 | * Foundation, either version 2 of that License or (at your option) any | ||
21 | * later version. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY | ||
24 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
26 | * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY | ||
27 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
28 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
29 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
30 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | /include/ "p3060si.dtsi" | ||
36 | |||
37 | / { | ||
38 | model = "fsl,P3060QDS"; | ||
39 | compatible = "fsl,P3060QDS"; | ||
40 | #address-cells = <2>; | ||
41 | #size-cells = <2>; | ||
42 | interrupt-parent = <&mpic>; | ||
43 | |||
44 | memory { | ||
45 | device_type = "memory"; | ||
46 | }; | ||
47 | |||
48 | dcsr: dcsr@f00000000 { | ||
49 | ranges = <0x00000000 0xf 0x00000000 0x01008000>; | ||
50 | }; | ||
51 | |||
52 | soc: soc@ffe000000 { | ||
53 | spi@110000 { | ||
54 | flash@0 { | ||
55 | #address-cells = <1>; | ||
56 | #size-cells = <1>; | ||
57 | compatible = "spansion,s25sl12801"; | ||
58 | reg = <0>; | ||
59 | spi-max-frequency = <40000000>; /* input clock */ | ||
60 | partition@u-boot { | ||
61 | label = "u-boot"; | ||
62 | reg = <0x00000000 0x00100000>; | ||
63 | read-only; | ||
64 | }; | ||
65 | partition@kernel { | ||
66 | label = "kernel"; | ||
67 | reg = <0x00100000 0x00500000>; | ||
68 | read-only; | ||
69 | }; | ||
70 | partition@dtb { | ||
71 | label = "dtb"; | ||
72 | reg = <0x00600000 0x00100000>; | ||
73 | read-only; | ||
74 | }; | ||
75 | partition@fs { | ||
76 | label = "file system"; | ||
77 | reg = <0x00700000 0x00900000>; | ||
78 | }; | ||
79 | }; | ||
80 | flash@1 { | ||
81 | #address-cells = <1>; | ||
82 | #size-cells = <1>; | ||
83 | compatible = "spansion,en25q32b"; | ||
84 | reg = <1>; | ||
85 | spi-max-frequency = <40000000>; /* input clock */ | ||
86 | partition@spi1 { | ||
87 | label = "spi1"; | ||
88 | reg = <0x00000000 0x00400000>; | ||
89 | }; | ||
90 | }; | ||
91 | flash@2 { | ||
92 | #address-cells = <1>; | ||
93 | #size-cells = <1>; | ||
94 | compatible = "atmel,at45db081d"; | ||
95 | reg = <2>; | ||
96 | spi-max-frequency = <40000000>; /* input clock */ | ||
97 | partition@spi1 { | ||
98 | label = "spi2"; | ||
99 | reg = <0x00000000 0x00100000>; | ||
100 | }; | ||
101 | }; | ||
102 | flash@3 { | ||
103 | #address-cells = <1>; | ||
104 | #size-cells = <1>; | ||
105 | compatible = "spansion,sst25wf040"; | ||
106 | reg = <3>; | ||
107 | spi-max-frequency = <40000000>; /* input clock */ | ||
108 | partition@spi3 { | ||
109 | label = "spi3"; | ||
110 | reg = <0x00000000 0x00080000>; | ||
111 | }; | ||
112 | }; | ||
113 | }; | ||
114 | |||
115 | i2c@118000 { | ||
116 | eeprom@51 { | ||
117 | compatible = "at24,24c256"; | ||
118 | reg = <0x51>; | ||
119 | }; | ||
120 | eeprom@53 { | ||
121 | compatible = "at24,24c256"; | ||
122 | reg = <0x53>; | ||
123 | }; | ||
124 | rtc@68 { | ||
125 | compatible = "dallas,ds3232"; | ||
126 | reg = <0x68>; | ||
127 | interrupts = <0x1 0x1 0 0>; | ||
128 | }; | ||
129 | }; | ||
130 | |||
131 | usb0: usb@210000 { | ||
132 | phy_type = "ulpi"; | ||
133 | }; | ||
134 | |||
135 | usb1: usb@211000 { | ||
136 | dr_mode = "host"; | ||
137 | phy_type = "ulpi"; | ||
138 | }; | ||
139 | }; | ||
140 | |||
141 | rapidio@ffe0c0000 { | ||
142 | reg = <0xf 0xfe0c0000 0 0x11000>; | ||
143 | |||
144 | port1 { | ||
145 | ranges = <0 0 0xc 0x20000000 0 0x10000000>; | ||
146 | }; | ||
147 | port2 { | ||
148 | ranges = <0 0 0xc 0x30000000 0 0x10000000>; | ||
149 | }; | ||
150 | }; | ||
151 | |||
152 | localbus@ffe124000 { | ||
153 | reg = <0xf 0xfe124000 0 0x1000>; | ||
154 | ranges = <0 0 0xf 0xe8000000 0x08000000 | ||
155 | 2 0 0xf 0xffa00000 0x00040000 | ||
156 | 3 0 0xf 0xffdf0000 0x00008000>; | ||
157 | |||
158 | flash@0,0 { | ||
159 | compatible = "cfi-flash"; | ||
160 | reg = <0 0 0x08000000>; | ||
161 | bank-width = <2>; | ||
162 | device-width = <2>; | ||
163 | }; | ||
164 | |||
165 | nand@2,0 { | ||
166 | #address-cells = <1>; | ||
167 | #size-cells = <1>; | ||
168 | compatible = "fsl,elbc-fcm-nand"; | ||
169 | reg = <0x2 0x0 0x40000>; | ||
170 | |||
171 | partition@0 { | ||
172 | label = "NAND U-Boot Image"; | ||
173 | reg = <0x0 0x02000000>; | ||
174 | read-only; | ||
175 | }; | ||
176 | |||
177 | partition@2000000 { | ||
178 | label = "NAND Root File System"; | ||
179 | reg = <0x02000000 0x10000000>; | ||
180 | }; | ||
181 | |||
182 | partition@12000000 { | ||
183 | label = "NAND Compressed RFS Image"; | ||
184 | reg = <0x12000000 0x08000000>; | ||
185 | }; | ||
186 | |||
187 | partition@1a000000 { | ||
188 | label = "NAND Linux Kernel Image"; | ||
189 | reg = <0x1a000000 0x04000000>; | ||
190 | }; | ||
191 | |||
192 | partition@1e000000 { | ||
193 | label = "NAND DTB Image"; | ||
194 | reg = <0x1e000000 0x01000000>; | ||
195 | }; | ||
196 | |||
197 | partition@1f000000 { | ||
198 | label = "NAND Writable User area"; | ||
199 | reg = <0x1f000000 0x21000000>; | ||
200 | }; | ||
201 | }; | ||
202 | |||
203 | board-control@3,0 { | ||
204 | compatible = "fsl,p3060qds-fpga", "fsl,fpga-qixis"; | ||
205 | reg = <3 0 0x100>; | ||
206 | }; | ||
207 | }; | ||
208 | |||
209 | pci0: pcie@ffe200000 { | ||
210 | reg = <0xf 0xfe200000 0 0x1000>; | ||
211 | ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000 | ||
212 | 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>; | ||
213 | pcie@0 { | ||
214 | ranges = <0x02000000 0 0xe0000000 | ||
215 | 0x02000000 0 0xe0000000 | ||
216 | 0 0x20000000 | ||
217 | |||
218 | 0x01000000 0 0x00000000 | ||
219 | 0x01000000 0 0x00000000 | ||
220 | 0 0x00010000>; | ||
221 | }; | ||
222 | }; | ||
223 | |||
224 | pci1: pcie@ffe201000 { | ||
225 | reg = <0xf 0xfe201000 0 0x1000>; | ||
226 | ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000 | ||
227 | 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>; | ||
228 | pcie@0 { | ||
229 | ranges = <0x02000000 0 0xe0000000 | ||
230 | 0x02000000 0 0xe0000000 | ||
231 | 0 0x20000000 | ||
232 | |||
233 | 0x01000000 0 0x00000000 | ||
234 | 0x01000000 0 0x00000000 | ||
235 | 0 0x00010000>; | ||
236 | }; | ||
237 | }; | ||
238 | }; | ||
diff --git a/arch/powerpc/boot/dts/p3060si.dtsi b/arch/powerpc/boot/dts/p3060si.dtsi new file mode 100644 index 000000000000..68947e157bbc --- /dev/null +++ b/arch/powerpc/boot/dts/p3060si.dtsi | |||
@@ -0,0 +1,719 @@ | |||
1 | /* | ||
2 | * P3060 Silicon Device Tree Source | ||
3 | * | ||
4 | * Copyright 2011 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are met: | ||
8 | * * Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * * Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * * Neither the name of Freescale Semiconductor nor the | ||
14 | * names of its contributors may be used to endorse or promote products | ||
15 | * derived from this software without specific prior written permission. | ||
16 | * | ||
17 | * | ||
18 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
19 | * GNU General Public License ("GPL") as published by the Free Software | ||
20 | * Foundation, either version 2 of that License or (at your option) any | ||
21 | * later version. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY | ||
24 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
26 | * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY | ||
27 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
28 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
29 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
30 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | /dts-v1/; | ||
36 | |||
37 | / { | ||
38 | compatible = "fsl,P3060"; | ||
39 | #address-cells = <2>; | ||
40 | #size-cells = <2>; | ||
41 | interrupt-parent = <&mpic>; | ||
42 | |||
43 | aliases { | ||
44 | ccsr = &soc; | ||
45 | dcsr = &dcsr; | ||
46 | |||
47 | serial0 = &serial0; | ||
48 | serial1 = &serial1; | ||
49 | serial2 = &serial2; | ||
50 | serial3 = &serial3; | ||
51 | pci0 = &pci0; | ||
52 | pci1 = &pci1; | ||
53 | usb0 = &usb0; | ||
54 | usb1 = &usb1; | ||
55 | dma0 = &dma0; | ||
56 | dma1 = &dma1; | ||
57 | msi0 = &msi0; | ||
58 | msi1 = &msi1; | ||
59 | msi2 = &msi2; | ||
60 | |||
61 | crypto = &crypto; | ||
62 | sec_jr0 = &sec_jr0; | ||
63 | sec_jr1 = &sec_jr1; | ||
64 | sec_jr2 = &sec_jr2; | ||
65 | sec_jr3 = &sec_jr3; | ||
66 | rtic_a = &rtic_a; | ||
67 | rtic_b = &rtic_b; | ||
68 | rtic_c = &rtic_c; | ||
69 | rtic_d = &rtic_d; | ||
70 | sec_mon = &sec_mon; | ||
71 | }; | ||
72 | |||
73 | cpus { | ||
74 | #address-cells = <1>; | ||
75 | #size-cells = <0>; | ||
76 | |||
77 | cpu0: PowerPC,e500mc@0 { | ||
78 | device_type = "cpu"; | ||
79 | reg = <0>; | ||
80 | next-level-cache = <&L2_0>; | ||
81 | L2_0: l2-cache { | ||
82 | next-level-cache = <&cpc>; | ||
83 | }; | ||
84 | }; | ||
85 | cpu1: PowerPC,e500mc@1 { | ||
86 | device_type = "cpu"; | ||
87 | reg = <1>; | ||
88 | next-level-cache = <&L2_1>; | ||
89 | L2_1: l2-cache { | ||
90 | next-level-cache = <&cpc>; | ||
91 | }; | ||
92 | }; | ||
93 | cpu4: PowerPC,e500mc@4 { | ||
94 | device_type = "cpu"; | ||
95 | reg = <4>; | ||
96 | next-level-cache = <&L2_4>; | ||
97 | L2_4: l2-cache { | ||
98 | next-level-cache = <&cpc>; | ||
99 | }; | ||
100 | }; | ||
101 | cpu5: PowerPC,e500mc@5 { | ||
102 | device_type = "cpu"; | ||
103 | reg = <5>; | ||
104 | next-level-cache = <&L2_5>; | ||
105 | L2_5: l2-cache { | ||
106 | next-level-cache = <&cpc>; | ||
107 | }; | ||
108 | }; | ||
109 | cpu6: PowerPC,e500mc@6 { | ||
110 | device_type = "cpu"; | ||
111 | reg = <6>; | ||
112 | next-level-cache = <&L2_6>; | ||
113 | L2_6: l2-cache { | ||
114 | next-level-cache = <&cpc>; | ||
115 | }; | ||
116 | }; | ||
117 | cpu7: PowerPC,e500mc@7 { | ||
118 | device_type = "cpu"; | ||
119 | reg = <7>; | ||
120 | next-level-cache = <&L2_7>; | ||
121 | L2_7: l2-cache { | ||
122 | next-level-cache = <&cpc>; | ||
123 | }; | ||
124 | }; | ||
125 | }; | ||
126 | |||
127 | dcsr: dcsr@f00000000 { | ||
128 | #address-cells = <1>; | ||
129 | #size-cells = <1>; | ||
130 | compatible = "fsl,dcsr", "simple-bus"; | ||
131 | |||
132 | dcsr-epu@0 { | ||
133 | compatible = "fsl,dcsr-epu"; | ||
134 | interrupts = <52 2 0 0 | ||
135 | 84 2 0 0 | ||
136 | 85 2 0 0>; | ||
137 | interrupt-parent = <&mpic>; | ||
138 | reg = <0x0 0x1000>; | ||
139 | }; | ||
140 | dcsr-npc { | ||
141 | compatible = "fsl,dcsr-npc"; | ||
142 | reg = <0x1000 0x1000 0x1000000 0x8000>; | ||
143 | }; | ||
144 | dcsr-nxc@2000 { | ||
145 | compatible = "fsl,dcsr-nxc"; | ||
146 | reg = <0x2000 0x1000>; | ||
147 | }; | ||
148 | dcsr-corenet { | ||
149 | compatible = "fsl,dcsr-corenet"; | ||
150 | reg = <0x8000 0x1000 0xB0000 0x1000>; | ||
151 | }; | ||
152 | dcsr-dpaa@9000 { | ||
153 | compatible = "fsl,p3060-dcsr-dpaa", "fsl,dcsr-dpaa"; | ||
154 | reg = <0x9000 0x1000>; | ||
155 | }; | ||
156 | dcsr-ocn@11000 { | ||
157 | compatible = "fsl,p3060-dcsr-ocn", "fsl,dcsr-ocn"; | ||
158 | reg = <0x11000 0x1000>; | ||
159 | }; | ||
160 | dcsr-ddr@12000 { | ||
161 | compatible = "fsl,dcsr-ddr"; | ||
162 | dev-handle = <&ddr>; | ||
163 | reg = <0x12000 0x1000>; | ||
164 | }; | ||
165 | dcsr-nal@18000 { | ||
166 | compatible = "fsl,p3060-dcsr-nal", "fsl,dcsr-nal"; | ||
167 | reg = <0x18000 0x1000>; | ||
168 | }; | ||
169 | dcsr-rcpm@22000 { | ||
170 | compatible = "fsl,p3060-dcsr-rcpm", "fsl,dcsr-rcpm"; | ||
171 | reg = <0x22000 0x1000>; | ||
172 | }; | ||
173 | dcsr-cpu-sb-proxy@40000 { | ||
174 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
175 | cpu-handle = <&cpu0>; | ||
176 | reg = <0x40000 0x1000>; | ||
177 | }; | ||
178 | dcsr-cpu-sb-proxy@41000 { | ||
179 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
180 | cpu-handle = <&cpu1>; | ||
181 | reg = <0x41000 0x1000>; | ||
182 | }; | ||
183 | dcsr-cpu-sb-proxy@44000 { | ||
184 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
185 | cpu-handle = <&cpu4>; | ||
186 | reg = <0x44000 0x1000>; | ||
187 | }; | ||
188 | dcsr-cpu-sb-proxy@45000 { | ||
189 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
190 | cpu-handle = <&cpu5>; | ||
191 | reg = <0x45000 0x1000>; | ||
192 | }; | ||
193 | dcsr-cpu-sb-proxy@46000 { | ||
194 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
195 | cpu-handle = <&cpu6>; | ||
196 | reg = <0x46000 0x1000>; | ||
197 | }; | ||
198 | dcsr-cpu-sb-proxy@47000 { | ||
199 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
200 | cpu-handle = <&cpu7>; | ||
201 | reg = <0x47000 0x1000>; | ||
202 | }; | ||
203 | }; | ||
204 | |||
205 | soc: soc@ffe000000 { | ||
206 | #address-cells = <1>; | ||
207 | #size-cells = <1>; | ||
208 | device_type = "soc"; | ||
209 | compatible = "simple-bus"; | ||
210 | ranges = <0x00000000 0xf 0xfe000000 0x1000000>; | ||
211 | reg = <0xf 0xfe000000 0 0x00001000>; | ||
212 | |||
213 | soc-sram-error { | ||
214 | compatible = "fsl,soc-sram-error"; | ||
215 | interrupts = <16 2 1 29>; | ||
216 | }; | ||
217 | |||
218 | corenet-law@0 { | ||
219 | compatible = "fsl,corenet-law"; | ||
220 | reg = <0x0 0x1000>; | ||
221 | fsl,num-laws = <32>; | ||
222 | }; | ||
223 | |||
224 | ddr: memory-controller@8000 { | ||
225 | compatible = "fsl,qoriq-memory-controller-v4.4", "fsl,qoriq-memory-controller"; | ||
226 | reg = <0x8000 0x1000>; | ||
227 | interrupts = <16 2 1 23>; | ||
228 | }; | ||
229 | |||
230 | cpc: l3-cache-controller@10000 { | ||
231 | compatible = "fsl,p3060-l3-cache-controller", "cache"; | ||
232 | reg = <0x10000 0x1000 | ||
233 | 0x11000 0x1000>; | ||
234 | interrupts = <16 2 1 27>; | ||
235 | }; | ||
236 | |||
237 | corenet-cf@18000 { | ||
238 | compatible = "fsl,corenet-cf"; | ||
239 | reg = <0x18000 0x1000>; | ||
240 | interrupts = <16 2 1 31>; | ||
241 | fsl,ccf-num-csdids = <32>; | ||
242 | fsl,ccf-num-snoopids = <32>; | ||
243 | }; | ||
244 | |||
245 | iommu@20000 { | ||
246 | compatible = "fsl,pamu-v1.0", "fsl,pamu"; | ||
247 | reg = <0x20000 0x5000>; | ||
248 | interrupts = < | ||
249 | 24 2 0 0 | ||
250 | 16 2 1 30>; | ||
251 | }; | ||
252 | |||
253 | mpic: pic@40000 { | ||
254 | clock-frequency = <0>; | ||
255 | interrupt-controller; | ||
256 | #address-cells = <0>; | ||
257 | #interrupt-cells = <4>; | ||
258 | reg = <0x40000 0x40000>; | ||
259 | compatible = "fsl,mpic", "chrp,open-pic"; | ||
260 | device_type = "open-pic"; | ||
261 | }; | ||
262 | |||
263 | msi0: msi@41600 { | ||
264 | compatible = "fsl,mpic-msi"; | ||
265 | reg = <0x41600 0x200>; | ||
266 | msi-available-ranges = <0 0x100>; | ||
267 | interrupts = < | ||
268 | 0xe0 0 0 0 | ||
269 | 0xe1 0 0 0 | ||
270 | 0xe2 0 0 0 | ||
271 | 0xe3 0 0 0 | ||
272 | 0xe4 0 0 0 | ||
273 | 0xe5 0 0 0 | ||
274 | 0xe6 0 0 0 | ||
275 | 0xe7 0 0 0>; | ||
276 | }; | ||
277 | |||
278 | msi1: msi@41800 { | ||
279 | compatible = "fsl,mpic-msi"; | ||
280 | reg = <0x41800 0x200>; | ||
281 | msi-available-ranges = <0 0x100>; | ||
282 | interrupts = < | ||
283 | 0xe8 0 0 0 | ||
284 | 0xe9 0 0 0 | ||
285 | 0xea 0 0 0 | ||
286 | 0xeb 0 0 0 | ||
287 | 0xec 0 0 0 | ||
288 | 0xed 0 0 0 | ||
289 | 0xee 0 0 0 | ||
290 | 0xef 0 0 0>; | ||
291 | }; | ||
292 | |||
293 | msi2: msi@41a00 { | ||
294 | compatible = "fsl,mpic-msi"; | ||
295 | reg = <0x41a00 0x200>; | ||
296 | msi-available-ranges = <0 0x100>; | ||
297 | interrupts = < | ||
298 | 0xf0 0 0 0 | ||
299 | 0xf1 0 0 0 | ||
300 | 0xf2 0 0 0 | ||
301 | 0xf3 0 0 0 | ||
302 | 0xf4 0 0 0 | ||
303 | 0xf5 0 0 0 | ||
304 | 0xf6 0 0 0 | ||
305 | 0xf7 0 0 0>; | ||
306 | }; | ||
307 | |||
308 | rmu: rmu@d3000 { | ||
309 | #address-cells = <1>; | ||
310 | #size-cells = <1>; | ||
311 | compatible = "fsl,srio-rmu"; | ||
312 | reg = <0xd3000 0x500>; | ||
313 | ranges = <0x0 0xd3000 0x500>; | ||
314 | |||
315 | message-unit@0 { | ||
316 | compatible = "fsl,srio-msg-unit"; | ||
317 | reg = <0x0 0x100>; | ||
318 | interrupts = < | ||
319 | 60 2 0 0 /* msg1_tx_irq */ | ||
320 | 61 2 0 0>;/* msg1_rx_irq */ | ||
321 | }; | ||
322 | message-unit@100 { | ||
323 | compatible = "fsl,srio-msg-unit"; | ||
324 | reg = <0x100 0x100>; | ||
325 | interrupts = < | ||
326 | 62 2 0 0 /* msg2_tx_irq */ | ||
327 | 63 2 0 0>;/* msg2_rx_irq */ | ||
328 | }; | ||
329 | doorbell-unit@400 { | ||
330 | compatible = "fsl,srio-dbell-unit"; | ||
331 | reg = <0x400 0x80>; | ||
332 | interrupts = < | ||
333 | 56 2 0 0 /* bell_outb_irq */ | ||
334 | 57 2 0 0>;/* bell_inb_irq */ | ||
335 | }; | ||
336 | port-write-unit@4e0 { | ||
337 | compatible = "fsl,srio-port-write-unit"; | ||
338 | reg = <0x4e0 0x20>; | ||
339 | interrupts = <16 2 1 11>; | ||
340 | }; | ||
341 | }; | ||
342 | |||
343 | guts: global-utilities@e0000 { | ||
344 | compatible = "fsl,qoriq-device-config-1.0"; | ||
345 | reg = <0xe0000 0xe00>; | ||
346 | fsl,has-rstcr; | ||
347 | #sleep-cells = <1>; | ||
348 | fsl,liodn-bits = <12>; | ||
349 | }; | ||
350 | |||
351 | pins: global-utilities@e0e00 { | ||
352 | compatible = "fsl,qoriq-pin-control-1.0"; | ||
353 | reg = <0xe0e00 0x200>; | ||
354 | #sleep-cells = <2>; | ||
355 | }; | ||
356 | |||
357 | clockgen: global-utilities@e1000 { | ||
358 | compatible = "fsl,p3060-clockgen", "fsl,qoriq-clockgen-1.0"; | ||
359 | reg = <0xe1000 0x1000>; | ||
360 | clock-frequency = <0>; | ||
361 | }; | ||
362 | |||
363 | rcpm: global-utilities@e2000 { | ||
364 | compatible = "fsl,qoriq-rcpm-1.0"; | ||
365 | reg = <0xe2000 0x1000>; | ||
366 | #sleep-cells = <1>; | ||
367 | }; | ||
368 | |||
369 | sfp: sfp@e8000 { | ||
370 | compatible = "fsl,p3060-sfp", "fsl,qoriq-sfp-1.0"; | ||
371 | reg = <0xe8000 0x1000>; | ||
372 | }; | ||
373 | |||
374 | serdes: serdes@ea000 { | ||
375 | compatible = "fsl,p3060-serdes"; | ||
376 | reg = <0xea000 0x1000>; | ||
377 | }; | ||
378 | |||
379 | dma0: dma@100300 { | ||
380 | #address-cells = <1>; | ||
381 | #size-cells = <1>; | ||
382 | compatible = "fsl,p3060-dma", "fsl,eloplus-dma"; | ||
383 | reg = <0x100300 0x4>; | ||
384 | ranges = <0x0 0x100100 0x200>; | ||
385 | cell-index = <0>; | ||
386 | dma-channel@0 { | ||
387 | compatible = "fsl,p3060-dma-channel", | ||
388 | "fsl,eloplus-dma-channel"; | ||
389 | reg = <0x0 0x80>; | ||
390 | cell-index = <0>; | ||
391 | interrupts = <28 2 0 0>; | ||
392 | }; | ||
393 | dma-channel@80 { | ||
394 | compatible = "fsl,p3060-dma-channel", | ||
395 | "fsl,eloplus-dma-channel"; | ||
396 | reg = <0x80 0x80>; | ||
397 | cell-index = <1>; | ||
398 | interrupts = <29 2 0 0>; | ||
399 | }; | ||
400 | dma-channel@100 { | ||
401 | compatible = "fsl,p3060-dma-channel", | ||
402 | "fsl,eloplus-dma-channel"; | ||
403 | reg = <0x100 0x80>; | ||
404 | cell-index = <2>; | ||
405 | interrupts = <30 2 0 0>; | ||
406 | }; | ||
407 | dma-channel@180 { | ||
408 | compatible = "fsl,p3060-dma-channel", | ||
409 | "fsl,eloplus-dma-channel"; | ||
410 | reg = <0x180 0x80>; | ||
411 | cell-index = <3>; | ||
412 | interrupts = <31 2 0 0>; | ||
413 | }; | ||
414 | }; | ||
415 | |||
416 | dma1: dma@101300 { | ||
417 | #address-cells = <1>; | ||
418 | #size-cells = <1>; | ||
419 | compatible = "fsl,p3060-dma", "fsl,eloplus-dma"; | ||
420 | reg = <0x101300 0x4>; | ||
421 | ranges = <0x0 0x101100 0x200>; | ||
422 | cell-index = <1>; | ||
423 | dma-channel@0 { | ||
424 | compatible = "fsl,p3060-dma-channel", | ||
425 | "fsl,eloplus-dma-channel"; | ||
426 | reg = <0x0 0x80>; | ||
427 | cell-index = <0>; | ||
428 | interrupts = <32 2 0 0>; | ||
429 | }; | ||
430 | dma-channel@80 { | ||
431 | compatible = "fsl,p3060-dma-channel", | ||
432 | "fsl,eloplus-dma-channel"; | ||
433 | reg = <0x80 0x80>; | ||
434 | cell-index = <1>; | ||
435 | interrupts = <33 2 0 0>; | ||
436 | }; | ||
437 | dma-channel@100 { | ||
438 | compatible = "fsl,p3060-dma-channel", | ||
439 | "fsl,eloplus-dma-channel"; | ||
440 | reg = <0x100 0x80>; | ||
441 | cell-index = <2>; | ||
442 | interrupts = <34 2 0 0>; | ||
443 | }; | ||
444 | dma-channel@180 { | ||
445 | compatible = "fsl,p3060-dma-channel", | ||
446 | "fsl,eloplus-dma-channel"; | ||
447 | reg = <0x180 0x80>; | ||
448 | cell-index = <3>; | ||
449 | interrupts = <35 2 0 0>; | ||
450 | }; | ||
451 | }; | ||
452 | |||
453 | spi@110000 { | ||
454 | #address-cells = <1>; | ||
455 | #size-cells = <0>; | ||
456 | compatible = "fsl,p3060-espi", "fsl,mpc8536-espi"; | ||
457 | reg = <0x110000 0x1000>; | ||
458 | interrupts = <53 0x2 0 0>; | ||
459 | fsl,espi-num-chipselects = <4>; | ||
460 | }; | ||
461 | |||
462 | i2c@118000 { | ||
463 | #address-cells = <1>; | ||
464 | #size-cells = <0>; | ||
465 | cell-index = <0>; | ||
466 | compatible = "fsl-i2c"; | ||
467 | reg = <0x118000 0x100>; | ||
468 | interrupts = <38 2 0 0>; | ||
469 | dfsrr; | ||
470 | }; | ||
471 | |||
472 | i2c@118100 { | ||
473 | #address-cells = <1>; | ||
474 | #size-cells = <0>; | ||
475 | cell-index = <1>; | ||
476 | compatible = "fsl-i2c"; | ||
477 | reg = <0x118100 0x100>; | ||
478 | interrupts = <38 2 0 0>; | ||
479 | dfsrr; | ||
480 | }; | ||
481 | |||
482 | i2c@119000 { | ||
483 | #address-cells = <1>; | ||
484 | #size-cells = <0>; | ||
485 | cell-index = <2>; | ||
486 | compatible = "fsl-i2c"; | ||
487 | reg = <0x119000 0x100>; | ||
488 | interrupts = <39 2 0 0>; | ||
489 | dfsrr; | ||
490 | }; | ||
491 | |||
492 | i2c@119100 { | ||
493 | #address-cells = <1>; | ||
494 | #size-cells = <0>; | ||
495 | cell-index = <3>; | ||
496 | compatible = "fsl-i2c"; | ||
497 | reg = <0x119100 0x100>; | ||
498 | interrupts = <39 2 0 0>; | ||
499 | dfsrr; | ||
500 | }; | ||
501 | |||
502 | serial0: serial@11c500 { | ||
503 | cell-index = <0>; | ||
504 | device_type = "serial"; | ||
505 | compatible = "ns16550"; | ||
506 | reg = <0x11c500 0x100>; | ||
507 | clock-frequency = <0>; | ||
508 | interrupts = <36 2 0 0>; | ||
509 | }; | ||
510 | |||
511 | serial1: serial@11c600 { | ||
512 | cell-index = <1>; | ||
513 | device_type = "serial"; | ||
514 | compatible = "ns16550"; | ||
515 | reg = <0x11c600 0x100>; | ||
516 | clock-frequency = <0>; | ||
517 | interrupts = <36 2 0 0>; | ||
518 | }; | ||
519 | |||
520 | serial2: serial@11d500 { | ||
521 | cell-index = <2>; | ||
522 | device_type = "serial"; | ||
523 | compatible = "ns16550"; | ||
524 | reg = <0x11d500 0x100>; | ||
525 | clock-frequency = <0>; | ||
526 | interrupts = <37 2 0 0>; | ||
527 | }; | ||
528 | |||
529 | serial3: serial@11d600 { | ||
530 | cell-index = <3>; | ||
531 | device_type = "serial"; | ||
532 | compatible = "ns16550"; | ||
533 | reg = <0x11d600 0x100>; | ||
534 | clock-frequency = <0>; | ||
535 | interrupts = <37 2 0 0>; | ||
536 | }; | ||
537 | |||
538 | gpio0: gpio@130000 { | ||
539 | compatible = "fsl,p3060-gpio", "fsl,qoriq-gpio"; | ||
540 | reg = <0x130000 0x1000>; | ||
541 | interrupts = <55 2 0 0>; | ||
542 | #gpio-cells = <2>; | ||
543 | gpio-controller; | ||
544 | }; | ||
545 | |||
546 | usb0: usb@210000 { | ||
547 | compatible = "fsl,p3060-usb2-mph", | ||
548 | "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph"; | ||
549 | reg = <0x210000 0x1000>; | ||
550 | #address-cells = <1>; | ||
551 | #size-cells = <0>; | ||
552 | interrupts = <44 0x2 0 0>; | ||
553 | }; | ||
554 | |||
555 | usb1: usb@211000 { | ||
556 | compatible = "fsl,p3060-usb2-dr", | ||
557 | "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr"; | ||
558 | reg = <0x211000 0x1000>; | ||
559 | #address-cells = <1>; | ||
560 | #size-cells = <0>; | ||
561 | interrupts = <45 0x2 0 0>; | ||
562 | }; | ||
563 | |||
564 | crypto: crypto@300000 { | ||
565 | compatible = "fsl,sec-v4.1", "fsl,sec-v4.0"; | ||
566 | #address-cells = <1>; | ||
567 | #size-cells = <1>; | ||
568 | reg = <0x300000 0x10000>; | ||
569 | ranges = <0 0x300000 0x10000>; | ||
570 | interrupt-parent = <&mpic>; | ||
571 | interrupts = <92 2 0 0>; | ||
572 | |||
573 | sec_jr0: jr@1000 { | ||
574 | compatible = "fsl,sec-v4.1-job-ring", "fsl,sec-v4.0-job-ring"; | ||
575 | reg = <0x1000 0x1000>; | ||
576 | interrupt-parent = <&mpic>; | ||
577 | interrupts = <88 2 0 0>; | ||
578 | }; | ||
579 | |||
580 | sec_jr1: jr@2000 { | ||
581 | compatible = "fsl,sec-v4.1-job-ring", "fsl,sec-v4.0-job-ring"; | ||
582 | reg = <0x2000 0x1000>; | ||
583 | interrupt-parent = <&mpic>; | ||
584 | interrupts = <89 2 0 0>; | ||
585 | }; | ||
586 | |||
587 | sec_jr2: jr@3000 { | ||
588 | compatible = "fsl,sec-v4.1-job-ring", "fsl,sec-v4.0-job-ring"; | ||
589 | reg = <0x3000 0x1000>; | ||
590 | interrupt-parent = <&mpic>; | ||
591 | interrupts = <90 2 0 0>; | ||
592 | }; | ||
593 | |||
594 | sec_jr3: jr@4000 { | ||
595 | compatible = "fsl,sec-v4.1-job-ring", "fsl,sec-v4.0-job-ring"; | ||
596 | reg = <0x4000 0x1000>; | ||
597 | interrupt-parent = <&mpic>; | ||
598 | interrupts = <91 2 0 0>; | ||
599 | }; | ||
600 | |||
601 | rtic@6000 { | ||
602 | compatible = "fsl,sec-v4.1-rtic", "fsl,sec-v4.0-rtic"; | ||
603 | #address-cells = <1>; | ||
604 | #size-cells = <1>; | ||
605 | reg = <0x6000 0x100>; | ||
606 | ranges = <0x0 0x6100 0xe00>; | ||
607 | |||
608 | rtic_a: rtic-a@0 { | ||
609 | compatible = "fsl,sec-v4.1-rtic-memory", "fsl,sec-v4.0-rtic-memory"; | ||
610 | reg = <0x00 0x20 0x100 0x80>; | ||
611 | }; | ||
612 | |||
613 | rtic_b: rtic-b@20 { | ||
614 | compatible = "fsl,sec-v4.1-rtic-memory", "fsl,sec-v4.0-rtic-memory"; | ||
615 | reg = <0x20 0x20 0x200 0x80>; | ||
616 | }; | ||
617 | |||
618 | rtic_c: rtic-c@40 { | ||
619 | compatible = "fsl,sec-v4.1-rtic-memory", "fsl,sec-v4.0-rtic-memory"; | ||
620 | reg = <0x40 0x20 0x300 0x80>; | ||
621 | }; | ||
622 | |||
623 | rtic_d: rtic-d@60 { | ||
624 | compatible = "fsl,sec-v4.1-rtic-memory", "fsl,sec-v4.0-rtic-memory"; | ||
625 | reg = <0x60 0x20 0x500 0x80>; | ||
626 | }; | ||
627 | }; | ||
628 | }; | ||
629 | |||
630 | sec_mon: sec_mon@314000 { | ||
631 | compatible = "fsl,sec-v4.1-mon", "fsl,sec-v4.0-mon"; | ||
632 | reg = <0x314000 0x1000>; | ||
633 | interrupt-parent = <&mpic>; | ||
634 | interrupts = <93 2 0 0>; | ||
635 | }; | ||
636 | }; | ||
637 | |||
638 | rapidio@ffe0c0000 { | ||
639 | compatible = "fsl,srio"; | ||
640 | interrupts = <16 2 1 11>; | ||
641 | #address-cells = <2>; | ||
642 | #size-cells = <2>; | ||
643 | fsl,srio-rmu-handle = <&rmu>; | ||
644 | ranges; | ||
645 | |||
646 | port1 { | ||
647 | #address-cells = <2>; | ||
648 | #size-cells = <2>; | ||
649 | cell-index = <1>; | ||
650 | }; | ||
651 | |||
652 | port2 { | ||
653 | #address-cells = <2>; | ||
654 | #size-cells = <2>; | ||
655 | cell-index = <2>; | ||
656 | }; | ||
657 | }; | ||
658 | |||
659 | localbus@ffe124000 { | ||
660 | compatible = "fsl,p3060-elbc", "fsl,elbc", "simple-bus"; | ||
661 | interrupts = <25 2 0 0>; | ||
662 | #address-cells = <2>; | ||
663 | #size-cells = <1>; | ||
664 | }; | ||
665 | |||
666 | pci0: pcie@ffe200000 { | ||
667 | compatible = "fsl,p3060-pcie", "fsl,qoriq-pcie-v2.2"; | ||
668 | device_type = "pci"; | ||
669 | #size-cells = <2>; | ||
670 | #address-cells = <3>; | ||
671 | bus-range = <0x0 0xff>; | ||
672 | clock-frequency = <33333333>; | ||
673 | fsl,msi = <&msi0>; | ||
674 | interrupts = <16 2 1 15>; | ||
675 | pcie@0 { | ||
676 | reg = <0 0 0 0 0>; | ||
677 | #interrupt-cells = <1>; | ||
678 | #size-cells = <2>; | ||
679 | #address-cells = <3>; | ||
680 | device_type = "pci"; | ||
681 | interrupts = <16 2 1 15>; | ||
682 | interrupt-map-mask = <0xf800 0 0 7>; | ||
683 | interrupt-map = < | ||
684 | /* IDSEL 0x0 */ | ||
685 | 0000 0 0 1 &mpic 40 1 0 0 | ||
686 | 0000 0 0 2 &mpic 1 1 0 0 | ||
687 | 0000 0 0 3 &mpic 2 1 0 0 | ||
688 | 0000 0 0 4 &mpic 3 1 0 0 | ||
689 | >; | ||
690 | }; | ||
691 | }; | ||
692 | |||
693 | pci1: pcie@ffe201000 { | ||
694 | compatible = "fsl,p3060-pcie", "fsl,qoriq-pcie-v2.2"; | ||
695 | device_type = "pci"; | ||
696 | #size-cells = <2>; | ||
697 | #address-cells = <3>; | ||
698 | bus-range = <0 0xff>; | ||
699 | clock-frequency = <33333333>; | ||
700 | fsl,msi = <&msi1>; | ||
701 | interrupts = <16 2 1 14>; | ||
702 | pcie@0 { | ||
703 | reg = <0 0 0 0 0>; | ||
704 | #interrupt-cells = <1>; | ||
705 | #size-cells = <2>; | ||
706 | #address-cells = <3>; | ||
707 | device_type = "pci"; | ||
708 | interrupts = <16 2 1 14>; | ||
709 | interrupt-map-mask = <0xf800 0 0 7>; | ||
710 | interrupt-map = < | ||
711 | /* IDSEL 0x0 */ | ||
712 | 0000 0 0 1 &mpic 41 1 0 0 | ||
713 | 0000 0 0 2 &mpic 5 1 0 0 | ||
714 | 0000 0 0 3 &mpic 6 1 0 0 | ||
715 | 0000 0 0 4 &mpic 7 1 0 0 | ||
716 | >; | ||
717 | }; | ||
718 | }; | ||
719 | }; | ||
diff --git a/arch/powerpc/boot/dts/p4080ds.dts b/arch/powerpc/boot/dts/p4080ds.dts index eb11098bb687..c7916dc28014 100644 --- a/arch/powerpc/boot/dts/p4080ds.dts +++ b/arch/powerpc/boot/dts/p4080ds.dts | |||
@@ -45,6 +45,10 @@ | |||
45 | device_type = "memory"; | 45 | device_type = "memory"; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | dcsr: dcsr@f00000000 { | ||
49 | ranges = <0x00000000 0xf 0x00000000 0x01008000>; | ||
50 | }; | ||
51 | |||
48 | soc: soc@ffe000000 { | 52 | soc: soc@ffe000000 { |
49 | spi@110000 { | 53 | spi@110000 { |
50 | flash@0 { | 54 | flash@0 { |
@@ -108,7 +112,8 @@ | |||
108 | 112 | ||
109 | localbus@ffe124000 { | 113 | localbus@ffe124000 { |
110 | reg = <0xf 0xfe124000 0 0x1000>; | 114 | reg = <0xf 0xfe124000 0 0x1000>; |
111 | ranges = <0 0 0xf 0xe8000000 0x08000000>; | 115 | ranges = <0 0 0xf 0xe8000000 0x08000000 |
116 | 3 0 0xf 0xffdf0000 0x00008000>; | ||
112 | 117 | ||
113 | flash@0,0 { | 118 | flash@0,0 { |
114 | compatible = "cfi-flash"; | 119 | compatible = "cfi-flash"; |
@@ -116,6 +121,11 @@ | |||
116 | bank-width = <2>; | 121 | bank-width = <2>; |
117 | device-width = <2>; | 122 | device-width = <2>; |
118 | }; | 123 | }; |
124 | |||
125 | board-control@3,0 { | ||
126 | compatible = "fsl,p4080ds-fpga", "fsl,fpga-ngpixis"; | ||
127 | reg = <3 0 0x30>; | ||
128 | }; | ||
119 | }; | 129 | }; |
120 | 130 | ||
121 | pci0: pcie@ffe200000 { | 131 | pci0: pcie@ffe200000 { |
diff --git a/arch/powerpc/boot/dts/p4080si.dtsi b/arch/powerpc/boot/dts/p4080si.dtsi index b71051f506c1..f20c01ab2473 100644 --- a/arch/powerpc/boot/dts/p4080si.dtsi +++ b/arch/powerpc/boot/dts/p4080si.dtsi | |||
@@ -42,6 +42,7 @@ | |||
42 | 42 | ||
43 | aliases { | 43 | aliases { |
44 | ccsr = &soc; | 44 | ccsr = &soc; |
45 | dcsr = &dcsr; | ||
45 | 46 | ||
46 | serial0 = &serial0; | 47 | serial0 = &serial0; |
47 | serial1 = &serial1; | 48 | serial1 = &serial1; |
@@ -77,7 +78,7 @@ | |||
77 | #address-cells = <1>; | 78 | #address-cells = <1>; |
78 | #size-cells = <0>; | 79 | #size-cells = <0>; |
79 | 80 | ||
80 | cpu0: PowerPC,4080@0 { | 81 | cpu0: PowerPC,e500mc@0 { |
81 | device_type = "cpu"; | 82 | device_type = "cpu"; |
82 | reg = <0>; | 83 | reg = <0>; |
83 | next-level-cache = <&L2_0>; | 84 | next-level-cache = <&L2_0>; |
@@ -85,7 +86,7 @@ | |||
85 | next-level-cache = <&cpc>; | 86 | next-level-cache = <&cpc>; |
86 | }; | 87 | }; |
87 | }; | 88 | }; |
88 | cpu1: PowerPC,4080@1 { | 89 | cpu1: PowerPC,e500mc@1 { |
89 | device_type = "cpu"; | 90 | device_type = "cpu"; |
90 | reg = <1>; | 91 | reg = <1>; |
91 | next-level-cache = <&L2_1>; | 92 | next-level-cache = <&L2_1>; |
@@ -93,7 +94,7 @@ | |||
93 | next-level-cache = <&cpc>; | 94 | next-level-cache = <&cpc>; |
94 | }; | 95 | }; |
95 | }; | 96 | }; |
96 | cpu2: PowerPC,4080@2 { | 97 | cpu2: PowerPC,e500mc@2 { |
97 | device_type = "cpu"; | 98 | device_type = "cpu"; |
98 | reg = <2>; | 99 | reg = <2>; |
99 | next-level-cache = <&L2_2>; | 100 | next-level-cache = <&L2_2>; |
@@ -101,7 +102,7 @@ | |||
101 | next-level-cache = <&cpc>; | 102 | next-level-cache = <&cpc>; |
102 | }; | 103 | }; |
103 | }; | 104 | }; |
104 | cpu3: PowerPC,4080@3 { | 105 | cpu3: PowerPC,e500mc@3 { |
105 | device_type = "cpu"; | 106 | device_type = "cpu"; |
106 | reg = <3>; | 107 | reg = <3>; |
107 | next-level-cache = <&L2_3>; | 108 | next-level-cache = <&L2_3>; |
@@ -109,7 +110,7 @@ | |||
109 | next-level-cache = <&cpc>; | 110 | next-level-cache = <&cpc>; |
110 | }; | 111 | }; |
111 | }; | 112 | }; |
112 | cpu4: PowerPC,4080@4 { | 113 | cpu4: PowerPC,e500mc@4 { |
113 | device_type = "cpu"; | 114 | device_type = "cpu"; |
114 | reg = <4>; | 115 | reg = <4>; |
115 | next-level-cache = <&L2_4>; | 116 | next-level-cache = <&L2_4>; |
@@ -117,7 +118,7 @@ | |||
117 | next-level-cache = <&cpc>; | 118 | next-level-cache = <&cpc>; |
118 | }; | 119 | }; |
119 | }; | 120 | }; |
120 | cpu5: PowerPC,4080@5 { | 121 | cpu5: PowerPC,e500mc@5 { |
121 | device_type = "cpu"; | 122 | device_type = "cpu"; |
122 | reg = <5>; | 123 | reg = <5>; |
123 | next-level-cache = <&L2_5>; | 124 | next-level-cache = <&L2_5>; |
@@ -125,7 +126,7 @@ | |||
125 | next-level-cache = <&cpc>; | 126 | next-level-cache = <&cpc>; |
126 | }; | 127 | }; |
127 | }; | 128 | }; |
128 | cpu6: PowerPC,4080@6 { | 129 | cpu6: PowerPC,e500mc@6 { |
129 | device_type = "cpu"; | 130 | device_type = "cpu"; |
130 | reg = <6>; | 131 | reg = <6>; |
131 | next-level-cache = <&L2_6>; | 132 | next-level-cache = <&L2_6>; |
@@ -133,7 +134,7 @@ | |||
133 | next-level-cache = <&cpc>; | 134 | next-level-cache = <&cpc>; |
134 | }; | 135 | }; |
135 | }; | 136 | }; |
136 | cpu7: PowerPC,4080@7 { | 137 | cpu7: PowerPC,e500mc@7 { |
137 | device_type = "cpu"; | 138 | device_type = "cpu"; |
138 | reg = <7>; | 139 | reg = <7>; |
139 | next-level-cache = <&L2_7>; | 140 | next-level-cache = <&L2_7>; |
@@ -143,6 +144,99 @@ | |||
143 | }; | 144 | }; |
144 | }; | 145 | }; |
145 | 146 | ||
147 | dcsr: dcsr@f00000000 { | ||
148 | #address-cells = <1>; | ||
149 | #size-cells = <1>; | ||
150 | compatible = "fsl,dcsr", "simple-bus"; | ||
151 | |||
152 | dcsr-epu@0 { | ||
153 | compatible = "fsl,dcsr-epu"; | ||
154 | interrupts = <52 2 0 0 | ||
155 | 84 2 0 0 | ||
156 | 85 2 0 0>; | ||
157 | interrupt-parent = <&mpic>; | ||
158 | reg = <0x0 0x1000>; | ||
159 | }; | ||
160 | dcsr-npc { | ||
161 | compatible = "fsl,dcsr-npc"; | ||
162 | reg = <0x1000 0x1000 0x1000000 0x8000>; | ||
163 | }; | ||
164 | dcsr-nxc@2000 { | ||
165 | compatible = "fsl,dcsr-nxc"; | ||
166 | reg = <0x2000 0x1000>; | ||
167 | }; | ||
168 | dcsr-corenet { | ||
169 | compatible = "fsl,dcsr-corenet"; | ||
170 | reg = <0x8000 0x1000 0xB0000 0x1000>; | ||
171 | }; | ||
172 | dcsr-dpaa@9000 { | ||
173 | compatible = "fsl,p4080-dcsr-dpaa", "fsl,dcsr-dpaa"; | ||
174 | reg = <0x9000 0x1000>; | ||
175 | }; | ||
176 | dcsr-ocn@11000 { | ||
177 | compatible = "fsl,p4080-dcsr-ocn", "fsl,dcsr-ocn"; | ||
178 | reg = <0x11000 0x1000>; | ||
179 | }; | ||
180 | dcsr-ddr@12000 { | ||
181 | compatible = "fsl,dcsr-ddr"; | ||
182 | dev-handle = <&ddr1>; | ||
183 | reg = <0x12000 0x1000>; | ||
184 | }; | ||
185 | dcsr-ddr@13000 { | ||
186 | compatible = "fsl,dcsr-ddr"; | ||
187 | dev-handle = <&ddr2>; | ||
188 | reg = <0x13000 0x1000>; | ||
189 | }; | ||
190 | dcsr-nal@18000 { | ||
191 | compatible = "fsl,p4080-dcsr-nal", "fsl,dcsr-nal"; | ||
192 | reg = <0x18000 0x1000>; | ||
193 | }; | ||
194 | dcsr-rcpm@22000 { | ||
195 | compatible = "fsl,p4080-dcsr-rcpm", "fsl,dcsr-rcpm"; | ||
196 | reg = <0x22000 0x1000>; | ||
197 | }; | ||
198 | dcsr-cpu-sb-proxy@40000 { | ||
199 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
200 | cpu-handle = <&cpu0>; | ||
201 | reg = <0x40000 0x1000>; | ||
202 | }; | ||
203 | dcsr-cpu-sb-proxy@41000 { | ||
204 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
205 | cpu-handle = <&cpu1>; | ||
206 | reg = <0x41000 0x1000>; | ||
207 | }; | ||
208 | dcsr-cpu-sb-proxy@42000 { | ||
209 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
210 | cpu-handle = <&cpu2>; | ||
211 | reg = <0x42000 0x1000>; | ||
212 | }; | ||
213 | dcsr-cpu-sb-proxy@43000 { | ||
214 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
215 | cpu-handle = <&cpu3>; | ||
216 | reg = <0x43000 0x1000>; | ||
217 | }; | ||
218 | dcsr-cpu-sb-proxy@44000 { | ||
219 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
220 | cpu-handle = <&cpu4>; | ||
221 | reg = <0x44000 0x1000>; | ||
222 | }; | ||
223 | dcsr-cpu-sb-proxy@45000 { | ||
224 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
225 | cpu-handle = <&cpu5>; | ||
226 | reg = <0x45000 0x1000>; | ||
227 | }; | ||
228 | dcsr-cpu-sb-proxy@46000 { | ||
229 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
230 | cpu-handle = <&cpu6>; | ||
231 | reg = <0x46000 0x1000>; | ||
232 | }; | ||
233 | dcsr-cpu-sb-proxy@47000 { | ||
234 | compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
235 | cpu-handle = <&cpu7>; | ||
236 | reg = <0x47000 0x1000>; | ||
237 | }; | ||
238 | }; | ||
239 | |||
146 | soc: soc@ffe000000 { | 240 | soc: soc@ffe000000 { |
147 | #address-cells = <1>; | 241 | #address-cells = <1>; |
148 | #size-cells = <1>; | 242 | #size-cells = <1>; |
@@ -162,13 +256,13 @@ | |||
162 | fsl,num-laws = <32>; | 256 | fsl,num-laws = <32>; |
163 | }; | 257 | }; |
164 | 258 | ||
165 | memory-controller@8000 { | 259 | ddr1: memory-controller@8000 { |
166 | compatible = "fsl,qoriq-memory-controller-v4.4", "fsl,qoriq-memory-controller"; | 260 | compatible = "fsl,qoriq-memory-controller-v4.4", "fsl,qoriq-memory-controller"; |
167 | reg = <0x8000 0x1000>; | 261 | reg = <0x8000 0x1000>; |
168 | interrupts = <16 2 1 23>; | 262 | interrupts = <16 2 1 23>; |
169 | }; | 263 | }; |
170 | 264 | ||
171 | memory-controller@9000 { | 265 | ddr2: memory-controller@9000 { |
172 | compatible = "fsl,qoriq-memory-controller-v4.4","fsl,qoriq-memory-controller"; | 266 | compatible = "fsl,qoriq-memory-controller-v4.4","fsl,qoriq-memory-controller"; |
173 | reg = <0x9000 0x1000>; | 267 | reg = <0x9000 0x1000>; |
174 | interrupts = <16 2 1 22>; | 268 | interrupts = <16 2 1 22>; |
diff --git a/arch/powerpc/boot/dts/p5020ds.dts b/arch/powerpc/boot/dts/p5020ds.dts index 8366e2fd2fba..e6d40999ccd7 100644 --- a/arch/powerpc/boot/dts/p5020ds.dts +++ b/arch/powerpc/boot/dts/p5020ds.dts | |||
@@ -45,6 +45,10 @@ | |||
45 | device_type = "memory"; | 45 | device_type = "memory"; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | dcsr: dcsr@f00000000 { | ||
49 | ranges = <0x00000000 0xf 0x00000000 0x01008000>; | ||
50 | }; | ||
51 | |||
48 | soc: soc@ffe000000 { | 52 | soc: soc@ffe000000 { |
49 | spi@110000 { | 53 | spi@110000 { |
50 | flash@0 { | 54 | flash@0 { |
@@ -147,8 +151,8 @@ | |||
147 | }; | 151 | }; |
148 | 152 | ||
149 | board-control@3,0 { | 153 | board-control@3,0 { |
150 | compatible = "fsl,p5020ds-pixis"; | 154 | compatible = "fsl,p5020ds-fpga", "fsl,fpga-ngpixis"; |
151 | reg = <3 0 0x20>; | 155 | reg = <3 0 0x30>; |
152 | }; | 156 | }; |
153 | }; | 157 | }; |
154 | 158 | ||
diff --git a/arch/powerpc/boot/dts/p5020si.dtsi b/arch/powerpc/boot/dts/p5020si.dtsi index 5e6048ec55bb..e7948ad71fa3 100644 --- a/arch/powerpc/boot/dts/p5020si.dtsi +++ b/arch/powerpc/boot/dts/p5020si.dtsi | |||
@@ -42,6 +42,7 @@ | |||
42 | 42 | ||
43 | aliases { | 43 | aliases { |
44 | ccsr = &soc; | 44 | ccsr = &soc; |
45 | dcsr = &dcsr; | ||
45 | 46 | ||
46 | serial0 = &serial0; | 47 | serial0 = &serial0; |
47 | serial1 = &serial1; | 48 | serial1 = &serial1; |
@@ -98,6 +99,69 @@ | |||
98 | }; | 99 | }; |
99 | }; | 100 | }; |
100 | 101 | ||
102 | dcsr: dcsr@f00000000 { | ||
103 | #address-cells = <1>; | ||
104 | #size-cells = <1>; | ||
105 | compatible = "fsl,dcsr", "simple-bus"; | ||
106 | |||
107 | dcsr-epu@0 { | ||
108 | compatible = "fsl,dcsr-epu"; | ||
109 | interrupts = <52 2 0 0 | ||
110 | 84 2 0 0 | ||
111 | 85 2 0 0>; | ||
112 | interrupt-parent = <&mpic>; | ||
113 | reg = <0x0 0x1000>; | ||
114 | }; | ||
115 | dcsr-npc { | ||
116 | compatible = "fsl,dcsr-npc"; | ||
117 | reg = <0x1000 0x1000 0x1000000 0x8000>; | ||
118 | }; | ||
119 | dcsr-nxc@2000 { | ||
120 | compatible = "fsl,dcsr-nxc"; | ||
121 | reg = <0x2000 0x1000>; | ||
122 | }; | ||
123 | dcsr-corenet { | ||
124 | compatible = "fsl,dcsr-corenet"; | ||
125 | reg = <0x8000 0x1000 0xB0000 0x1000>; | ||
126 | }; | ||
127 | dcsr-dpaa@9000 { | ||
128 | compatible = "fsl,p5020-dcsr-dpaa", "fsl,dcsr-dpaa"; | ||
129 | reg = <0x9000 0x1000>; | ||
130 | }; | ||
131 | dcsr-ocn@11000 { | ||
132 | compatible = "fsl,p5020-dcsr-ocn", "fsl,dcsr-ocn"; | ||
133 | reg = <0x11000 0x1000>; | ||
134 | }; | ||
135 | dcsr-ddr@12000 { | ||
136 | compatible = "fsl,dcsr-ddr"; | ||
137 | dev-handle = <&ddr1>; | ||
138 | reg = <0x12000 0x1000>; | ||
139 | }; | ||
140 | dcsr-ddr@13000 { | ||
141 | compatible = "fsl,dcsr-ddr"; | ||
142 | dev-handle = <&ddr2>; | ||
143 | reg = <0x13000 0x1000>; | ||
144 | }; | ||
145 | dcsr-nal@18000 { | ||
146 | compatible = "fsl,p5020-dcsr-nal", "fsl,dcsr-nal"; | ||
147 | reg = <0x18000 0x1000>; | ||
148 | }; | ||
149 | dcsr-rcpm@22000 { | ||
150 | compatible = "fsl,p5020-dcsr-rcpm", "fsl,dcsr-rcpm"; | ||
151 | reg = <0x22000 0x1000>; | ||
152 | }; | ||
153 | dcsr-cpu-sb-proxy@40000 { | ||
154 | compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
155 | cpu-handle = <&cpu0>; | ||
156 | reg = <0x40000 0x1000>; | ||
157 | }; | ||
158 | dcsr-cpu-sb-proxy@41000 { | ||
159 | compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
160 | cpu-handle = <&cpu1>; | ||
161 | reg = <0x41000 0x1000>; | ||
162 | }; | ||
163 | }; | ||
164 | |||
101 | soc: soc@ffe000000 { | 165 | soc: soc@ffe000000 { |
102 | #address-cells = <1>; | 166 | #address-cells = <1>; |
103 | #size-cells = <1>; | 167 | #size-cells = <1>; |
@@ -117,13 +181,13 @@ | |||
117 | fsl,num-laws = <32>; | 181 | fsl,num-laws = <32>; |
118 | }; | 182 | }; |
119 | 183 | ||
120 | memory-controller@8000 { | 184 | ddr1: memory-controller@8000 { |
121 | compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; | 185 | compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; |
122 | reg = <0x8000 0x1000>; | 186 | reg = <0x8000 0x1000>; |
123 | interrupts = <16 2 1 23>; | 187 | interrupts = <16 2 1 23>; |
124 | }; | 188 | }; |
125 | 189 | ||
126 | memory-controller@9000 { | 190 | ddr2: memory-controller@9000 { |
127 | compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; | 191 | compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; |
128 | reg = <0x9000 0x1000>; | 192 | reg = <0x9000 0x1000>; |
129 | interrupts = <16 2 1 22>; | 193 | interrupts = <16 2 1 22>; |
diff --git a/arch/powerpc/boot/dts/sbc8560.dts b/arch/powerpc/boot/dts/sbc8560.dts index 9e13ed8a1193..72078eb15616 100644 --- a/arch/powerpc/boot/dts/sbc8560.dts +++ b/arch/powerpc/boot/dts/sbc8560.dts | |||
@@ -331,7 +331,7 @@ | |||
331 | }; | 331 | }; |
332 | 332 | ||
333 | localbus@ff705000 { | 333 | localbus@ff705000 { |
334 | compatible = "fsl,mpc8560-localbus"; | 334 | compatible = "fsl,mpc8560-localbus", "simple-bus"; |
335 | #address-cells = <2>; | 335 | #address-cells = <2>; |
336 | #size-cells = <1>; | 336 | #size-cells = <1>; |
337 | reg = <0xff705000 0x100>; // BRx, ORx, etc. | 337 | reg = <0xff705000 0x100>; // BRx, ORx, etc. |
diff --git a/arch/powerpc/boot/dts/yosemite.dts b/arch/powerpc/boot/dts/yosemite.dts index 64923245f0e5..30bb4753577a 100644 --- a/arch/powerpc/boot/dts/yosemite.dts +++ b/arch/powerpc/boot/dts/yosemite.dts | |||
@@ -138,6 +138,42 @@ | |||
138 | clock-frequency = <0>; /* Filled in by zImage */ | 138 | clock-frequency = <0>; /* Filled in by zImage */ |
139 | interrupts = <0x5 0x1>; | 139 | interrupts = <0x5 0x1>; |
140 | interrupt-parent = <&UIC1>; | 140 | interrupt-parent = <&UIC1>; |
141 | |||
142 | nor_flash@0,0 { | ||
143 | compatible = "amd,s29gl256n", "cfi-flash"; | ||
144 | bank-width = <2>; | ||
145 | reg = <0x00000000 0x00000000 0x04000000>; | ||
146 | #address-cells = <1>; | ||
147 | #size-cells = <1>; | ||
148 | partition@0 { | ||
149 | label = "kernel"; | ||
150 | reg = <0x00000000 0x001e0000>; | ||
151 | }; | ||
152 | partition@1e0000 { | ||
153 | label = "dtb"; | ||
154 | reg = <0x001e0000 0x00020000>; | ||
155 | }; | ||
156 | partition@200000 { | ||
157 | label = "ramdisk"; | ||
158 | reg = <0x00200000 0x01400000>; | ||
159 | }; | ||
160 | partition@1600000 { | ||
161 | label = "jffs2"; | ||
162 | reg = <0x01600000 0x00400000>; | ||
163 | }; | ||
164 | partition@1a00000 { | ||
165 | label = "user"; | ||
166 | reg = <0x01a00000 0x02540000>; | ||
167 | }; | ||
168 | partition@3f40000 { | ||
169 | label = "env"; | ||
170 | reg = <0x03f40000 0x00040000>; | ||
171 | }; | ||
172 | partition@3f80000 { | ||
173 | label = "u-boot"; | ||
174 | reg = <0x03f80000 0x00080000>; | ||
175 | }; | ||
176 | }; | ||
141 | }; | 177 | }; |
142 | 178 | ||
143 | UART0: serial@ef600300 { | 179 | UART0: serial@ef600300 { |
diff --git a/arch/powerpc/configs/40x/hcu4_defconfig b/arch/powerpc/configs/40x/hcu4_defconfig deleted file mode 100644 index dba263c1d3a2..000000000000 --- a/arch/powerpc/configs/40x/hcu4_defconfig +++ /dev/null | |||
@@ -1,81 +0,0 @@ | |||
1 | CONFIG_40x=y | ||
2 | CONFIG_EXPERIMENTAL=y | ||
3 | CONFIG_SYSVIPC=y | ||
4 | CONFIG_POSIX_MQUEUE=y | ||
5 | CONFIG_LOG_BUF_SHIFT=14 | ||
6 | CONFIG_BLK_DEV_INITRD=y | ||
7 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
8 | CONFIG_EXPERT=y | ||
9 | CONFIG_KALLSYMS_ALL=y | ||
10 | CONFIG_KALLSYMS_EXTRA_PASS=y | ||
11 | CONFIG_MODULES=y | ||
12 | CONFIG_MODULE_UNLOAD=y | ||
13 | # CONFIG_BLK_DEV_BSG is not set | ||
14 | CONFIG_HCU4=y | ||
15 | # CONFIG_WALNUT is not set | ||
16 | CONFIG_SPARSE_IRQ=y | ||
17 | CONFIG_PCI=y | ||
18 | CONFIG_NET=y | ||
19 | CONFIG_PACKET=y | ||
20 | CONFIG_UNIX=y | ||
21 | CONFIG_INET=y | ||
22 | CONFIG_IP_PNP=y | ||
23 | CONFIG_IP_PNP_DHCP=y | ||
24 | CONFIG_IP_PNP_BOOTP=y | ||
25 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
26 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
27 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
28 | # CONFIG_INET_LRO is not set | ||
29 | # CONFIG_IPV6 is not set | ||
30 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
31 | CONFIG_CONNECTOR=y | ||
32 | CONFIG_MTD=y | ||
33 | CONFIG_MTD_PARTITIONS=y | ||
34 | CONFIG_MTD_CMDLINE_PARTS=y | ||
35 | CONFIG_MTD_OF_PARTS=y | ||
36 | CONFIG_MTD_CHAR=y | ||
37 | CONFIG_MTD_BLOCK=m | ||
38 | CONFIG_MTD_CFI=y | ||
39 | CONFIG_MTD_JEDECPROBE=y | ||
40 | CONFIG_MTD_CFI_AMDSTD=y | ||
41 | CONFIG_MTD_PHYSMAP_OF=y | ||
42 | CONFIG_PROC_DEVICETREE=y | ||
43 | CONFIG_BLK_DEV_RAM=y | ||
44 | CONFIG_BLK_DEV_RAM_SIZE=35000 | ||
45 | CONFIG_NETDEVICES=y | ||
46 | CONFIG_ETHERNET=y | ||
47 | CONFIG_NET_VENDOR_IBM=y | ||
48 | CONFIG_IBM_EMAC=y | ||
49 | # CONFIG_INPUT is not set | ||
50 | # CONFIG_SERIO is not set | ||
51 | # CONFIG_VT is not set | ||
52 | CONFIG_SERIAL_8250=y | ||
53 | CONFIG_SERIAL_8250_CONSOLE=y | ||
54 | CONFIG_SERIAL_8250_EXTENDED=y | ||
55 | CONFIG_SERIAL_8250_SHARE_IRQ=y | ||
56 | CONFIG_SERIAL_OF_PLATFORM=y | ||
57 | # CONFIG_HW_RANDOM is not set | ||
58 | # CONFIG_HWMON is not set | ||
59 | CONFIG_VIDEO_OUTPUT_CONTROL=m | ||
60 | # CONFIG_USB_SUPPORT is not set | ||
61 | CONFIG_EXT2_FS=y | ||
62 | CONFIG_INOTIFY=y | ||
63 | CONFIG_PROC_KCORE=y | ||
64 | CONFIG_TMPFS=y | ||
65 | CONFIG_CRAMFS=y | ||
66 | CONFIG_NFS_FS=y | ||
67 | CONFIG_NFS_V3=y | ||
68 | CONFIG_ROOT_NFS=y | ||
69 | CONFIG_MAGIC_SYSRQ=y | ||
70 | CONFIG_DEBUG_FS=y | ||
71 | CONFIG_DEBUG_KERNEL=y | ||
72 | CONFIG_DETECT_HUNG_TASK=y | ||
73 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
74 | CONFIG_SYSCTL_SYSCALL_CHECK=y | ||
75 | CONFIG_CRYPTO=y | ||
76 | CONFIG_CRYPTO_CBC=y | ||
77 | CONFIG_CRYPTO_ECB=y | ||
78 | CONFIG_CRYPTO_PCBC=y | ||
79 | CONFIG_CRYPTO_MD5=y | ||
80 | CONFIG_CRYPTO_DES=y | ||
81 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
diff --git a/arch/powerpc/configs/85xx/p1023rds_defconfig b/arch/powerpc/configs/85xx/p1023rds_defconfig index 3ff5a81c709f..c091aaf7685f 100644 --- a/arch/powerpc/configs/85xx/p1023rds_defconfig +++ b/arch/powerpc/configs/85xx/p1023rds_defconfig | |||
@@ -24,7 +24,7 @@ CONFIG_P1023_RDS=y | |||
24 | CONFIG_QUICC_ENGINE=y | 24 | CONFIG_QUICC_ENGINE=y |
25 | CONFIG_QE_GPIO=y | 25 | CONFIG_QE_GPIO=y |
26 | CONFIG_CPM2=y | 26 | CONFIG_CPM2=y |
27 | CONFIG_MPC8xxx_GPIO=y | 27 | CONFIG_GPIO_MPC8XXX=y |
28 | CONFIG_HIGHMEM=y | 28 | CONFIG_HIGHMEM=y |
29 | CONFIG_NO_HZ=y | 29 | CONFIG_NO_HZ=y |
30 | CONFIG_HIGH_RES_TIMERS=y | 30 | CONFIG_HIGH_RES_TIMERS=y |
diff --git a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig index 5ea3124518fd..1cd6fcb368e9 100644 --- a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig +++ b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig | |||
@@ -20,7 +20,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y | |||
20 | CONFIG_MODVERSIONS=y | 20 | CONFIG_MODVERSIONS=y |
21 | # CONFIG_BLK_DEV_BSG is not set | 21 | # CONFIG_BLK_DEV_BSG is not set |
22 | CONFIG_XES_MPC85xx=y | 22 | CONFIG_XES_MPC85xx=y |
23 | CONFIG_MPC8xxx_GPIO=y | 23 | CONFIG_GPIO_MPC8XXX=y |
24 | CONFIG_HIGHMEM=y | 24 | CONFIG_HIGHMEM=y |
25 | CONFIG_MATH_EMULATION=y | 25 | CONFIG_MATH_EMULATION=y |
26 | CONFIG_SPARSE_IRQ=y | 26 | CONFIG_SPARSE_IRQ=y |
diff --git a/arch/powerpc/configs/corenet32_smp_defconfig b/arch/powerpc/configs/corenet32_smp_defconfig index 4311d02a3bfd..f087de6ec03f 100644 --- a/arch/powerpc/configs/corenet32_smp_defconfig +++ b/arch/powerpc/configs/corenet32_smp_defconfig | |||
@@ -12,9 +12,7 @@ CONFIG_IKCONFIG=y | |||
12 | CONFIG_IKCONFIG_PROC=y | 12 | CONFIG_IKCONFIG_PROC=y |
13 | CONFIG_LOG_BUF_SHIFT=14 | 13 | CONFIG_LOG_BUF_SHIFT=14 |
14 | CONFIG_BLK_DEV_INITRD=y | 14 | CONFIG_BLK_DEV_INITRD=y |
15 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
16 | CONFIG_KALLSYMS_ALL=y | 15 | CONFIG_KALLSYMS_ALL=y |
17 | CONFIG_KALLSYMS_EXTRA_PASS=y | ||
18 | CONFIG_EMBEDDED=y | 16 | CONFIG_EMBEDDED=y |
19 | CONFIG_PERF_EVENTS=y | 17 | CONFIG_PERF_EVENTS=y |
20 | CONFIG_SLAB=y | 18 | CONFIG_SLAB=y |
@@ -23,8 +21,9 @@ CONFIG_MODULE_UNLOAD=y | |||
23 | CONFIG_MODULE_FORCE_UNLOAD=y | 21 | CONFIG_MODULE_FORCE_UNLOAD=y |
24 | CONFIG_MODVERSIONS=y | 22 | CONFIG_MODVERSIONS=y |
25 | # CONFIG_BLK_DEV_BSG is not set | 23 | # CONFIG_BLK_DEV_BSG is not set |
26 | CONFIG_P2040_RDB=y | 24 | CONFIG_P2041_RDB=y |
27 | CONFIG_P3041_DS=y | 25 | CONFIG_P3041_DS=y |
26 | CONFIG_P3060_QDS=y | ||
28 | CONFIG_P4080_DS=y | 27 | CONFIG_P4080_DS=y |
29 | CONFIG_P5020_DS=y | 28 | CONFIG_P5020_DS=y |
30 | CONFIG_HIGHMEM=y | 29 | CONFIG_HIGHMEM=y |
@@ -69,7 +68,6 @@ CONFIG_IPV6=y | |||
69 | CONFIG_IP_SCTP=m | 68 | CONFIG_IP_SCTP=m |
70 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 69 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
71 | CONFIG_MTD=y | 70 | CONFIG_MTD=y |
72 | CONFIG_MTD_PARTITIONS=y | ||
73 | CONFIG_MTD_CMDLINE_PARTS=y | 71 | CONFIG_MTD_CMDLINE_PARTS=y |
74 | CONFIG_MTD_CHAR=y | 72 | CONFIG_MTD_CHAR=y |
75 | CONFIG_MTD_BLOCK=y | 73 | CONFIG_MTD_BLOCK=y |
@@ -107,7 +105,6 @@ CONFIG_FSL_PQ_MDIO=y | |||
107 | # CONFIG_INPUT_MOUSE is not set | 105 | # CONFIG_INPUT_MOUSE is not set |
108 | CONFIG_SERIO_LIBPS2=y | 106 | CONFIG_SERIO_LIBPS2=y |
109 | # CONFIG_LEGACY_PTYS is not set | 107 | # CONFIG_LEGACY_PTYS is not set |
110 | CONFIG_PPC_EPAPR_HV_BYTECHAN=y | ||
111 | CONFIG_SERIAL_8250=y | 108 | CONFIG_SERIAL_8250=y |
112 | CONFIG_SERIAL_8250_CONSOLE=y | 109 | CONFIG_SERIAL_8250_CONSOLE=y |
113 | CONFIG_SERIAL_8250_EXTENDED=y | 110 | CONFIG_SERIAL_8250_EXTENDED=y |
@@ -136,8 +133,6 @@ CONFIG_USB_OHCI_HCD_PPC_OF_LE=y | |||
136 | CONFIG_USB_STORAGE=y | 133 | CONFIG_USB_STORAGE=y |
137 | CONFIG_MMC=y | 134 | CONFIG_MMC=y |
138 | CONFIG_MMC_SDHCI=y | 135 | CONFIG_MMC_SDHCI=y |
139 | CONFIG_MMC_SDHCI_OF=y | ||
140 | CONFIG_MMC_SDHCI_OF_ESDHC=y | ||
141 | CONFIG_EDAC=y | 136 | CONFIG_EDAC=y |
142 | CONFIG_EDAC_MM_EDAC=y | 137 | CONFIG_EDAC_MM_EDAC=y |
143 | CONFIG_EDAC_MPC85XX=y | 138 | CONFIG_EDAC_MPC85XX=y |
@@ -146,7 +141,6 @@ CONFIG_RTC_DRV_DS3232=y | |||
146 | CONFIG_RTC_DRV_CMOS=y | 141 | CONFIG_RTC_DRV_CMOS=y |
147 | CONFIG_UIO=y | 142 | CONFIG_UIO=y |
148 | CONFIG_STAGING=y | 143 | CONFIG_STAGING=y |
149 | # CONFIG_STAGING_EXCLUDE_BUILD is not set | ||
150 | CONFIG_VIRT_DRIVERS=y | 144 | CONFIG_VIRT_DRIVERS=y |
151 | CONFIG_FSL_HV_MANAGER=y | 145 | CONFIG_FSL_HV_MANAGER=y |
152 | CONFIG_EXT2_FS=y | 146 | CONFIG_EXT2_FS=y |
@@ -173,7 +167,6 @@ CONFIG_MAC_PARTITION=y | |||
173 | CONFIG_NLS_ISO8859_1=y | 167 | CONFIG_NLS_ISO8859_1=y |
174 | CONFIG_NLS_UTF8=m | 168 | CONFIG_NLS_UTF8=m |
175 | CONFIG_MAGIC_SYSRQ=y | 169 | CONFIG_MAGIC_SYSRQ=y |
176 | CONFIG_DEBUG_KERNEL=y | ||
177 | CONFIG_DEBUG_SHIRQ=y | 170 | CONFIG_DEBUG_SHIRQ=y |
178 | CONFIG_DETECT_HUNG_TASK=y | 171 | CONFIG_DETECT_HUNG_TASK=y |
179 | CONFIG_DEBUG_INFO=y | 172 | CONFIG_DEBUG_INFO=y |
diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig index c92c204a204b..782822c32d15 100644 --- a/arch/powerpc/configs/corenet64_smp_defconfig +++ b/arch/powerpc/configs/corenet64_smp_defconfig | |||
@@ -11,10 +11,8 @@ CONFIG_IKCONFIG=y | |||
11 | CONFIG_IKCONFIG_PROC=y | 11 | CONFIG_IKCONFIG_PROC=y |
12 | CONFIG_LOG_BUF_SHIFT=14 | 12 | CONFIG_LOG_BUF_SHIFT=14 |
13 | CONFIG_BLK_DEV_INITRD=y | 13 | CONFIG_BLK_DEV_INITRD=y |
14 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
15 | CONFIG_EXPERT=y | 14 | CONFIG_EXPERT=y |
16 | CONFIG_KALLSYMS_ALL=y | 15 | CONFIG_KALLSYMS_ALL=y |
17 | CONFIG_KALLSYMS_EXTRA_PASS=y | ||
18 | CONFIG_MODULES=y | 16 | CONFIG_MODULES=y |
19 | CONFIG_MODULE_UNLOAD=y | 17 | CONFIG_MODULE_UNLOAD=y |
20 | CONFIG_MODULE_FORCE_UNLOAD=y | 18 | CONFIG_MODULE_FORCE_UNLOAD=y |
@@ -25,7 +23,6 @@ CONFIG_P5020_DS=y | |||
25 | CONFIG_NO_HZ=y | 23 | CONFIG_NO_HZ=y |
26 | CONFIG_HIGH_RES_TIMERS=y | 24 | CONFIG_HIGH_RES_TIMERS=y |
27 | CONFIG_BINFMT_MISC=m | 25 | CONFIG_BINFMT_MISC=m |
28 | # CONFIG_PCI is not set | ||
29 | CONFIG_NET=y | 26 | CONFIG_NET=y |
30 | CONFIG_PACKET=y | 27 | CONFIG_PACKET=y |
31 | CONFIG_UNIX=y | 28 | CONFIG_UNIX=y |
@@ -93,10 +90,8 @@ CONFIG_CRC_T10DIF=y | |||
93 | CONFIG_CRC_ITU_T=m | 90 | CONFIG_CRC_ITU_T=m |
94 | CONFIG_FRAME_WARN=1024 | 91 | CONFIG_FRAME_WARN=1024 |
95 | CONFIG_DEBUG_FS=y | 92 | CONFIG_DEBUG_FS=y |
96 | CONFIG_DEBUG_KERNEL=y | ||
97 | CONFIG_DETECT_HUNG_TASK=y | 93 | CONFIG_DETECT_HUNG_TASK=y |
98 | CONFIG_DEBUG_INFO=y | 94 | CONFIG_DEBUG_INFO=y |
99 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
100 | CONFIG_SYSCTL_SYSCALL_CHECK=y | 95 | CONFIG_SYSCTL_SYSCALL_CHECK=y |
101 | CONFIG_VIRQ_DEBUG=y | 96 | CONFIG_VIRQ_DEBUG=y |
102 | CONFIG_CRYPTO_PCBC=m | 97 | CONFIG_CRYPTO_PCBC=m |
diff --git a/arch/powerpc/configs/mgcoge_defconfig b/arch/powerpc/configs/mgcoge_defconfig index 6cb588a7d425..0d36b0e1e268 100644 --- a/arch/powerpc/configs/mgcoge_defconfig +++ b/arch/powerpc/configs/mgcoge_defconfig | |||
@@ -1,15 +1,22 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | ||
2 | # CONFIG_SWAP is not set | ||
1 | CONFIG_SYSVIPC=y | 3 | CONFIG_SYSVIPC=y |
4 | CONFIG_POSIX_MQUEUE=y | ||
2 | CONFIG_SPARSE_IRQ=y | 5 | CONFIG_SPARSE_IRQ=y |
3 | CONFIG_IKCONFIG=y | 6 | CONFIG_IKCONFIG=y |
4 | CONFIG_IKCONFIG_PROC=y | 7 | CONFIG_IKCONFIG_PROC=y |
5 | CONFIG_LOG_BUF_SHIFT=14 | 8 | CONFIG_LOG_BUF_SHIFT=14 |
6 | CONFIG_BLK_DEV_INITRD=y | 9 | CONFIG_BLK_DEV_INITRD=y |
7 | CONFIG_EXPERT=y | 10 | # CONFIG_RD_GZIP is not set |
8 | CONFIG_KALLSYMS_ALL=y | 11 | CONFIG_KALLSYMS_ALL=y |
12 | # CONFIG_PCSPKR_PLATFORM is not set | ||
13 | CONFIG_EMBEDDED=y | ||
9 | CONFIG_SLAB=y | 14 | CONFIG_SLAB=y |
10 | # CONFIG_IOSCHED_CFQ is not set | 15 | # CONFIG_IOSCHED_CFQ is not set |
16 | # CONFIG_PPC_PMAC is not set | ||
11 | CONFIG_PPC_82xx=y | 17 | CONFIG_PPC_82xx=y |
12 | CONFIG_MGCOGE=y | 18 | CONFIG_MGCOGE=y |
19 | CONFIG_HIGH_RES_TIMERS=y | ||
13 | CONFIG_BINFMT_MISC=y | 20 | CONFIG_BINFMT_MISC=y |
14 | # CONFIG_SECCOMP is not set | 21 | # CONFIG_SECCOMP is not set |
15 | CONFIG_NET=y | 22 | CONFIG_NET=y |
@@ -24,11 +31,10 @@ CONFIG_SYN_COOKIES=y | |||
24 | # CONFIG_INET_LRO is not set | 31 | # CONFIG_INET_LRO is not set |
25 | # CONFIG_IPV6 is not set | 32 | # CONFIG_IPV6 is not set |
26 | CONFIG_NETFILTER=y | 33 | CONFIG_NETFILTER=y |
34 | CONFIG_TIPC=y | ||
27 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 35 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
28 | # CONFIG_FW_LOADER is not set | 36 | # CONFIG_FW_LOADER is not set |
29 | CONFIG_MTD=y | 37 | CONFIG_MTD=y |
30 | CONFIG_MTD_CONCAT=y | ||
31 | CONFIG_MTD_PARTITIONS=y | ||
32 | CONFIG_MTD_CMDLINE_PARTS=y | 38 | CONFIG_MTD_CMDLINE_PARTS=y |
33 | CONFIG_MTD_CHAR=y | 39 | CONFIG_MTD_CHAR=y |
34 | CONFIG_MTD_BLKDEVS=y | 40 | CONFIG_MTD_BLKDEVS=y |
@@ -42,7 +48,6 @@ CONFIG_MTD_PHYSMAP_OF=y | |||
42 | CONFIG_PROC_DEVICETREE=y | 48 | CONFIG_PROC_DEVICETREE=y |
43 | CONFIG_BLK_DEV_LOOP=y | 49 | CONFIG_BLK_DEV_LOOP=y |
44 | CONFIG_BLK_DEV_RAM=y | 50 | CONFIG_BLK_DEV_RAM=y |
45 | # CONFIG_MACINTOSH_DRIVERS is not set | ||
46 | CONFIG_NETDEVICES=y | 51 | CONFIG_NETDEVICES=y |
47 | CONFIG_FIXED_PHY=y | 52 | CONFIG_FIXED_PHY=y |
48 | CONFIG_NET_ETHERNET=y | 53 | CONFIG_NET_ETHERNET=y |
@@ -50,6 +55,7 @@ CONFIG_FS_ENET=y | |||
50 | CONFIG_FS_ENET_MDIO_FCC=y | 55 | CONFIG_FS_ENET_MDIO_FCC=y |
51 | # CONFIG_NETDEV_1000 is not set | 56 | # CONFIG_NETDEV_1000 is not set |
52 | # CONFIG_NETDEV_10000 is not set | 57 | # CONFIG_NETDEV_10000 is not set |
58 | # CONFIG_WLAN is not set | ||
53 | # CONFIG_INPUT is not set | 59 | # CONFIG_INPUT is not set |
54 | # CONFIG_SERIO is not set | 60 | # CONFIG_SERIO is not set |
55 | # CONFIG_VT is not set | 61 | # CONFIG_VT is not set |
@@ -57,24 +63,24 @@ CONFIG_SERIAL_CPM=y | |||
57 | CONFIG_SERIAL_CPM_CONSOLE=y | 63 | CONFIG_SERIAL_CPM_CONSOLE=y |
58 | CONFIG_I2C=y | 64 | CONFIG_I2C=y |
59 | CONFIG_I2C_CHARDEV=y | 65 | CONFIG_I2C_CHARDEV=y |
60 | # CONFIG_I2C_POWERMAC is not set | ||
61 | CONFIG_I2C_CPM=y | 66 | CONFIG_I2C_CPM=y |
62 | # CONFIG_HWMON is not set | 67 | # CONFIG_HWMON is not set |
63 | # CONFIG_USB_SUPPORT is not set | 68 | CONFIG_USB_GADGET=y |
69 | CONFIG_USB_FSL_USB2=y | ||
70 | CONFIG_USB_G_SERIAL=y | ||
71 | CONFIG_UIO=y | ||
72 | CONFIG_UIO_PDRV=y | ||
64 | CONFIG_EXT2_FS=y | 73 | CONFIG_EXT2_FS=y |
65 | CONFIG_EXT3_FS=y | ||
66 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
67 | # CONFIG_EXT3_FS_XATTR is not set | ||
68 | CONFIG_AUTOFS4_FS=y | 74 | CONFIG_AUTOFS4_FS=y |
69 | CONFIG_PROC_KCORE=y | 75 | CONFIG_PROC_KCORE=y |
70 | CONFIG_TMPFS=y | 76 | CONFIG_TMPFS=y |
71 | CONFIG_JFFS2_FS=y | 77 | CONFIG_JFFS2_FS=y |
72 | CONFIG_CRAMFS=y | 78 | CONFIG_CRAMFS=y |
79 | CONFIG_SQUASHFS=y | ||
73 | CONFIG_NFS_FS=y | 80 | CONFIG_NFS_FS=y |
74 | CONFIG_NFS_V3=y | 81 | CONFIG_NFS_V3=y |
75 | CONFIG_ROOT_NFS=y | 82 | CONFIG_ROOT_NFS=y |
76 | CONFIG_PARTITION_ADVANCED=y | 83 | CONFIG_PARTITION_ADVANCED=y |
77 | # CONFIG_MAC_PARTITION is not set | ||
78 | CONFIG_NLS=y | 84 | CONFIG_NLS=y |
79 | CONFIG_NLS_CODEPAGE_437=y | 85 | CONFIG_NLS_CODEPAGE_437=y |
80 | CONFIG_NLS_ASCII=y | 86 | CONFIG_NLS_ASCII=y |
@@ -82,7 +88,6 @@ CONFIG_NLS_ISO8859_1=y | |||
82 | CONFIG_NLS_UTF8=y | 88 | CONFIG_NLS_UTF8=y |
83 | CONFIG_MAGIC_SYSRQ=y | 89 | CONFIG_MAGIC_SYSRQ=y |
84 | CONFIG_DEBUG_FS=y | 90 | CONFIG_DEBUG_FS=y |
85 | CONFIG_DEBUG_KERNEL=y | ||
86 | # CONFIG_SCHED_DEBUG is not set | 91 | # CONFIG_SCHED_DEBUG is not set |
87 | CONFIG_DEBUG_INFO=y | 92 | CONFIG_DEBUG_INFO=y |
88 | CONFIG_SYSCTL_SYSCALL_CHECK=y | 93 | CONFIG_SYSCTL_SYSCALL_CHECK=y |
diff --git a/arch/powerpc/configs/mpc512x_defconfig b/arch/powerpc/configs/mpc512x_defconfig index c02bbb2fddf8..211fcc9ed700 100644 --- a/arch/powerpc/configs/mpc512x_defconfig +++ b/arch/powerpc/configs/mpc512x_defconfig | |||
@@ -1,9 +1,9 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | 1 | CONFIG_EXPERIMENTAL=y |
2 | # CONFIG_SWAP is not set | 2 | # CONFIG_SWAP is not set |
3 | CONFIG_SYSVIPC=y | 3 | CONFIG_SYSVIPC=y |
4 | CONFIG_SPARSE_IRQ=y | ||
4 | CONFIG_LOG_BUF_SHIFT=16 | 5 | CONFIG_LOG_BUF_SHIFT=16 |
5 | CONFIG_BLK_DEV_INITRD=y | 6 | CONFIG_BLK_DEV_INITRD=y |
6 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
7 | # CONFIG_COMPAT_BRK is not set | 7 | # CONFIG_COMPAT_BRK is not set |
8 | CONFIG_SLAB=y | 8 | CONFIG_SLAB=y |
9 | CONFIG_MODULES=y | 9 | CONFIG_MODULES=y |
@@ -13,10 +13,11 @@ CONFIG_MODULE_UNLOAD=y | |||
13 | # CONFIG_PPC_CHRP is not set | 13 | # CONFIG_PPC_CHRP is not set |
14 | CONFIG_PPC_MPC512x=y | 14 | CONFIG_PPC_MPC512x=y |
15 | CONFIG_MPC5121_ADS=y | 15 | CONFIG_MPC5121_ADS=y |
16 | CONFIG_MPC5121_GENERIC=y | ||
17 | CONFIG_PDM360NG=y | ||
16 | # CONFIG_PPC_PMAC is not set | 18 | # CONFIG_PPC_PMAC is not set |
17 | CONFIG_NO_HZ=y | 19 | CONFIG_NO_HZ=y |
18 | CONFIG_HZ_1000=y | 20 | CONFIG_HZ_1000=y |
19 | CONFIG_SPARSE_IRQ=y | ||
20 | # CONFIG_MIGRATION is not set | 21 | # CONFIG_MIGRATION is not set |
21 | # CONFIG_SECCOMP is not set | 22 | # CONFIG_SECCOMP is not set |
22 | # CONFIG_PCI is not set | 23 | # CONFIG_PCI is not set |
@@ -35,18 +36,16 @@ CONFIG_CAN=y | |||
35 | CONFIG_CAN_RAW=y | 36 | CONFIG_CAN_RAW=y |
36 | CONFIG_CAN_BCM=y | 37 | CONFIG_CAN_BCM=y |
37 | CONFIG_CAN_VCAN=y | 38 | CONFIG_CAN_VCAN=y |
38 | CONFIG_CAN_DEV=y | ||
39 | CONFIG_CAN_MSCAN=y | 39 | CONFIG_CAN_MSCAN=y |
40 | CONFIG_CAN_DEBUG_DEVICES=y | 40 | CONFIG_CAN_DEBUG_DEVICES=y |
41 | # CONFIG_WIRELESS is not set | 41 | # CONFIG_WIRELESS is not set |
42 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 42 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
43 | CONFIG_DEVTMPFS=y | ||
44 | CONFIG_DEVTMPFS_MOUNT=y | ||
43 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set | 45 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set |
44 | # CONFIG_FIRMWARE_IN_KERNEL is not set | 46 | # CONFIG_FIRMWARE_IN_KERNEL is not set |
45 | CONFIG_MTD=y | 47 | CONFIG_MTD=y |
46 | CONFIG_MTD_CONCAT=y | ||
47 | CONFIG_MTD_PARTITIONS=y | ||
48 | CONFIG_MTD_CMDLINE_PARTS=y | 48 | CONFIG_MTD_CMDLINE_PARTS=y |
49 | CONFIG_MTD_OF_PARTS=y | ||
50 | CONFIG_MTD_CHAR=y | 49 | CONFIG_MTD_CHAR=y |
51 | CONFIG_MTD_BLOCK=y | 50 | CONFIG_MTD_BLOCK=y |
52 | CONFIG_MTD_CFI=y | 51 | CONFIG_MTD_CFI=y |
@@ -63,6 +62,7 @@ CONFIG_BLK_DEV_RAM_SIZE=8192 | |||
63 | CONFIG_BLK_DEV_XIP=y | 62 | CONFIG_BLK_DEV_XIP=y |
64 | CONFIG_MISC_DEVICES=y | 63 | CONFIG_MISC_DEVICES=y |
65 | CONFIG_EEPROM_AT24=y | 64 | CONFIG_EEPROM_AT24=y |
65 | CONFIG_EEPROM_AT25=y | ||
66 | CONFIG_SCSI=y | 66 | CONFIG_SCSI=y |
67 | # CONFIG_SCSI_PROC_FS is not set | 67 | # CONFIG_SCSI_PROC_FS is not set |
68 | CONFIG_BLK_DEV_SD=y | 68 | CONFIG_BLK_DEV_SD=y |
@@ -99,10 +99,14 @@ CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 | |||
99 | CONFIG_I2C=y | 99 | CONFIG_I2C=y |
100 | CONFIG_I2C_CHARDEV=y | 100 | CONFIG_I2C_CHARDEV=y |
101 | CONFIG_I2C_MPC=y | 101 | CONFIG_I2C_MPC=y |
102 | CONFIG_SPI=y | ||
103 | CONFIG_SPI_MPC512x_PSC=y | ||
104 | CONFIG_GPIOLIB=y | ||
105 | CONFIG_GPIO_SYSFS=y | ||
106 | CONFIG_GPIO_MPC8XXX=y | ||
102 | # CONFIG_HWMON is not set | 107 | # CONFIG_HWMON is not set |
103 | CONFIG_MEDIA_SUPPORT=y | 108 | CONFIG_MEDIA_SUPPORT=y |
104 | CONFIG_VIDEO_DEV=y | 109 | CONFIG_VIDEO_DEV=y |
105 | # CONFIG_VIDEO_ALLOW_V4L1 is not set | ||
106 | CONFIG_VIDEO_ADV_DEBUG=y | 110 | CONFIG_VIDEO_ADV_DEBUG=y |
107 | # CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set | 111 | # CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set |
108 | CONFIG_VIDEO_SAA711X=y | 112 | CONFIG_VIDEO_SAA711X=y |
@@ -132,6 +136,5 @@ CONFIG_NLS_CODEPAGE_437=y | |||
132 | CONFIG_NLS_ISO8859_1=y | 136 | CONFIG_NLS_ISO8859_1=y |
133 | # CONFIG_ENABLE_WARN_DEPRECATED is not set | 137 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
134 | # CONFIG_ENABLE_MUST_CHECK is not set | 138 | # CONFIG_ENABLE_MUST_CHECK is not set |
135 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
136 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 139 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
137 | # CONFIG_CRYPTO_HW is not set | 140 | # CONFIG_CRYPTO_HW is not set |
diff --git a/arch/powerpc/configs/mpc5200_defconfig b/arch/powerpc/configs/mpc5200_defconfig index e63f537b854a..2a1320fb2723 100644 --- a/arch/powerpc/configs/mpc5200_defconfig +++ b/arch/powerpc/configs/mpc5200_defconfig | |||
@@ -88,6 +88,18 @@ CONFIG_FB_RADEON=y | |||
88 | # CONFIG_VGA_CONSOLE is not set | 88 | # CONFIG_VGA_CONSOLE is not set |
89 | CONFIG_FRAMEBUFFER_CONSOLE=y | 89 | CONFIG_FRAMEBUFFER_CONSOLE=y |
90 | CONFIG_LOGO=y | 90 | CONFIG_LOGO=y |
91 | CONFIG_SOUND=y | ||
92 | CONFIG_SND=y | ||
93 | # CONFIG_SND_SUPPORT_OLD_API is not set | ||
94 | # CONFIG_SND_DRIVERS is not set | ||
95 | # CONFIG_SND_PCI is not set | ||
96 | # CONFIG_SND_PPC is not set | ||
97 | # CONFIG_SND_SPI is not set | ||
98 | # CONFIG_SND_USB is not set | ||
99 | CONFIG_SND_SOC=y | ||
100 | CONFIG_SND_SOC_MPC5200_I2S=y | ||
101 | CONFIG_SND_MPC52xx_SOC_PCM030=y | ||
102 | CONFIG_SND_MPC52xx_SOC_EFIKA=y | ||
91 | CONFIG_HID_DRAGONRISE=y | 103 | CONFIG_HID_DRAGONRISE=y |
92 | CONFIG_HID_GYRATION=y | 104 | CONFIG_HID_GYRATION=y |
93 | CONFIG_HID_TWINHAN=y | 105 | CONFIG_HID_TWINHAN=y |
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index a3467bfb7671..a1e5a178a4ac 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig | |||
@@ -10,10 +10,8 @@ CONFIG_IKCONFIG=y | |||
10 | CONFIG_IKCONFIG_PROC=y | 10 | CONFIG_IKCONFIG_PROC=y |
11 | CONFIG_LOG_BUF_SHIFT=14 | 11 | CONFIG_LOG_BUF_SHIFT=14 |
12 | CONFIG_BLK_DEV_INITRD=y | 12 | CONFIG_BLK_DEV_INITRD=y |
13 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
14 | CONFIG_EXPERT=y | 13 | CONFIG_EXPERT=y |
15 | CONFIG_KALLSYMS_ALL=y | 14 | CONFIG_KALLSYMS_ALL=y |
16 | CONFIG_KALLSYMS_EXTRA_PASS=y | ||
17 | CONFIG_MODULES=y | 15 | CONFIG_MODULES=y |
18 | CONFIG_MODULE_UNLOAD=y | 16 | CONFIG_MODULE_UNLOAD=y |
19 | CONFIG_MODULE_FORCE_UNLOAD=y | 17 | CONFIG_MODULE_FORCE_UNLOAD=y |
@@ -41,7 +39,6 @@ CONFIG_TQM8560=y | |||
41 | CONFIG_SBC8548=y | 39 | CONFIG_SBC8548=y |
42 | CONFIG_QUICC_ENGINE=y | 40 | CONFIG_QUICC_ENGINE=y |
43 | CONFIG_QE_GPIO=y | 41 | CONFIG_QE_GPIO=y |
44 | CONFIG_MPC8xxx_GPIO=y | ||
45 | CONFIG_HIGHMEM=y | 42 | CONFIG_HIGHMEM=y |
46 | CONFIG_NO_HZ=y | 43 | CONFIG_NO_HZ=y |
47 | CONFIG_HIGH_RES_TIMERS=y | 44 | CONFIG_HIGH_RES_TIMERS=y |
@@ -123,6 +120,7 @@ CONFIG_NVRAM=y | |||
123 | CONFIG_I2C=y | 120 | CONFIG_I2C=y |
124 | CONFIG_I2C_CPM=m | 121 | CONFIG_I2C_CPM=m |
125 | CONFIG_I2C_MPC=y | 122 | CONFIG_I2C_MPC=y |
123 | CONFIG_GPIO_MPC8XXX=y | ||
126 | # CONFIG_HWMON is not set | 124 | # CONFIG_HWMON is not set |
127 | CONFIG_VIDEO_OUTPUT_CONTROL=y | 125 | CONFIG_VIDEO_OUTPUT_CONTROL=y |
128 | CONFIG_FB=y | 126 | CONFIG_FB=y |
@@ -206,7 +204,6 @@ CONFIG_PARTITION_ADVANCED=y | |||
206 | CONFIG_MAC_PARTITION=y | 204 | CONFIG_MAC_PARTITION=y |
207 | CONFIG_CRC_T10DIF=y | 205 | CONFIG_CRC_T10DIF=y |
208 | CONFIG_DEBUG_FS=y | 206 | CONFIG_DEBUG_FS=y |
209 | CONFIG_DEBUG_KERNEL=y | ||
210 | CONFIG_DETECT_HUNG_TASK=y | 207 | CONFIG_DETECT_HUNG_TASK=y |
211 | CONFIG_DEBUG_INFO=y | 208 | CONFIG_DEBUG_INFO=y |
212 | CONFIG_SYSCTL_SYSCALL_CHECK=y | 209 | CONFIG_SYSCTL_SYSCALL_CHECK=y |
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig index 9693f6ed3da0..dd1e41386c4c 100644 --- a/arch/powerpc/configs/mpc85xx_smp_defconfig +++ b/arch/powerpc/configs/mpc85xx_smp_defconfig | |||
@@ -12,10 +12,8 @@ CONFIG_IKCONFIG=y | |||
12 | CONFIG_IKCONFIG_PROC=y | 12 | CONFIG_IKCONFIG_PROC=y |
13 | CONFIG_LOG_BUF_SHIFT=14 | 13 | CONFIG_LOG_BUF_SHIFT=14 |
14 | CONFIG_BLK_DEV_INITRD=y | 14 | CONFIG_BLK_DEV_INITRD=y |
15 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
16 | CONFIG_EXPERT=y | 15 | CONFIG_EXPERT=y |
17 | CONFIG_KALLSYMS_ALL=y | 16 | CONFIG_KALLSYMS_ALL=y |
18 | CONFIG_KALLSYMS_EXTRA_PASS=y | ||
19 | CONFIG_MODULES=y | 17 | CONFIG_MODULES=y |
20 | CONFIG_MODULE_UNLOAD=y | 18 | CONFIG_MODULE_UNLOAD=y |
21 | CONFIG_MODULE_FORCE_UNLOAD=y | 19 | CONFIG_MODULE_FORCE_UNLOAD=y |
@@ -42,7 +40,6 @@ CONFIG_TQM8560=y | |||
42 | CONFIG_SBC8548=y | 40 | CONFIG_SBC8548=y |
43 | CONFIG_QUICC_ENGINE=y | 41 | CONFIG_QUICC_ENGINE=y |
44 | CONFIG_QE_GPIO=y | 42 | CONFIG_QE_GPIO=y |
45 | CONFIG_MPC8xxx_GPIO=y | ||
46 | CONFIG_HIGHMEM=y | 43 | CONFIG_HIGHMEM=y |
47 | CONFIG_NO_HZ=y | 44 | CONFIG_NO_HZ=y |
48 | CONFIG_HIGH_RES_TIMERS=y | 45 | CONFIG_HIGH_RES_TIMERS=y |
@@ -124,6 +121,7 @@ CONFIG_NVRAM=y | |||
124 | CONFIG_I2C=y | 121 | CONFIG_I2C=y |
125 | CONFIG_I2C_CPM=m | 122 | CONFIG_I2C_CPM=m |
126 | CONFIG_I2C_MPC=y | 123 | CONFIG_I2C_MPC=y |
124 | CONFIG_GPIO_MPC8XXX=y | ||
127 | # CONFIG_HWMON is not set | 125 | # CONFIG_HWMON is not set |
128 | CONFIG_VIDEO_OUTPUT_CONTROL=y | 126 | CONFIG_VIDEO_OUTPUT_CONTROL=y |
129 | CONFIG_FB=y | 127 | CONFIG_FB=y |
@@ -207,10 +205,8 @@ CONFIG_PARTITION_ADVANCED=y | |||
207 | CONFIG_MAC_PARTITION=y | 205 | CONFIG_MAC_PARTITION=y |
208 | CONFIG_CRC_T10DIF=y | 206 | CONFIG_CRC_T10DIF=y |
209 | CONFIG_DEBUG_FS=y | 207 | CONFIG_DEBUG_FS=y |
210 | CONFIG_DEBUG_KERNEL=y | ||
211 | CONFIG_DETECT_HUNG_TASK=y | 208 | CONFIG_DETECT_HUNG_TASK=y |
212 | CONFIG_DEBUG_INFO=y | 209 | CONFIG_DEBUG_INFO=y |
213 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
214 | CONFIG_SYSCTL_SYSCALL_CHECK=y | 210 | CONFIG_SYSCTL_SYSCALL_CHECK=y |
215 | CONFIG_VIRQ_DEBUG=y | 211 | CONFIG_VIRQ_DEBUG=y |
216 | CONFIG_CRYPTO_PCBC=m | 212 | CONFIG_CRYPTO_PCBC=m |
diff --git a/arch/powerpc/configs/ppc40x_defconfig b/arch/powerpc/configs/ppc40x_defconfig index 7cb703b948b1..1eb19ac45d09 100644 --- a/arch/powerpc/configs/ppc40x_defconfig +++ b/arch/powerpc/configs/ppc40x_defconfig | |||
@@ -14,7 +14,6 @@ CONFIG_MODULE_UNLOAD=y | |||
14 | CONFIG_PPC4xx_GPIO=y | 14 | CONFIG_PPC4xx_GPIO=y |
15 | CONFIG_ACADIA=y | 15 | CONFIG_ACADIA=y |
16 | CONFIG_EP405=y | 16 | CONFIG_EP405=y |
17 | CONFIG_HCU4=y | ||
18 | CONFIG_HOTFOOT=y | 17 | CONFIG_HOTFOOT=y |
19 | CONFIG_KILAUEA=y | 18 | CONFIG_KILAUEA=y |
20 | CONFIG_MAKALU=y | 19 | CONFIG_MAKALU=y |
diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index 04360f9b0109..c47f2becfbc3 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig | |||
@@ -70,7 +70,7 @@ CONFIG_TAU_AVERAGE=y | |||
70 | CONFIG_QUICC_ENGINE=y | 70 | CONFIG_QUICC_ENGINE=y |
71 | CONFIG_QE_GPIO=y | 71 | CONFIG_QE_GPIO=y |
72 | CONFIG_PPC_BESTCOMM=y | 72 | CONFIG_PPC_BESTCOMM=y |
73 | CONFIG_MPC8xxx_GPIO=y | 73 | CONFIG_GPIO_MPC8XXX=y |
74 | CONFIG_MCU_MPC8349EMITX=m | 74 | CONFIG_MCU_MPC8349EMITX=m |
75 | CONFIG_HIGHMEM=y | 75 | CONFIG_HIGHMEM=y |
76 | CONFIG_NO_HZ=y | 76 | CONFIG_NO_HZ=y |
diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index 16d25c0974be..d57c08acedfc 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h | |||
@@ -37,4 +37,6 @@ struct pdev_archdata { | |||
37 | u64 dma_mask; | 37 | u64 dma_mask; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | #define ARCH_HAS_DMA_GET_REQUIRED_MASK | ||
41 | |||
40 | #endif /* _ASM_POWERPC_DEVICE_H */ | 42 | #endif /* _ASM_POWERPC_DEVICE_H */ |
diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h index 3a6c586c4e40..14db29b18d0e 100644 --- a/arch/powerpc/include/asm/firmware.h +++ b/arch/powerpc/include/asm/firmware.h | |||
@@ -48,6 +48,8 @@ | |||
48 | #define FW_FEATURE_CMO ASM_CONST(0x0000000002000000) | 48 | #define FW_FEATURE_CMO ASM_CONST(0x0000000002000000) |
49 | #define FW_FEATURE_VPHN ASM_CONST(0x0000000004000000) | 49 | #define FW_FEATURE_VPHN ASM_CONST(0x0000000004000000) |
50 | #define FW_FEATURE_XCMO ASM_CONST(0x0000000008000000) | 50 | #define FW_FEATURE_XCMO ASM_CONST(0x0000000008000000) |
51 | #define FW_FEATURE_OPAL ASM_CONST(0x0000000010000000) | ||
52 | #define FW_FEATURE_OPALv2 ASM_CONST(0x0000000020000000) | ||
51 | 53 | ||
52 | #ifndef __ASSEMBLY__ | 54 | #ifndef __ASSEMBLY__ |
53 | 55 | ||
@@ -65,6 +67,8 @@ enum { | |||
65 | FW_FEATURE_PSERIES_ALWAYS = 0, | 67 | FW_FEATURE_PSERIES_ALWAYS = 0, |
66 | FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, | 68 | FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, |
67 | FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, | 69 | FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, |
70 | FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2, | ||
71 | FW_FEATURE_POWERNV_ALWAYS = 0, | ||
68 | FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, | 72 | FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, |
69 | FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, | 73 | FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, |
70 | FW_FEATURE_CELLEB_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_BEAT, | 74 | FW_FEATURE_CELLEB_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_BEAT, |
@@ -78,6 +82,9 @@ enum { | |||
78 | #ifdef CONFIG_PPC_ISERIES | 82 | #ifdef CONFIG_PPC_ISERIES |
79 | FW_FEATURE_ISERIES_POSSIBLE | | 83 | FW_FEATURE_ISERIES_POSSIBLE | |
80 | #endif | 84 | #endif |
85 | #ifdef CONFIG_PPC_POWERNV | ||
86 | FW_FEATURE_POWERNV_POSSIBLE | | ||
87 | #endif | ||
81 | #ifdef CONFIG_PPC_PS3 | 88 | #ifdef CONFIG_PPC_PS3 |
82 | FW_FEATURE_PS3_POSSIBLE | | 89 | FW_FEATURE_PS3_POSSIBLE | |
83 | #endif | 90 | #endif |
@@ -95,6 +102,9 @@ enum { | |||
95 | #ifdef CONFIG_PPC_ISERIES | 102 | #ifdef CONFIG_PPC_ISERIES |
96 | FW_FEATURE_ISERIES_ALWAYS & | 103 | FW_FEATURE_ISERIES_ALWAYS & |
97 | #endif | 104 | #endif |
105 | #ifdef CONFIG_PPC_POWERNV | ||
106 | FW_FEATURE_POWERNV_ALWAYS & | ||
107 | #endif | ||
98 | #ifdef CONFIG_PPC_PS3 | 108 | #ifdef CONFIG_PPC_PS3 |
99 | FW_FEATURE_PS3_ALWAYS & | 109 | FW_FEATURE_PS3_ALWAYS & |
100 | #endif | 110 | #endif |
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 5856a66ab404..86004930a78e 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h | |||
@@ -1,15 +1,60 @@ | |||
1 | #ifndef _ASM_POWERPC_HUGETLB_H | 1 | #ifndef _ASM_POWERPC_HUGETLB_H |
2 | #define _ASM_POWERPC_HUGETLB_H | 2 | #define _ASM_POWERPC_HUGETLB_H |
3 | 3 | ||
4 | #ifdef CONFIG_HUGETLB_PAGE | ||
4 | #include <asm/page.h> | 5 | #include <asm/page.h> |
5 | 6 | ||
7 | extern struct kmem_cache *hugepte_cache; | ||
8 | extern void __init reserve_hugetlb_gpages(void); | ||
9 | |||
10 | static inline pte_t *hugepd_page(hugepd_t hpd) | ||
11 | { | ||
12 | BUG_ON(!hugepd_ok(hpd)); | ||
13 | return (pte_t *)((hpd.pd & ~HUGEPD_SHIFT_MASK) | PD_HUGE); | ||
14 | } | ||
15 | |||
16 | static inline unsigned int hugepd_shift(hugepd_t hpd) | ||
17 | { | ||
18 | return hpd.pd & HUGEPD_SHIFT_MASK; | ||
19 | } | ||
20 | |||
21 | static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, | ||
22 | unsigned pdshift) | ||
23 | { | ||
24 | /* | ||
25 | * On 32-bit, we have multiple higher-level table entries that point to | ||
26 | * the same hugepte. Just use the first one since they're all | ||
27 | * identical. So for that case, idx=0. | ||
28 | */ | ||
29 | unsigned long idx = 0; | ||
30 | |||
31 | pte_t *dir = hugepd_page(*hpdp); | ||
32 | #ifdef CONFIG_PPC64 | ||
33 | idx = (addr & ((1UL << pdshift) - 1)) >> hugepd_shift(*hpdp); | ||
34 | #endif | ||
35 | |||
36 | return dir + idx; | ||
37 | } | ||
38 | |||
6 | pte_t *huge_pte_offset_and_shift(struct mm_struct *mm, | 39 | pte_t *huge_pte_offset_and_shift(struct mm_struct *mm, |
7 | unsigned long addr, unsigned *shift); | 40 | unsigned long addr, unsigned *shift); |
8 | 41 | ||
9 | void flush_dcache_icache_hugepage(struct page *page); | 42 | void flush_dcache_icache_hugepage(struct page *page); |
10 | 43 | ||
44 | #if defined(CONFIG_PPC_MM_SLICES) || defined(CONFIG_PPC_SUBPAGE_PROT) | ||
11 | int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr, | 45 | int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr, |
12 | unsigned long len); | 46 | unsigned long len); |
47 | #else | ||
48 | static inline int is_hugepage_only_range(struct mm_struct *mm, | ||
49 | unsigned long addr, | ||
50 | unsigned long len) | ||
51 | { | ||
52 | return 0; | ||
53 | } | ||
54 | #endif | ||
55 | |||
56 | void book3e_hugetlb_preload(struct mm_struct *mm, unsigned long ea, pte_t pte); | ||
57 | void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr); | ||
13 | 58 | ||
14 | void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr, | 59 | void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr, |
15 | unsigned long end, unsigned long floor, | 60 | unsigned long end, unsigned long floor, |
@@ -50,8 +95,11 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | |||
50 | static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | 95 | static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, |
51 | unsigned long addr, pte_t *ptep) | 96 | unsigned long addr, pte_t *ptep) |
52 | { | 97 | { |
53 | unsigned long old = pte_update(mm, addr, ptep, ~0UL, 1); | 98 | #ifdef CONFIG_PPC64 |
54 | return __pte(old); | 99 | return __pte(pte_update(mm, addr, ptep, ~0UL, 1)); |
100 | #else | ||
101 | return __pte(pte_update(ptep, ~0UL, 0)); | ||
102 | #endif | ||
55 | } | 103 | } |
56 | 104 | ||
57 | static inline void huge_ptep_clear_flush(struct vm_area_struct *vma, | 105 | static inline void huge_ptep_clear_flush(struct vm_area_struct *vma, |
@@ -93,4 +141,15 @@ static inline void arch_release_hugepage(struct page *page) | |||
93 | { | 141 | { |
94 | } | 142 | } |
95 | 143 | ||
144 | #else /* ! CONFIG_HUGETLB_PAGE */ | ||
145 | static inline void reserve_hugetlb_gpages(void) | ||
146 | { | ||
147 | pr_err("Cannot reserve gpages without hugetlb enabled\n"); | ||
148 | } | ||
149 | static inline void flush_hugetlb_page(struct vm_area_struct *vma, | ||
150 | unsigned long vmaddr) | ||
151 | { | ||
152 | } | ||
153 | #endif | ||
154 | |||
96 | #endif /* _ASM_POWERPC_HUGETLB_H */ | 155 | #endif /* _ASM_POWERPC_HUGETLB_H */ |
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h index 8a33698c61bd..f921eb121d39 100644 --- a/arch/powerpc/include/asm/kexec.h +++ b/arch/powerpc/include/asm/kexec.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #define _ASM_POWERPC_KEXEC_H | 2 | #define _ASM_POWERPC_KEXEC_H |
3 | #ifdef __KERNEL__ | 3 | #ifdef __KERNEL__ |
4 | 4 | ||
5 | #ifdef CONFIG_FSL_BOOKE | 5 | #if defined(CONFIG_FSL_BOOKE) || defined(CONFIG_44x) |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * On FSL-BookE we setup a 1:1 mapping which covers the first 2GiB of memory | 8 | * On FSL-BookE we setup a 1:1 mapping which covers the first 2GiB of memory |
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 47cacddb14cf..58fc21623014 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h | |||
@@ -85,8 +85,9 @@ struct machdep_calls { | |||
85 | void (*pci_dma_dev_setup)(struct pci_dev *dev); | 85 | void (*pci_dma_dev_setup)(struct pci_dev *dev); |
86 | void (*pci_dma_bus_setup)(struct pci_bus *bus); | 86 | void (*pci_dma_bus_setup)(struct pci_bus *bus); |
87 | 87 | ||
88 | /* Platform set_dma_mask override */ | 88 | /* Platform set_dma_mask and dma_get_required_mask overrides */ |
89 | int (*dma_set_mask)(struct device *dev, u64 dma_mask); | 89 | int (*dma_set_mask)(struct device *dev, u64 dma_mask); |
90 | u64 (*dma_get_required_mask)(struct device *dev); | ||
90 | 91 | ||
91 | int (*probe)(void); | 92 | int (*probe)(void); |
92 | void (*setup_arch)(void); /* Optional, may be NULL */ | 93 | void (*setup_arch)(void); /* Optional, may be NULL */ |
diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/mmu-book3e.h index 3ea0f9a259d8..0260ea5ec3c2 100644 --- a/arch/powerpc/include/asm/mmu-book3e.h +++ b/arch/powerpc/include/asm/mmu-book3e.h | |||
@@ -66,6 +66,7 @@ | |||
66 | #define MAS2_M 0x00000004 | 66 | #define MAS2_M 0x00000004 |
67 | #define MAS2_G 0x00000002 | 67 | #define MAS2_G 0x00000002 |
68 | #define MAS2_E 0x00000001 | 68 | #define MAS2_E 0x00000001 |
69 | #define MAS2_WIMGE_MASK 0x0000001f | ||
69 | #define MAS2_EPN_MASK(size) (~0 << (size + 10)) | 70 | #define MAS2_EPN_MASK(size) (~0 << (size + 10)) |
70 | #define MAS2_VAL(addr, size, flags) ((addr) & MAS2_EPN_MASK(size) | (flags)) | 71 | #define MAS2_VAL(addr, size, flags) ((addr) & MAS2_EPN_MASK(size) | (flags)) |
71 | 72 | ||
@@ -80,6 +81,7 @@ | |||
80 | #define MAS3_SW 0x00000004 | 81 | #define MAS3_SW 0x00000004 |
81 | #define MAS3_UR 0x00000002 | 82 | #define MAS3_UR 0x00000002 |
82 | #define MAS3_SR 0x00000001 | 83 | #define MAS3_SR 0x00000001 |
84 | #define MAS3_BAP_MASK 0x0000003f | ||
83 | #define MAS3_SPSIZE 0x0000003e | 85 | #define MAS3_SPSIZE 0x0000003e |
84 | #define MAS3_SPSIZE_SHIFT 1 | 86 | #define MAS3_SPSIZE_SHIFT 1 |
85 | 87 | ||
@@ -212,6 +214,11 @@ typedef struct { | |||
212 | unsigned int id; | 214 | unsigned int id; |
213 | unsigned int active; | 215 | unsigned int active; |
214 | unsigned long vdso_base; | 216 | unsigned long vdso_base; |
217 | #ifdef CONFIG_PPC_MM_SLICES | ||
218 | u64 low_slices_psize; /* SLB page size encodings */ | ||
219 | u64 high_slices_psize; /* 4 bits per slice for now */ | ||
220 | u16 user_psize; /* page size index */ | ||
221 | #endif | ||
215 | } mm_context_t; | 222 | } mm_context_t; |
216 | 223 | ||
217 | /* Page size definitions, common between 32 and 64-bit | 224 | /* Page size definitions, common between 32 and 64-bit |
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h index b445e0af4c2b..db645ec842bd 100644 --- a/arch/powerpc/include/asm/mmu-hash64.h +++ b/arch/powerpc/include/asm/mmu-hash64.h | |||
@@ -262,8 +262,7 @@ extern void hash_failure_debug(unsigned long ea, unsigned long access, | |||
262 | extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | 262 | extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend, |
263 | unsigned long pstart, unsigned long prot, | 263 | unsigned long pstart, unsigned long prot, |
264 | int psize, int ssize); | 264 | int psize, int ssize); |
265 | extern void add_gpage(unsigned long addr, unsigned long page_size, | 265 | extern void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages); |
266 | unsigned long number_of_pages); | ||
267 | extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr); | 266 | extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr); |
268 | 267 | ||
269 | extern void hpte_init_native(void); | 268 | extern void hpte_init_native(void); |
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index 698b30638681..f0145522cfba 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h | |||
@@ -175,14 +175,16 @@ extern u64 ppc64_rma_size; | |||
175 | #define MMU_PAGE_64K_AP 3 /* "Admixed pages" (hash64 only) */ | 175 | #define MMU_PAGE_64K_AP 3 /* "Admixed pages" (hash64 only) */ |
176 | #define MMU_PAGE_256K 4 | 176 | #define MMU_PAGE_256K 4 |
177 | #define MMU_PAGE_1M 5 | 177 | #define MMU_PAGE_1M 5 |
178 | #define MMU_PAGE_8M 6 | 178 | #define MMU_PAGE_4M 6 |
179 | #define MMU_PAGE_16M 7 | 179 | #define MMU_PAGE_8M 7 |
180 | #define MMU_PAGE_256M 8 | 180 | #define MMU_PAGE_16M 8 |
181 | #define MMU_PAGE_1G 9 | 181 | #define MMU_PAGE_64M 9 |
182 | #define MMU_PAGE_16G 10 | 182 | #define MMU_PAGE_256M 10 |
183 | #define MMU_PAGE_64G 11 | 183 | #define MMU_PAGE_1G 11 |
184 | #define MMU_PAGE_COUNT 12 | 184 | #define MMU_PAGE_16G 12 |
185 | 185 | #define MMU_PAGE_64G 13 | |
186 | |||
187 | #define MMU_PAGE_COUNT 14 | ||
186 | 188 | ||
187 | #if defined(CONFIG_PPC_STD_MMU_64) | 189 | #if defined(CONFIG_PPC_STD_MMU_64) |
188 | /* 64-bit classic hash table MMU */ | 190 | /* 64-bit classic hash table MMU */ |
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h index df18989e78d4..e6fae49e0b74 100644 --- a/arch/powerpc/include/asm/mpic.h +++ b/arch/powerpc/include/asm/mpic.h | |||
@@ -273,8 +273,6 @@ struct mpic | |||
273 | unsigned int irq_count; | 273 | unsigned int irq_count; |
274 | /* Number of sources */ | 274 | /* Number of sources */ |
275 | unsigned int num_sources; | 275 | unsigned int num_sources; |
276 | /* Number of CPUs */ | ||
277 | unsigned int num_cpus; | ||
278 | /* default senses array */ | 276 | /* default senses array */ |
279 | unsigned char *senses; | 277 | unsigned char *senses; |
280 | unsigned int senses_count; | 278 | unsigned int senses_count; |
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h new file mode 100644 index 000000000000..2893e8f5406d --- /dev/null +++ b/arch/powerpc/include/asm/opal.h | |||
@@ -0,0 +1,443 @@ | |||
1 | /* | ||
2 | * PowerNV OPAL definitions. | ||
3 | * | ||
4 | * Copyright 2011 IBM Corp. | ||
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 | #ifndef __OPAL_H | ||
13 | #define __OPAL_H | ||
14 | |||
15 | /****** Takeover interface ********/ | ||
16 | |||
17 | /* PAPR H-Call used to querty the HAL existence and/or instanciate | ||
18 | * it from within pHyp (tech preview only). | ||
19 | * | ||
20 | * This is exclusively used in prom_init.c | ||
21 | */ | ||
22 | |||
23 | #ifndef __ASSEMBLY__ | ||
24 | |||
25 | struct opal_takeover_args { | ||
26 | u64 k_image; /* r4 */ | ||
27 | u64 k_size; /* r5 */ | ||
28 | u64 k_entry; /* r6 */ | ||
29 | u64 k_entry2; /* r7 */ | ||
30 | u64 hal_addr; /* r8 */ | ||
31 | u64 rd_image; /* r9 */ | ||
32 | u64 rd_size; /* r10 */ | ||
33 | u64 rd_loc; /* r11 */ | ||
34 | }; | ||
35 | |||
36 | extern long opal_query_takeover(u64 *hal_size, u64 *hal_align); | ||
37 | |||
38 | extern long opal_do_takeover(struct opal_takeover_args *args); | ||
39 | |||
40 | struct rtas_args; | ||
41 | extern int opal_enter_rtas(struct rtas_args *args, | ||
42 | unsigned long data, | ||
43 | unsigned long entry); | ||
44 | |||
45 | #endif /* __ASSEMBLY__ */ | ||
46 | |||
47 | /****** OPAL APIs ******/ | ||
48 | |||
49 | /* Return codes */ | ||
50 | #define OPAL_SUCCESS 0 | ||
51 | #define OPAL_PARAMETER -1 | ||
52 | #define OPAL_BUSY -2 | ||
53 | #define OPAL_PARTIAL -3 | ||
54 | #define OPAL_CONSTRAINED -4 | ||
55 | #define OPAL_CLOSED -5 | ||
56 | #define OPAL_HARDWARE -6 | ||
57 | #define OPAL_UNSUPPORTED -7 | ||
58 | #define OPAL_PERMISSION -8 | ||
59 | #define OPAL_NO_MEM -9 | ||
60 | #define OPAL_RESOURCE -10 | ||
61 | #define OPAL_INTERNAL_ERROR -11 | ||
62 | #define OPAL_BUSY_EVENT -12 | ||
63 | #define OPAL_HARDWARE_FROZEN -13 | ||
64 | |||
65 | /* API Tokens (in r0) */ | ||
66 | #define OPAL_CONSOLE_WRITE 1 | ||
67 | #define OPAL_CONSOLE_READ 2 | ||
68 | #define OPAL_RTC_READ 3 | ||
69 | #define OPAL_RTC_WRITE 4 | ||
70 | #define OPAL_CEC_POWER_DOWN 5 | ||
71 | #define OPAL_CEC_REBOOT 6 | ||
72 | #define OPAL_READ_NVRAM 7 | ||
73 | #define OPAL_WRITE_NVRAM 8 | ||
74 | #define OPAL_HANDLE_INTERRUPT 9 | ||
75 | #define OPAL_POLL_EVENTS 10 | ||
76 | #define OPAL_PCI_SET_HUB_TCE_MEMORY 11 | ||
77 | #define OPAL_PCI_SET_PHB_TCE_MEMORY 12 | ||
78 | #define OPAL_PCI_CONFIG_READ_BYTE 13 | ||
79 | #define OPAL_PCI_CONFIG_READ_HALF_WORD 14 | ||
80 | #define OPAL_PCI_CONFIG_READ_WORD 15 | ||
81 | #define OPAL_PCI_CONFIG_WRITE_BYTE 16 | ||
82 | #define OPAL_PCI_CONFIG_WRITE_HALF_WORD 17 | ||
83 | #define OPAL_PCI_CONFIG_WRITE_WORD 18 | ||
84 | #define OPAL_SET_XIVE 19 | ||
85 | #define OPAL_GET_XIVE 20 | ||
86 | #define OPAL_GET_COMPLETION_TOKEN_STATUS 21 /* obsolete */ | ||
87 | #define OPAL_REGISTER_OPAL_EXCEPTION_HANDLER 22 | ||
88 | #define OPAL_PCI_EEH_FREEZE_STATUS 23 | ||
89 | #define OPAL_PCI_SHPC 24 | ||
90 | #define OPAL_CONSOLE_WRITE_BUFFER_SPACE 25 | ||
91 | #define OPAL_PCI_EEH_FREEZE_CLEAR 26 | ||
92 | #define OPAL_PCI_PHB_MMIO_ENABLE 27 | ||
93 | #define OPAL_PCI_SET_PHB_MEM_WINDOW 28 | ||
94 | #define OPAL_PCI_MAP_PE_MMIO_WINDOW 29 | ||
95 | #define OPAL_PCI_SET_PHB_TABLE_MEMORY 30 | ||
96 | #define OPAL_PCI_SET_PE 31 | ||
97 | #define OPAL_PCI_SET_PELTV 32 | ||
98 | #define OPAL_PCI_SET_MVE 33 | ||
99 | #define OPAL_PCI_SET_MVE_ENABLE 34 | ||
100 | #define OPAL_PCI_GET_XIVE_REISSUE 35 | ||
101 | #define OPAL_PCI_SET_XIVE_REISSUE 36 | ||
102 | #define OPAL_PCI_SET_XIVE_PE 37 | ||
103 | #define OPAL_GET_XIVE_SOURCE 38 | ||
104 | #define OPAL_GET_MSI_32 39 | ||
105 | #define OPAL_GET_MSI_64 40 | ||
106 | #define OPAL_START_CPU 41 | ||
107 | #define OPAL_QUERY_CPU_STATUS 42 | ||
108 | #define OPAL_WRITE_OPPANEL 43 | ||
109 | #define OPAL_PCI_MAP_PE_DMA_WINDOW 44 | ||
110 | #define OPAL_PCI_MAP_PE_DMA_WINDOW_REAL 45 | ||
111 | #define OPAL_PCI_RESET 49 | ||
112 | |||
113 | #ifndef __ASSEMBLY__ | ||
114 | |||
115 | /* Other enums */ | ||
116 | enum OpalVendorApiTokens { | ||
117 | OPAL_START_VENDOR_API_RANGE = 1000, OPAL_END_VENDOR_API_RANGE = 1999 | ||
118 | }; | ||
119 | enum OpalFreezeState { | ||
120 | OPAL_EEH_STOPPED_NOT_FROZEN = 0, | ||
121 | OPAL_EEH_STOPPED_MMIO_FREEZE = 1, | ||
122 | OPAL_EEH_STOPPED_DMA_FREEZE = 2, | ||
123 | OPAL_EEH_STOPPED_MMIO_DMA_FREEZE = 3, | ||
124 | OPAL_EEH_STOPPED_RESET = 4, | ||
125 | OPAL_EEH_STOPPED_TEMP_UNAVAIL = 5, | ||
126 | OPAL_EEH_STOPPED_PERM_UNAVAIL = 6 | ||
127 | }; | ||
128 | enum OpalEehFreezeActionToken { | ||
129 | OPAL_EEH_ACTION_CLEAR_FREEZE_MMIO = 1, | ||
130 | OPAL_EEH_ACTION_CLEAR_FREEZE_DMA = 2, | ||
131 | OPAL_EEH_ACTION_CLEAR_FREEZE_ALL = 3 | ||
132 | }; | ||
133 | enum OpalPciStatusToken { | ||
134 | OPAL_EEH_PHB_NO_ERROR = 0, | ||
135 | OPAL_EEH_PHB_FATAL = 1, | ||
136 | OPAL_EEH_PHB_RECOVERABLE = 2, | ||
137 | OPAL_EEH_PHB_BUS_ERROR = 3, | ||
138 | OPAL_EEH_PCI_NO_DEVSEL = 4, | ||
139 | OPAL_EEH_PCI_TA = 5, | ||
140 | OPAL_EEH_PCIEX_UR = 6, | ||
141 | OPAL_EEH_PCIEX_CA = 7, | ||
142 | OPAL_EEH_PCI_MMIO_ERROR = 8, | ||
143 | OPAL_EEH_PCI_DMA_ERROR = 9 | ||
144 | }; | ||
145 | enum OpalShpcAction { | ||
146 | OPAL_SHPC_GET_LINK_STATE = 0, | ||
147 | OPAL_SHPC_GET_SLOT_STATE = 1 | ||
148 | }; | ||
149 | enum OpalShpcLinkState { | ||
150 | OPAL_SHPC_LINK_DOWN = 0, | ||
151 | OPAL_SHPC_LINK_UP = 1 | ||
152 | }; | ||
153 | enum OpalMmioWindowType { | ||
154 | OPAL_M32_WINDOW_TYPE = 1, | ||
155 | OPAL_M64_WINDOW_TYPE = 2, | ||
156 | OPAL_IO_WINDOW_TYPE = 3 | ||
157 | }; | ||
158 | enum OpalShpcSlotState { | ||
159 | OPAL_SHPC_DEV_NOT_PRESENT = 0, | ||
160 | OPAL_SHPC_DEV_PRESENT = 1 | ||
161 | }; | ||
162 | enum OpalExceptionHandler { | ||
163 | OPAL_MACHINE_CHECK_HANDLER = 1, | ||
164 | OPAL_HYPERVISOR_MAINTENANCE_HANDLER = 2, | ||
165 | OPAL_SOFTPATCH_HANDLER = 3 | ||
166 | }; | ||
167 | enum OpalPendingState { | ||
168 | OPAL_EVENT_OPAL_INTERNAL = 0x1, | ||
169 | OPAL_EVENT_NVRAM = 0x2, | ||
170 | OPAL_EVENT_RTC = 0x4, | ||
171 | OPAL_EVENT_CONSOLE_OUTPUT = 0x8, | ||
172 | OPAL_EVENT_CONSOLE_INPUT = 0x10 | ||
173 | }; | ||
174 | |||
175 | /* Machine check related definitions */ | ||
176 | enum OpalMCE_Version { | ||
177 | OpalMCE_V1 = 1, | ||
178 | }; | ||
179 | |||
180 | enum OpalMCE_Severity { | ||
181 | OpalMCE_SEV_NO_ERROR = 0, | ||
182 | OpalMCE_SEV_WARNING = 1, | ||
183 | OpalMCE_SEV_ERROR_SYNC = 2, | ||
184 | OpalMCE_SEV_FATAL = 3, | ||
185 | }; | ||
186 | |||
187 | enum OpalMCE_Disposition { | ||
188 | OpalMCE_DISPOSITION_RECOVERED = 0, | ||
189 | OpalMCE_DISPOSITION_NOT_RECOVERED = 1, | ||
190 | }; | ||
191 | |||
192 | enum OpalMCE_Initiator { | ||
193 | OpalMCE_INITIATOR_UNKNOWN = 0, | ||
194 | OpalMCE_INITIATOR_CPU = 1, | ||
195 | }; | ||
196 | |||
197 | enum OpalMCE_ErrorType { | ||
198 | OpalMCE_ERROR_TYPE_UNKNOWN = 0, | ||
199 | OpalMCE_ERROR_TYPE_UE = 1, | ||
200 | OpalMCE_ERROR_TYPE_SLB = 2, | ||
201 | OpalMCE_ERROR_TYPE_ERAT = 3, | ||
202 | OpalMCE_ERROR_TYPE_TLB = 4, | ||
203 | }; | ||
204 | |||
205 | enum OpalMCE_UeErrorType { | ||
206 | OpalMCE_UE_ERROR_INDETERMINATE = 0, | ||
207 | OpalMCE_UE_ERROR_IFETCH = 1, | ||
208 | OpalMCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH = 2, | ||
209 | OpalMCE_UE_ERROR_LOAD_STORE = 3, | ||
210 | OpalMCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE = 4, | ||
211 | }; | ||
212 | |||
213 | enum OpalMCE_SlbErrorType { | ||
214 | OpalMCE_SLB_ERROR_INDETERMINATE = 0, | ||
215 | OpalMCE_SLB_ERROR_PARITY = 1, | ||
216 | OpalMCE_SLB_ERROR_MULTIHIT = 2, | ||
217 | }; | ||
218 | |||
219 | enum OpalMCE_EratErrorType { | ||
220 | OpalMCE_ERAT_ERROR_INDETERMINATE = 0, | ||
221 | OpalMCE_ERAT_ERROR_PARITY = 1, | ||
222 | OpalMCE_ERAT_ERROR_MULTIHIT = 2, | ||
223 | }; | ||
224 | |||
225 | enum OpalMCE_TlbErrorType { | ||
226 | OpalMCE_TLB_ERROR_INDETERMINATE = 0, | ||
227 | OpalMCE_TLB_ERROR_PARITY = 1, | ||
228 | OpalMCE_TLB_ERROR_MULTIHIT = 2, | ||
229 | }; | ||
230 | |||
231 | enum OpalThreadStatus { | ||
232 | OPAL_THREAD_INACTIVE = 0x0, | ||
233 | OPAL_THREAD_STARTED = 0x1 | ||
234 | }; | ||
235 | |||
236 | enum OpalPciBusCompare { | ||
237 | OpalPciBusAny = 0, /* Any bus number match */ | ||
238 | OpalPciBus3Bits = 2, /* Match top 3 bits of bus number */ | ||
239 | OpalPciBus4Bits = 3, /* Match top 4 bits of bus number */ | ||
240 | OpalPciBus5Bits = 4, /* Match top 5 bits of bus number */ | ||
241 | OpalPciBus6Bits = 5, /* Match top 6 bits of bus number */ | ||
242 | OpalPciBus7Bits = 6, /* Match top 7 bits of bus number */ | ||
243 | OpalPciBusAll = 7, /* Match bus number exactly */ | ||
244 | }; | ||
245 | |||
246 | enum OpalDeviceCompare { | ||
247 | OPAL_IGNORE_RID_DEVICE_NUMBER = 0, | ||
248 | OPAL_COMPARE_RID_DEVICE_NUMBER = 1 | ||
249 | }; | ||
250 | |||
251 | enum OpalFuncCompare { | ||
252 | OPAL_IGNORE_RID_FUNCTION_NUMBER = 0, | ||
253 | OPAL_COMPARE_RID_FUNCTION_NUMBER = 1 | ||
254 | }; | ||
255 | |||
256 | enum OpalPeAction { | ||
257 | OPAL_UNMAP_PE = 0, | ||
258 | OPAL_MAP_PE = 1 | ||
259 | }; | ||
260 | |||
261 | enum OpalPciResetAndReinitScope { | ||
262 | OPAL_PHB_COMPLETE = 1, OPAL_PCI_LINK = 2, OPAL_PHB_ERROR = 3, | ||
263 | OPAL_PCI_HOT_RESET = 4, OPAL_PCI_FUNDAMENTAL_RESET = 5, | ||
264 | OPAL_PCI_IODA_RESET = 6, | ||
265 | }; | ||
266 | |||
267 | enum OpalPciResetState { OPAL_DEASSERT_RESET = 0, OPAL_ASSERT_RESET = 1 }; | ||
268 | |||
269 | struct opal_machine_check_event { | ||
270 | enum OpalMCE_Version version:8; /* 0x00 */ | ||
271 | uint8_t in_use; /* 0x01 */ | ||
272 | enum OpalMCE_Severity severity:8; /* 0x02 */ | ||
273 | enum OpalMCE_Initiator initiator:8; /* 0x03 */ | ||
274 | enum OpalMCE_ErrorType error_type:8; /* 0x04 */ | ||
275 | enum OpalMCE_Disposition disposition:8; /* 0x05 */ | ||
276 | uint8_t reserved_1[2]; /* 0x06 */ | ||
277 | uint64_t gpr3; /* 0x08 */ | ||
278 | uint64_t srr0; /* 0x10 */ | ||
279 | uint64_t srr1; /* 0x18 */ | ||
280 | union { /* 0x20 */ | ||
281 | struct { | ||
282 | enum OpalMCE_UeErrorType ue_error_type:8; | ||
283 | uint8_t effective_address_provided; | ||
284 | uint8_t physical_address_provided; | ||
285 | uint8_t reserved_1[5]; | ||
286 | uint64_t effective_address; | ||
287 | uint64_t physical_address; | ||
288 | uint8_t reserved_2[8]; | ||
289 | } ue_error; | ||
290 | |||
291 | struct { | ||
292 | enum OpalMCE_SlbErrorType slb_error_type:8; | ||
293 | uint8_t effective_address_provided; | ||
294 | uint8_t reserved_1[6]; | ||
295 | uint64_t effective_address; | ||
296 | uint8_t reserved_2[16]; | ||
297 | } slb_error; | ||
298 | |||
299 | struct { | ||
300 | enum OpalMCE_EratErrorType erat_error_type:8; | ||
301 | uint8_t effective_address_provided; | ||
302 | uint8_t reserved_1[6]; | ||
303 | uint64_t effective_address; | ||
304 | uint8_t reserved_2[16]; | ||
305 | } erat_error; | ||
306 | |||
307 | struct { | ||
308 | enum OpalMCE_TlbErrorType tlb_error_type:8; | ||
309 | uint8_t effective_address_provided; | ||
310 | uint8_t reserved_1[6]; | ||
311 | uint64_t effective_address; | ||
312 | uint8_t reserved_2[16]; | ||
313 | } tlb_error; | ||
314 | } u; | ||
315 | }; | ||
316 | |||
317 | typedef struct oppanel_line { | ||
318 | /* XXX */ | ||
319 | } oppanel_line_t; | ||
320 | |||
321 | /* API functions */ | ||
322 | int64_t opal_console_write(int64_t term_number, int64_t *length, | ||
323 | const uint8_t *buffer); | ||
324 | int64_t opal_console_read(int64_t term_number, int64_t *length, | ||
325 | uint8_t *buffer); | ||
326 | int64_t opal_console_write_buffer_space(int64_t term_number, | ||
327 | int64_t *length); | ||
328 | int64_t opal_rtc_read(uint32_t *year_month_day, | ||
329 | uint64_t *hour_minute_second_millisecond); | ||
330 | int64_t opal_rtc_write(uint32_t year_month_day, | ||
331 | uint64_t hour_minute_second_millisecond); | ||
332 | int64_t opal_cec_power_down(uint64_t request); | ||
333 | int64_t opal_cec_reboot(void); | ||
334 | int64_t opal_read_nvram(uint64_t buffer, uint64_t size, uint64_t offset); | ||
335 | int64_t opal_write_nvram(uint64_t buffer, uint64_t size, uint64_t offset); | ||
336 | int64_t opal_handle_interrupt(uint64_t isn, uint64_t *outstanding_event_mask); | ||
337 | int64_t opal_poll_events(uint64_t *outstanding_event_mask); | ||
338 | int64_t opal_pci_set_hub_tce_memory(uint64_t hub_id, uint64_t tce_mem_addr, | ||
339 | uint64_t tce_mem_size); | ||
340 | int64_t opal_pci_set_phb_tce_memory(uint64_t phb_id, uint64_t tce_mem_addr, | ||
341 | uint64_t tce_mem_size); | ||
342 | int64_t opal_pci_config_read_byte(uint64_t phb_id, uint64_t bus_dev_func, | ||
343 | uint64_t offset, uint8_t *data); | ||
344 | int64_t opal_pci_config_read_half_word(uint64_t phb_id, uint64_t bus_dev_func, | ||
345 | uint64_t offset, uint16_t *data); | ||
346 | int64_t opal_pci_config_read_word(uint64_t phb_id, uint64_t bus_dev_func, | ||
347 | uint64_t offset, uint32_t *data); | ||
348 | int64_t opal_pci_config_write_byte(uint64_t phb_id, uint64_t bus_dev_func, | ||
349 | uint64_t offset, uint8_t data); | ||
350 | int64_t opal_pci_config_write_half_word(uint64_t phb_id, uint64_t bus_dev_func, | ||
351 | uint64_t offset, uint16_t data); | ||
352 | int64_t opal_pci_config_write_word(uint64_t phb_id, uint64_t bus_dev_func, | ||
353 | uint64_t offset, uint32_t data); | ||
354 | int64_t opal_set_xive(uint32_t isn, uint16_t server, uint8_t priority); | ||
355 | int64_t opal_get_xive(uint32_t isn, uint16_t *server, uint8_t *priority); | ||
356 | int64_t opal_register_exception_handler(uint64_t opal_exception, | ||
357 | uint64_t handler_address, | ||
358 | uint64_t glue_cache_line); | ||
359 | int64_t opal_pci_eeh_freeze_status(uint64_t phb_id, uint64_t pe_number, | ||
360 | uint8_t *freeze_state, | ||
361 | uint16_t *pci_error_type, | ||
362 | uint64_t *phb_status); | ||
363 | int64_t opal_pci_eeh_freeze_clear(uint64_t phb_id, uint64_t pe_number, | ||
364 | uint64_t eeh_action_token); | ||
365 | int64_t opal_pci_shpc(uint64_t phb_id, uint64_t shpc_action, uint8_t *state); | ||
366 | |||
367 | |||
368 | |||
369 | int64_t opal_pci_phb_mmio_enable(uint64_t phb_id, uint16_t window_type, | ||
370 | uint16_t window_num, uint16_t enable); | ||
371 | int64_t opal_pci_set_phb_mem_window(uint64_t phb_id, uint16_t window_type, | ||
372 | uint16_t window_num, | ||
373 | uint64_t starting_real_address, | ||
374 | uint64_t starting_pci_address, | ||
375 | uint16_t segment_size); | ||
376 | int64_t opal_pci_map_pe_mmio_window(uint64_t phb_id, uint16_t pe_number, | ||
377 | uint16_t window_type, uint16_t window_num, | ||
378 | uint16_t segment_num); | ||
379 | int64_t opal_pci_set_phb_table_memory(uint64_t phb_id, uint64_t rtt_addr, | ||
380 | uint64_t ivt_addr, uint64_t ivt_len, | ||
381 | uint64_t reject_array_addr, | ||
382 | uint64_t peltv_addr); | ||
383 | int64_t opal_pci_set_pe(uint64_t phb_id, uint64_t pe_number, uint64_t bus_dev_func, | ||
384 | uint8_t bus_compare, uint8_t dev_compare, uint8_t func_compare, | ||
385 | uint8_t pe_action); | ||
386 | int64_t opal_pci_set_peltv(uint64_t phb_id, uint32_t parent_pe, uint32_t child_pe, | ||
387 | uint8_t state); | ||
388 | int64_t opal_pci_set_mve(uint64_t phb_id, uint32_t mve_number, uint32_t pe_number); | ||
389 | int64_t opal_pci_set_mve_enable(uint64_t phb_id, uint32_t mve_number, | ||
390 | uint32_t state); | ||
391 | int64_t opal_pci_get_xive_reissue(uint64_t phb_id, uint32_t xive_number, | ||
392 | uint8_t *p_bit, uint8_t *q_bit); | ||
393 | int64_t opal_pci_set_xive_reissue(uint64_t phb_id, uint32_t xive_number, | ||
394 | uint8_t p_bit, uint8_t q_bit); | ||
395 | int64_t opal_pci_set_xive_pe(uint64_t phb_id, uint32_t pe_number, | ||
396 | uint32_t xive_num); | ||
397 | int64_t opal_get_xive_source(uint64_t phb_id, uint32_t xive_num, | ||
398 | int32_t *interrupt_source_number); | ||
399 | int64_t opal_get_msi_32(uint64_t phb_id, uint32_t mve_number, uint32_t xive_num, | ||
400 | uint8_t msi_range, uint32_t *msi_address, | ||
401 | uint32_t *message_data); | ||
402 | int64_t opal_get_msi_64(uint64_t phb_id, uint32_t mve_number, | ||
403 | uint32_t xive_num, uint8_t msi_range, | ||
404 | uint64_t *msi_address, uint32_t *message_data); | ||
405 | int64_t opal_start_cpu(uint64_t thread_number, uint64_t start_address); | ||
406 | int64_t opal_query_cpu_status(uint64_t thread_number, uint8_t *thread_status); | ||
407 | int64_t opal_write_oppanel(oppanel_line_t *lines, uint64_t num_lines); | ||
408 | int64_t opal_pci_map_pe_dma_window(uint64_t phb_id, uint16_t pe_number, uint16_t window_id, | ||
409 | uint16_t tce_levels, uint64_t tce_table_addr, | ||
410 | uint64_t tce_table_size, uint64_t tce_page_size); | ||
411 | int64_t opal_pci_map_pe_dma_window_real(uint64_t phb_id, uint16_t pe_number, | ||
412 | uint16_t dma_window_number, uint64_t pci_start_addr, | ||
413 | uint64_t pci_mem_size); | ||
414 | int64_t opal_pci_reset(uint64_t phb_id, uint8_t reset_scope, uint8_t assert_state); | ||
415 | |||
416 | /* Internal functions */ | ||
417 | extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data); | ||
418 | |||
419 | extern int opal_get_chars(uint32_t vtermno, char *buf, int count); | ||
420 | extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len); | ||
421 | |||
422 | extern void hvc_opal_init_early(void); | ||
423 | |||
424 | /* Internal functions */ | ||
425 | extern int early_init_dt_scan_opal(unsigned long node, const char *uname, | ||
426 | int depth, void *data); | ||
427 | |||
428 | extern int opal_get_chars(uint32_t vtermno, char *buf, int count); | ||
429 | extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len); | ||
430 | |||
431 | extern void hvc_opal_init_early(void); | ||
432 | |||
433 | struct rtc_time; | ||
434 | extern int opal_set_rtc_time(struct rtc_time *tm); | ||
435 | extern void opal_get_rtc_time(struct rtc_time *tm); | ||
436 | extern unsigned long opal_get_boot_time(void); | ||
437 | extern void opal_nvram_init(void); | ||
438 | |||
439 | extern int opal_machine_check(struct pt_regs *regs); | ||
440 | |||
441 | #endif /* __ASSEMBLY__ */ | ||
442 | |||
443 | #endif /* __OPAL_H */ | ||
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 516bfb3f47d9..17722c73ba2e 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h | |||
@@ -43,6 +43,7 @@ extern unsigned int debug_smp_processor_id(void); /* from linux/smp.h */ | |||
43 | #define get_slb_shadow() (get_paca()->slb_shadow_ptr) | 43 | #define get_slb_shadow() (get_paca()->slb_shadow_ptr) |
44 | 44 | ||
45 | struct task_struct; | 45 | struct task_struct; |
46 | struct opal_machine_check_event; | ||
46 | 47 | ||
47 | /* | 48 | /* |
48 | * Defines the layout of the paca. | 49 | * Defines the layout of the paca. |
@@ -135,6 +136,13 @@ struct paca_struct { | |||
135 | u8 io_sync; /* writel() needs spin_unlock sync */ | 136 | u8 io_sync; /* writel() needs spin_unlock sync */ |
136 | u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */ | 137 | u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */ |
137 | 138 | ||
139 | #ifdef CONFIG_PPC_POWERNV | ||
140 | /* Pointer to OPAL machine check event structure set by the | ||
141 | * early exception handler for use by high level C handler | ||
142 | */ | ||
143 | struct opal_machine_check_event *opal_mc_evt; | ||
144 | #endif | ||
145 | |||
138 | /* Stuff for accurate time accounting */ | 146 | /* Stuff for accurate time accounting */ |
139 | u64 user_time; /* accumulated usermode TB ticks */ | 147 | u64 user_time; /* accumulated usermode TB ticks */ |
140 | u64 system_time; /* accumulated system TB ticks */ | 148 | u64 system_time; /* accumulated system TB ticks */ |
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index 2cd664ef0a5e..dd9c4fd038e0 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h | |||
@@ -36,6 +36,18 @@ | |||
36 | 36 | ||
37 | #define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT) | 37 | #define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT) |
38 | 38 | ||
39 | #ifndef __ASSEMBLY__ | ||
40 | #ifdef CONFIG_HUGETLB_PAGE | ||
41 | extern unsigned int HPAGE_SHIFT; | ||
42 | #else | ||
43 | #define HPAGE_SHIFT PAGE_SHIFT | ||
44 | #endif | ||
45 | #define HPAGE_SIZE ((1UL) << HPAGE_SHIFT) | ||
46 | #define HPAGE_MASK (~(HPAGE_SIZE - 1)) | ||
47 | #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) | ||
48 | #define HUGE_MAX_HSTATE (MMU_PAGE_COUNT-1) | ||
49 | #endif | ||
50 | |||
39 | /* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */ | 51 | /* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */ |
40 | #define __HAVE_ARCH_GATE_AREA 1 | 52 | #define __HAVE_ARCH_GATE_AREA 1 |
41 | 53 | ||
@@ -158,6 +170,24 @@ extern phys_addr_t kernstart_addr; | |||
158 | #define is_kernel_addr(x) ((x) >= PAGE_OFFSET) | 170 | #define is_kernel_addr(x) ((x) >= PAGE_OFFSET) |
159 | #endif | 171 | #endif |
160 | 172 | ||
173 | /* | ||
174 | * Use the top bit of the higher-level page table entries to indicate whether | ||
175 | * the entries we point to contain hugepages. This works because we know that | ||
176 | * the page tables live in kernel space. If we ever decide to support having | ||
177 | * page tables at arbitrary addresses, this breaks and will have to change. | ||
178 | */ | ||
179 | #ifdef CONFIG_PPC64 | ||
180 | #define PD_HUGE 0x8000000000000000 | ||
181 | #else | ||
182 | #define PD_HUGE 0x80000000 | ||
183 | #endif | ||
184 | |||
185 | /* | ||
186 | * Some number of bits at the level of the page table that points to | ||
187 | * a hugepte are used to encode the size. This masks those bits. | ||
188 | */ | ||
189 | #define HUGEPD_SHIFT_MASK 0x3f | ||
190 | |||
161 | #ifndef __ASSEMBLY__ | 191 | #ifndef __ASSEMBLY__ |
162 | 192 | ||
163 | #undef STRICT_MM_TYPECHECKS | 193 | #undef STRICT_MM_TYPECHECKS |
@@ -243,7 +273,6 @@ typedef unsigned long pgprot_t; | |||
243 | #endif | 273 | #endif |
244 | 274 | ||
245 | typedef struct { signed long pd; } hugepd_t; | 275 | typedef struct { signed long pd; } hugepd_t; |
246 | #define HUGEPD_SHIFT_MASK 0x3f | ||
247 | 276 | ||
248 | #ifdef CONFIG_HUGETLB_PAGE | 277 | #ifdef CONFIG_HUGETLB_PAGE |
249 | static inline int hugepd_ok(hugepd_t hpd) | 278 | static inline int hugepd_ok(hugepd_t hpd) |
diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h index 9356262fd3cc..fb40ede6bc0d 100644 --- a/arch/powerpc/include/asm/page_64.h +++ b/arch/powerpc/include/asm/page_64.h | |||
@@ -64,17 +64,6 @@ extern void copy_page(void *to, void *from); | |||
64 | /* Log 2 of page table size */ | 64 | /* Log 2 of page table size */ |
65 | extern u64 ppc64_pft_size; | 65 | extern u64 ppc64_pft_size; |
66 | 66 | ||
67 | /* Large pages size */ | ||
68 | #ifdef CONFIG_HUGETLB_PAGE | ||
69 | extern unsigned int HPAGE_SHIFT; | ||
70 | #else | ||
71 | #define HPAGE_SHIFT PAGE_SHIFT | ||
72 | #endif | ||
73 | #define HPAGE_SIZE ((1UL) << HPAGE_SHIFT) | ||
74 | #define HPAGE_MASK (~(HPAGE_SIZE - 1)) | ||
75 | #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) | ||
76 | #define HUGE_MAX_HSTATE (MMU_PAGE_COUNT-1) | ||
77 | |||
78 | #endif /* __ASSEMBLY__ */ | 67 | #endif /* __ASSEMBLY__ */ |
79 | 68 | ||
80 | #ifdef CONFIG_PPC_MM_SLICES | 69 | #ifdef CONFIG_PPC_MM_SLICES |
diff --git a/arch/powerpc/include/asm/pte-book3e.h b/arch/powerpc/include/asm/pte-book3e.h index 082d515930a2..0156702ba24e 100644 --- a/arch/powerpc/include/asm/pte-book3e.h +++ b/arch/powerpc/include/asm/pte-book3e.h | |||
@@ -72,6 +72,9 @@ | |||
72 | #define PTE_RPN_SHIFT (24) | 72 | #define PTE_RPN_SHIFT (24) |
73 | #endif | 73 | #endif |
74 | 74 | ||
75 | #define PTE_WIMGE_SHIFT (19) | ||
76 | #define PTE_BAP_SHIFT (2) | ||
77 | |||
75 | /* On 32-bit, we never clear the top part of the PTE */ | 78 | /* On 32-bit, we never clear the top part of the PTE */ |
76 | #ifdef CONFIG_PPC32 | 79 | #ifdef CONFIG_PPC32 |
77 | #define _PTE_NONE_MASK 0xffffffff00000000ULL | 80 | #define _PTE_NONE_MASK 0xffffffff00000000ULL |
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index 9ec0b39f9ddc..28cdbd9f399c 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h | |||
@@ -548,6 +548,9 @@ | |||
548 | #define L1CSR1_ICFI 0x00000002 /* Instr Cache Flash Invalidate */ | 548 | #define L1CSR1_ICFI 0x00000002 /* Instr Cache Flash Invalidate */ |
549 | #define L1CSR1_ICE 0x00000001 /* Instr Cache Enable */ | 549 | #define L1CSR1_ICE 0x00000001 /* Instr Cache Enable */ |
550 | 550 | ||
551 | /* Bit definitions for L1CSR2. */ | ||
552 | #define L1CSR2_DCWS 0x40000000 /* Data Cache write shadow */ | ||
553 | |||
551 | /* Bit definitions for L2CSR0. */ | 554 | /* Bit definitions for L2CSR0. */ |
552 | #define L2CSR0_L2E 0x80000000 /* L2 Cache Enable */ | 555 | #define L2CSR0_L2E 0x80000000 /* L2 Cache Enable */ |
553 | #define L2CSR0_L2PE 0x40000000 /* L2 Cache Parity/ECC Enable */ | 556 | #define L2CSR0_L2PE 0x40000000 /* L2 Cache Parity/ECC Enable */ |
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index 58625d1e7802..41f69ae79d4e 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h | |||
@@ -249,10 +249,12 @@ extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal); | |||
249 | #define ERR_FLAG_ALREADY_LOGGED 0x0 | 249 | #define ERR_FLAG_ALREADY_LOGGED 0x0 |
250 | #define ERR_FLAG_BOOT 0x1 /* log was pulled from NVRAM on boot */ | 250 | #define ERR_FLAG_BOOT 0x1 /* log was pulled from NVRAM on boot */ |
251 | #define ERR_TYPE_RTAS_LOG 0x2 /* from rtas event-scan */ | 251 | #define ERR_TYPE_RTAS_LOG 0x2 /* from rtas event-scan */ |
252 | #define ERR_TYPE_KERNEL_PANIC 0x4 /* from panic() */ | 252 | #define ERR_TYPE_KERNEL_PANIC 0x4 /* from die()/panic() */ |
253 | #define ERR_TYPE_KERNEL_PANIC_GZ 0x8 /* ditto, compressed */ | ||
253 | 254 | ||
254 | /* All the types and not flags */ | 255 | /* All the types and not flags */ |
255 | #define ERR_TYPE_MASK (ERR_TYPE_RTAS_LOG | ERR_TYPE_KERNEL_PANIC) | 256 | #define ERR_TYPE_MASK \ |
257 | (ERR_TYPE_RTAS_LOG | ERR_TYPE_KERNEL_PANIC | ERR_TYPE_KERNEL_PANIC_GZ) | ||
256 | 258 | ||
257 | #define RTAS_DEBUG KERN_DEBUG "RTAS: " | 259 | #define RTAS_DEBUG KERN_DEBUG "RTAS: " |
258 | 260 | ||
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 15a70b7f638b..adba970ce918 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h | |||
@@ -65,6 +65,7 @@ int generic_cpu_disable(void); | |||
65 | void generic_cpu_die(unsigned int cpu); | 65 | void generic_cpu_die(unsigned int cpu); |
66 | void generic_mach_cpu_die(void); | 66 | void generic_mach_cpu_die(void); |
67 | void generic_set_cpu_dead(unsigned int cpu); | 67 | void generic_set_cpu_dead(unsigned int cpu); |
68 | int generic_check_cpu_restart(unsigned int cpu); | ||
68 | #endif | 69 | #endif |
69 | 70 | ||
70 | #ifdef CONFIG_PPC64 | 71 | #ifdef CONFIG_PPC64 |
diff --git a/arch/powerpc/include/asm/sparsemem.h b/arch/powerpc/include/asm/sparsemem.h index 54a47ea2c3aa..0c5fa3145615 100644 --- a/arch/powerpc/include/asm/sparsemem.h +++ b/arch/powerpc/include/asm/sparsemem.h | |||
@@ -16,7 +16,7 @@ | |||
16 | #endif /* CONFIG_SPARSEMEM */ | 16 | #endif /* CONFIG_SPARSEMEM */ |
17 | 17 | ||
18 | #ifdef CONFIG_MEMORY_HOTPLUG | 18 | #ifdef CONFIG_MEMORY_HOTPLUG |
19 | extern void create_section_mapping(unsigned long start, unsigned long end); | 19 | extern int create_section_mapping(unsigned long start, unsigned long end); |
20 | extern int remove_section_mapping(unsigned long start, unsigned long end); | 20 | extern int remove_section_mapping(unsigned long start, unsigned long end); |
21 | #ifdef CONFIG_NUMA | 21 | #ifdef CONFIG_NUMA |
22 | extern int hot_add_scn_to_nid(unsigned long scn_addr); | 22 | extern int hot_add_scn_to_nid(unsigned long scn_addr); |
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 7ef0d90defc8..1e104af08483 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h | |||
@@ -19,14 +19,10 @@ struct device_node; | |||
19 | #define RECLAIM_DISTANCE 10 | 19 | #define RECLAIM_DISTANCE 10 |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * Before going off node we want the VM to try and reclaim from the local | 22 | * Avoid creating an extra level of balancing (SD_ALLNODES) on the largest |
23 | * node. It does this if the remote distance is larger than RECLAIM_DISTANCE. | 23 | * POWER7 boxes which have a maximum of 32 nodes. |
24 | * With the default REMOTE_DISTANCE of 20 and the default RECLAIM_DISTANCE of | ||
25 | * 20, we never reclaim and go off node straight away. | ||
26 | * | ||
27 | * To fix this we choose a smaller value of RECLAIM_DISTANCE. | ||
28 | */ | 24 | */ |
29 | #define RECLAIM_DISTANCE 10 | 25 | #define SD_NODES_PER_DOMAIN 32 |
30 | 26 | ||
31 | #include <asm/mmzone.h> | 27 | #include <asm/mmzone.h> |
32 | 28 | ||
@@ -69,11 +65,11 @@ static inline int pcibus_to_node(struct pci_bus *bus) | |||
69 | .forkexec_idx = 0, \ | 65 | .forkexec_idx = 0, \ |
70 | \ | 66 | \ |
71 | .flags = 1*SD_LOAD_BALANCE \ | 67 | .flags = 1*SD_LOAD_BALANCE \ |
72 | | 1*SD_BALANCE_NEWIDLE \ | 68 | | 0*SD_BALANCE_NEWIDLE \ |
73 | | 1*SD_BALANCE_EXEC \ | 69 | | 1*SD_BALANCE_EXEC \ |
74 | | 1*SD_BALANCE_FORK \ | 70 | | 1*SD_BALANCE_FORK \ |
75 | | 0*SD_BALANCE_WAKE \ | 71 | | 0*SD_BALANCE_WAKE \ |
76 | | 0*SD_WAKE_AFFINE \ | 72 | | 1*SD_WAKE_AFFINE \ |
77 | | 0*SD_PREFER_LOCAL \ | 73 | | 0*SD_PREFER_LOCAL \ |
78 | | 0*SD_SHARE_CPUPOWER \ | 74 | | 0*SD_SHARE_CPUPOWER \ |
79 | | 0*SD_POWERSAVINGS_BALANCE \ | 75 | | 0*SD_POWERSAVINGS_BALANCE \ |
diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h index 5354ae91bdde..8338aef5a4d3 100644 --- a/arch/powerpc/include/asm/udbg.h +++ b/arch/powerpc/include/asm/udbg.h | |||
@@ -55,6 +55,9 @@ extern void __init udbg_init_cpm(void); | |||
55 | extern void __init udbg_init_usbgecko(void); | 55 | extern void __init udbg_init_usbgecko(void); |
56 | extern void __init udbg_init_wsp(void); | 56 | extern void __init udbg_init_wsp(void); |
57 | extern void __init udbg_init_ehv_bc(void); | 57 | extern void __init udbg_init_ehv_bc(void); |
58 | extern void __init udbg_init_ps3gelic(void); | ||
59 | extern void __init udbg_init_debug_opal_raw(void); | ||
60 | extern void __init udbg_init_debug_opal_hvsi(void); | ||
58 | 61 | ||
59 | #endif /* __KERNEL__ */ | 62 | #endif /* __KERNEL__ */ |
60 | #endif /* _ASM_POWERPC_UDBG_H */ | 63 | #endif /* _ASM_POWERPC_UDBG_H */ |
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h index b183a4062011..bd6c401c0ee5 100644 --- a/arch/powerpc/include/asm/xics.h +++ b/arch/powerpc/include/asm/xics.h | |||
@@ -27,10 +27,18 @@ | |||
27 | #define MAX_NUM_PRIORITIES 3 | 27 | #define MAX_NUM_PRIORITIES 3 |
28 | 28 | ||
29 | /* Native ICP */ | 29 | /* Native ICP */ |
30 | #ifdef CONFIG_PPC_ICP_NATIVE | ||
30 | extern int icp_native_init(void); | 31 | extern int icp_native_init(void); |
32 | #else | ||
33 | static inline int icp_native_init(void) { return -ENODEV; } | ||
34 | #endif | ||
31 | 35 | ||
32 | /* PAPR ICP */ | 36 | /* PAPR ICP */ |
37 | #ifdef CONFIG_PPC_ICP_HV | ||
33 | extern int icp_hv_init(void); | 38 | extern int icp_hv_init(void); |
39 | #else | ||
40 | static inline int icp_hv_init(void) { return -ENODEV; } | ||
41 | #endif | ||
34 | 42 | ||
35 | /* ICP ops */ | 43 | /* ICP ops */ |
36 | struct icp_ops { | 44 | struct icp_ops { |
@@ -51,7 +59,18 @@ extern const struct icp_ops *icp_ops; | |||
51 | extern int ics_native_init(void); | 59 | extern int ics_native_init(void); |
52 | 60 | ||
53 | /* RTAS ICS */ | 61 | /* RTAS ICS */ |
62 | #ifdef CONFIG_PPC_ICS_RTAS | ||
54 | extern int ics_rtas_init(void); | 63 | extern int ics_rtas_init(void); |
64 | #else | ||
65 | static inline int ics_rtas_init(void) { return -ENODEV; } | ||
66 | #endif | ||
67 | |||
68 | /* HAL ICS */ | ||
69 | #ifdef CONFIG_PPC_POWERNV | ||
70 | extern int ics_opal_init(void); | ||
71 | #else | ||
72 | static inline int ics_opal_init(void) { return -ENODEV; } | ||
73 | #endif | ||
55 | 74 | ||
56 | /* ICS instance, hooked up to chip_data of an irq */ | 75 | /* ICS instance, hooked up to chip_data of an irq */ |
57 | struct ics { | 76 | struct ics { |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 69f7ffe7f674..7c5324f1ec9c 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -49,6 +49,9 @@ | |||
49 | #ifdef CONFIG_PPC_ISERIES | 49 | #ifdef CONFIG_PPC_ISERIES |
50 | #include <asm/iseries/alpaca.h> | 50 | #include <asm/iseries/alpaca.h> |
51 | #endif | 51 | #endif |
52 | #ifdef CONFIG_PPC_POWERNV | ||
53 | #include <asm/opal.h> | ||
54 | #endif | ||
52 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_GUEST) | 55 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_GUEST) |
53 | #include <linux/kvm_host.h> | 56 | #include <linux/kvm_host.h> |
54 | #endif | 57 | #endif |
@@ -610,5 +613,12 @@ int main(void) | |||
610 | arch.timing_last_enter.tv32.tbl)); | 613 | arch.timing_last_enter.tv32.tbl)); |
611 | #endif | 614 | #endif |
612 | 615 | ||
616 | #ifdef CONFIG_PPC_POWERNV | ||
617 | DEFINE(OPAL_MC_GPR3, offsetof(struct opal_machine_check_event, gpr3)); | ||
618 | DEFINE(OPAL_MC_SRR0, offsetof(struct opal_machine_check_event, srr0)); | ||
619 | DEFINE(OPAL_MC_SRR1, offsetof(struct opal_machine_check_event, srr1)); | ||
620 | DEFINE(PACA_OPAL_MC_EVT, offsetof(struct paca_struct, opal_mc_evt)); | ||
621 | #endif | ||
622 | |||
613 | return 0; | 623 | return 0; |
614 | } | 624 | } |
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index e7554154a6de..6f04b9c383a7 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c | |||
@@ -90,13 +90,27 @@ static int dma_iommu_dma_supported(struct device *dev, u64 mask) | |||
90 | return 1; | 90 | return 1; |
91 | } | 91 | } |
92 | 92 | ||
93 | static u64 dma_iommu_get_required_mask(struct device *dev) | ||
94 | { | ||
95 | struct iommu_table *tbl = get_iommu_table_base(dev); | ||
96 | u64 mask; | ||
97 | if (!tbl) | ||
98 | return 0; | ||
99 | |||
100 | mask = 1ULL < (fls_long(tbl->it_offset + tbl->it_size) - 1); | ||
101 | mask += mask - 1; | ||
102 | |||
103 | return mask; | ||
104 | } | ||
105 | |||
93 | struct dma_map_ops dma_iommu_ops = { | 106 | struct dma_map_ops dma_iommu_ops = { |
94 | .alloc_coherent = dma_iommu_alloc_coherent, | 107 | .alloc_coherent = dma_iommu_alloc_coherent, |
95 | .free_coherent = dma_iommu_free_coherent, | 108 | .free_coherent = dma_iommu_free_coherent, |
96 | .map_sg = dma_iommu_map_sg, | 109 | .map_sg = dma_iommu_map_sg, |
97 | .unmap_sg = dma_iommu_unmap_sg, | 110 | .unmap_sg = dma_iommu_unmap_sg, |
98 | .dma_supported = dma_iommu_dma_supported, | 111 | .dma_supported = dma_iommu_dma_supported, |
99 | .map_page = dma_iommu_map_page, | 112 | .map_page = dma_iommu_map_page, |
100 | .unmap_page = dma_iommu_unmap_page, | 113 | .unmap_page = dma_iommu_unmap_page, |
114 | .get_required_mask = dma_iommu_get_required_mask, | ||
101 | }; | 115 | }; |
102 | EXPORT_SYMBOL(dma_iommu_ops); | 116 | EXPORT_SYMBOL(dma_iommu_ops); |
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c index 4295e0b94b2d..1ebc9189aada 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c | |||
@@ -24,6 +24,21 @@ | |||
24 | 24 | ||
25 | unsigned int ppc_swiotlb_enable; | 25 | unsigned int ppc_swiotlb_enable; |
26 | 26 | ||
27 | static u64 swiotlb_powerpc_get_required(struct device *dev) | ||
28 | { | ||
29 | u64 end, mask, max_direct_dma_addr = dev->archdata.max_direct_dma_addr; | ||
30 | |||
31 | end = memblock_end_of_DRAM(); | ||
32 | if (max_direct_dma_addr && end > max_direct_dma_addr) | ||
33 | end = max_direct_dma_addr; | ||
34 | end += get_dma_offset(dev); | ||
35 | |||
36 | mask = 1ULL << (fls64(end) - 1); | ||
37 | mask += mask - 1; | ||
38 | |||
39 | return mask; | ||
40 | } | ||
41 | |||
27 | /* | 42 | /* |
28 | * At the moment, all platforms that use this code only require | 43 | * At the moment, all platforms that use this code only require |
29 | * swiotlb to be used if we're operating on HIGHMEM. Since | 44 | * swiotlb to be used if we're operating on HIGHMEM. Since |
@@ -44,6 +59,7 @@ struct dma_map_ops swiotlb_dma_ops = { | |||
44 | .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, | 59 | .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, |
45 | .sync_sg_for_device = swiotlb_sync_sg_for_device, | 60 | .sync_sg_for_device = swiotlb_sync_sg_for_device, |
46 | .mapping_error = swiotlb_dma_mapping_error, | 61 | .mapping_error = swiotlb_dma_mapping_error, |
62 | .get_required_mask = swiotlb_powerpc_get_required, | ||
47 | }; | 63 | }; |
48 | 64 | ||
49 | void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev) | 65 | void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev) |
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c index 4f0959fbfbee..8593f53c4f6c 100644 --- a/arch/powerpc/kernel/dma.c +++ b/arch/powerpc/kernel/dma.c | |||
@@ -96,6 +96,18 @@ static int dma_direct_dma_supported(struct device *dev, u64 mask) | |||
96 | #endif | 96 | #endif |
97 | } | 97 | } |
98 | 98 | ||
99 | static u64 dma_direct_get_required_mask(struct device *dev) | ||
100 | { | ||
101 | u64 end, mask; | ||
102 | |||
103 | end = memblock_end_of_DRAM() + get_dma_offset(dev); | ||
104 | |||
105 | mask = 1ULL << (fls64(end) - 1); | ||
106 | mask += mask - 1; | ||
107 | |||
108 | return mask; | ||
109 | } | ||
110 | |||
99 | static inline dma_addr_t dma_direct_map_page(struct device *dev, | 111 | static inline dma_addr_t dma_direct_map_page(struct device *dev, |
100 | struct page *page, | 112 | struct page *page, |
101 | unsigned long offset, | 113 | unsigned long offset, |
@@ -137,13 +149,14 @@ static inline void dma_direct_sync_single(struct device *dev, | |||
137 | #endif | 149 | #endif |
138 | 150 | ||
139 | struct dma_map_ops dma_direct_ops = { | 151 | struct dma_map_ops dma_direct_ops = { |
140 | .alloc_coherent = dma_direct_alloc_coherent, | 152 | .alloc_coherent = dma_direct_alloc_coherent, |
141 | .free_coherent = dma_direct_free_coherent, | 153 | .free_coherent = dma_direct_free_coherent, |
142 | .map_sg = dma_direct_map_sg, | 154 | .map_sg = dma_direct_map_sg, |
143 | .unmap_sg = dma_direct_unmap_sg, | 155 | .unmap_sg = dma_direct_unmap_sg, |
144 | .dma_supported = dma_direct_dma_supported, | 156 | .dma_supported = dma_direct_dma_supported, |
145 | .map_page = dma_direct_map_page, | 157 | .map_page = dma_direct_map_page, |
146 | .unmap_page = dma_direct_unmap_page, | 158 | .unmap_page = dma_direct_unmap_page, |
159 | .get_required_mask = dma_direct_get_required_mask, | ||
147 | #ifdef CONFIG_NOT_COHERENT_CACHE | 160 | #ifdef CONFIG_NOT_COHERENT_CACHE |
148 | .sync_single_for_cpu = dma_direct_sync_single, | 161 | .sync_single_for_cpu = dma_direct_sync_single, |
149 | .sync_single_for_device = dma_direct_sync_single, | 162 | .sync_single_for_device = dma_direct_sync_single, |
@@ -170,6 +183,23 @@ int dma_set_mask(struct device *dev, u64 dma_mask) | |||
170 | } | 183 | } |
171 | EXPORT_SYMBOL(dma_set_mask); | 184 | EXPORT_SYMBOL(dma_set_mask); |
172 | 185 | ||
186 | u64 dma_get_required_mask(struct device *dev) | ||
187 | { | ||
188 | struct dma_map_ops *dma_ops = get_dma_ops(dev); | ||
189 | |||
190 | if (ppc_md.dma_get_required_mask) | ||
191 | return ppc_md.dma_get_required_mask(dev); | ||
192 | |||
193 | if (unlikely(dma_ops == NULL)) | ||
194 | return 0; | ||
195 | |||
196 | if (dma_ops->get_required_mask) | ||
197 | return dma_ops->get_required_mask(dev); | ||
198 | |||
199 | return DMA_BIT_MASK(8 * sizeof(dma_addr_t)); | ||
200 | } | ||
201 | EXPORT_SYMBOL_GPL(dma_get_required_mask); | ||
202 | |||
173 | static int __init dma_init(void) | 203 | static int __init dma_init(void) |
174 | { | 204 | { |
175 | dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); | 205 | dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 29ddd8b1c274..a54d92fec612 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -1133,7 +1133,7 @@ _GLOBAL(do_stab_bolted) | |||
1133 | rfid | 1133 | rfid |
1134 | b . /* prevent speculative execution */ | 1134 | b . /* prevent speculative execution */ |
1135 | 1135 | ||
1136 | #ifdef CONFIG_PPC_PSERIES | 1136 | #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) |
1137 | /* | 1137 | /* |
1138 | * Data area reserved for FWNMI option. | 1138 | * Data area reserved for FWNMI option. |
1139 | * This address (0x7000) is fixed by the RPA. | 1139 | * This address (0x7000) is fixed by the RPA. |
@@ -1141,7 +1141,7 @@ _GLOBAL(do_stab_bolted) | |||
1141 | .= 0x7000 | 1141 | .= 0x7000 |
1142 | .globl fwnmi_data_area | 1142 | .globl fwnmi_data_area |
1143 | fwnmi_data_area: | 1143 | fwnmi_data_area: |
1144 | #endif /* CONFIG_PPC_PSERIES */ | 1144 | #endif /* defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */ |
1145 | 1145 | ||
1146 | /* iSeries does not use the FWNMI stuff, so it is safe to put | 1146 | /* iSeries does not use the FWNMI stuff, so it is safe to put |
1147 | * this here, even if we later allow kernels that will boot on | 1147 | * this here, even if we later allow kernels that will boot on |
@@ -1166,9 +1166,12 @@ xLparMap: | |||
1166 | 1166 | ||
1167 | #endif /* CONFIG_PPC_ISERIES */ | 1167 | #endif /* CONFIG_PPC_ISERIES */ |
1168 | 1168 | ||
1169 | #ifdef CONFIG_PPC_PSERIES | 1169 | #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) |
1170 | /* pseries and powernv need to keep the whole page from | ||
1171 | * 0x7000 to 0x8000 free for use by the firmware | ||
1172 | */ | ||
1170 | . = 0x8000 | 1173 | . = 0x8000 |
1171 | #endif /* CONFIG_PPC_PSERIES */ | 1174 | #endif /* defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */ |
1172 | 1175 | ||
1173 | /* | 1176 | /* |
1174 | * Space for CPU0's segment table. | 1177 | * Space for CPU0's segment table. |
@@ -1183,3 +1186,19 @@ xLparMap: | |||
1183 | .globl initial_stab | 1186 | .globl initial_stab |
1184 | initial_stab: | 1187 | initial_stab: |
1185 | .space 4096 | 1188 | .space 4096 |
1189 | #ifdef CONFIG_PPC_POWERNV | ||
1190 | _GLOBAL(opal_mc_secondary_handler) | ||
1191 | HMT_MEDIUM | ||
1192 | SET_SCRATCH0(r13) | ||
1193 | GET_PACA(r13) | ||
1194 | clrldi r3,r3,2 | ||
1195 | tovirt(r3,r3) | ||
1196 | std r3,PACA_OPAL_MC_EVT(r13) | ||
1197 | ld r13,OPAL_MC_SRR0(r3) | ||
1198 | mtspr SPRN_SRR0,r13 | ||
1199 | ld r13,OPAL_MC_SRR1(r3) | ||
1200 | mtspr SPRN_SRR1,r13 | ||
1201 | ld r3,OPAL_MC_GPR3(r3) | ||
1202 | GET_SCRATCH0(r13) | ||
1203 | b machine_check_pSeries | ||
1204 | #endif /* CONFIG_PPC_POWERNV */ | ||
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index ba250d505e07..0654dba2c1f1 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S | |||
@@ -139,8 +139,7 @@ __start: | |||
139 | trap | 139 | trap |
140 | #endif /* CONFIG_PPC_PMAC */ | 140 | #endif /* CONFIG_PPC_PMAC */ |
141 | 141 | ||
142 | 1: mr r31,r3 /* save parameters */ | 142 | 1: mr r31,r3 /* save device tree ptr */ |
143 | mr r30,r4 | ||
144 | li r24,0 /* cpu # */ | 143 | li r24,0 /* cpu # */ |
145 | 144 | ||
146 | /* | 145 | /* |
@@ -964,8 +963,8 @@ start_here: | |||
964 | * Do early platform-specific initialization, | 963 | * Do early platform-specific initialization, |
965 | * and set up the MMU. | 964 | * and set up the MMU. |
966 | */ | 965 | */ |
967 | mr r3,r31 | 966 | li r3,0 |
968 | mr r4,r30 | 967 | mr r4,r31 |
969 | bl machine_init | 968 | bl machine_init |
970 | bl __save_cpu_setup | 969 | bl __save_cpu_setup |
971 | bl MMU_init | 970 | bl MMU_init |
diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S index a91626d87fc9..872a6af83bad 100644 --- a/arch/powerpc/kernel/head_40x.S +++ b/arch/powerpc/kernel/head_40x.S | |||
@@ -58,13 +58,7 @@ | |||
58 | _ENTRY(_stext); | 58 | _ENTRY(_stext); |
59 | _ENTRY(_start); | 59 | _ENTRY(_start); |
60 | 60 | ||
61 | /* Save parameters we are passed. | 61 | mr r31,r3 /* save device tree ptr */ |
62 | */ | ||
63 | mr r31,r3 | ||
64 | mr r30,r4 | ||
65 | mr r29,r5 | ||
66 | mr r28,r6 | ||
67 | mr r27,r7 | ||
68 | 62 | ||
69 | /* We have to turn on the MMU right away so we get cache modes | 63 | /* We have to turn on the MMU right away so we get cache modes |
70 | * set correctly. | 64 | * set correctly. |
@@ -849,11 +843,8 @@ start_here: | |||
849 | /* | 843 | /* |
850 | * Decide what sort of machine this is and initialize the MMU. | 844 | * Decide what sort of machine this is and initialize the MMU. |
851 | */ | 845 | */ |
852 | mr r3,r31 | 846 | li r3,0 |
853 | mr r4,r30 | 847 | mr r4,r31 |
854 | mr r5,r29 | ||
855 | mr r6,r28 | ||
856 | mr r7,r27 | ||
857 | bl machine_init | 848 | bl machine_init |
858 | bl MMU_init | 849 | bl MMU_init |
859 | 850 | ||
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index f8e971ba94f5..b725dab0f88a 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S | |||
@@ -61,14 +61,7 @@ _ENTRY(_start); | |||
61 | * of abatron_pteptrs | 61 | * of abatron_pteptrs |
62 | */ | 62 | */ |
63 | nop | 63 | nop |
64 | /* | 64 | mr r31,r3 /* save device tree ptr */ |
65 | * Save parameters we are passed | ||
66 | */ | ||
67 | mr r31,r3 | ||
68 | mr r30,r4 | ||
69 | mr r29,r5 | ||
70 | mr r28,r6 | ||
71 | mr r27,r7 | ||
72 | li r24,0 /* CPU number */ | 65 | li r24,0 /* CPU number */ |
73 | 66 | ||
74 | bl init_cpu_state | 67 | bl init_cpu_state |
@@ -120,11 +113,8 @@ _ENTRY(_start); | |||
120 | /* | 113 | /* |
121 | * Decide what sort of machine this is and initialize the MMU. | 114 | * Decide what sort of machine this is and initialize the MMU. |
122 | */ | 115 | */ |
123 | mr r3,r31 | 116 | li r3,0 |
124 | mr r4,r30 | 117 | mr r4,r31 |
125 | mr r5,r29 | ||
126 | mr r6,r28 | ||
127 | mr r7,r27 | ||
128 | bl machine_init | 118 | bl machine_init |
129 | bl MMU_init | 119 | bl MMU_init |
130 | 120 | ||
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 3564c49c683e..06c7251c1bf7 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -51,6 +51,11 @@ | |||
51 | * For pSeries or server processors: | 51 | * For pSeries or server processors: |
52 | * 1. The MMU is off & open firmware is running in real mode. | 52 | * 1. The MMU is off & open firmware is running in real mode. |
53 | * 2. The kernel is entered at __start | 53 | * 2. The kernel is entered at __start |
54 | * -or- For OPAL entry: | ||
55 | * 1. The MMU is off, processor in HV mode, primary CPU enters at 0 | ||
56 | * with device-tree in gpr3. We also get OPAL base in r8 and | ||
57 | * entry in r9 for debugging purposes | ||
58 | * 2. Secondary processors enter at 0x60 with PIR in gpr3 | ||
54 | * | 59 | * |
55 | * For iSeries: | 60 | * For iSeries: |
56 | * 1. The MMU is on (as it always is for iSeries) | 61 | * 1. The MMU is on (as it always is for iSeries) |
@@ -331,6 +336,11 @@ _GLOBAL(__start_initialization_multiplatform) | |||
331 | /* Save parameters */ | 336 | /* Save parameters */ |
332 | mr r31,r3 | 337 | mr r31,r3 |
333 | mr r30,r4 | 338 | mr r30,r4 |
339 | #ifdef CONFIG_PPC_EARLY_DEBUG_OPAL | ||
340 | /* Save OPAL entry */ | ||
341 | mr r28,r8 | ||
342 | mr r29,r9 | ||
343 | #endif | ||
334 | 344 | ||
335 | #ifdef CONFIG_PPC_BOOK3E | 345 | #ifdef CONFIG_PPC_BOOK3E |
336 | bl .start_initialization_book3e | 346 | bl .start_initialization_book3e |
@@ -674,9 +684,9 @@ _GLOBAL(enable_64b_mode) | |||
674 | _GLOBAL(relative_toc) | 684 | _GLOBAL(relative_toc) |
675 | mflr r0 | 685 | mflr r0 |
676 | bcl 20,31,$+4 | 686 | bcl 20,31,$+4 |
677 | 0: mflr r9 | 687 | 0: mflr r11 |
678 | ld r2,(p_toc - 0b)(r9) | 688 | ld r2,(p_toc - 0b)(r11) |
679 | add r2,r2,r9 | 689 | add r2,r2,r11 |
680 | mtlr r0 | 690 | mtlr r0 |
681 | blr | 691 | blr |
682 | 692 | ||
@@ -707,6 +717,12 @@ _INIT_STATIC(start_here_multiplatform) | |||
707 | bdnz 3b | 717 | bdnz 3b |
708 | 4: | 718 | 4: |
709 | 719 | ||
720 | #ifdef CONFIG_PPC_EARLY_DEBUG_OPAL | ||
721 | /* Setup OPAL entry */ | ||
722 | std r28,0(r11); | ||
723 | std r29,8(r11); | ||
724 | #endif | ||
725 | |||
710 | #ifndef CONFIG_PPC_BOOK3E | 726 | #ifndef CONFIG_PPC_BOOK3E |
711 | mfmsr r6 | 727 | mfmsr r6 |
712 | ori r6,r6,MSR_RI | 728 | ori r6,r6,MSR_RI |
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 1cbf64e6b416..b68cb173ba2c 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S | |||
@@ -76,11 +76,7 @@ _ENTRY(_start); | |||
76 | */ | 76 | */ |
77 | .globl __start | 77 | .globl __start |
78 | __start: | 78 | __start: |
79 | mr r31,r3 /* save parameters */ | 79 | mr r31,r3 /* save device tree ptr */ |
80 | mr r30,r4 | ||
81 | mr r29,r5 | ||
82 | mr r28,r6 | ||
83 | mr r27,r7 | ||
84 | 80 | ||
85 | /* We have to turn on the MMU right away so we get cache modes | 81 | /* We have to turn on the MMU right away so we get cache modes |
86 | * set correctly. | 82 | * set correctly. |
@@ -723,11 +719,8 @@ start_here: | |||
723 | /* | 719 | /* |
724 | * Decide what sort of machine this is and initialize the MMU. | 720 | * Decide what sort of machine this is and initialize the MMU. |
725 | */ | 721 | */ |
726 | mr r3,r31 | 722 | li r3,0 |
727 | mr r4,r30 | 723 | mr r4,r31 |
728 | mr r5,r29 | ||
729 | mr r6,r28 | ||
730 | mr r7,r27 | ||
731 | bl machine_init | 724 | bl machine_init |
732 | bl MMU_init | 725 | bl MMU_init |
733 | 726 | ||
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 50845924b7d9..9f5d210ddf3f 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S | |||
@@ -63,17 +63,30 @@ _ENTRY(_start); | |||
63 | * of abatron_pteptrs | 63 | * of abatron_pteptrs |
64 | */ | 64 | */ |
65 | nop | 65 | nop |
66 | /* | 66 | |
67 | * Save parameters we are passed | 67 | /* Translate device tree address to physical, save in r30/r31 */ |
68 | */ | 68 | mfmsr r16 |
69 | mr r31,r3 | 69 | mfspr r17,SPRN_PID |
70 | mr r30,r4 | 70 | rlwinm r17,r17,16,0x3fff0000 /* turn PID into MAS6[SPID] */ |
71 | mr r29,r5 | 71 | rlwimi r17,r16,28,0x00000001 /* turn MSR[DS] into MAS6[SAS] */ |
72 | mr r28,r6 | 72 | mtspr SPRN_MAS6,r17 |
73 | mr r27,r7 | 73 | |
74 | li r25,0 /* phys kernel start (low) */ | 74 | tlbsx 0,r3 /* must succeed */ |
75 | li r24,0 /* CPU number */ | 75 | |
76 | li r23,0 /* phys kernel start (high) */ | 76 | mfspr r16,SPRN_MAS1 |
77 | mfspr r20,SPRN_MAS3 | ||
78 | rlwinm r17,r16,25,0x1f /* r17 = log2(page size) */ | ||
79 | li r18,1024 | ||
80 | slw r18,r18,r17 /* r18 = page size */ | ||
81 | addi r18,r18,-1 | ||
82 | and r19,r3,r18 /* r19 = page offset */ | ||
83 | andc r31,r20,r18 /* r31 = page base */ | ||
84 | or r31,r31,r19 /* r31 = devtree phys addr */ | ||
85 | mfspr r30,SPRN_MAS7 | ||
86 | |||
87 | li r25,0 /* phys kernel start (low) */ | ||
88 | li r24,0 /* CPU number */ | ||
89 | li r23,0 /* phys kernel start (high) */ | ||
77 | 90 | ||
78 | /* We try to not make any assumptions about how the boot loader | 91 | /* We try to not make any assumptions about how the boot loader |
79 | * setup or used the TLBs. We invalidate all mappings from the | 92 | * setup or used the TLBs. We invalidate all mappings from the |
@@ -198,11 +211,8 @@ _ENTRY(__early_start) | |||
198 | /* | 211 | /* |
199 | * Decide what sort of machine this is and initialize the MMU. | 212 | * Decide what sort of machine this is and initialize the MMU. |
200 | */ | 213 | */ |
201 | mr r3,r31 | 214 | mr r3,r30 |
202 | mr r4,r30 | 215 | mr r4,r31 |
203 | mr r5,r29 | ||
204 | mr r6,r28 | ||
205 | mr r7,r27 | ||
206 | bl machine_init | 216 | bl machine_init |
207 | bl MMU_init | 217 | bl MMU_init |
208 | 218 | ||
@@ -236,8 +246,24 @@ _ENTRY(__early_start) | |||
236 | * if we find the pte (fall through): | 246 | * if we find the pte (fall through): |
237 | * r11 is low pte word | 247 | * r11 is low pte word |
238 | * r12 is pointer to the pte | 248 | * r12 is pointer to the pte |
249 | * r10 is the pshift from the PGD, if we're a hugepage | ||
239 | */ | 250 | */ |
240 | #ifdef CONFIG_PTE_64BIT | 251 | #ifdef CONFIG_PTE_64BIT |
252 | #ifdef CONFIG_HUGETLB_PAGE | ||
253 | #define FIND_PTE \ | ||
254 | rlwinm r12, r10, 13, 19, 29; /* Compute pgdir/pmd offset */ \ | ||
255 | lwzx r11, r12, r11; /* Get pgd/pmd entry */ \ | ||
256 | rlwinm. r12, r11, 0, 0, 20; /* Extract pt base address */ \ | ||
257 | blt 1000f; /* Normal non-huge page */ \ | ||
258 | beq 2f; /* Bail if no table */ \ | ||
259 | oris r11, r11, PD_HUGE@h; /* Put back address bit */ \ | ||
260 | andi. r10, r11, HUGEPD_SHIFT_MASK@l; /* extract size field */ \ | ||
261 | xor r12, r10, r11; /* drop size bits from pointer */ \ | ||
262 | b 1001f; \ | ||
263 | 1000: rlwimi r12, r10, 23, 20, 28; /* Compute pte address */ \ | ||
264 | li r10, 0; /* clear r10 */ \ | ||
265 | 1001: lwz r11, 4(r12); /* Get pte entry */ | ||
266 | #else | ||
241 | #define FIND_PTE \ | 267 | #define FIND_PTE \ |
242 | rlwinm r12, r10, 13, 19, 29; /* Compute pgdir/pmd offset */ \ | 268 | rlwinm r12, r10, 13, 19, 29; /* Compute pgdir/pmd offset */ \ |
243 | lwzx r11, r12, r11; /* Get pgd/pmd entry */ \ | 269 | lwzx r11, r12, r11; /* Get pgd/pmd entry */ \ |
@@ -245,7 +271,8 @@ _ENTRY(__early_start) | |||
245 | beq 2f; /* Bail if no table */ \ | 271 | beq 2f; /* Bail if no table */ \ |
246 | rlwimi r12, r10, 23, 20, 28; /* Compute pte address */ \ | 272 | rlwimi r12, r10, 23, 20, 28; /* Compute pte address */ \ |
247 | lwz r11, 4(r12); /* Get pte entry */ | 273 | lwz r11, 4(r12); /* Get pte entry */ |
248 | #else | 274 | #endif /* HUGEPAGE */ |
275 | #else /* !PTE_64BIT */ | ||
249 | #define FIND_PTE \ | 276 | #define FIND_PTE \ |
250 | rlwimi r11, r10, 12, 20, 29; /* Create L1 (pgdir/pmd) address */ \ | 277 | rlwimi r11, r10, 12, 20, 29; /* Create L1 (pgdir/pmd) address */ \ |
251 | lwz r11, 0(r11); /* Get L1 entry */ \ | 278 | lwz r11, 0(r11); /* Get L1 entry */ \ |
@@ -402,8 +429,8 @@ interrupt_base: | |||
402 | 429 | ||
403 | #ifdef CONFIG_PTE_64BIT | 430 | #ifdef CONFIG_PTE_64BIT |
404 | #ifdef CONFIG_SMP | 431 | #ifdef CONFIG_SMP |
405 | subf r10,r11,r12 /* create false data dep */ | 432 | subf r13,r11,r12 /* create false data dep */ |
406 | lwzx r13,r11,r10 /* Get upper pte bits */ | 433 | lwzx r13,r11,r13 /* Get upper pte bits */ |
407 | #else | 434 | #else |
408 | lwz r13,0(r12) /* Get upper pte bits */ | 435 | lwz r13,0(r12) /* Get upper pte bits */ |
409 | #endif | 436 | #endif |
@@ -483,8 +510,8 @@ interrupt_base: | |||
483 | 510 | ||
484 | #ifdef CONFIG_PTE_64BIT | 511 | #ifdef CONFIG_PTE_64BIT |
485 | #ifdef CONFIG_SMP | 512 | #ifdef CONFIG_SMP |
486 | subf r10,r11,r12 /* create false data dep */ | 513 | subf r13,r11,r12 /* create false data dep */ |
487 | lwzx r13,r11,r10 /* Get upper pte bits */ | 514 | lwzx r13,r11,r13 /* Get upper pte bits */ |
488 | #else | 515 | #else |
489 | lwz r13,0(r12) /* Get upper pte bits */ | 516 | lwz r13,0(r12) /* Get upper pte bits */ |
490 | #endif | 517 | #endif |
@@ -548,7 +575,7 @@ interrupt_base: | |||
548 | /* | 575 | /* |
549 | * Both the instruction and data TLB miss get to this | 576 | * Both the instruction and data TLB miss get to this |
550 | * point to load the TLB. | 577 | * point to load the TLB. |
551 | * r10 - available to use | 578 | * r10 - tsize encoding (if HUGETLB_PAGE) or available to use |
552 | * r11 - TLB (info from Linux PTE) | 579 | * r11 - TLB (info from Linux PTE) |
553 | * r12 - available to use | 580 | * r12 - available to use |
554 | * r13 - upper bits of PTE (if PTE_64BIT) or available to use | 581 | * r13 - upper bits of PTE (if PTE_64BIT) or available to use |
@@ -558,21 +585,73 @@ interrupt_base: | |||
558 | * Upon exit, we reload everything and RFI. | 585 | * Upon exit, we reload everything and RFI. |
559 | */ | 586 | */ |
560 | finish_tlb_load: | 587 | finish_tlb_load: |
588 | #ifdef CONFIG_HUGETLB_PAGE | ||
589 | cmpwi 6, r10, 0 /* check for huge page */ | ||
590 | beq 6, finish_tlb_load_cont /* !huge */ | ||
591 | |||
592 | /* Alas, we need more scratch registers for hugepages */ | ||
593 | mfspr r12, SPRN_SPRG_THREAD | ||
594 | stw r14, THREAD_NORMSAVE(4)(r12) | ||
595 | stw r15, THREAD_NORMSAVE(5)(r12) | ||
596 | stw r16, THREAD_NORMSAVE(6)(r12) | ||
597 | stw r17, THREAD_NORMSAVE(7)(r12) | ||
598 | |||
599 | /* Get the next_tlbcam_idx percpu var */ | ||
600 | #ifdef CONFIG_SMP | ||
601 | lwz r12, THREAD_INFO-THREAD(r12) | ||
602 | lwz r15, TI_CPU(r12) | ||
603 | lis r14, __per_cpu_offset@h | ||
604 | ori r14, r14, __per_cpu_offset@l | ||
605 | rlwinm r15, r15, 2, 0, 29 | ||
606 | lwzx r16, r14, r15 | ||
607 | #else | ||
608 | li r16, 0 | ||
609 | #endif | ||
610 | lis r17, next_tlbcam_idx@h | ||
611 | ori r17, r17, next_tlbcam_idx@l | ||
612 | add r17, r17, r16 /* r17 = *next_tlbcam_idx */ | ||
613 | lwz r15, 0(r17) /* r15 = next_tlbcam_idx */ | ||
614 | |||
615 | lis r14, MAS0_TLBSEL(1)@h /* select TLB1 (TLBCAM) */ | ||
616 | rlwimi r14, r15, 16, 4, 15 /* next_tlbcam_idx entry */ | ||
617 | mtspr SPRN_MAS0, r14 | ||
618 | |||
619 | /* Extract TLB1CFG(NENTRY) */ | ||
620 | mfspr r16, SPRN_TLB1CFG | ||
621 | andi. r16, r16, 0xfff | ||
622 | |||
623 | /* Update next_tlbcam_idx, wrapping when necessary */ | ||
624 | addi r15, r15, 1 | ||
625 | cmpw r15, r16 | ||
626 | blt 100f | ||
627 | lis r14, tlbcam_index@h | ||
628 | ori r14, r14, tlbcam_index@l | ||
629 | lwz r15, 0(r14) | ||
630 | 100: stw r15, 0(r17) | ||
631 | |||
632 | /* | ||
633 | * Calc MAS1_TSIZE from r10 (which has pshift encoded) | ||
634 | * tlb_enc = (pshift - 10). | ||
635 | */ | ||
636 | subi r15, r10, 10 | ||
637 | mfspr r16, SPRN_MAS1 | ||
638 | rlwimi r16, r15, 7, 20, 24 | ||
639 | mtspr SPRN_MAS1, r16 | ||
640 | |||
641 | /* copy the pshift for use later */ | ||
642 | mr r14, r10 | ||
643 | |||
644 | /* fall through */ | ||
645 | |||
646 | #endif /* CONFIG_HUGETLB_PAGE */ | ||
647 | |||
561 | /* | 648 | /* |
562 | * We set execute, because we don't have the granularity to | 649 | * We set execute, because we don't have the granularity to |
563 | * properly set this at the page level (Linux problem). | 650 | * properly set this at the page level (Linux problem). |
564 | * Many of these bits are software only. Bits we don't set | 651 | * Many of these bits are software only. Bits we don't set |
565 | * here we (properly should) assume have the appropriate value. | 652 | * here we (properly should) assume have the appropriate value. |
566 | */ | 653 | */ |
567 | 654 | finish_tlb_load_cont: | |
568 | mfspr r12, SPRN_MAS2 | ||
569 | #ifdef CONFIG_PTE_64BIT | ||
570 | rlwimi r12, r11, 32-19, 27, 31 /* extract WIMGE from pte */ | ||
571 | #else | ||
572 | rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */ | ||
573 | #endif | ||
574 | mtspr SPRN_MAS2, r12 | ||
575 | |||
576 | #ifdef CONFIG_PTE_64BIT | 655 | #ifdef CONFIG_PTE_64BIT |
577 | rlwinm r12, r11, 32-2, 26, 31 /* Move in perm bits */ | 656 | rlwinm r12, r11, 32-2, 26, 31 /* Move in perm bits */ |
578 | andi. r10, r11, _PAGE_DIRTY | 657 | andi. r10, r11, _PAGE_DIRTY |
@@ -581,22 +660,40 @@ finish_tlb_load: | |||
581 | andc r12, r12, r10 | 660 | andc r12, r12, r10 |
582 | 1: rlwimi r12, r13, 20, 0, 11 /* grab RPN[32:43] */ | 661 | 1: rlwimi r12, r13, 20, 0, 11 /* grab RPN[32:43] */ |
583 | rlwimi r12, r11, 20, 12, 19 /* grab RPN[44:51] */ | 662 | rlwimi r12, r11, 20, 12, 19 /* grab RPN[44:51] */ |
584 | mtspr SPRN_MAS3, r12 | 663 | 2: mtspr SPRN_MAS3, r12 |
585 | BEGIN_MMU_FTR_SECTION | 664 | BEGIN_MMU_FTR_SECTION |
586 | srwi r10, r13, 12 /* grab RPN[12:31] */ | 665 | srwi r10, r13, 12 /* grab RPN[12:31] */ |
587 | mtspr SPRN_MAS7, r10 | 666 | mtspr SPRN_MAS7, r10 |
588 | END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS) | 667 | END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS) |
589 | #else | 668 | #else |
590 | li r10, (_PAGE_EXEC | _PAGE_PRESENT) | 669 | li r10, (_PAGE_EXEC | _PAGE_PRESENT) |
670 | mr r13, r11 | ||
591 | rlwimi r10, r11, 31, 29, 29 /* extract _PAGE_DIRTY into SW */ | 671 | rlwimi r10, r11, 31, 29, 29 /* extract _PAGE_DIRTY into SW */ |
592 | and r12, r11, r10 | 672 | and r12, r11, r10 |
593 | andi. r10, r11, _PAGE_USER /* Test for _PAGE_USER */ | 673 | andi. r10, r11, _PAGE_USER /* Test for _PAGE_USER */ |
594 | slwi r10, r12, 1 | 674 | slwi r10, r12, 1 |
595 | or r10, r10, r12 | 675 | or r10, r10, r12 |
596 | iseleq r12, r12, r10 | 676 | iseleq r12, r12, r10 |
597 | rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */ | 677 | rlwimi r13, r12, 0, 20, 31 /* Get RPN from PTE, merge w/ perms */ |
598 | mtspr SPRN_MAS3, r11 | 678 | mtspr SPRN_MAS3, r13 |
599 | #endif | 679 | #endif |
680 | |||
681 | mfspr r12, SPRN_MAS2 | ||
682 | #ifdef CONFIG_PTE_64BIT | ||
683 | rlwimi r12, r11, 32-19, 27, 31 /* extract WIMGE from pte */ | ||
684 | #else | ||
685 | rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */ | ||
686 | #endif | ||
687 | #ifdef CONFIG_HUGETLB_PAGE | ||
688 | beq 6, 3f /* don't mask if page isn't huge */ | ||
689 | li r13, 1 | ||
690 | slw r13, r13, r14 | ||
691 | subi r13, r13, 1 | ||
692 | rlwinm r13, r13, 0, 0, 19 /* bottom bits used for WIMGE/etc */ | ||
693 | andc r12, r12, r13 /* mask off ea bits within the page */ | ||
694 | #endif | ||
695 | 3: mtspr SPRN_MAS2, r12 | ||
696 | |||
600 | #ifdef CONFIG_E200 | 697 | #ifdef CONFIG_E200 |
601 | /* Round robin TLB1 entries assignment */ | 698 | /* Round robin TLB1 entries assignment */ |
602 | mfspr r12, SPRN_MAS0 | 699 | mfspr r12, SPRN_MAS0 |
@@ -622,11 +719,19 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS) | |||
622 | mtspr SPRN_MAS0,r12 | 719 | mtspr SPRN_MAS0,r12 |
623 | #endif /* CONFIG_E200 */ | 720 | #endif /* CONFIG_E200 */ |
624 | 721 | ||
722 | tlb_write_entry: | ||
625 | tlbwe | 723 | tlbwe |
626 | 724 | ||
627 | /* Done...restore registers and get out of here. */ | 725 | /* Done...restore registers and get out of here. */ |
628 | mfspr r10, SPRN_SPRG_THREAD | 726 | mfspr r10, SPRN_SPRG_THREAD |
629 | lwz r11, THREAD_NORMSAVE(3)(r10) | 727 | #ifdef CONFIG_HUGETLB_PAGE |
728 | beq 6, 8f /* skip restore for 4k page faults */ | ||
729 | lwz r14, THREAD_NORMSAVE(4)(r10) | ||
730 | lwz r15, THREAD_NORMSAVE(5)(r10) | ||
731 | lwz r16, THREAD_NORMSAVE(6)(r10) | ||
732 | lwz r17, THREAD_NORMSAVE(7)(r10) | ||
733 | #endif | ||
734 | 8: lwz r11, THREAD_NORMSAVE(3)(r10) | ||
630 | mtcr r11 | 735 | mtcr r11 |
631 | lwz r13, THREAD_NORMSAVE(2)(r10) | 736 | lwz r13, THREAD_NORMSAVE(2)(r10) |
632 | lwz r12, THREAD_NORMSAVE(1)(r10) | 737 | lwz r12, THREAD_NORMSAVE(1)(r10) |
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 28581f1ad2c0..73110fb6bb6c 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c | |||
@@ -125,17 +125,23 @@ static void ibmebus_unmap_sg(struct device *dev, | |||
125 | 125 | ||
126 | static int ibmebus_dma_supported(struct device *dev, u64 mask) | 126 | static int ibmebus_dma_supported(struct device *dev, u64 mask) |
127 | { | 127 | { |
128 | return 1; | 128 | return mask == DMA_BIT_MASK(64); |
129 | } | ||
130 | |||
131 | static u64 ibmebus_dma_get_required_mask(struct device *dev) | ||
132 | { | ||
133 | return DMA_BIT_MASK(64); | ||
129 | } | 134 | } |
130 | 135 | ||
131 | static struct dma_map_ops ibmebus_dma_ops = { | 136 | static struct dma_map_ops ibmebus_dma_ops = { |
132 | .alloc_coherent = ibmebus_alloc_coherent, | 137 | .alloc_coherent = ibmebus_alloc_coherent, |
133 | .free_coherent = ibmebus_free_coherent, | 138 | .free_coherent = ibmebus_free_coherent, |
134 | .map_sg = ibmebus_map_sg, | 139 | .map_sg = ibmebus_map_sg, |
135 | .unmap_sg = ibmebus_unmap_sg, | 140 | .unmap_sg = ibmebus_unmap_sg, |
136 | .dma_supported = ibmebus_dma_supported, | 141 | .dma_supported = ibmebus_dma_supported, |
137 | .map_page = ibmebus_map_page, | 142 | .get_required_mask = ibmebus_dma_get_required_mask, |
138 | .unmap_page = ibmebus_unmap_page, | 143 | .map_page = ibmebus_map_page, |
144 | .unmap_page = ibmebus_unmap_page, | ||
139 | }; | 145 | }; |
140 | 146 | ||
141 | static int ibmebus_match_path(struct device *dev, void *data) | 147 | static int ibmebus_match_path(struct device *dev, void *data) |
diff --git a/arch/powerpc/kernel/idle_e500.S b/arch/powerpc/kernel/idle_e500.S index 3e2b95c6ae67..4f0ab85f3788 100644 --- a/arch/powerpc/kernel/idle_e500.S +++ b/arch/powerpc/kernel/idle_e500.S | |||
@@ -26,7 +26,7 @@ _GLOBAL(e500_idle) | |||
26 | ori r4,r4,_TLF_NAPPING /* so when we take an exception */ | 26 | ori r4,r4,_TLF_NAPPING /* so when we take an exception */ |
27 | stw r4,TI_LOCAL_FLAGS(r3) /* it will return to our caller */ | 27 | stw r4,TI_LOCAL_FLAGS(r3) /* it will return to our caller */ |
28 | 28 | ||
29 | #ifdef CONFIG_E500MC | 29 | #ifdef CONFIG_PPC_E500MC |
30 | wrteei 1 | 30 | wrteei 1 |
31 | 1: wait | 31 | 1: wait |
32 | 32 | ||
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 961bb03413f3..0cfcf98aafca 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -501,6 +501,14 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) | |||
501 | tbl->it_map = page_address(page); | 501 | tbl->it_map = page_address(page); |
502 | memset(tbl->it_map, 0, sz); | 502 | memset(tbl->it_map, 0, sz); |
503 | 503 | ||
504 | /* | ||
505 | * Reserve page 0 so it will not be used for any mappings. | ||
506 | * This avoids buggy drivers that consider page 0 to be invalid | ||
507 | * to crash the machine or even lose data. | ||
508 | */ | ||
509 | if (tbl->it_offset == 0) | ||
510 | set_bit(0, tbl->it_map); | ||
511 | |||
504 | tbl->it_hint = 0; | 512 | tbl->it_hint = 0; |
505 | tbl->it_largehint = tbl->it_halfpoint; | 513 | tbl->it_largehint = tbl->it_halfpoint; |
506 | spin_lock_init(&tbl->it_lock); | 514 | spin_lock_init(&tbl->it_lock); |
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 2b97b80d6d7d..c7b5afeecaf2 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/pci.h> | 6 | #include <linux/pci.h> |
7 | #include <linux/of_address.h> | 7 | #include <linux/of_address.h> |
8 | #include <linux/of_device.h> | 8 | #include <linux/of_device.h> |
9 | #include <linux/serial_reg.h> | ||
9 | #include <asm/io.h> | 10 | #include <asm/io.h> |
10 | #include <asm/mmu.h> | 11 | #include <asm/mmu.h> |
11 | #include <asm/prom.h> | 12 | #include <asm/prom.h> |
@@ -47,6 +48,24 @@ static struct __initdata of_device_id legacy_serial_parents[] = { | |||
47 | static unsigned int legacy_serial_count; | 48 | static unsigned int legacy_serial_count; |
48 | static int legacy_serial_console = -1; | 49 | static int legacy_serial_console = -1; |
49 | 50 | ||
51 | static unsigned int tsi_serial_in(struct uart_port *p, int offset) | ||
52 | { | ||
53 | unsigned int tmp; | ||
54 | offset = offset << p->regshift; | ||
55 | if (offset == UART_IIR) { | ||
56 | tmp = readl(p->membase + (UART_IIR & ~3)); | ||
57 | return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */ | ||
58 | } else | ||
59 | return readb(p->membase + offset); | ||
60 | } | ||
61 | |||
62 | static void tsi_serial_out(struct uart_port *p, int offset, int value) | ||
63 | { | ||
64 | offset = offset << p->regshift; | ||
65 | if (!((offset == UART_IER) && (value & UART_IER_UUE))) | ||
66 | writeb(value, p->membase + offset); | ||
67 | } | ||
68 | |||
50 | static int __init add_legacy_port(struct device_node *np, int want_index, | 69 | static int __init add_legacy_port(struct device_node *np, int want_index, |
51 | int iotype, phys_addr_t base, | 70 | int iotype, phys_addr_t base, |
52 | phys_addr_t taddr, unsigned long irq, | 71 | phys_addr_t taddr, unsigned long irq, |
@@ -102,6 +121,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index, | |||
102 | legacy_serial_ports[index].iobase = base; | 121 | legacy_serial_ports[index].iobase = base; |
103 | else | 122 | else |
104 | legacy_serial_ports[index].mapbase = base; | 123 | legacy_serial_ports[index].mapbase = base; |
124 | |||
105 | legacy_serial_ports[index].iotype = iotype; | 125 | legacy_serial_ports[index].iotype = iotype; |
106 | legacy_serial_ports[index].uartclk = clock; | 126 | legacy_serial_ports[index].uartclk = clock; |
107 | legacy_serial_ports[index].irq = irq; | 127 | legacy_serial_ports[index].irq = irq; |
@@ -112,6 +132,11 @@ static int __init add_legacy_port(struct device_node *np, int want_index, | |||
112 | legacy_serial_infos[index].speed = spd ? be32_to_cpup(spd) : 0; | 132 | legacy_serial_infos[index].speed = spd ? be32_to_cpup(spd) : 0; |
113 | legacy_serial_infos[index].irq_check_parent = irq_check_parent; | 133 | legacy_serial_infos[index].irq_check_parent = irq_check_parent; |
114 | 134 | ||
135 | if (iotype == UPIO_TSI) { | ||
136 | legacy_serial_ports[index].serial_in = tsi_serial_in; | ||
137 | legacy_serial_ports[index].serial_out = tsi_serial_out; | ||
138 | } | ||
139 | |||
115 | printk(KERN_DEBUG "Found legacy serial port %d for %s\n", | 140 | printk(KERN_DEBUG "Found legacy serial port %d for %s\n", |
116 | index, np->full_name); | 141 | index, np->full_name); |
117 | printk(KERN_DEBUG " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n", | 142 | printk(KERN_DEBUG " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n", |
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index 583af70c4b14..26ccbf77dd41 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
@@ -74,8 +74,7 @@ int default_machine_kexec_prepare(struct kimage *image) | |||
74 | } | 74 | } |
75 | 75 | ||
76 | /* We also should not overwrite the tce tables */ | 76 | /* We also should not overwrite the tce tables */ |
77 | for (node = of_find_node_by_type(NULL, "pci"); node != NULL; | 77 | for_each_node_by_type(node, "pci") { |
78 | node = of_find_node_by_type(node, "pci")) { | ||
79 | basep = of_get_property(node, "linux,tce-base", NULL); | 78 | basep = of_get_property(node, "linux,tce-base", NULL); |
80 | sizep = of_get_property(node, "linux,tce-size", NULL); | 79 | sizep = of_get_property(node, "linux,tce-size", NULL); |
81 | if (basep == NULL || sizep == NULL) | 80 | if (basep == NULL || sizep == NULL) |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 998a10028608..f7d760ab5ca1 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -8,6 +8,8 @@ | |||
8 | * kexec bits: | 8 | * kexec bits: |
9 | * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com> | 9 | * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com> |
10 | * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz | 10 | * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz |
11 | * PPC44x port. Copyright (C) 2011, IBM Corporation | ||
12 | * Author: Suzuki Poulose <suzuki@in.ibm.com> | ||
11 | * | 13 | * |
12 | * This program is free software; you can redistribute it and/or | 14 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License | 15 | * modify it under the terms of the GNU General Public License |
@@ -736,6 +738,175 @@ relocate_new_kernel: | |||
736 | mr r5, r31 | 738 | mr r5, r31 |
737 | 739 | ||
738 | li r0, 0 | 740 | li r0, 0 |
741 | #elif defined(CONFIG_44x) && !defined(CONFIG_47x) | ||
742 | |||
743 | /* | ||
744 | * Code for setting up 1:1 mapping for PPC440x for KEXEC | ||
745 | * | ||
746 | * We cannot switch off the MMU on PPC44x. | ||
747 | * So we: | ||
748 | * 1) Invalidate all the mappings except the one we are running from. | ||
749 | * 2) Create a tmp mapping for our code in the other address space(TS) and | ||
750 | * jump to it. Invalidate the entry we started in. | ||
751 | * 3) Create a 1:1 mapping for 0-2GiB in chunks of 256M in original TS. | ||
752 | * 4) Jump to the 1:1 mapping in original TS. | ||
753 | * 5) Invalidate the tmp mapping. | ||
754 | * | ||
755 | * - Based on the kexec support code for FSL BookE | ||
756 | * - Doesn't support 47x yet. | ||
757 | * | ||
758 | */ | ||
759 | /* Save our parameters */ | ||
760 | mr r29, r3 | ||
761 | mr r30, r4 | ||
762 | mr r31, r5 | ||
763 | |||
764 | /* Load our MSR_IS and TID to MMUCR for TLB search */ | ||
765 | mfspr r3,SPRN_PID | ||
766 | mfmsr r4 | ||
767 | andi. r4,r4,MSR_IS@l | ||
768 | beq wmmucr | ||
769 | oris r3,r3,PPC44x_MMUCR_STS@h | ||
770 | wmmucr: | ||
771 | mtspr SPRN_MMUCR,r3 | ||
772 | sync | ||
773 | |||
774 | /* | ||
775 | * Invalidate all the TLB entries except the current entry | ||
776 | * where we are running from | ||
777 | */ | ||
778 | bl 0f /* Find our address */ | ||
779 | 0: mflr r5 /* Make it accessible */ | ||
780 | tlbsx r23,0,r5 /* Find entry we are in */ | ||
781 | li r4,0 /* Start at TLB entry 0 */ | ||
782 | li r3,0 /* Set PAGEID inval value */ | ||
783 | 1: cmpw r23,r4 /* Is this our entry? */ | ||
784 | beq skip /* If so, skip the inval */ | ||
785 | tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */ | ||
786 | skip: | ||
787 | addi r4,r4,1 /* Increment */ | ||
788 | cmpwi r4,64 /* Are we done? */ | ||
789 | bne 1b /* If not, repeat */ | ||
790 | isync | ||
791 | |||
792 | /* Create a temp mapping and jump to it */ | ||
793 | andi. r6, r23, 1 /* Find the index to use */ | ||
794 | addi r24, r6, 1 /* r24 will contain 1 or 2 */ | ||
795 | |||
796 | mfmsr r9 /* get the MSR */ | ||
797 | rlwinm r5, r9, 27, 31, 31 /* Extract the MSR[IS] */ | ||
798 | xori r7, r5, 1 /* Use the other address space */ | ||
799 | |||
800 | /* Read the current mapping entries */ | ||
801 | tlbre r3, r23, PPC44x_TLB_PAGEID | ||
802 | tlbre r4, r23, PPC44x_TLB_XLAT | ||
803 | tlbre r5, r23, PPC44x_TLB_ATTRIB | ||
804 | |||
805 | /* Save our current XLAT entry */ | ||
806 | mr r25, r4 | ||
807 | |||
808 | /* Extract the TLB PageSize */ | ||
809 | li r10, 1 /* r10 will hold PageSize */ | ||
810 | rlwinm r11, r3, 0, 24, 27 /* bits 24-27 */ | ||
811 | |||
812 | /* XXX: As of now we use 256M, 4K pages */ | ||
813 | cmpwi r11, PPC44x_TLB_256M | ||
814 | bne tlb_4k | ||
815 | rotlwi r10, r10, 28 /* r10 = 256M */ | ||
816 | b write_out | ||
817 | tlb_4k: | ||
818 | cmpwi r11, PPC44x_TLB_4K | ||
819 | bne default | ||
820 | rotlwi r10, r10, 12 /* r10 = 4K */ | ||
821 | b write_out | ||
822 | default: | ||
823 | rotlwi r10, r10, 10 /* r10 = 1K */ | ||
824 | |||
825 | write_out: | ||
826 | /* | ||
827 | * Write out the tmp 1:1 mapping for this code in other address space | ||
828 | * Fixup EPN = RPN , TS=other address space | ||
829 | */ | ||
830 | insrwi r3, r7, 1, 23 /* Bit 23 is TS for PAGEID field */ | ||
831 | |||
832 | /* Write out the tmp mapping entries */ | ||
833 | tlbwe r3, r24, PPC44x_TLB_PAGEID | ||
834 | tlbwe r4, r24, PPC44x_TLB_XLAT | ||
835 | tlbwe r5, r24, PPC44x_TLB_ATTRIB | ||
836 | |||
837 | subi r11, r10, 1 /* PageOffset Mask = PageSize - 1 */ | ||
838 | not r10, r11 /* Mask for PageNum */ | ||
839 | |||
840 | /* Switch to other address space in MSR */ | ||
841 | insrwi r9, r7, 1, 26 /* Set MSR[IS] = r7 */ | ||
842 | |||
843 | bl 1f | ||
844 | 1: mflr r8 | ||
845 | addi r8, r8, (2f-1b) /* Find the target offset */ | ||
846 | |||
847 | /* Jump to the tmp mapping */ | ||
848 | mtspr SPRN_SRR0, r8 | ||
849 | mtspr SPRN_SRR1, r9 | ||
850 | rfi | ||
851 | |||
852 | 2: | ||
853 | /* Invalidate the entry we were executing from */ | ||
854 | li r3, 0 | ||
855 | tlbwe r3, r23, PPC44x_TLB_PAGEID | ||
856 | |||
857 | /* attribute fields. rwx for SUPERVISOR mode */ | ||
858 | li r5, 0 | ||
859 | ori r5, r5, (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G) | ||
860 | |||
861 | /* Create 1:1 mapping in 256M pages */ | ||
862 | xori r7, r7, 1 /* Revert back to Original TS */ | ||
863 | |||
864 | li r8, 0 /* PageNumber */ | ||
865 | li r6, 3 /* TLB Index, start at 3 */ | ||
866 | |||
867 | next_tlb: | ||
868 | rotlwi r3, r8, 28 /* Create EPN (bits 0-3) */ | ||
869 | mr r4, r3 /* RPN = EPN */ | ||
870 | ori r3, r3, (PPC44x_TLB_VALID | PPC44x_TLB_256M) /* SIZE = 256M, Valid */ | ||
871 | insrwi r3, r7, 1, 23 /* Set TS from r7 */ | ||
872 | |||
873 | tlbwe r3, r6, PPC44x_TLB_PAGEID /* PageID field : EPN, V, SIZE */ | ||
874 | tlbwe r4, r6, PPC44x_TLB_XLAT /* Address translation : RPN */ | ||
875 | tlbwe r5, r6, PPC44x_TLB_ATTRIB /* Attributes */ | ||
876 | |||
877 | addi r8, r8, 1 /* Increment PN */ | ||
878 | addi r6, r6, 1 /* Increment TLB Index */ | ||
879 | cmpwi r8, 8 /* Are we done ? */ | ||
880 | bne next_tlb | ||
881 | isync | ||
882 | |||
883 | /* Jump to the new mapping 1:1 */ | ||
884 | li r9,0 | ||
885 | insrwi r9, r7, 1, 26 /* Set MSR[IS] = r7 */ | ||
886 | |||
887 | bl 1f | ||
888 | 1: mflr r8 | ||
889 | and r8, r8, r11 /* Get our offset within page */ | ||
890 | addi r8, r8, (2f-1b) | ||
891 | |||
892 | and r5, r25, r10 /* Get our target PageNum */ | ||
893 | or r8, r8, r5 /* Target jump address */ | ||
894 | |||
895 | mtspr SPRN_SRR0, r8 | ||
896 | mtspr SPRN_SRR1, r9 | ||
897 | rfi | ||
898 | 2: | ||
899 | /* Invalidate the tmp entry we used */ | ||
900 | li r3, 0 | ||
901 | tlbwe r3, r24, PPC44x_TLB_PAGEID | ||
902 | sync | ||
903 | |||
904 | /* Restore the parameters */ | ||
905 | mr r3, r29 | ||
906 | mr r4, r30 | ||
907 | mr r5, r31 | ||
908 | |||
909 | li r0, 0 | ||
739 | #else | 910 | #else |
740 | li r0, 0 | 911 | li r0, 0 |
741 | 912 | ||
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 32656f105250..677ecccbe10d 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -1730,6 +1730,17 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose) | |||
1730 | 1730 | ||
1731 | if (mode == PCI_PROBE_NORMAL) | 1731 | if (mode == PCI_PROBE_NORMAL) |
1732 | hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); | 1732 | hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); |
1733 | |||
1734 | /* Configure PCI Express settings */ | ||
1735 | if (bus && !pci_has_flag(PCI_PROBE_ONLY)) { | ||
1736 | struct pci_bus *child; | ||
1737 | list_for_each_entry(child, &bus->children, node) { | ||
1738 | struct pci_dev *self = child->self; | ||
1739 | if (!self) | ||
1740 | continue; | ||
1741 | pcie_bus_configure_settings(child, self->pcie_mpss); | ||
1742 | } | ||
1743 | } | ||
1733 | } | 1744 | } |
1734 | 1745 | ||
1735 | static void fixup_hide_host_resource_fsl(struct pci_dev *dev) | 1746 | static void fixup_hide_host_resource_fsl(struct pci_dev *dev) |
diff --git a/arch/powerpc/kernel/power6-pmu.c b/arch/powerpc/kernel/power6-pmu.c index 03b95e2c6d65..0bbc901e7efc 100644 --- a/arch/powerpc/kernel/power6-pmu.c +++ b/arch/powerpc/kernel/power6-pmu.c | |||
@@ -487,8 +487,8 @@ static int power6_generic_events[] = { | |||
487 | */ | 487 | */ |
488 | static int power6_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { | 488 | static int power6_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { |
489 | [C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */ | 489 | [C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */ |
490 | [C(OP_READ)] = { 0x80082, 0x80080 }, | 490 | [C(OP_READ)] = { 0x280030, 0x80080 }, |
491 | [C(OP_WRITE)] = { 0x80086, 0x80088 }, | 491 | [C(OP_WRITE)] = { 0x180032, 0x80088 }, |
492 | [C(OP_PREFETCH)] = { 0x810a4, 0 }, | 492 | [C(OP_PREFETCH)] = { 0x810a4, 0 }, |
493 | }, | 493 | }, |
494 | [C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */ | 494 | [C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */ |
diff --git a/arch/powerpc/kernel/power7-pmu.c b/arch/powerpc/kernel/power7-pmu.c index de83d6060dda..1251e4d7e262 100644 --- a/arch/powerpc/kernel/power7-pmu.c +++ b/arch/powerpc/kernel/power7-pmu.c | |||
@@ -297,6 +297,8 @@ static void power7_disable_pmc(unsigned int pmc, unsigned long mmcr[]) | |||
297 | 297 | ||
298 | static int power7_generic_events[] = { | 298 | static int power7_generic_events[] = { |
299 | [PERF_COUNT_HW_CPU_CYCLES] = 0x1e, | 299 | [PERF_COUNT_HW_CPU_CYCLES] = 0x1e, |
300 | [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x100f8, /* GCT_NOSLOT_CYC */ | ||
301 | [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x4000a, /* CMPLU_STALL */ | ||
300 | [PERF_COUNT_HW_INSTRUCTIONS] = 2, | 302 | [PERF_COUNT_HW_INSTRUCTIONS] = 2, |
301 | [PERF_COUNT_HW_CACHE_REFERENCES] = 0xc880, /* LD_REF_L1_LSU*/ | 303 | [PERF_COUNT_HW_CACHE_REFERENCES] = 0xc880, /* LD_REF_L1_LSU*/ |
302 | [PERF_COUNT_HW_CACHE_MISSES] = 0x400f0, /* LD_MISS_L1 */ | 304 | [PERF_COUNT_HW_CACHE_MISSES] = 0x400f0, /* LD_MISS_L1 */ |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 174e1e96175e..8ad825c063c4 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -54,6 +54,8 @@ | |||
54 | #include <asm/pci-bridge.h> | 54 | #include <asm/pci-bridge.h> |
55 | #include <asm/phyp_dump.h> | 55 | #include <asm/phyp_dump.h> |
56 | #include <asm/kexec.h> | 56 | #include <asm/kexec.h> |
57 | #include <asm/opal.h> | ||
58 | |||
57 | #include <mm/mmu_decl.h> | 59 | #include <mm/mmu_decl.h> |
58 | 60 | ||
59 | #ifdef DEBUG | 61 | #ifdef DEBUG |
@@ -707,11 +709,23 @@ void __init early_init_devtree(void *params) | |||
707 | of_scan_flat_dt(early_init_dt_scan_rtas, NULL); | 709 | of_scan_flat_dt(early_init_dt_scan_rtas, NULL); |
708 | #endif | 710 | #endif |
709 | 711 | ||
712 | #ifdef CONFIG_PPC_POWERNV | ||
713 | /* Some machines might need OPAL info for debugging, grab it now. */ | ||
714 | of_scan_flat_dt(early_init_dt_scan_opal, NULL); | ||
715 | #endif | ||
716 | |||
710 | #ifdef CONFIG_PHYP_DUMP | 717 | #ifdef CONFIG_PHYP_DUMP |
711 | /* scan tree to see if dump occurred during last boot */ | 718 | /* scan tree to see if dump occurred during last boot */ |
712 | of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL); | 719 | of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL); |
713 | #endif | 720 | #endif |
714 | 721 | ||
722 | /* Pre-initialize the cmd_line with the content of boot_commmand_line, | ||
723 | * which will be empty except when the content of the variable has | ||
724 | * been overriden by a bootloading mechanism. This happens typically | ||
725 | * with HAL takeover | ||
726 | */ | ||
727 | strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE); | ||
728 | |||
715 | /* Retrieve various informations from the /chosen node of the | 729 | /* Retrieve various informations from the /chosen node of the |
716 | * device-tree, including the platform type, initrd location and | 730 | * device-tree, including the platform type, initrd location and |
717 | * size, TCE reserve, and more ... | 731 | * size, TCE reserve, and more ... |
@@ -723,12 +737,15 @@ void __init early_init_devtree(void *params) | |||
723 | 737 | ||
724 | of_scan_flat_dt(early_init_dt_scan_root, NULL); | 738 | of_scan_flat_dt(early_init_dt_scan_root, NULL); |
725 | of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL); | 739 | of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL); |
726 | setup_initial_memory_limit(memstart_addr, first_memblock_size); | ||
727 | 740 | ||
728 | /* Save command line for /proc/cmdline and then parse parameters */ | 741 | /* Save command line for /proc/cmdline and then parse parameters */ |
729 | strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE); | 742 | strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE); |
730 | parse_early_param(); | 743 | parse_early_param(); |
731 | 744 | ||
745 | /* make sure we've parsed cmdline for mem= before this */ | ||
746 | if (memory_limit) | ||
747 | first_memblock_size = min(first_memblock_size, memory_limit); | ||
748 | setup_initial_memory_limit(memstart_addr, first_memblock_size); | ||
732 | /* Reserve MEMBLOCK regions used by kernel, initrd, dt, etc... */ | 749 | /* Reserve MEMBLOCK regions used by kernel, initrd, dt, etc... */ |
733 | memblock_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START); | 750 | memblock_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START); |
734 | /* If relocatable, reserve first 32k for interrupt vectors etc. */ | 751 | /* If relocatable, reserve first 32k for interrupt vectors etc. */ |
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index a909f4e9343b..b4fa66127495 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <asm/btext.h> | 43 | #include <asm/btext.h> |
44 | #include <asm/sections.h> | 44 | #include <asm/sections.h> |
45 | #include <asm/machdep.h> | 45 | #include <asm/machdep.h> |
46 | #include <asm/opal.h> | ||
46 | 47 | ||
47 | #include <linux/linux_logo.h> | 48 | #include <linux/linux_logo.h> |
48 | 49 | ||
@@ -139,7 +140,9 @@ struct mem_map_entry { | |||
139 | 140 | ||
140 | typedef u32 cell_t; | 141 | typedef u32 cell_t; |
141 | 142 | ||
142 | extern void __start(unsigned long r3, unsigned long r4, unsigned long r5); | 143 | extern void __start(unsigned long r3, unsigned long r4, unsigned long r5, |
144 | unsigned long r6, unsigned long r7, unsigned long r8, | ||
145 | unsigned long r9); | ||
143 | 146 | ||
144 | #ifdef CONFIG_PPC64 | 147 | #ifdef CONFIG_PPC64 |
145 | extern int enter_prom(struct prom_args *args, unsigned long entry); | 148 | extern int enter_prom(struct prom_args *args, unsigned long entry); |
@@ -185,6 +188,7 @@ static unsigned long __initdata prom_tce_alloc_end; | |||
185 | #define PLATFORM_LPAR 0x0001 | 188 | #define PLATFORM_LPAR 0x0001 |
186 | #define PLATFORM_POWERMAC 0x0400 | 189 | #define PLATFORM_POWERMAC 0x0400 |
187 | #define PLATFORM_GENERIC 0x0500 | 190 | #define PLATFORM_GENERIC 0x0500 |
191 | #define PLATFORM_OPAL 0x0600 | ||
188 | 192 | ||
189 | static int __initdata of_platform; | 193 | static int __initdata of_platform; |
190 | 194 | ||
@@ -644,7 +648,7 @@ static void __init early_cmdline_parse(void) | |||
644 | } | 648 | } |
645 | } | 649 | } |
646 | 650 | ||
647 | #ifdef CONFIG_PPC_PSERIES | 651 | #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) |
648 | /* | 652 | /* |
649 | * There are two methods for telling firmware what our capabilities are. | 653 | * There are two methods for telling firmware what our capabilities are. |
650 | * Newer machines have an "ibm,client-architecture-support" method on the | 654 | * Newer machines have an "ibm,client-architecture-support" method on the |
@@ -1274,6 +1278,284 @@ static void __init prom_init_mem(void) | |||
1274 | prom_printf(" ram_top : %x\n", RELOC(ram_top)); | 1278 | prom_printf(" ram_top : %x\n", RELOC(ram_top)); |
1275 | } | 1279 | } |
1276 | 1280 | ||
1281 | static void __init prom_close_stdin(void) | ||
1282 | { | ||
1283 | struct prom_t *_prom = &RELOC(prom); | ||
1284 | ihandle val; | ||
1285 | |||
1286 | if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0) | ||
1287 | call_prom("close", 1, 0, val); | ||
1288 | } | ||
1289 | |||
1290 | #ifdef CONFIG_PPC_POWERNV | ||
1291 | |||
1292 | static u64 __initdata prom_opal_size; | ||
1293 | static u64 __initdata prom_opal_align; | ||
1294 | static int __initdata prom_rtas_start_cpu; | ||
1295 | static u64 __initdata prom_rtas_data; | ||
1296 | static u64 __initdata prom_rtas_entry; | ||
1297 | |||
1298 | #ifdef CONFIG_PPC_EARLY_DEBUG_OPAL | ||
1299 | static u64 __initdata prom_opal_base; | ||
1300 | static u64 __initdata prom_opal_entry; | ||
1301 | #endif | ||
1302 | |||
1303 | /* XXX Don't change this structure without updating opal-takeover.S */ | ||
1304 | static struct opal_secondary_data { | ||
1305 | s64 ack; /* 0 */ | ||
1306 | u64 go; /* 8 */ | ||
1307 | struct opal_takeover_args args; /* 16 */ | ||
1308 | } opal_secondary_data; | ||
1309 | |||
1310 | extern char opal_secondary_entry; | ||
1311 | |||
1312 | static void prom_query_opal(void) | ||
1313 | { | ||
1314 | long rc; | ||
1315 | |||
1316 | /* We must not query for OPAL presence on a machine that | ||
1317 | * supports TNK takeover (970 blades), as this uses the same | ||
1318 | * h-call with different arguments and will crash | ||
1319 | */ | ||
1320 | if (PHANDLE_VALID(call_prom("finddevice", 1, 1, | ||
1321 | ADDR("/tnk-memory-map")))) { | ||
1322 | prom_printf("TNK takeover detected, skipping OPAL check\n"); | ||
1323 | return; | ||
1324 | } | ||
1325 | |||
1326 | prom_printf("Querying for OPAL presence... "); | ||
1327 | rc = opal_query_takeover(&RELOC(prom_opal_size), | ||
1328 | &RELOC(prom_opal_align)); | ||
1329 | prom_debug("(rc = %ld) ", rc); | ||
1330 | if (rc != 0) { | ||
1331 | prom_printf("not there.\n"); | ||
1332 | return; | ||
1333 | } | ||
1334 | RELOC(of_platform) = PLATFORM_OPAL; | ||
1335 | prom_printf(" there !\n"); | ||
1336 | prom_debug(" opal_size = 0x%lx\n", RELOC(prom_opal_size)); | ||
1337 | prom_debug(" opal_align = 0x%lx\n", RELOC(prom_opal_align)); | ||
1338 | if (RELOC(prom_opal_align) < 0x10000) | ||
1339 | RELOC(prom_opal_align) = 0x10000; | ||
1340 | } | ||
1341 | |||
1342 | static int prom_rtas_call(int token, int nargs, int nret, int *outputs, ...) | ||
1343 | { | ||
1344 | struct rtas_args rtas_args; | ||
1345 | va_list list; | ||
1346 | int i; | ||
1347 | |||
1348 | rtas_args.token = token; | ||
1349 | rtas_args.nargs = nargs; | ||
1350 | rtas_args.nret = nret; | ||
1351 | rtas_args.rets = (rtas_arg_t *)&(rtas_args.args[nargs]); | ||
1352 | va_start(list, outputs); | ||
1353 | for (i = 0; i < nargs; ++i) | ||
1354 | rtas_args.args[i] = va_arg(list, rtas_arg_t); | ||
1355 | va_end(list); | ||
1356 | |||
1357 | for (i = 0; i < nret; ++i) | ||
1358 | rtas_args.rets[i] = 0; | ||
1359 | |||
1360 | opal_enter_rtas(&rtas_args, RELOC(prom_rtas_data), | ||
1361 | RELOC(prom_rtas_entry)); | ||
1362 | |||
1363 | if (nret > 1 && outputs != NULL) | ||
1364 | for (i = 0; i < nret-1; ++i) | ||
1365 | outputs[i] = rtas_args.rets[i+1]; | ||
1366 | return (nret > 0)? rtas_args.rets[0]: 0; | ||
1367 | } | ||
1368 | |||
1369 | static void __init prom_opal_hold_cpus(void) | ||
1370 | { | ||
1371 | int i, cnt, cpu, rc; | ||
1372 | long j; | ||
1373 | phandle node; | ||
1374 | char type[64]; | ||
1375 | u32 servers[8]; | ||
1376 | struct prom_t *_prom = &RELOC(prom); | ||
1377 | void *entry = (unsigned long *)&RELOC(opal_secondary_entry); | ||
1378 | struct opal_secondary_data *data = &RELOC(opal_secondary_data); | ||
1379 | |||
1380 | prom_debug("prom_opal_hold_cpus: start...\n"); | ||
1381 | prom_debug(" - entry = 0x%x\n", entry); | ||
1382 | prom_debug(" - data = 0x%x\n", data); | ||
1383 | |||
1384 | data->ack = -1; | ||
1385 | data->go = 0; | ||
1386 | |||
1387 | /* look for cpus */ | ||
1388 | for (node = 0; prom_next_node(&node); ) { | ||
1389 | type[0] = 0; | ||
1390 | prom_getprop(node, "device_type", type, sizeof(type)); | ||
1391 | if (strcmp(type, RELOC("cpu")) != 0) | ||
1392 | continue; | ||
1393 | |||
1394 | /* Skip non-configured cpus. */ | ||
1395 | if (prom_getprop(node, "status", type, sizeof(type)) > 0) | ||
1396 | if (strcmp(type, RELOC("okay")) != 0) | ||
1397 | continue; | ||
1398 | |||
1399 | cnt = prom_getprop(node, "ibm,ppc-interrupt-server#s", servers, | ||
1400 | sizeof(servers)); | ||
1401 | if (cnt == PROM_ERROR) | ||
1402 | break; | ||
1403 | cnt >>= 2; | ||
1404 | for (i = 0; i < cnt; i++) { | ||
1405 | cpu = servers[i]; | ||
1406 | prom_debug("CPU %d ... ", cpu); | ||
1407 | if (cpu == _prom->cpu) { | ||
1408 | prom_debug("booted !\n"); | ||
1409 | continue; | ||
1410 | } | ||
1411 | prom_debug("starting ... "); | ||
1412 | |||
1413 | /* Init the acknowledge var which will be reset by | ||
1414 | * the secondary cpu when it awakens from its OF | ||
1415 | * spinloop. | ||
1416 | */ | ||
1417 | data->ack = -1; | ||
1418 | rc = prom_rtas_call(RELOC(prom_rtas_start_cpu), 3, 1, | ||
1419 | NULL, cpu, entry, data); | ||
1420 | prom_debug("rtas rc=%d ...", rc); | ||
1421 | |||
1422 | for (j = 0; j < 100000000 && data->ack == -1; j++) { | ||
1423 | HMT_low(); | ||
1424 | mb(); | ||
1425 | } | ||
1426 | HMT_medium(); | ||
1427 | if (data->ack != -1) | ||
1428 | prom_debug("done, PIR=0x%x\n", data->ack); | ||
1429 | else | ||
1430 | prom_debug("timeout !\n"); | ||
1431 | } | ||
1432 | } | ||
1433 | prom_debug("prom_opal_hold_cpus: end...\n"); | ||
1434 | } | ||
1435 | |||
1436 | static void prom_opal_takeover(void) | ||
1437 | { | ||
1438 | struct opal_secondary_data *data = &RELOC(opal_secondary_data); | ||
1439 | struct opal_takeover_args *args = &data->args; | ||
1440 | u64 align = RELOC(prom_opal_align); | ||
1441 | u64 top_addr, opal_addr; | ||
1442 | |||
1443 | args->k_image = (u64)RELOC(_stext); | ||
1444 | args->k_size = _end - _stext; | ||
1445 | args->k_entry = 0; | ||
1446 | args->k_entry2 = 0x60; | ||
1447 | |||
1448 | top_addr = _ALIGN_UP(args->k_size, align); | ||
1449 | |||
1450 | if (RELOC(prom_initrd_start) != 0) { | ||
1451 | args->rd_image = RELOC(prom_initrd_start); | ||
1452 | args->rd_size = RELOC(prom_initrd_end) - args->rd_image; | ||
1453 | args->rd_loc = top_addr; | ||
1454 | top_addr = _ALIGN_UP(args->rd_loc + args->rd_size, align); | ||
1455 | } | ||
1456 | |||
1457 | /* Pickup an address for the HAL. We want to go really high | ||
1458 | * up to avoid problem with future kexecs. On the other hand | ||
1459 | * we don't want to be all over the TCEs on P5IOC2 machines | ||
1460 | * which are going to be up there too. We assume the machine | ||
1461 | * has plenty of memory, and we ask for the HAL for now to | ||
1462 | * be just below the 1G point, or above the initrd | ||
1463 | */ | ||
1464 | opal_addr = _ALIGN_DOWN(0x40000000 - RELOC(prom_opal_size), align); | ||
1465 | if (opal_addr < top_addr) | ||
1466 | opal_addr = top_addr; | ||
1467 | args->hal_addr = opal_addr; | ||
1468 | |||
1469 | /* Copy the command line to the kernel image */ | ||
1470 | strlcpy(RELOC(boot_command_line), RELOC(prom_cmd_line), | ||
1471 | COMMAND_LINE_SIZE); | ||
1472 | |||
1473 | prom_debug(" k_image = 0x%lx\n", args->k_image); | ||
1474 | prom_debug(" k_size = 0x%lx\n", args->k_size); | ||
1475 | prom_debug(" k_entry = 0x%lx\n", args->k_entry); | ||
1476 | prom_debug(" k_entry2 = 0x%lx\n", args->k_entry2); | ||
1477 | prom_debug(" hal_addr = 0x%lx\n", args->hal_addr); | ||
1478 | prom_debug(" rd_image = 0x%lx\n", args->rd_image); | ||
1479 | prom_debug(" rd_size = 0x%lx\n", args->rd_size); | ||
1480 | prom_debug(" rd_loc = 0x%lx\n", args->rd_loc); | ||
1481 | prom_printf("Performing OPAL takeover,this can take a few minutes..\n"); | ||
1482 | prom_close_stdin(); | ||
1483 | mb(); | ||
1484 | data->go = 1; | ||
1485 | for (;;) | ||
1486 | opal_do_takeover(args); | ||
1487 | } | ||
1488 | |||
1489 | /* | ||
1490 | * Allocate room for and instantiate OPAL | ||
1491 | */ | ||
1492 | static void __init prom_instantiate_opal(void) | ||
1493 | { | ||
1494 | phandle opal_node; | ||
1495 | ihandle opal_inst; | ||
1496 | u64 base, entry; | ||
1497 | u64 size = 0, align = 0x10000; | ||
1498 | u32 rets[2]; | ||
1499 | |||
1500 | prom_debug("prom_instantiate_opal: start...\n"); | ||
1501 | |||
1502 | opal_node = call_prom("finddevice", 1, 1, ADDR("/ibm,opal")); | ||
1503 | prom_debug("opal_node: %x\n", opal_node); | ||
1504 | if (!PHANDLE_VALID(opal_node)) | ||
1505 | return; | ||
1506 | |||
1507 | prom_getprop(opal_node, "opal-runtime-size", &size, sizeof(size)); | ||
1508 | if (size == 0) | ||
1509 | return; | ||
1510 | prom_getprop(opal_node, "opal-runtime-alignment", &align, | ||
1511 | sizeof(align)); | ||
1512 | |||
1513 | base = alloc_down(size, align, 0); | ||
1514 | if (base == 0) { | ||
1515 | prom_printf("OPAL allocation failed !\n"); | ||
1516 | return; | ||
1517 | } | ||
1518 | |||
1519 | opal_inst = call_prom("open", 1, 1, ADDR("/ibm,opal")); | ||
1520 | if (!IHANDLE_VALID(opal_inst)) { | ||
1521 | prom_printf("opening opal package failed (%x)\n", opal_inst); | ||
1522 | return; | ||
1523 | } | ||
1524 | |||
1525 | prom_printf("instantiating opal at 0x%x...", base); | ||
1526 | |||
1527 | if (call_prom_ret("call-method", 4, 3, rets, | ||
1528 | ADDR("load-opal-runtime"), | ||
1529 | opal_inst, | ||
1530 | base >> 32, base & 0xffffffff) != 0 | ||
1531 | || (rets[0] == 0 && rets[1] == 0)) { | ||
1532 | prom_printf(" failed\n"); | ||
1533 | return; | ||
1534 | } | ||
1535 | entry = (((u64)rets[0]) << 32) | rets[1]; | ||
1536 | |||
1537 | prom_printf(" done\n"); | ||
1538 | |||
1539 | reserve_mem(base, size); | ||
1540 | |||
1541 | prom_debug("opal base = 0x%x\n", base); | ||
1542 | prom_debug("opal align = 0x%x\n", align); | ||
1543 | prom_debug("opal entry = 0x%x\n", entry); | ||
1544 | prom_debug("opal size = 0x%x\n", (long)size); | ||
1545 | |||
1546 | prom_setprop(opal_node, "/ibm,opal", "opal-base-address", | ||
1547 | &base, sizeof(base)); | ||
1548 | prom_setprop(opal_node, "/ibm,opal", "opal-entry-address", | ||
1549 | &entry, sizeof(entry)); | ||
1550 | |||
1551 | #ifdef CONFIG_PPC_EARLY_DEBUG_OPAL | ||
1552 | RELOC(prom_opal_base) = base; | ||
1553 | RELOC(prom_opal_entry) = entry; | ||
1554 | #endif | ||
1555 | prom_debug("prom_instantiate_opal: end...\n"); | ||
1556 | } | ||
1557 | |||
1558 | #endif /* CONFIG_PPC_POWERNV */ | ||
1277 | 1559 | ||
1278 | /* | 1560 | /* |
1279 | * Allocate room for and instantiate RTAS | 1561 | * Allocate room for and instantiate RTAS |
@@ -1326,6 +1608,12 @@ static void __init prom_instantiate_rtas(void) | |||
1326 | prom_setprop(rtas_node, "/rtas", "linux,rtas-entry", | 1608 | prom_setprop(rtas_node, "/rtas", "linux,rtas-entry", |
1327 | &entry, sizeof(entry)); | 1609 | &entry, sizeof(entry)); |
1328 | 1610 | ||
1611 | #ifdef CONFIG_PPC_POWERNV | ||
1612 | /* PowerVN takeover hack */ | ||
1613 | RELOC(prom_rtas_data) = base; | ||
1614 | RELOC(prom_rtas_entry) = entry; | ||
1615 | prom_getprop(rtas_node, "start-cpu", &RELOC(prom_rtas_start_cpu), 4); | ||
1616 | #endif | ||
1329 | prom_debug("rtas base = 0x%x\n", base); | 1617 | prom_debug("rtas base = 0x%x\n", base); |
1330 | prom_debug("rtas entry = 0x%x\n", entry); | 1618 | prom_debug("rtas entry = 0x%x\n", entry); |
1331 | prom_debug("rtas size = 0x%x\n", (long)size); | 1619 | prom_debug("rtas size = 0x%x\n", (long)size); |
@@ -1543,7 +1831,7 @@ static void __init prom_hold_cpus(void) | |||
1543 | *acknowledge = (unsigned long)-1; | 1831 | *acknowledge = (unsigned long)-1; |
1544 | 1832 | ||
1545 | if (reg != _prom->cpu) { | 1833 | if (reg != _prom->cpu) { |
1546 | /* Primary Thread of non-boot cpu */ | 1834 | /* Primary Thread of non-boot cpu or any thread */ |
1547 | prom_printf("starting cpu hw idx %lu... ", reg); | 1835 | prom_printf("starting cpu hw idx %lu... ", reg); |
1548 | call_prom("start-cpu", 3, 0, node, | 1836 | call_prom("start-cpu", 3, 0, node, |
1549 | secondary_hold, reg); | 1837 | secondary_hold, reg); |
@@ -1652,15 +1940,6 @@ static void __init prom_init_stdout(void) | |||
1652 | prom_setprop(val, path, "linux,boot-display", NULL, 0); | 1940 | prom_setprop(val, path, "linux,boot-display", NULL, 0); |
1653 | } | 1941 | } |
1654 | 1942 | ||
1655 | static void __init prom_close_stdin(void) | ||
1656 | { | ||
1657 | struct prom_t *_prom = &RELOC(prom); | ||
1658 | ihandle val; | ||
1659 | |||
1660 | if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0) | ||
1661 | call_prom("close", 1, 0, val); | ||
1662 | } | ||
1663 | |||
1664 | static int __init prom_find_machine_type(void) | 1943 | static int __init prom_find_machine_type(void) |
1665 | { | 1944 | { |
1666 | struct prom_t *_prom = &RELOC(prom); | 1945 | struct prom_t *_prom = &RELOC(prom); |
@@ -1671,7 +1950,7 @@ static int __init prom_find_machine_type(void) | |||
1671 | int x; | 1950 | int x; |
1672 | #endif | 1951 | #endif |
1673 | 1952 | ||
1674 | /* Look for a PowerMac */ | 1953 | /* Look for a PowerMac or a Cell */ |
1675 | len = prom_getprop(_prom->root, "compatible", | 1954 | len = prom_getprop(_prom->root, "compatible", |
1676 | compat, sizeof(compat)-1); | 1955 | compat, sizeof(compat)-1); |
1677 | if (len > 0) { | 1956 | if (len > 0) { |
@@ -1697,7 +1976,11 @@ static int __init prom_find_machine_type(void) | |||
1697 | } | 1976 | } |
1698 | } | 1977 | } |
1699 | #ifdef CONFIG_PPC64 | 1978 | #ifdef CONFIG_PPC64 |
1700 | /* If not a mac, try to figure out if it's an IBM pSeries or any other | 1979 | /* Try to detect OPAL */ |
1980 | if (PHANDLE_VALID(call_prom("finddevice", 1, 1, ADDR("/ibm,opal")))) | ||
1981 | return PLATFORM_OPAL; | ||
1982 | |||
1983 | /* Try to figure out if it's an IBM pSeries or any other | ||
1701 | * PAPR compliant platform. We assume it is if : | 1984 | * PAPR compliant platform. We assume it is if : |
1702 | * - /device_type is "chrp" (please, do NOT use that for future | 1985 | * - /device_type is "chrp" (please, do NOT use that for future |
1703 | * non-IBM designs ! | 1986 | * non-IBM designs ! |
@@ -1924,7 +2207,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | |||
1924 | unsigned long soff; | 2207 | unsigned long soff; |
1925 | unsigned char *valp; | 2208 | unsigned char *valp; |
1926 | static char pname[MAX_PROPERTY_NAME]; | 2209 | static char pname[MAX_PROPERTY_NAME]; |
1927 | int l, room; | 2210 | int l, room, has_phandle = 0; |
1928 | 2211 | ||
1929 | dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end); | 2212 | dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end); |
1930 | 2213 | ||
@@ -2008,19 +2291,26 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | |||
2008 | valp = make_room(mem_start, mem_end, l, 4); | 2291 | valp = make_room(mem_start, mem_end, l, 4); |
2009 | call_prom("getprop", 4, 1, node, RELOC(pname), valp, l); | 2292 | call_prom("getprop", 4, 1, node, RELOC(pname), valp, l); |
2010 | *mem_start = _ALIGN(*mem_start, 4); | 2293 | *mem_start = _ALIGN(*mem_start, 4); |
2294 | |||
2295 | if (!strcmp(RELOC(pname), RELOC("phandle"))) | ||
2296 | has_phandle = 1; | ||
2011 | } | 2297 | } |
2012 | 2298 | ||
2013 | /* Add a "linux,phandle" property. */ | 2299 | /* Add a "linux,phandle" property if no "phandle" property already |
2014 | soff = dt_find_string(RELOC("linux,phandle")); | 2300 | * existed (can happen with OPAL) |
2015 | if (soff == 0) | 2301 | */ |
2016 | prom_printf("WARNING: Can't find string index for" | 2302 | if (!has_phandle) { |
2017 | " <linux-phandle> node %s\n", path); | 2303 | soff = dt_find_string(RELOC("linux,phandle")); |
2018 | else { | 2304 | if (soff == 0) |
2019 | dt_push_token(OF_DT_PROP, mem_start, mem_end); | 2305 | prom_printf("WARNING: Can't find string index for" |
2020 | dt_push_token(4, mem_start, mem_end); | 2306 | " <linux-phandle> node %s\n", path); |
2021 | dt_push_token(soff, mem_start, mem_end); | 2307 | else { |
2022 | valp = make_room(mem_start, mem_end, 4, 4); | 2308 | dt_push_token(OF_DT_PROP, mem_start, mem_end); |
2023 | *(u32 *)valp = node; | 2309 | dt_push_token(4, mem_start, mem_end); |
2310 | dt_push_token(soff, mem_start, mem_end); | ||
2311 | valp = make_room(mem_start, mem_end, 4, 4); | ||
2312 | *(u32 *)valp = node; | ||
2313 | } | ||
2024 | } | 2314 | } |
2025 | 2315 | ||
2026 | /* do all our children */ | 2316 | /* do all our children */ |
@@ -2504,6 +2794,7 @@ static void __init prom_check_initrd(unsigned long r3, unsigned long r4) | |||
2504 | #endif /* CONFIG_BLK_DEV_INITRD */ | 2794 | #endif /* CONFIG_BLK_DEV_INITRD */ |
2505 | } | 2795 | } |
2506 | 2796 | ||
2797 | |||
2507 | /* | 2798 | /* |
2508 | * We enter here early on, when the Open Firmware prom is still | 2799 | * We enter here early on, when the Open Firmware prom is still |
2509 | * handling exceptions and the MMU hash table for us. | 2800 | * handling exceptions and the MMU hash table for us. |
@@ -2553,6 +2844,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
2553 | * between pSeries SMP and pSeries LPAR | 2844 | * between pSeries SMP and pSeries LPAR |
2554 | */ | 2845 | */ |
2555 | RELOC(of_platform) = prom_find_machine_type(); | 2846 | RELOC(of_platform) = prom_find_machine_type(); |
2847 | prom_printf("Detected machine type: %x\n", RELOC(of_platform)); | ||
2556 | 2848 | ||
2557 | #ifndef CONFIG_RELOCATABLE | 2849 | #ifndef CONFIG_RELOCATABLE |
2558 | /* Bail if this is a kdump kernel. */ | 2850 | /* Bail if this is a kdump kernel. */ |
@@ -2565,7 +2857,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
2565 | */ | 2857 | */ |
2566 | prom_check_initrd(r3, r4); | 2858 | prom_check_initrd(r3, r4); |
2567 | 2859 | ||
2568 | #ifdef CONFIG_PPC_PSERIES | 2860 | #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) |
2569 | /* | 2861 | /* |
2570 | * On pSeries, inform the firmware about our capabilities | 2862 | * On pSeries, inform the firmware about our capabilities |
2571 | */ | 2863 | */ |
@@ -2611,14 +2903,33 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
2611 | #endif | 2903 | #endif |
2612 | 2904 | ||
2613 | /* | 2905 | /* |
2614 | * On non-powermacs, try to instantiate RTAS and puts all CPUs | 2906 | * On non-powermacs, try to instantiate RTAS. PowerMacs don't |
2615 | * in spin-loops. PowerMacs don't have a working RTAS and use | 2907 | * have a usable RTAS implementation. |
2616 | * a different way to spin CPUs | ||
2617 | */ | 2908 | */ |
2618 | if (RELOC(of_platform) != PLATFORM_POWERMAC) { | 2909 | if (RELOC(of_platform) != PLATFORM_POWERMAC && |
2910 | RELOC(of_platform) != PLATFORM_OPAL) | ||
2619 | prom_instantiate_rtas(); | 2911 | prom_instantiate_rtas(); |
2912 | |||
2913 | #ifdef CONFIG_PPC_POWERNV | ||
2914 | /* Detect HAL and try instanciating it & doing takeover */ | ||
2915 | if (RELOC(of_platform) == PLATFORM_PSERIES_LPAR) { | ||
2916 | prom_query_opal(); | ||
2917 | if (RELOC(of_platform) == PLATFORM_OPAL) { | ||
2918 | prom_opal_hold_cpus(); | ||
2919 | prom_opal_takeover(); | ||
2920 | } | ||
2921 | } else if (RELOC(of_platform) == PLATFORM_OPAL) | ||
2922 | prom_instantiate_opal(); | ||
2923 | #endif | ||
2924 | |||
2925 | /* | ||
2926 | * On non-powermacs, put all CPUs in spin-loops. | ||
2927 | * | ||
2928 | * PowerMacs use a different mechanism to spin CPUs | ||
2929 | */ | ||
2930 | if (RELOC(of_platform) != PLATFORM_POWERMAC && | ||
2931 | RELOC(of_platform) != PLATFORM_OPAL) | ||
2620 | prom_hold_cpus(); | 2932 | prom_hold_cpus(); |
2621 | } | ||
2622 | 2933 | ||
2623 | /* | 2934 | /* |
2624 | * Fill in some infos for use by the kernel later on | 2935 | * Fill in some infos for use by the kernel later on |
@@ -2685,7 +2996,13 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
2685 | reloc_got2(-offset); | 2996 | reloc_got2(-offset); |
2686 | #endif | 2997 | #endif |
2687 | 2998 | ||
2688 | __start(hdr, kbase, 0); | 2999 | #ifdef CONFIG_PPC_EARLY_DEBUG_OPAL |
3000 | /* OPAL early debug gets the OPAL base & entry in r8 and r9 */ | ||
3001 | __start(hdr, kbase, 0, 0, 0, | ||
3002 | RELOC(prom_opal_base), RELOC(prom_opal_entry)); | ||
3003 | #else | ||
3004 | __start(hdr, kbase, 0, 0, 0, 0, 0); | ||
3005 | #endif | ||
2689 | 3006 | ||
2690 | return 0; | 3007 | return 0; |
2691 | } | 3008 | } |
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh index 9f82f4937892..70f4286eaa7a 100644 --- a/arch/powerpc/kernel/prom_init_check.sh +++ b/arch/powerpc/kernel/prom_init_check.sh | |||
@@ -20,7 +20,9 @@ WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush | |||
20 | _end enter_prom memcpy memset reloc_offset __secondary_hold | 20 | _end enter_prom memcpy memset reloc_offset __secondary_hold |
21 | __secondary_hold_acknowledge __secondary_hold_spinloop __start | 21 | __secondary_hold_acknowledge __secondary_hold_spinloop __start |
22 | strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224 | 22 | strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224 |
23 | reloc_got2 kernstart_addr memstart_addr linux_banner" | 23 | reloc_got2 kernstart_addr memstart_addr linux_banner _stext |
24 | opal_query_takeover opal_do_takeover opal_enter_rtas opal_secondary_entry | ||
25 | boot_command_line" | ||
24 | 26 | ||
25 | NM="$1" | 27 | NM="$1" |
26 | OBJ="$2" | 28 | OBJ="$2" |
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 05b7dd217f60..18447c4fbad3 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -1497,9 +1497,14 @@ long arch_ptrace(struct task_struct *child, long request, | |||
1497 | if (index < PT_FPR0) { | 1497 | if (index < PT_FPR0) { |
1498 | tmp = ptrace_get_reg(child, (int) index); | 1498 | tmp = ptrace_get_reg(child, (int) index); |
1499 | } else { | 1499 | } else { |
1500 | unsigned int fpidx = index - PT_FPR0; | ||
1501 | |||
1500 | flush_fp_to_thread(child); | 1502 | flush_fp_to_thread(child); |
1501 | tmp = ((unsigned long *)child->thread.fpr) | 1503 | if (fpidx < (PT_FPSCR - PT_FPR0)) |
1502 | [TS_FPRWIDTH * (index - PT_FPR0)]; | 1504 | tmp = ((unsigned long *)child->thread.fpr) |
1505 | [fpidx * TS_FPRWIDTH]; | ||
1506 | else | ||
1507 | tmp = child->thread.fpscr.val; | ||
1503 | } | 1508 | } |
1504 | ret = put_user(tmp, datalp); | 1509 | ret = put_user(tmp, datalp); |
1505 | break; | 1510 | break; |
@@ -1525,9 +1530,14 @@ long arch_ptrace(struct task_struct *child, long request, | |||
1525 | if (index < PT_FPR0) { | 1530 | if (index < PT_FPR0) { |
1526 | ret = ptrace_put_reg(child, index, data); | 1531 | ret = ptrace_put_reg(child, index, data); |
1527 | } else { | 1532 | } else { |
1533 | unsigned int fpidx = index - PT_FPR0; | ||
1534 | |||
1528 | flush_fp_to_thread(child); | 1535 | flush_fp_to_thread(child); |
1529 | ((unsigned long *)child->thread.fpr) | 1536 | if (fpidx < (PT_FPSCR - PT_FPR0)) |
1530 | [TS_FPRWIDTH * (index - PT_FPR0)] = data; | 1537 | ((unsigned long *)child->thread.fpr) |
1538 | [fpidx * TS_FPRWIDTH] = data; | ||
1539 | else | ||
1540 | child->thread.fpscr.val = data; | ||
1531 | ret = 0; | 1541 | ret = 0; |
1532 | } | 1542 | } |
1533 | break; | 1543 | break; |
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 209135af0a40..c1ce86357ecb 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -117,7 +117,7 @@ notrace unsigned long __init early_init(unsigned long dt_ptr) | |||
117 | * This is called very early on the boot process, after a minimal | 117 | * This is called very early on the boot process, after a minimal |
118 | * MMU environment has been set up but before MMU_init is called. | 118 | * MMU environment has been set up but before MMU_init is called. |
119 | */ | 119 | */ |
120 | notrace void __init machine_init(unsigned long dt_ptr) | 120 | notrace void __init machine_init(u64 dt_ptr) |
121 | { | 121 | { |
122 | lockdep_init(); | 122 | lockdep_init(); |
123 | 123 | ||
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index aebef1320ed7..d4168c93098f 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -278,14 +278,14 @@ static void __init initialize_cache_info(void) | |||
278 | 278 | ||
279 | DBG(" -> initialize_cache_info()\n"); | 279 | DBG(" -> initialize_cache_info()\n"); |
280 | 280 | ||
281 | for (np = NULL; (np = of_find_node_by_type(np, "cpu"));) { | 281 | for_each_node_by_type(np, "cpu") { |
282 | num_cpus += 1; | 282 | num_cpus += 1; |
283 | 283 | ||
284 | /* We're assuming *all* of the CPUs have the same | 284 | /* |
285 | * We're assuming *all* of the CPUs have the same | ||
285 | * d-cache and i-cache sizes... -Peter | 286 | * d-cache and i-cache sizes... -Peter |
286 | */ | 287 | */ |
287 | 288 | if (num_cpus == 1) { | |
288 | if ( num_cpus == 1 ) { | ||
289 | const u32 *sizep, *lsizep; | 289 | const u32 *sizep, *lsizep; |
290 | u32 size, lsize; | 290 | u32 size, lsize; |
291 | 291 | ||
@@ -294,10 +294,13 @@ static void __init initialize_cache_info(void) | |||
294 | sizep = of_get_property(np, "d-cache-size", NULL); | 294 | sizep = of_get_property(np, "d-cache-size", NULL); |
295 | if (sizep != NULL) | 295 | if (sizep != NULL) |
296 | size = *sizep; | 296 | size = *sizep; |
297 | lsizep = of_get_property(np, "d-cache-block-size", NULL); | 297 | lsizep = of_get_property(np, "d-cache-block-size", |
298 | NULL); | ||
298 | /* fallback if block size missing */ | 299 | /* fallback if block size missing */ |
299 | if (lsizep == NULL) | 300 | if (lsizep == NULL) |
300 | lsizep = of_get_property(np, "d-cache-line-size", NULL); | 301 | lsizep = of_get_property(np, |
302 | "d-cache-line-size", | ||
303 | NULL); | ||
301 | if (lsizep != NULL) | 304 | if (lsizep != NULL) |
302 | lsize = *lsizep; | 305 | lsize = *lsizep; |
303 | if (sizep == 0 || lsizep == 0) | 306 | if (sizep == 0 || lsizep == 0) |
@@ -314,9 +317,12 @@ static void __init initialize_cache_info(void) | |||
314 | sizep = of_get_property(np, "i-cache-size", NULL); | 317 | sizep = of_get_property(np, "i-cache-size", NULL); |
315 | if (sizep != NULL) | 318 | if (sizep != NULL) |
316 | size = *sizep; | 319 | size = *sizep; |
317 | lsizep = of_get_property(np, "i-cache-block-size", NULL); | 320 | lsizep = of_get_property(np, "i-cache-block-size", |
321 | NULL); | ||
318 | if (lsizep == NULL) | 322 | if (lsizep == NULL) |
319 | lsizep = of_get_property(np, "i-cache-line-size", NULL); | 323 | lsizep = of_get_property(np, |
324 | "i-cache-line-size", | ||
325 | NULL); | ||
320 | if (lsizep != NULL) | 326 | if (lsizep != NULL) |
321 | lsize = *lsizep; | 327 | lsize = *lsizep; |
322 | if (sizep == 0 || lsizep == 0) | 328 | if (sizep == 0 || lsizep == 0) |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 7bf2187dfd99..af7e7722ecae 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -70,6 +70,10 @@ | |||
70 | static DEFINE_PER_CPU(struct task_struct *, idle_thread_array); | 70 | static DEFINE_PER_CPU(struct task_struct *, idle_thread_array); |
71 | #define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x)) | 71 | #define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x)) |
72 | #define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p)) | 72 | #define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p)) |
73 | |||
74 | /* State of each CPU during hotplug phases */ | ||
75 | static DEFINE_PER_CPU(int, cpu_state) = { 0 }; | ||
76 | |||
73 | #else | 77 | #else |
74 | static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; | 78 | static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; |
75 | #define get_idle_for_cpu(x) (idle_thread_array[(x)]) | 79 | #define get_idle_for_cpu(x) (idle_thread_array[(x)]) |
@@ -104,12 +108,25 @@ int __devinit smp_generic_kick_cpu(int nr) | |||
104 | * cpu_start field to become non-zero After we set cpu_start, | 108 | * cpu_start field to become non-zero After we set cpu_start, |
105 | * the processor will continue on to secondary_start | 109 | * the processor will continue on to secondary_start |
106 | */ | 110 | */ |
107 | paca[nr].cpu_start = 1; | 111 | if (!paca[nr].cpu_start) { |
108 | smp_mb(); | 112 | paca[nr].cpu_start = 1; |
113 | smp_mb(); | ||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | #ifdef CONFIG_HOTPLUG_CPU | ||
118 | /* | ||
119 | * Ok it's not there, so it might be soft-unplugged, let's | ||
120 | * try to bring it back | ||
121 | */ | ||
122 | per_cpu(cpu_state, nr) = CPU_UP_PREPARE; | ||
123 | smp_wmb(); | ||
124 | smp_send_reschedule(nr); | ||
125 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
109 | 126 | ||
110 | return 0; | 127 | return 0; |
111 | } | 128 | } |
112 | #endif | 129 | #endif /* CONFIG_PPC64 */ |
113 | 130 | ||
114 | static irqreturn_t call_function_action(int irq, void *data) | 131 | static irqreturn_t call_function_action(int irq, void *data) |
115 | { | 132 | { |
@@ -357,8 +374,6 @@ void __devinit smp_prepare_boot_cpu(void) | |||
357 | } | 374 | } |
358 | 375 | ||
359 | #ifdef CONFIG_HOTPLUG_CPU | 376 | #ifdef CONFIG_HOTPLUG_CPU |
360 | /* State of each CPU during hotplug phases */ | ||
361 | static DEFINE_PER_CPU(int, cpu_state) = { 0 }; | ||
362 | 377 | ||
363 | int generic_cpu_disable(void) | 378 | int generic_cpu_disable(void) |
364 | { | 379 | { |
@@ -406,6 +421,11 @@ void generic_set_cpu_dead(unsigned int cpu) | |||
406 | { | 421 | { |
407 | per_cpu(cpu_state, cpu) = CPU_DEAD; | 422 | per_cpu(cpu_state, cpu) = CPU_DEAD; |
408 | } | 423 | } |
424 | |||
425 | int generic_check_cpu_restart(unsigned int cpu) | ||
426 | { | ||
427 | return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; | ||
428 | } | ||
409 | #endif | 429 | #endif |
410 | 430 | ||
411 | struct create_idle { | 431 | struct create_idle { |
diff --git a/arch/powerpc/kernel/swsusp.c b/arch/powerpc/kernel/swsusp.c index aa17b76dd427..641f9adc6205 100644 --- a/arch/powerpc/kernel/swsusp.c +++ b/arch/powerpc/kernel/swsusp.c | |||
@@ -33,6 +33,6 @@ void save_processor_state(void) | |||
33 | void restore_processor_state(void) | 33 | void restore_processor_state(void) |
34 | { | 34 | { |
35 | #ifdef CONFIG_PPC32 | 35 | #ifdef CONFIG_PPC32 |
36 | switch_mmu_context(NULL, current->active_mm); | 36 | switch_mmu_context(current->active_mm, current->active_mm); |
37 | #endif | 37 | #endif |
38 | } | 38 | } |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index f19d9777d3c1..4e5908264d1a 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -457,7 +457,14 @@ int machine_check_e500mc(struct pt_regs *regs) | |||
457 | 457 | ||
458 | if (reason & MCSR_DCPERR_MC) { | 458 | if (reason & MCSR_DCPERR_MC) { |
459 | printk("Data Cache Parity Error\n"); | 459 | printk("Data Cache Parity Error\n"); |
460 | recoverable = 0; | 460 | |
461 | /* | ||
462 | * In write shadow mode we auto-recover from the error, but it | ||
463 | * may still get logged and cause a machine check. We should | ||
464 | * only treat the non-write shadow case as non-recoverable. | ||
465 | */ | ||
466 | if (!(mfspr(SPRN_L1CSR2) & L1CSR2_DCWS)) | ||
467 | recoverable = 0; | ||
461 | } | 468 | } |
462 | 469 | ||
463 | if (reason & MCSR_L2MMU_MHIT) { | 470 | if (reason & MCSR_L2MMU_MHIT) { |
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c index b4607a91d1f4..57fa2c0a531c 100644 --- a/arch/powerpc/kernel/udbg.c +++ b/arch/powerpc/kernel/udbg.c | |||
@@ -69,6 +69,12 @@ void __init udbg_early_init(void) | |||
69 | udbg_init_wsp(); | 69 | udbg_init_wsp(); |
70 | #elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC) | 70 | #elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC) |
71 | udbg_init_ehv_bc(); | 71 | udbg_init_ehv_bc(); |
72 | #elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC) | ||
73 | udbg_init_ps3gelic(); | ||
74 | #elif defined(CONFIG_PPC_EARLY_DEBUG_OPAL_RAW) | ||
75 | udbg_init_debug_opal_raw(); | ||
76 | #elif defined(CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI) | ||
77 | udbg_init_debug_opal_hvsi(); | ||
72 | #endif | 78 | #endif |
73 | 79 | ||
74 | #ifdef CONFIG_PPC_EARLY_DEBUG | 80 | #ifdef CONFIG_PPC_EARLY_DEBUG |
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 1b695fdc362b..34d291d83ec8 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -605,15 +605,20 @@ static int vio_dma_iommu_dma_supported(struct device *dev, u64 mask) | |||
605 | return dma_iommu_ops.dma_supported(dev, mask); | 605 | return dma_iommu_ops.dma_supported(dev, mask); |
606 | } | 606 | } |
607 | 607 | ||
608 | struct dma_map_ops vio_dma_mapping_ops = { | 608 | static u64 vio_dma_get_required_mask(struct device *dev) |
609 | .alloc_coherent = vio_dma_iommu_alloc_coherent, | 609 | { |
610 | .free_coherent = vio_dma_iommu_free_coherent, | 610 | return dma_iommu_ops.get_required_mask(dev); |
611 | .map_sg = vio_dma_iommu_map_sg, | 611 | } |
612 | .unmap_sg = vio_dma_iommu_unmap_sg, | ||
613 | .map_page = vio_dma_iommu_map_page, | ||
614 | .unmap_page = vio_dma_iommu_unmap_page, | ||
615 | .dma_supported = vio_dma_iommu_dma_supported, | ||
616 | 612 | ||
613 | struct dma_map_ops vio_dma_mapping_ops = { | ||
614 | .alloc_coherent = vio_dma_iommu_alloc_coherent, | ||
615 | .free_coherent = vio_dma_iommu_free_coherent, | ||
616 | .map_sg = vio_dma_iommu_map_sg, | ||
617 | .unmap_sg = vio_dma_iommu_unmap_sg, | ||
618 | .map_page = vio_dma_iommu_map_page, | ||
619 | .unmap_page = vio_dma_iommu_unmap_page, | ||
620 | .dma_supported = vio_dma_iommu_dma_supported, | ||
621 | .get_required_mask = vio_dma_get_required_mask, | ||
617 | }; | 622 | }; |
618 | 623 | ||
619 | /** | 624 | /** |
diff --git a/arch/powerpc/math-emu/math_efp.c b/arch/powerpc/math-emu/math_efp.c index 62279200d965..a73f0884d358 100644 --- a/arch/powerpc/math-emu/math_efp.c +++ b/arch/powerpc/math-emu/math_efp.c | |||
@@ -171,10 +171,6 @@ static unsigned long insn_type(unsigned long speinsn) | |||
171 | case EFDNABS: ret = XA; break; | 171 | case EFDNABS: ret = XA; break; |
172 | case EFDNEG: ret = XA; break; | 172 | case EFDNEG: ret = XA; break; |
173 | case EFDSUB: ret = AB; break; | 173 | case EFDSUB: ret = AB; break; |
174 | |||
175 | default: | ||
176 | printk(KERN_ERR "\nOoops! SPE instruction no type found."); | ||
177 | printk(KERN_ERR "\ninst code: %08lx\n", speinsn); | ||
178 | } | 174 | } |
179 | 175 | ||
180 | return ret; | 176 | return ret; |
@@ -195,7 +191,7 @@ int do_spe_mathemu(struct pt_regs *regs) | |||
195 | 191 | ||
196 | type = insn_type(speinsn); | 192 | type = insn_type(speinsn); |
197 | if (type == NOTYPE) | 193 | if (type == NOTYPE) |
198 | return -ENOSYS; | 194 | goto illegal; |
199 | 195 | ||
200 | func = speinsn & 0x7ff; | 196 | func = speinsn & 0x7ff; |
201 | fc = (speinsn >> 21) & 0x1f; | 197 | fc = (speinsn >> 21) & 0x1f; |
@@ -212,12 +208,10 @@ int do_spe_mathemu(struct pt_regs *regs) | |||
212 | 208 | ||
213 | __FPU_FPSCR = mfspr(SPRN_SPEFSCR); | 209 | __FPU_FPSCR = mfspr(SPRN_SPEFSCR); |
214 | 210 | ||
215 | #ifdef DEBUG | 211 | pr_debug("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR); |
216 | printk("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR); | 212 | pr_debug("vc: %08x %08x\n", vc.wp[0], vc.wp[1]); |
217 | printk("vc: %08x %08x\n", vc.wp[0], vc.wp[1]); | 213 | pr_debug("va: %08x %08x\n", va.wp[0], va.wp[1]); |
218 | printk("va: %08x %08x\n", va.wp[0], va.wp[1]); | 214 | pr_debug("vb: %08x %08x\n", vb.wp[0], vb.wp[1]); |
219 | printk("vb: %08x %08x\n", vb.wp[0], vb.wp[1]); | ||
220 | #endif | ||
221 | 215 | ||
222 | switch (src) { | 216 | switch (src) { |
223 | case SPFP: { | 217 | case SPFP: { |
@@ -235,10 +229,8 @@ int do_spe_mathemu(struct pt_regs *regs) | |||
235 | break; | 229 | break; |
236 | } | 230 | } |
237 | 231 | ||
238 | #ifdef DEBUG | 232 | pr_debug("SA: %ld %08lx %ld (%ld)\n", SA_s, SA_f, SA_e, SA_c); |
239 | printk("SA: %ld %08lx %ld (%ld)\n", SA_s, SA_f, SA_e, SA_c); | 233 | pr_debug("SB: %ld %08lx %ld (%ld)\n", SB_s, SB_f, SB_e, SB_c); |
240 | printk("SB: %ld %08lx %ld (%ld)\n", SB_s, SB_f, SB_e, SB_c); | ||
241 | #endif | ||
242 | 234 | ||
243 | switch (func) { | 235 | switch (func) { |
244 | case EFSABS: | 236 | case EFSABS: |
@@ -305,10 +297,10 @@ int do_spe_mathemu(struct pt_regs *regs) | |||
305 | FP_DECL_D(DB); | 297 | FP_DECL_D(DB); |
306 | FP_CLEAR_EXCEPTIONS; | 298 | FP_CLEAR_EXCEPTIONS; |
307 | FP_UNPACK_DP(DB, vb.dp); | 299 | FP_UNPACK_DP(DB, vb.dp); |
308 | #ifdef DEBUG | 300 | |
309 | printk("DB: %ld %08lx %08lx %ld (%ld)\n", | 301 | pr_debug("DB: %ld %08lx %08lx %ld (%ld)\n", |
310 | DB_s, DB_f1, DB_f0, DB_e, DB_c); | 302 | DB_s, DB_f1, DB_f0, DB_e, DB_c); |
311 | #endif | 303 | |
312 | FP_CONV(S, D, 1, 2, SR, DB); | 304 | FP_CONV(S, D, 1, 2, SR, DB); |
313 | goto pack_s; | 305 | goto pack_s; |
314 | } | 306 | } |
@@ -332,9 +324,8 @@ int do_spe_mathemu(struct pt_regs *regs) | |||
332 | break; | 324 | break; |
333 | 325 | ||
334 | pack_s: | 326 | pack_s: |
335 | #ifdef DEBUG | 327 | pr_debug("SR: %ld %08lx %ld (%ld)\n", SR_s, SR_f, SR_e, SR_c); |
336 | printk("SR: %ld %08lx %ld (%ld)\n", SR_s, SR_f, SR_e, SR_c); | 328 | |
337 | #endif | ||
338 | FP_PACK_SP(vc.wp + 1, SR); | 329 | FP_PACK_SP(vc.wp + 1, SR); |
339 | goto update_regs; | 330 | goto update_regs; |
340 | 331 | ||
@@ -365,12 +356,10 @@ cmp_s: | |||
365 | break; | 356 | break; |
366 | } | 357 | } |
367 | 358 | ||
368 | #ifdef DEBUG | 359 | pr_debug("DA: %ld %08lx %08lx %ld (%ld)\n", |
369 | printk("DA: %ld %08lx %08lx %ld (%ld)\n", | ||
370 | DA_s, DA_f1, DA_f0, DA_e, DA_c); | 360 | DA_s, DA_f1, DA_f0, DA_e, DA_c); |
371 | printk("DB: %ld %08lx %08lx %ld (%ld)\n", | 361 | pr_debug("DB: %ld %08lx %08lx %ld (%ld)\n", |
372 | DB_s, DB_f1, DB_f0, DB_e, DB_c); | 362 | DB_s, DB_f1, DB_f0, DB_e, DB_c); |
373 | #endif | ||
374 | 363 | ||
375 | switch (func) { | 364 | switch (func) { |
376 | case EFDABS: | 365 | case EFDABS: |
@@ -438,10 +427,10 @@ cmp_s: | |||
438 | FP_DECL_S(SB); | 427 | FP_DECL_S(SB); |
439 | FP_CLEAR_EXCEPTIONS; | 428 | FP_CLEAR_EXCEPTIONS; |
440 | FP_UNPACK_SP(SB, vb.wp + 1); | 429 | FP_UNPACK_SP(SB, vb.wp + 1); |
441 | #ifdef DEBUG | 430 | |
442 | printk("SB: %ld %08lx %ld (%ld)\n", | 431 | pr_debug("SB: %ld %08lx %ld (%ld)\n", |
443 | SB_s, SB_f, SB_e, SB_c); | 432 | SB_s, SB_f, SB_e, SB_c); |
444 | #endif | 433 | |
445 | FP_CONV(D, S, 2, 1, DR, SB); | 434 | FP_CONV(D, S, 2, 1, DR, SB); |
446 | goto pack_d; | 435 | goto pack_d; |
447 | } | 436 | } |
@@ -471,10 +460,9 @@ cmp_s: | |||
471 | break; | 460 | break; |
472 | 461 | ||
473 | pack_d: | 462 | pack_d: |
474 | #ifdef DEBUG | 463 | pr_debug("DR: %ld %08lx %08lx %ld (%ld)\n", |
475 | printk("DR: %ld %08lx %08lx %ld (%ld)\n", | ||
476 | DR_s, DR_f1, DR_f0, DR_e, DR_c); | 464 | DR_s, DR_f1, DR_f0, DR_e, DR_c); |
477 | #endif | 465 | |
478 | FP_PACK_DP(vc.dp, DR); | 466 | FP_PACK_DP(vc.dp, DR); |
479 | goto update_regs; | 467 | goto update_regs; |
480 | 468 | ||
@@ -511,12 +499,14 @@ cmp_d: | |||
511 | break; | 499 | break; |
512 | } | 500 | } |
513 | 501 | ||
514 | #ifdef DEBUG | 502 | pr_debug("SA0: %ld %08lx %ld (%ld)\n", |
515 | printk("SA0: %ld %08lx %ld (%ld)\n", SA0_s, SA0_f, SA0_e, SA0_c); | 503 | SA0_s, SA0_f, SA0_e, SA0_c); |
516 | printk("SA1: %ld %08lx %ld (%ld)\n", SA1_s, SA1_f, SA1_e, SA1_c); | 504 | pr_debug("SA1: %ld %08lx %ld (%ld)\n", |
517 | printk("SB0: %ld %08lx %ld (%ld)\n", SB0_s, SB0_f, SB0_e, SB0_c); | 505 | SA1_s, SA1_f, SA1_e, SA1_c); |
518 | printk("SB1: %ld %08lx %ld (%ld)\n", SB1_s, SB1_f, SB1_e, SB1_c); | 506 | pr_debug("SB0: %ld %08lx %ld (%ld)\n", |
519 | #endif | 507 | SB0_s, SB0_f, SB0_e, SB0_c); |
508 | pr_debug("SB1: %ld %08lx %ld (%ld)\n", | ||
509 | SB1_s, SB1_f, SB1_e, SB1_c); | ||
520 | 510 | ||
521 | switch (func) { | 511 | switch (func) { |
522 | case EVFSABS: | 512 | case EVFSABS: |
@@ -605,10 +595,11 @@ cmp_d: | |||
605 | break; | 595 | break; |
606 | 596 | ||
607 | pack_vs: | 597 | pack_vs: |
608 | #ifdef DEBUG | 598 | pr_debug("SR0: %ld %08lx %ld (%ld)\n", |
609 | printk("SR0: %ld %08lx %ld (%ld)\n", SR0_s, SR0_f, SR0_e, SR0_c); | 599 | SR0_s, SR0_f, SR0_e, SR0_c); |
610 | printk("SR1: %ld %08lx %ld (%ld)\n", SR1_s, SR1_f, SR1_e, SR1_c); | 600 | pr_debug("SR1: %ld %08lx %ld (%ld)\n", |
611 | #endif | 601 | SR1_s, SR1_f, SR1_e, SR1_c); |
602 | |||
612 | FP_PACK_SP(vc.wp, SR0); | 603 | FP_PACK_SP(vc.wp, SR0); |
613 | FP_PACK_SP(vc.wp + 1, SR1); | 604 | FP_PACK_SP(vc.wp + 1, SR1); |
614 | goto update_regs; | 605 | goto update_regs; |
@@ -646,14 +637,12 @@ update_regs: | |||
646 | current->thread.evr[fc] = vc.wp[0]; | 637 | current->thread.evr[fc] = vc.wp[0]; |
647 | regs->gpr[fc] = vc.wp[1]; | 638 | regs->gpr[fc] = vc.wp[1]; |
648 | 639 | ||
649 | #ifdef DEBUG | 640 | pr_debug("ccr = %08lx\n", regs->ccr); |
650 | printk("ccr = %08lx\n", regs->ccr); | 641 | pr_debug("cur exceptions = %08x spefscr = %08lx\n", |
651 | printk("cur exceptions = %08x spefscr = %08lx\n", | ||
652 | FP_CUR_EXCEPTIONS, __FPU_FPSCR); | 642 | FP_CUR_EXCEPTIONS, __FPU_FPSCR); |
653 | printk("vc: %08x %08x\n", vc.wp[0], vc.wp[1]); | 643 | pr_debug("vc: %08x %08x\n", vc.wp[0], vc.wp[1]); |
654 | printk("va: %08x %08x\n", va.wp[0], va.wp[1]); | 644 | pr_debug("va: %08x %08x\n", va.wp[0], va.wp[1]); |
655 | printk("vb: %08x %08x\n", vb.wp[0], vb.wp[1]); | 645 | pr_debug("vb: %08x %08x\n", vb.wp[0], vb.wp[1]); |
656 | #endif | ||
657 | 646 | ||
658 | return 0; | 647 | return 0; |
659 | 648 | ||
@@ -661,9 +650,7 @@ illegal: | |||
661 | if (have_e500_cpu_a005_erratum) { | 650 | if (have_e500_cpu_a005_erratum) { |
662 | /* according to e500 cpu a005 erratum, reissue efp inst */ | 651 | /* according to e500 cpu a005 erratum, reissue efp inst */ |
663 | regs->nip -= 4; | 652 | regs->nip -= 4; |
664 | #ifdef DEBUG | 653 | pr_debug("re-issue efp inst: %08lx\n", speinsn); |
665 | printk(KERN_DEBUG "re-issue efp inst: %08lx\n", speinsn); | ||
666 | #endif | ||
667 | return 0; | 654 | return 0; |
668 | } | 655 | } |
669 | 656 | ||
@@ -685,13 +672,20 @@ int speround_handler(struct pt_regs *regs) | |||
685 | type = insn_type(speinsn & 0x7ff); | 672 | type = insn_type(speinsn & 0x7ff); |
686 | if (type == XCR) return -ENOSYS; | 673 | if (type == XCR) return -ENOSYS; |
687 | 674 | ||
675 | __FPU_FPSCR = mfspr(SPRN_SPEFSCR); | ||
676 | pr_debug("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR); | ||
677 | |||
678 | /* No need to round if the result is exact */ | ||
679 | if (!(__FPU_FPSCR & FP_EX_INEXACT)) | ||
680 | return 0; | ||
681 | |||
688 | fc = (speinsn >> 21) & 0x1f; | 682 | fc = (speinsn >> 21) & 0x1f; |
689 | s_lo = regs->gpr[fc] & SIGN_BIT_S; | 683 | s_lo = regs->gpr[fc] & SIGN_BIT_S; |
690 | s_hi = current->thread.evr[fc] & SIGN_BIT_S; | 684 | s_hi = current->thread.evr[fc] & SIGN_BIT_S; |
691 | fgpr.wp[0] = current->thread.evr[fc]; | 685 | fgpr.wp[0] = current->thread.evr[fc]; |
692 | fgpr.wp[1] = regs->gpr[fc]; | 686 | fgpr.wp[1] = regs->gpr[fc]; |
693 | 687 | ||
694 | __FPU_FPSCR = mfspr(SPRN_SPEFSCR); | 688 | pr_debug("round fgpr: %08x %08x\n", fgpr.wp[0], fgpr.wp[1]); |
695 | 689 | ||
696 | switch ((speinsn >> 5) & 0x7) { | 690 | switch ((speinsn >> 5) & 0x7) { |
697 | /* Since SPE instructions on E500 core can handle round to nearest | 691 | /* Since SPE instructions on E500 core can handle round to nearest |
@@ -731,6 +725,8 @@ int speround_handler(struct pt_regs *regs) | |||
731 | current->thread.evr[fc] = fgpr.wp[0]; | 725 | current->thread.evr[fc] = fgpr.wp[0]; |
732 | regs->gpr[fc] = fgpr.wp[1]; | 726 | regs->gpr[fc] = fgpr.wp[1]; |
733 | 727 | ||
728 | pr_debug(" to fgpr: %08x %08x\n", fgpr.wp[0], fgpr.wp[1]); | ||
729 | |||
734 | return 0; | 730 | return 0; |
735 | } | 731 | } |
736 | 732 | ||
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index bdca46e08382..991ee813d2a8 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile | |||
@@ -29,6 +29,7 @@ obj-$(CONFIG_PPC_MM_SLICES) += slice.o | |||
29 | ifeq ($(CONFIG_HUGETLB_PAGE),y) | 29 | ifeq ($(CONFIG_HUGETLB_PAGE),y) |
30 | obj-y += hugetlbpage.o | 30 | obj-y += hugetlbpage.o |
31 | obj-$(CONFIG_PPC_STD_MMU_64) += hugetlbpage-hash64.o | 31 | obj-$(CONFIG_PPC_STD_MMU_64) += hugetlbpage-hash64.o |
32 | obj-$(CONFIG_PPC_BOOK3E_MMU) += hugetlbpage-book3e.o | ||
32 | endif | 33 | endif |
33 | obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o | 34 | obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o |
34 | obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o | 35 | obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o |
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index f7802c8bba0a..66a6fd38e9cd 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c | |||
@@ -101,17 +101,17 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa) | |||
101 | 101 | ||
102 | /* | 102 | /* |
103 | * Set up a variable-size TLB entry (tlbcam). The parameters are not checked; | 103 | * Set up a variable-size TLB entry (tlbcam). The parameters are not checked; |
104 | * in particular size must be a power of 4 between 4k and 256M (or 1G, for cpus | 104 | * in particular size must be a power of 4 between 4k and the max supported by |
105 | * that support extended page sizes). Note that while some cpus support a | 105 | * an implementation; max may further be limited by what can be represented in |
106 | * page size of 4G, we don't allow its use here. | 106 | * an unsigned long (for example, 32-bit implementations cannot support a 4GB |
107 | * size). | ||
107 | */ | 108 | */ |
108 | static void settlbcam(int index, unsigned long virt, phys_addr_t phys, | 109 | static void settlbcam(int index, unsigned long virt, phys_addr_t phys, |
109 | unsigned long size, unsigned long flags, unsigned int pid) | 110 | unsigned long size, unsigned long flags, unsigned int pid) |
110 | { | 111 | { |
111 | unsigned int tsize, lz; | 112 | unsigned int tsize; |
112 | 113 | ||
113 | asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (size)); | 114 | tsize = __ilog2(size) - 10; |
114 | tsize = 21 - lz; | ||
115 | 115 | ||
116 | #ifdef CONFIG_SMP | 116 | #ifdef CONFIG_SMP |
117 | if ((flags & _PAGE_NO_CACHE) == 0) | 117 | if ((flags & _PAGE_NO_CACHE) == 0) |
@@ -146,29 +146,36 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys, | |||
146 | loadcam_entry(index); | 146 | loadcam_entry(index); |
147 | } | 147 | } |
148 | 148 | ||
149 | unsigned long calc_cam_sz(unsigned long ram, unsigned long virt, | ||
150 | phys_addr_t phys) | ||
151 | { | ||
152 | unsigned int camsize = __ilog2(ram) & ~1U; | ||
153 | unsigned int align = __ffs(virt | phys) & ~1U; | ||
154 | unsigned long max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xf; | ||
155 | |||
156 | /* Convert (4^max) kB to (2^max) bytes */ | ||
157 | max_cam = max_cam * 2 + 10; | ||
158 | |||
159 | if (camsize > align) | ||
160 | camsize = align; | ||
161 | if (camsize > max_cam) | ||
162 | camsize = max_cam; | ||
163 | |||
164 | return 1UL << camsize; | ||
165 | } | ||
166 | |||
149 | unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx) | 167 | unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx) |
150 | { | 168 | { |
151 | int i; | 169 | int i; |
152 | unsigned long virt = PAGE_OFFSET; | 170 | unsigned long virt = PAGE_OFFSET; |
153 | phys_addr_t phys = memstart_addr; | 171 | phys_addr_t phys = memstart_addr; |
154 | unsigned long amount_mapped = 0; | 172 | unsigned long amount_mapped = 0; |
155 | unsigned long max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xf; | ||
156 | |||
157 | /* Convert (4^max) kB to (2^max) bytes */ | ||
158 | max_cam = max_cam * 2 + 10; | ||
159 | 173 | ||
160 | /* Calculate CAM values */ | 174 | /* Calculate CAM values */ |
161 | for (i = 0; ram && i < max_cam_idx; i++) { | 175 | for (i = 0; ram && i < max_cam_idx; i++) { |
162 | unsigned int camsize = __ilog2(ram) & ~1U; | ||
163 | unsigned int align = __ffs(virt | phys) & ~1U; | ||
164 | unsigned long cam_sz; | 176 | unsigned long cam_sz; |
165 | 177 | ||
166 | if (camsize > align) | 178 | cam_sz = calc_cam_sz(ram, virt, phys); |
167 | camsize = align; | ||
168 | if (camsize > max_cam) | ||
169 | camsize = max_cam; | ||
170 | |||
171 | cam_sz = 1UL << camsize; | ||
172 | settlbcam(i, virt, phys, cam_sz, PAGE_KERNEL_X, 0); | 179 | settlbcam(i, virt, phys, cam_sz, PAGE_KERNEL_X, 0); |
173 | 180 | ||
174 | ram -= cam_sz; | 181 | ram -= cam_sz; |
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 26b2872b3d00..1628201c8cea 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -105,9 +105,6 @@ int mmu_kernel_ssize = MMU_SEGSIZE_256M; | |||
105 | int mmu_highuser_ssize = MMU_SEGSIZE_256M; | 105 | int mmu_highuser_ssize = MMU_SEGSIZE_256M; |
106 | u16 mmu_slb_size = 64; | 106 | u16 mmu_slb_size = 64; |
107 | EXPORT_SYMBOL_GPL(mmu_slb_size); | 107 | EXPORT_SYMBOL_GPL(mmu_slb_size); |
108 | #ifdef CONFIG_HUGETLB_PAGE | ||
109 | unsigned int HPAGE_SHIFT; | ||
110 | #endif | ||
111 | #ifdef CONFIG_PPC_64K_PAGES | 108 | #ifdef CONFIG_PPC_64K_PAGES |
112 | int mmu_ci_restrictions; | 109 | int mmu_ci_restrictions; |
113 | #endif | 110 | #endif |
@@ -534,11 +531,11 @@ static unsigned long __init htab_get_table_size(void) | |||
534 | } | 531 | } |
535 | 532 | ||
536 | #ifdef CONFIG_MEMORY_HOTPLUG | 533 | #ifdef CONFIG_MEMORY_HOTPLUG |
537 | void create_section_mapping(unsigned long start, unsigned long end) | 534 | int create_section_mapping(unsigned long start, unsigned long end) |
538 | { | 535 | { |
539 | BUG_ON(htab_bolt_mapping(start, end, __pa(start), | 536 | return htab_bolt_mapping(start, end, __pa(start), |
540 | pgprot_val(PAGE_KERNEL), mmu_linear_psize, | 537 | pgprot_val(PAGE_KERNEL), mmu_linear_psize, |
541 | mmu_kernel_ssize)); | 538 | mmu_kernel_ssize); |
542 | } | 539 | } |
543 | 540 | ||
544 | int remove_section_mapping(unsigned long start, unsigned long end) | 541 | int remove_section_mapping(unsigned long start, unsigned long end) |
diff --git a/arch/powerpc/mm/hugetlbpage-book3e.c b/arch/powerpc/mm/hugetlbpage-book3e.c new file mode 100644 index 000000000000..343ad0b87261 --- /dev/null +++ b/arch/powerpc/mm/hugetlbpage-book3e.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * PPC Huge TLB Page Support for Book3E MMU | ||
3 | * | ||
4 | * Copyright (C) 2009 David Gibson, IBM Corporation. | ||
5 | * Copyright (C) 2011 Becky Bruce, Freescale Semiconductor | ||
6 | * | ||
7 | */ | ||
8 | #include <linux/mm.h> | ||
9 | #include <linux/hugetlb.h> | ||
10 | |||
11 | static inline int mmu_get_tsize(int psize) | ||
12 | { | ||
13 | return mmu_psize_defs[psize].enc; | ||
14 | } | ||
15 | |||
16 | static inline int book3e_tlb_exists(unsigned long ea, unsigned long pid) | ||
17 | { | ||
18 | int found = 0; | ||
19 | |||
20 | mtspr(SPRN_MAS6, pid << 16); | ||
21 | if (mmu_has_feature(MMU_FTR_USE_TLBRSRV)) { | ||
22 | asm volatile( | ||
23 | "li %0,0\n" | ||
24 | "tlbsx. 0,%1\n" | ||
25 | "bne 1f\n" | ||
26 | "li %0,1\n" | ||
27 | "1:\n" | ||
28 | : "=&r"(found) : "r"(ea)); | ||
29 | } else { | ||
30 | asm volatile( | ||
31 | "tlbsx 0,%1\n" | ||
32 | "mfspr %0,0x271\n" | ||
33 | "srwi %0,%0,31\n" | ||
34 | : "=&r"(found) : "r"(ea)); | ||
35 | } | ||
36 | |||
37 | return found; | ||
38 | } | ||
39 | |||
40 | void book3e_hugetlb_preload(struct mm_struct *mm, unsigned long ea, pte_t pte) | ||
41 | { | ||
42 | unsigned long mas1, mas2; | ||
43 | u64 mas7_3; | ||
44 | unsigned long psize, tsize, shift; | ||
45 | unsigned long flags; | ||
46 | |||
47 | #ifdef CONFIG_PPC_FSL_BOOK3E | ||
48 | int index, lz, ncams; | ||
49 | struct vm_area_struct *vma; | ||
50 | #endif | ||
51 | |||
52 | if (unlikely(is_kernel_addr(ea))) | ||
53 | return; | ||
54 | |||
55 | #ifdef CONFIG_PPC_MM_SLICES | ||
56 | psize = mmu_get_tsize(get_slice_psize(mm, ea)); | ||
57 | tsize = mmu_get_psize(psize); | ||
58 | shift = mmu_psize_defs[psize].shift; | ||
59 | #else | ||
60 | vma = find_vma(mm, ea); | ||
61 | psize = vma_mmu_pagesize(vma); /* returns actual size in bytes */ | ||
62 | asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (psize)); | ||
63 | shift = 31 - lz; | ||
64 | tsize = 21 - lz; | ||
65 | #endif | ||
66 | |||
67 | /* | ||
68 | * We can't be interrupted while we're setting up the MAS | ||
69 | * regusters or after we've confirmed that no tlb exists. | ||
70 | */ | ||
71 | local_irq_save(flags); | ||
72 | |||
73 | if (unlikely(book3e_tlb_exists(ea, mm->context.id))) { | ||
74 | local_irq_restore(flags); | ||
75 | return; | ||
76 | } | ||
77 | |||
78 | #ifdef CONFIG_PPC_FSL_BOOK3E | ||
79 | ncams = mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY; | ||
80 | |||
81 | /* We have to use the CAM(TLB1) on FSL parts for hugepages */ | ||
82 | index = __get_cpu_var(next_tlbcam_idx); | ||
83 | mtspr(SPRN_MAS0, MAS0_ESEL(index) | MAS0_TLBSEL(1)); | ||
84 | |||
85 | /* Just round-robin the entries and wrap when we hit the end */ | ||
86 | if (unlikely(index == ncams - 1)) | ||
87 | __get_cpu_var(next_tlbcam_idx) = tlbcam_index; | ||
88 | else | ||
89 | __get_cpu_var(next_tlbcam_idx)++; | ||
90 | #endif | ||
91 | mas1 = MAS1_VALID | MAS1_TID(mm->context.id) | MAS1_TSIZE(tsize); | ||
92 | mas2 = ea & ~((1UL << shift) - 1); | ||
93 | mas2 |= (pte_val(pte) >> PTE_WIMGE_SHIFT) & MAS2_WIMGE_MASK; | ||
94 | mas7_3 = (u64)pte_pfn(pte) << PAGE_SHIFT; | ||
95 | mas7_3 |= (pte_val(pte) >> PTE_BAP_SHIFT) & MAS3_BAP_MASK; | ||
96 | if (!pte_dirty(pte)) | ||
97 | mas7_3 &= ~(MAS3_SW|MAS3_UW); | ||
98 | |||
99 | mtspr(SPRN_MAS1, mas1); | ||
100 | mtspr(SPRN_MAS2, mas2); | ||
101 | |||
102 | if (mmu_has_feature(MMU_FTR_USE_PAIRED_MAS)) { | ||
103 | mtspr(SPRN_MAS7_MAS3, mas7_3); | ||
104 | } else { | ||
105 | mtspr(SPRN_MAS7, upper_32_bits(mas7_3)); | ||
106 | mtspr(SPRN_MAS3, lower_32_bits(mas7_3)); | ||
107 | } | ||
108 | |||
109 | asm volatile ("tlbwe"); | ||
110 | |||
111 | local_irq_restore(flags); | ||
112 | } | ||
113 | |||
114 | void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr) | ||
115 | { | ||
116 | struct hstate *hstate = hstate_file(vma->vm_file); | ||
117 | unsigned long tsize = huge_page_shift(hstate) - 10; | ||
118 | |||
119 | __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr, tsize, 0); | ||
120 | |||
121 | } | ||
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index da5eb3885702..5964371303ac 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * PPC64 (POWER4) Huge TLB Page Support for Kernel. | 2 | * PPC Huge TLB Page Support for Kernel. |
3 | * | 3 | * |
4 | * Copyright (C) 2003 David Gibson, IBM Corporation. | 4 | * Copyright (C) 2003 David Gibson, IBM Corporation. |
5 | * Copyright (C) 2011 Becky Bruce, Freescale Semiconductor | ||
5 | * | 6 | * |
6 | * Based on the IA-32 version: | 7 | * Based on the IA-32 version: |
7 | * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com> | 8 | * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com> |
@@ -11,24 +12,39 @@ | |||
11 | #include <linux/io.h> | 12 | #include <linux/io.h> |
12 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
13 | #include <linux/hugetlb.h> | 14 | #include <linux/hugetlb.h> |
15 | #include <linux/of_fdt.h> | ||
16 | #include <linux/memblock.h> | ||
17 | #include <linux/bootmem.h> | ||
14 | #include <asm/pgtable.h> | 18 | #include <asm/pgtable.h> |
15 | #include <asm/pgalloc.h> | 19 | #include <asm/pgalloc.h> |
16 | #include <asm/tlb.h> | 20 | #include <asm/tlb.h> |
21 | #include <asm/setup.h> | ||
17 | 22 | ||
18 | #define PAGE_SHIFT_64K 16 | 23 | #define PAGE_SHIFT_64K 16 |
19 | #define PAGE_SHIFT_16M 24 | 24 | #define PAGE_SHIFT_16M 24 |
20 | #define PAGE_SHIFT_16G 34 | 25 | #define PAGE_SHIFT_16G 34 |
21 | 26 | ||
22 | #define MAX_NUMBER_GPAGES 1024 | 27 | unsigned int HPAGE_SHIFT; |
23 | 28 | ||
24 | /* Tracks the 16G pages after the device tree is scanned and before the | 29 | /* |
25 | * huge_boot_pages list is ready. */ | 30 | * Tracks gpages after the device tree is scanned and before the |
26 | static unsigned long gpage_freearray[MAX_NUMBER_GPAGES]; | 31 | * huge_boot_pages list is ready. On 64-bit implementations, this is |
32 | * just used to track 16G pages and so is a single array. 32-bit | ||
33 | * implementations may have more than one gpage size due to limitations | ||
34 | * of the memory allocators, so we need multiple arrays | ||
35 | */ | ||
36 | #ifdef CONFIG_PPC64 | ||
37 | #define MAX_NUMBER_GPAGES 1024 | ||
38 | static u64 gpage_freearray[MAX_NUMBER_GPAGES]; | ||
27 | static unsigned nr_gpages; | 39 | static unsigned nr_gpages; |
28 | 40 | #else | |
29 | /* Flag to mark huge PD pointers. This means pmd_bad() and pud_bad() | 41 | #define MAX_NUMBER_GPAGES 128 |
30 | * will choke on pointers to hugepte tables, which is handy for | 42 | struct psize_gpages { |
31 | * catching screwups early. */ | 43 | u64 gpage_list[MAX_NUMBER_GPAGES]; |
44 | unsigned int nr_gpages; | ||
45 | }; | ||
46 | static struct psize_gpages gpage_freearray[MMU_PAGE_COUNT]; | ||
47 | #endif | ||
32 | 48 | ||
33 | static inline int shift_to_mmu_psize(unsigned int shift) | 49 | static inline int shift_to_mmu_psize(unsigned int shift) |
34 | { | 50 | { |
@@ -49,25 +65,6 @@ static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize) | |||
49 | 65 | ||
50 | #define hugepd_none(hpd) ((hpd).pd == 0) | 66 | #define hugepd_none(hpd) ((hpd).pd == 0) |
51 | 67 | ||
52 | static inline pte_t *hugepd_page(hugepd_t hpd) | ||
53 | { | ||
54 | BUG_ON(!hugepd_ok(hpd)); | ||
55 | return (pte_t *)((hpd.pd & ~HUGEPD_SHIFT_MASK) | 0xc000000000000000); | ||
56 | } | ||
57 | |||
58 | static inline unsigned int hugepd_shift(hugepd_t hpd) | ||
59 | { | ||
60 | return hpd.pd & HUGEPD_SHIFT_MASK; | ||
61 | } | ||
62 | |||
63 | static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, unsigned pdshift) | ||
64 | { | ||
65 | unsigned long idx = (addr & ((1UL << pdshift) - 1)) >> hugepd_shift(*hpdp); | ||
66 | pte_t *dir = hugepd_page(*hpdp); | ||
67 | |||
68 | return dir + idx; | ||
69 | } | ||
70 | |||
71 | pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift) | 68 | pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift) |
72 | { | 69 | { |
73 | pgd_t *pg; | 70 | pgd_t *pg; |
@@ -93,7 +90,7 @@ pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift | |||
93 | if (is_hugepd(pm)) | 90 | if (is_hugepd(pm)) |
94 | hpdp = (hugepd_t *)pm; | 91 | hpdp = (hugepd_t *)pm; |
95 | else if (!pmd_none(*pm)) { | 92 | else if (!pmd_none(*pm)) { |
96 | return pte_offset_map(pm, ea); | 93 | return pte_offset_kernel(pm, ea); |
97 | } | 94 | } |
98 | } | 95 | } |
99 | } | 96 | } |
@@ -114,8 +111,18 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) | |||
114 | static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, | 111 | static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, |
115 | unsigned long address, unsigned pdshift, unsigned pshift) | 112 | unsigned long address, unsigned pdshift, unsigned pshift) |
116 | { | 113 | { |
117 | pte_t *new = kmem_cache_zalloc(PGT_CACHE(pdshift - pshift), | 114 | struct kmem_cache *cachep; |
118 | GFP_KERNEL|__GFP_REPEAT); | 115 | pte_t *new; |
116 | |||
117 | #ifdef CONFIG_PPC64 | ||
118 | cachep = PGT_CACHE(pdshift - pshift); | ||
119 | #else | ||
120 | int i; | ||
121 | int num_hugepd = 1 << (pshift - pdshift); | ||
122 | cachep = hugepte_cache; | ||
123 | #endif | ||
124 | |||
125 | new = kmem_cache_zalloc(cachep, GFP_KERNEL|__GFP_REPEAT); | ||
119 | 126 | ||
120 | BUG_ON(pshift > HUGEPD_SHIFT_MASK); | 127 | BUG_ON(pshift > HUGEPD_SHIFT_MASK); |
121 | BUG_ON((unsigned long)new & HUGEPD_SHIFT_MASK); | 128 | BUG_ON((unsigned long)new & HUGEPD_SHIFT_MASK); |
@@ -124,10 +131,31 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, | |||
124 | return -ENOMEM; | 131 | return -ENOMEM; |
125 | 132 | ||
126 | spin_lock(&mm->page_table_lock); | 133 | spin_lock(&mm->page_table_lock); |
134 | #ifdef CONFIG_PPC64 | ||
127 | if (!hugepd_none(*hpdp)) | 135 | if (!hugepd_none(*hpdp)) |
128 | kmem_cache_free(PGT_CACHE(pdshift - pshift), new); | 136 | kmem_cache_free(cachep, new); |
129 | else | 137 | else |
130 | hpdp->pd = ((unsigned long)new & ~0x8000000000000000) | pshift; | 138 | hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift; |
139 | #else | ||
140 | /* | ||
141 | * We have multiple higher-level entries that point to the same | ||
142 | * actual pte location. Fill in each as we go and backtrack on error. | ||
143 | * We need all of these so the DTLB pgtable walk code can find the | ||
144 | * right higher-level entry without knowing if it's a hugepage or not. | ||
145 | */ | ||
146 | for (i = 0; i < num_hugepd; i++, hpdp++) { | ||
147 | if (unlikely(!hugepd_none(*hpdp))) | ||
148 | break; | ||
149 | else | ||
150 | hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift; | ||
151 | } | ||
152 | /* If we bailed from the for loop early, an error occurred, clean up */ | ||
153 | if (i < num_hugepd) { | ||
154 | for (i = i - 1 ; i >= 0; i--, hpdp--) | ||
155 | hpdp->pd = 0; | ||
156 | kmem_cache_free(cachep, new); | ||
157 | } | ||
158 | #endif | ||
131 | spin_unlock(&mm->page_table_lock); | 159 | spin_unlock(&mm->page_table_lock); |
132 | return 0; | 160 | return 0; |
133 | } | 161 | } |
@@ -169,11 +197,132 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz | |||
169 | return hugepte_offset(hpdp, addr, pdshift); | 197 | return hugepte_offset(hpdp, addr, pdshift); |
170 | } | 198 | } |
171 | 199 | ||
200 | #ifdef CONFIG_PPC32 | ||
172 | /* Build list of addresses of gigantic pages. This function is used in early | 201 | /* Build list of addresses of gigantic pages. This function is used in early |
173 | * boot before the buddy or bootmem allocator is setup. | 202 | * boot before the buddy or bootmem allocator is setup. |
174 | */ | 203 | */ |
175 | void add_gpage(unsigned long addr, unsigned long page_size, | 204 | void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages) |
176 | unsigned long number_of_pages) | 205 | { |
206 | unsigned int idx = shift_to_mmu_psize(__ffs(page_size)); | ||
207 | int i; | ||
208 | |||
209 | if (addr == 0) | ||
210 | return; | ||
211 | |||
212 | gpage_freearray[idx].nr_gpages = number_of_pages; | ||
213 | |||
214 | for (i = 0; i < number_of_pages; i++) { | ||
215 | gpage_freearray[idx].gpage_list[i] = addr; | ||
216 | addr += page_size; | ||
217 | } | ||
218 | } | ||
219 | |||
220 | /* | ||
221 | * Moves the gigantic page addresses from the temporary list to the | ||
222 | * huge_boot_pages list. | ||
223 | */ | ||
224 | int alloc_bootmem_huge_page(struct hstate *hstate) | ||
225 | { | ||
226 | struct huge_bootmem_page *m; | ||
227 | int idx = shift_to_mmu_psize(hstate->order + PAGE_SHIFT); | ||
228 | int nr_gpages = gpage_freearray[idx].nr_gpages; | ||
229 | |||
230 | if (nr_gpages == 0) | ||
231 | return 0; | ||
232 | |||
233 | #ifdef CONFIG_HIGHMEM | ||
234 | /* | ||
235 | * If gpages can be in highmem we can't use the trick of storing the | ||
236 | * data structure in the page; allocate space for this | ||
237 | */ | ||
238 | m = alloc_bootmem(sizeof(struct huge_bootmem_page)); | ||
239 | m->phys = gpage_freearray[idx].gpage_list[--nr_gpages]; | ||
240 | #else | ||
241 | m = phys_to_virt(gpage_freearray[idx].gpage_list[--nr_gpages]); | ||
242 | #endif | ||
243 | |||
244 | list_add(&m->list, &huge_boot_pages); | ||
245 | gpage_freearray[idx].nr_gpages = nr_gpages; | ||
246 | gpage_freearray[idx].gpage_list[nr_gpages] = 0; | ||
247 | m->hstate = hstate; | ||
248 | |||
249 | return 1; | ||
250 | } | ||
251 | /* | ||
252 | * Scan the command line hugepagesz= options for gigantic pages; store those in | ||
253 | * a list that we use to allocate the memory once all options are parsed. | ||
254 | */ | ||
255 | |||
256 | unsigned long gpage_npages[MMU_PAGE_COUNT]; | ||
257 | |||
258 | static int __init do_gpage_early_setup(char *param, char *val) | ||
259 | { | ||
260 | static phys_addr_t size; | ||
261 | unsigned long npages; | ||
262 | |||
263 | /* | ||
264 | * The hugepagesz and hugepages cmdline options are interleaved. We | ||
265 | * use the size variable to keep track of whether or not this was done | ||
266 | * properly and skip over instances where it is incorrect. Other | ||
267 | * command-line parsing code will issue warnings, so we don't need to. | ||
268 | * | ||
269 | */ | ||
270 | if ((strcmp(param, "default_hugepagesz") == 0) || | ||
271 | (strcmp(param, "hugepagesz") == 0)) { | ||
272 | size = memparse(val, NULL); | ||
273 | } else if (strcmp(param, "hugepages") == 0) { | ||
274 | if (size != 0) { | ||
275 | if (sscanf(val, "%lu", &npages) <= 0) | ||
276 | npages = 0; | ||
277 | gpage_npages[shift_to_mmu_psize(__ffs(size))] = npages; | ||
278 | size = 0; | ||
279 | } | ||
280 | } | ||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | |||
285 | /* | ||
286 | * This function allocates physical space for pages that are larger than the | ||
287 | * buddy allocator can handle. We want to allocate these in highmem because | ||
288 | * the amount of lowmem is limited. This means that this function MUST be | ||
289 | * called before lowmem_end_addr is set up in MMU_init() in order for the lmb | ||
290 | * allocate to grab highmem. | ||
291 | */ | ||
292 | void __init reserve_hugetlb_gpages(void) | ||
293 | { | ||
294 | static __initdata char cmdline[COMMAND_LINE_SIZE]; | ||
295 | phys_addr_t size, base; | ||
296 | int i; | ||
297 | |||
298 | strlcpy(cmdline, boot_command_line, COMMAND_LINE_SIZE); | ||
299 | parse_args("hugetlb gpages", cmdline, NULL, 0, &do_gpage_early_setup); | ||
300 | |||
301 | /* | ||
302 | * Walk gpage list in reverse, allocating larger page sizes first. | ||
303 | * Skip over unsupported sizes, or sizes that have 0 gpages allocated. | ||
304 | * When we reach the point in the list where pages are no longer | ||
305 | * considered gpages, we're done. | ||
306 | */ | ||
307 | for (i = MMU_PAGE_COUNT-1; i >= 0; i--) { | ||
308 | if (mmu_psize_defs[i].shift == 0 || gpage_npages[i] == 0) | ||
309 | continue; | ||
310 | else if (mmu_psize_to_shift(i) < (MAX_ORDER + PAGE_SHIFT)) | ||
311 | break; | ||
312 | |||
313 | size = (phys_addr_t)(1ULL << mmu_psize_to_shift(i)); | ||
314 | base = memblock_alloc_base(size * gpage_npages[i], size, | ||
315 | MEMBLOCK_ALLOC_ANYWHERE); | ||
316 | add_gpage(base, size, gpage_npages[i]); | ||
317 | } | ||
318 | } | ||
319 | |||
320 | #else /* PPC64 */ | ||
321 | |||
322 | /* Build list of addresses of gigantic pages. This function is used in early | ||
323 | * boot before the buddy or bootmem allocator is setup. | ||
324 | */ | ||
325 | void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages) | ||
177 | { | 326 | { |
178 | if (!addr) | 327 | if (!addr) |
179 | return; | 328 | return; |
@@ -199,19 +348,79 @@ int alloc_bootmem_huge_page(struct hstate *hstate) | |||
199 | m->hstate = hstate; | 348 | m->hstate = hstate; |
200 | return 1; | 349 | return 1; |
201 | } | 350 | } |
351 | #endif | ||
202 | 352 | ||
203 | int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) | 353 | int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) |
204 | { | 354 | { |
205 | return 0; | 355 | return 0; |
206 | } | 356 | } |
207 | 357 | ||
358 | #ifdef CONFIG_PPC32 | ||
359 | #define HUGEPD_FREELIST_SIZE \ | ||
360 | ((PAGE_SIZE - sizeof(struct hugepd_freelist)) / sizeof(pte_t)) | ||
361 | |||
362 | struct hugepd_freelist { | ||
363 | struct rcu_head rcu; | ||
364 | unsigned int index; | ||
365 | void *ptes[0]; | ||
366 | }; | ||
367 | |||
368 | static DEFINE_PER_CPU(struct hugepd_freelist *, hugepd_freelist_cur); | ||
369 | |||
370 | static void hugepd_free_rcu_callback(struct rcu_head *head) | ||
371 | { | ||
372 | struct hugepd_freelist *batch = | ||
373 | container_of(head, struct hugepd_freelist, rcu); | ||
374 | unsigned int i; | ||
375 | |||
376 | for (i = 0; i < batch->index; i++) | ||
377 | kmem_cache_free(hugepte_cache, batch->ptes[i]); | ||
378 | |||
379 | free_page((unsigned long)batch); | ||
380 | } | ||
381 | |||
382 | static void hugepd_free(struct mmu_gather *tlb, void *hugepte) | ||
383 | { | ||
384 | struct hugepd_freelist **batchp; | ||
385 | |||
386 | batchp = &__get_cpu_var(hugepd_freelist_cur); | ||
387 | |||
388 | if (atomic_read(&tlb->mm->mm_users) < 2 || | ||
389 | cpumask_equal(mm_cpumask(tlb->mm), | ||
390 | cpumask_of(smp_processor_id()))) { | ||
391 | kmem_cache_free(hugepte_cache, hugepte); | ||
392 | return; | ||
393 | } | ||
394 | |||
395 | if (*batchp == NULL) { | ||
396 | *batchp = (struct hugepd_freelist *)__get_free_page(GFP_ATOMIC); | ||
397 | (*batchp)->index = 0; | ||
398 | } | ||
399 | |||
400 | (*batchp)->ptes[(*batchp)->index++] = hugepte; | ||
401 | if ((*batchp)->index == HUGEPD_FREELIST_SIZE) { | ||
402 | call_rcu_sched(&(*batchp)->rcu, hugepd_free_rcu_callback); | ||
403 | *batchp = NULL; | ||
404 | } | ||
405 | } | ||
406 | #endif | ||
407 | |||
208 | static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshift, | 408 | static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshift, |
209 | unsigned long start, unsigned long end, | 409 | unsigned long start, unsigned long end, |
210 | unsigned long floor, unsigned long ceiling) | 410 | unsigned long floor, unsigned long ceiling) |
211 | { | 411 | { |
212 | pte_t *hugepte = hugepd_page(*hpdp); | 412 | pte_t *hugepte = hugepd_page(*hpdp); |
213 | unsigned shift = hugepd_shift(*hpdp); | 413 | int i; |
414 | |||
214 | unsigned long pdmask = ~((1UL << pdshift) - 1); | 415 | unsigned long pdmask = ~((1UL << pdshift) - 1); |
416 | unsigned int num_hugepd = 1; | ||
417 | |||
418 | #ifdef CONFIG_PPC64 | ||
419 | unsigned int shift = hugepd_shift(*hpdp); | ||
420 | #else | ||
421 | /* Note: On 32-bit the hpdp may be the first of several */ | ||
422 | num_hugepd = (1 << (hugepd_shift(*hpdp) - pdshift)); | ||
423 | #endif | ||
215 | 424 | ||
216 | start &= pdmask; | 425 | start &= pdmask; |
217 | if (start < floor) | 426 | if (start < floor) |
@@ -224,9 +433,15 @@ static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshif | |||
224 | if (end - 1 > ceiling - 1) | 433 | if (end - 1 > ceiling - 1) |
225 | return; | 434 | return; |
226 | 435 | ||
227 | hpdp->pd = 0; | 436 | for (i = 0; i < num_hugepd; i++, hpdp++) |
437 | hpdp->pd = 0; | ||
438 | |||
228 | tlb->need_flush = 1; | 439 | tlb->need_flush = 1; |
440 | #ifdef CONFIG_PPC64 | ||
229 | pgtable_free_tlb(tlb, hugepte, pdshift - shift); | 441 | pgtable_free_tlb(tlb, hugepte, pdshift - shift); |
442 | #else | ||
443 | hugepd_free(tlb, hugepte); | ||
444 | #endif | ||
230 | } | 445 | } |
231 | 446 | ||
232 | static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud, | 447 | static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud, |
@@ -331,18 +546,27 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb, | |||
331 | * too. | 546 | * too. |
332 | */ | 547 | */ |
333 | 548 | ||
334 | pgd = pgd_offset(tlb->mm, addr); | ||
335 | do { | 549 | do { |
336 | next = pgd_addr_end(addr, end); | 550 | next = pgd_addr_end(addr, end); |
551 | pgd = pgd_offset(tlb->mm, addr); | ||
337 | if (!is_hugepd(pgd)) { | 552 | if (!is_hugepd(pgd)) { |
338 | if (pgd_none_or_clear_bad(pgd)) | 553 | if (pgd_none_or_clear_bad(pgd)) |
339 | continue; | 554 | continue; |
340 | hugetlb_free_pud_range(tlb, pgd, addr, next, floor, ceiling); | 555 | hugetlb_free_pud_range(tlb, pgd, addr, next, floor, ceiling); |
341 | } else { | 556 | } else { |
557 | #ifdef CONFIG_PPC32 | ||
558 | /* | ||
559 | * Increment next by the size of the huge mapping since | ||
560 | * on 32-bit there may be more than one entry at the pgd | ||
561 | * level for a single hugepage, but all of them point to | ||
562 | * the same kmem cache that holds the hugepte. | ||
563 | */ | ||
564 | next = addr + (1 << hugepd_shift(*(hugepd_t *)pgd)); | ||
565 | #endif | ||
342 | free_hugepd_range(tlb, (hugepd_t *)pgd, PGDIR_SHIFT, | 566 | free_hugepd_range(tlb, (hugepd_t *)pgd, PGDIR_SHIFT, |
343 | addr, next, floor, ceiling); | 567 | addr, next, floor, ceiling); |
344 | } | 568 | } |
345 | } while (pgd++, addr = next, addr != end); | 569 | } while (addr = next, addr != end); |
346 | } | 570 | } |
347 | 571 | ||
348 | struct page * | 572 | struct page * |
@@ -477,17 +701,35 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, | |||
477 | unsigned long len, unsigned long pgoff, | 701 | unsigned long len, unsigned long pgoff, |
478 | unsigned long flags) | 702 | unsigned long flags) |
479 | { | 703 | { |
704 | #ifdef CONFIG_PPC_MM_SLICES | ||
480 | struct hstate *hstate = hstate_file(file); | 705 | struct hstate *hstate = hstate_file(file); |
481 | int mmu_psize = shift_to_mmu_psize(huge_page_shift(hstate)); | 706 | int mmu_psize = shift_to_mmu_psize(huge_page_shift(hstate)); |
482 | 707 | ||
483 | return slice_get_unmapped_area(addr, len, flags, mmu_psize, 1, 0); | 708 | return slice_get_unmapped_area(addr, len, flags, mmu_psize, 1, 0); |
709 | #else | ||
710 | return get_unmapped_area(file, addr, len, pgoff, flags); | ||
711 | #endif | ||
484 | } | 712 | } |
485 | 713 | ||
486 | unsigned long vma_mmu_pagesize(struct vm_area_struct *vma) | 714 | unsigned long vma_mmu_pagesize(struct vm_area_struct *vma) |
487 | { | 715 | { |
716 | #ifdef CONFIG_PPC_MM_SLICES | ||
488 | unsigned int psize = get_slice_psize(vma->vm_mm, vma->vm_start); | 717 | unsigned int psize = get_slice_psize(vma->vm_mm, vma->vm_start); |
489 | 718 | ||
490 | return 1UL << mmu_psize_to_shift(psize); | 719 | return 1UL << mmu_psize_to_shift(psize); |
720 | #else | ||
721 | if (!is_vm_hugetlb_page(vma)) | ||
722 | return PAGE_SIZE; | ||
723 | |||
724 | return huge_page_size(hstate_vma(vma)); | ||
725 | #endif | ||
726 | } | ||
727 | |||
728 | static inline bool is_power_of_4(unsigned long x) | ||
729 | { | ||
730 | if (is_power_of_2(x)) | ||
731 | return (__ilog2(x) % 2) ? false : true; | ||
732 | return false; | ||
491 | } | 733 | } |
492 | 734 | ||
493 | static int __init add_huge_page_size(unsigned long long size) | 735 | static int __init add_huge_page_size(unsigned long long size) |
@@ -497,9 +739,14 @@ static int __init add_huge_page_size(unsigned long long size) | |||
497 | 739 | ||
498 | /* Check that it is a page size supported by the hardware and | 740 | /* Check that it is a page size supported by the hardware and |
499 | * that it fits within pagetable and slice limits. */ | 741 | * that it fits within pagetable and slice limits. */ |
742 | #ifdef CONFIG_PPC_FSL_BOOK3E | ||
743 | if ((size < PAGE_SIZE) || !is_power_of_4(size)) | ||
744 | return -EINVAL; | ||
745 | #else | ||
500 | if (!is_power_of_2(size) | 746 | if (!is_power_of_2(size) |
501 | || (shift > SLICE_HIGH_SHIFT) || (shift <= PAGE_SHIFT)) | 747 | || (shift > SLICE_HIGH_SHIFT) || (shift <= PAGE_SHIFT)) |
502 | return -EINVAL; | 748 | return -EINVAL; |
749 | #endif | ||
503 | 750 | ||
504 | if ((mmu_psize = shift_to_mmu_psize(shift)) < 0) | 751 | if ((mmu_psize = shift_to_mmu_psize(shift)) < 0) |
505 | return -EINVAL; | 752 | return -EINVAL; |
@@ -536,6 +783,46 @@ static int __init hugepage_setup_sz(char *str) | |||
536 | } | 783 | } |
537 | __setup("hugepagesz=", hugepage_setup_sz); | 784 | __setup("hugepagesz=", hugepage_setup_sz); |
538 | 785 | ||
786 | #ifdef CONFIG_FSL_BOOKE | ||
787 | struct kmem_cache *hugepte_cache; | ||
788 | static int __init hugetlbpage_init(void) | ||
789 | { | ||
790 | int psize; | ||
791 | |||
792 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { | ||
793 | unsigned shift; | ||
794 | |||
795 | if (!mmu_psize_defs[psize].shift) | ||
796 | continue; | ||
797 | |||
798 | shift = mmu_psize_to_shift(psize); | ||
799 | |||
800 | /* Don't treat normal page sizes as huge... */ | ||
801 | if (shift != PAGE_SHIFT) | ||
802 | if (add_huge_page_size(1ULL << shift) < 0) | ||
803 | continue; | ||
804 | } | ||
805 | |||
806 | /* | ||
807 | * Create a kmem cache for hugeptes. The bottom bits in the pte have | ||
808 | * size information encoded in them, so align them to allow this | ||
809 | */ | ||
810 | hugepte_cache = kmem_cache_create("hugepte-cache", sizeof(pte_t), | ||
811 | HUGEPD_SHIFT_MASK + 1, 0, NULL); | ||
812 | if (hugepte_cache == NULL) | ||
813 | panic("%s: Unable to create kmem cache for hugeptes\n", | ||
814 | __func__); | ||
815 | |||
816 | /* Default hpage size = 4M */ | ||
817 | if (mmu_psize_defs[MMU_PAGE_4M].shift) | ||
818 | HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_4M].shift; | ||
819 | else | ||
820 | panic("%s: Unable to set default huge page size\n", __func__); | ||
821 | |||
822 | |||
823 | return 0; | ||
824 | } | ||
825 | #else | ||
539 | static int __init hugetlbpage_init(void) | 826 | static int __init hugetlbpage_init(void) |
540 | { | 827 | { |
541 | int psize; | 828 | int psize; |
@@ -578,15 +865,23 @@ static int __init hugetlbpage_init(void) | |||
578 | 865 | ||
579 | return 0; | 866 | return 0; |
580 | } | 867 | } |
581 | 868 | #endif | |
582 | module_init(hugetlbpage_init); | 869 | module_init(hugetlbpage_init); |
583 | 870 | ||
584 | void flush_dcache_icache_hugepage(struct page *page) | 871 | void flush_dcache_icache_hugepage(struct page *page) |
585 | { | 872 | { |
586 | int i; | 873 | int i; |
874 | void *start; | ||
587 | 875 | ||
588 | BUG_ON(!PageCompound(page)); | 876 | BUG_ON(!PageCompound(page)); |
589 | 877 | ||
590 | for (i = 0; i < (1UL << compound_order(page)); i++) | 878 | for (i = 0; i < (1UL << compound_order(page)); i++) { |
591 | __flush_dcache_icache(page_address(page+i)); | 879 | if (!PageHighMem(page)) { |
880 | __flush_dcache_icache(page_address(page+i)); | ||
881 | } else { | ||
882 | start = kmap_atomic(page+i, KM_PPC_SYNC_ICACHE); | ||
883 | __flush_dcache_icache(start); | ||
884 | kunmap_atomic(start, KM_PPC_SYNC_ICACHE); | ||
885 | } | ||
886 | } | ||
592 | } | 887 | } |
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index c77fef56dad6..161cefde5c15 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #include <linux/pagemap.h> | 32 | #include <linux/pagemap.h> |
33 | #include <linux/memblock.h> | 33 | #include <linux/memblock.h> |
34 | #include <linux/gfp.h> | 34 | #include <linux/gfp.h> |
35 | #include <linux/slab.h> | ||
36 | #include <linux/hugetlb.h> | ||
35 | 37 | ||
36 | #include <asm/pgalloc.h> | 38 | #include <asm/pgalloc.h> |
37 | #include <asm/prom.h> | 39 | #include <asm/prom.h> |
@@ -44,6 +46,7 @@ | |||
44 | #include <asm/tlb.h> | 46 | #include <asm/tlb.h> |
45 | #include <asm/sections.h> | 47 | #include <asm/sections.h> |
46 | #include <asm/system.h> | 48 | #include <asm/system.h> |
49 | #include <asm/hugetlb.h> | ||
47 | 50 | ||
48 | #include "mmu_decl.h" | 51 | #include "mmu_decl.h" |
49 | 52 | ||
@@ -123,6 +126,12 @@ void __init MMU_init(void) | |||
123 | /* parse args from command line */ | 126 | /* parse args from command line */ |
124 | MMU_setup(); | 127 | MMU_setup(); |
125 | 128 | ||
129 | /* | ||
130 | * Reserve gigantic pages for hugetlb. This MUST occur before | ||
131 | * lowmem_end_addr is initialized below. | ||
132 | */ | ||
133 | reserve_hugetlb_gpages(); | ||
134 | |||
126 | if (memblock.memory.cnt > 1) { | 135 | if (memblock.memory.cnt > 1) { |
127 | #ifndef CONFIG_WII | 136 | #ifndef CONFIG_WII |
128 | memblock.memory.cnt = 1; | 137 | memblock.memory.cnt = 1; |
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index c781bbcf7338..5db316cad47b 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c | |||
@@ -123,7 +123,8 @@ int arch_add_memory(int nid, u64 start, u64 size) | |||
123 | pgdata = NODE_DATA(nid); | 123 | pgdata = NODE_DATA(nid); |
124 | 124 | ||
125 | start = (unsigned long)__va(start); | 125 | start = (unsigned long)__va(start); |
126 | create_section_mapping(start, start + size); | 126 | if (create_section_mapping(start, start + size)) |
127 | return -EINVAL; | ||
127 | 128 | ||
128 | /* this should work for most non-highmem platforms */ | 129 | /* this should work for most non-highmem platforms */ |
129 | zone = pgdata->node_zones; | 130 | zone = pgdata->node_zones; |
@@ -548,4 +549,9 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, | |||
548 | return; | 549 | return; |
549 | hash_preload(vma->vm_mm, address, access, trap); | 550 | hash_preload(vma->vm_mm, address, access, trap); |
550 | #endif /* CONFIG_PPC_STD_MMU */ | 551 | #endif /* CONFIG_PPC_STD_MMU */ |
552 | #if (defined(CONFIG_PPC_BOOK3E_64) || defined(CONFIG_PPC_FSL_BOOK3E)) \ | ||
553 | && defined(CONFIG_HUGETLB_PAGE) | ||
554 | if (is_vm_hugetlb_page(vma)) | ||
555 | book3e_hugetlb_preload(vma->vm_mm, address, *ptep); | ||
556 | #endif | ||
551 | } | 557 | } |
diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c index 3bafc3deca6d..4ff587e38250 100644 --- a/arch/powerpc/mm/mmu_context_hash64.c +++ b/arch/powerpc/mm/mmu_context_hash64.c | |||
@@ -136,8 +136,8 @@ int use_cop(unsigned long acop, struct mm_struct *mm) | |||
136 | if (!mm || !acop) | 136 | if (!mm || !acop) |
137 | return -EINVAL; | 137 | return -EINVAL; |
138 | 138 | ||
139 | /* We need to make sure mm_users doesn't change */ | 139 | /* The page_table_lock ensures mm_users won't change under us */ |
140 | down_read(&mm->mmap_sem); | 140 | spin_lock(&mm->page_table_lock); |
141 | spin_lock(mm->context.cop_lockp); | 141 | spin_lock(mm->context.cop_lockp); |
142 | 142 | ||
143 | if (mm->context.cop_pid == COP_PID_NONE) { | 143 | if (mm->context.cop_pid == COP_PID_NONE) { |
@@ -164,7 +164,7 @@ int use_cop(unsigned long acop, struct mm_struct *mm) | |||
164 | 164 | ||
165 | out: | 165 | out: |
166 | spin_unlock(mm->context.cop_lockp); | 166 | spin_unlock(mm->context.cop_lockp); |
167 | up_read(&mm->mmap_sem); | 167 | spin_unlock(&mm->page_table_lock); |
168 | 168 | ||
169 | return ret; | 169 | return ret; |
170 | } | 170 | } |
@@ -185,8 +185,8 @@ void drop_cop(unsigned long acop, struct mm_struct *mm) | |||
185 | if (WARN_ON_ONCE(!mm)) | 185 | if (WARN_ON_ONCE(!mm)) |
186 | return; | 186 | return; |
187 | 187 | ||
188 | /* We need to make sure mm_users doesn't change */ | 188 | /* The page_table_lock ensures mm_users won't change under us */ |
189 | down_read(&mm->mmap_sem); | 189 | spin_lock(&mm->page_table_lock); |
190 | spin_lock(mm->context.cop_lockp); | 190 | spin_lock(mm->context.cop_lockp); |
191 | 191 | ||
192 | mm->context.acop &= ~acop; | 192 | mm->context.acop &= ~acop; |
@@ -213,7 +213,7 @@ void drop_cop(unsigned long acop, struct mm_struct *mm) | |||
213 | } | 213 | } |
214 | 214 | ||
215 | spin_unlock(mm->context.cop_lockp); | 215 | spin_unlock(mm->context.cop_lockp); |
216 | up_read(&mm->mmap_sem); | 216 | spin_unlock(&mm->page_table_lock); |
217 | } | 217 | } |
218 | EXPORT_SYMBOL_GPL(drop_cop); | 218 | EXPORT_SYMBOL_GPL(drop_cop); |
219 | 219 | ||
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c index 336807de550e..5b63bd3da4a9 100644 --- a/arch/powerpc/mm/mmu_context_nohash.c +++ b/arch/powerpc/mm/mmu_context_nohash.c | |||
@@ -292,6 +292,11 @@ int init_new_context(struct task_struct *t, struct mm_struct *mm) | |||
292 | mm->context.id = MMU_NO_CONTEXT; | 292 | mm->context.id = MMU_NO_CONTEXT; |
293 | mm->context.active = 0; | 293 | mm->context.active = 0; |
294 | 294 | ||
295 | #ifdef CONFIG_PPC_MM_SLICES | ||
296 | if (slice_mm_new_context(mm)) | ||
297 | slice_set_user_psize(mm, mmu_virtual_psize); | ||
298 | #endif | ||
299 | |||
295 | return 0; | 300 | return 0; |
296 | } | 301 | } |
297 | 302 | ||
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index dd0a2589591d..83eb5d5f53d5 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h | |||
@@ -142,6 +142,8 @@ extern unsigned long mmu_mapin_ram(unsigned long top); | |||
142 | 142 | ||
143 | #elif defined(CONFIG_PPC_FSL_BOOK3E) | 143 | #elif defined(CONFIG_PPC_FSL_BOOK3E) |
144 | extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx); | 144 | extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx); |
145 | extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt, | ||
146 | phys_addr_t phys); | ||
145 | #ifdef CONFIG_PPC32 | 147 | #ifdef CONFIG_PPC32 |
146 | extern void MMU_init_hw(void); | 148 | extern void MMU_init_hw(void); |
147 | extern unsigned long mmu_mapin_ram(unsigned long top); | 149 | extern unsigned long mmu_mapin_ram(unsigned long top); |
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 2164006fe170..0bfb90c50571 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
@@ -709,8 +709,7 @@ static void __init parse_drconf_memory(struct device_node *memory) | |||
709 | 709 | ||
710 | static int __init parse_numa_properties(void) | 710 | static int __init parse_numa_properties(void) |
711 | { | 711 | { |
712 | struct device_node *cpu = NULL; | 712 | struct device_node *memory; |
713 | struct device_node *memory = NULL; | ||
714 | int default_nid = 0; | 713 | int default_nid = 0; |
715 | unsigned long i; | 714 | unsigned long i; |
716 | 715 | ||
@@ -732,6 +731,7 @@ static int __init parse_numa_properties(void) | |||
732 | * each node to be onlined must have NODE_DATA etc backing it. | 731 | * each node to be onlined must have NODE_DATA etc backing it. |
733 | */ | 732 | */ |
734 | for_each_present_cpu(i) { | 733 | for_each_present_cpu(i) { |
734 | struct device_node *cpu; | ||
735 | int nid; | 735 | int nid; |
736 | 736 | ||
737 | cpu = of_get_cpu_node(i, NULL); | 737 | cpu = of_get_cpu_node(i, NULL); |
@@ -750,8 +750,8 @@ static int __init parse_numa_properties(void) | |||
750 | } | 750 | } |
751 | 751 | ||
752 | get_n_mem_cells(&n_mem_addr_cells, &n_mem_size_cells); | 752 | get_n_mem_cells(&n_mem_addr_cells, &n_mem_size_cells); |
753 | memory = NULL; | 753 | |
754 | while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { | 754 | for_each_node_by_type(memory, "memory") { |
755 | unsigned long start; | 755 | unsigned long start; |
756 | unsigned long size; | 756 | unsigned long size; |
757 | int nid; | 757 | int nid; |
@@ -800,8 +800,9 @@ new_range: | |||
800 | } | 800 | } |
801 | 801 | ||
802 | /* | 802 | /* |
803 | * Now do the same thing for each MEMBLOCK listed in the ibm,dynamic-memory | 803 | * Now do the same thing for each MEMBLOCK listed in the |
804 | * property in the ibm,dynamic-reconfiguration-memory node. | 804 | * ibm,dynamic-memory property in the |
805 | * ibm,dynamic-reconfiguration-memory node. | ||
805 | */ | 806 | */ |
806 | memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); | 807 | memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); |
807 | if (memory) | 808 | if (memory) |
@@ -1187,10 +1188,10 @@ static int hot_add_drconf_scn_to_nid(struct device_node *memory, | |||
1187 | */ | 1188 | */ |
1188 | int hot_add_node_scn_to_nid(unsigned long scn_addr) | 1189 | int hot_add_node_scn_to_nid(unsigned long scn_addr) |
1189 | { | 1190 | { |
1190 | struct device_node *memory = NULL; | 1191 | struct device_node *memory; |
1191 | int nid = -1; | 1192 | int nid = -1; |
1192 | 1193 | ||
1193 | while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { | 1194 | for_each_node_by_type(memory, "memory") { |
1194 | unsigned long start, size; | 1195 | unsigned long start, size; |
1195 | int ranges; | 1196 | int ranges; |
1196 | const unsigned int *memcell_buf; | 1197 | const unsigned int *memcell_buf; |
@@ -1214,11 +1215,12 @@ int hot_add_node_scn_to_nid(unsigned long scn_addr) | |||
1214 | break; | 1215 | break; |
1215 | } | 1216 | } |
1216 | 1217 | ||
1217 | of_node_put(memory); | ||
1218 | if (nid >= 0) | 1218 | if (nid >= 0) |
1219 | break; | 1219 | break; |
1220 | } | 1220 | } |
1221 | 1221 | ||
1222 | of_node_put(memory); | ||
1223 | |||
1222 | return nid; | 1224 | return nid; |
1223 | } | 1225 | } |
1224 | 1226 | ||
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c index af40c8768a78..214130a4edc6 100644 --- a/arch/powerpc/mm/pgtable.c +++ b/arch/powerpc/mm/pgtable.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/percpu.h> | 28 | #include <linux/percpu.h> |
29 | #include <linux/hardirq.h> | 29 | #include <linux/hardirq.h> |
30 | #include <linux/hugetlb.h> | ||
30 | #include <asm/pgalloc.h> | 31 | #include <asm/pgalloc.h> |
31 | #include <asm/tlbflush.h> | 32 | #include <asm/tlbflush.h> |
32 | #include <asm/tlb.h> | 33 | #include <asm/tlb.h> |
@@ -212,7 +213,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, | |||
212 | entry = set_access_flags_filter(entry, vma, dirty); | 213 | entry = set_access_flags_filter(entry, vma, dirty); |
213 | changed = !pte_same(*(ptep), entry); | 214 | changed = !pte_same(*(ptep), entry); |
214 | if (changed) { | 215 | if (changed) { |
215 | if (!(vma->vm_flags & VM_HUGETLB)) | 216 | if (!is_vm_hugetlb_page(vma)) |
216 | assert_pte_locked(vma->vm_mm, address); | 217 | assert_pte_locked(vma->vm_mm, address); |
217 | __ptep_set_access_flags(ptep, entry); | 218 | __ptep_set_access_flags(ptep, entry); |
218 | flush_tlb_page_nohash(vma, address); | 219 | flush_tlb_page_nohash(vma, address); |
diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S index 4ebb34bc01d6..dc4a5f385e41 100644 --- a/arch/powerpc/mm/tlb_low_64e.S +++ b/arch/powerpc/mm/tlb_low_64e.S | |||
@@ -553,24 +553,24 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_TLBRSRV) | |||
553 | rldicl r11,r16,64-VPTE_PGD_SHIFT,64-PGD_INDEX_SIZE-3 | 553 | rldicl r11,r16,64-VPTE_PGD_SHIFT,64-PGD_INDEX_SIZE-3 |
554 | clrrdi r10,r11,3 | 554 | clrrdi r10,r11,3 |
555 | ldx r15,r10,r15 | 555 | ldx r15,r10,r15 |
556 | cmpldi cr0,r15,0 | 556 | cmpdi cr0,r15,0 |
557 | beq virt_page_table_tlb_miss_fault | 557 | bge virt_page_table_tlb_miss_fault |
558 | 558 | ||
559 | #ifndef CONFIG_PPC_64K_PAGES | 559 | #ifndef CONFIG_PPC_64K_PAGES |
560 | /* Get to PUD entry */ | 560 | /* Get to PUD entry */ |
561 | rldicl r11,r16,64-VPTE_PUD_SHIFT,64-PUD_INDEX_SIZE-3 | 561 | rldicl r11,r16,64-VPTE_PUD_SHIFT,64-PUD_INDEX_SIZE-3 |
562 | clrrdi r10,r11,3 | 562 | clrrdi r10,r11,3 |
563 | ldx r15,r10,r15 | 563 | ldx r15,r10,r15 |
564 | cmpldi cr0,r15,0 | 564 | cmpdi cr0,r15,0 |
565 | beq virt_page_table_tlb_miss_fault | 565 | bge virt_page_table_tlb_miss_fault |
566 | #endif /* CONFIG_PPC_64K_PAGES */ | 566 | #endif /* CONFIG_PPC_64K_PAGES */ |
567 | 567 | ||
568 | /* Get to PMD entry */ | 568 | /* Get to PMD entry */ |
569 | rldicl r11,r16,64-VPTE_PMD_SHIFT,64-PMD_INDEX_SIZE-3 | 569 | rldicl r11,r16,64-VPTE_PMD_SHIFT,64-PMD_INDEX_SIZE-3 |
570 | clrrdi r10,r11,3 | 570 | clrrdi r10,r11,3 |
571 | ldx r15,r10,r15 | 571 | ldx r15,r10,r15 |
572 | cmpldi cr0,r15,0 | 572 | cmpdi cr0,r15,0 |
573 | beq virt_page_table_tlb_miss_fault | 573 | bge virt_page_table_tlb_miss_fault |
574 | 574 | ||
575 | /* Ok, we're all right, we can now create a kernel translation for | 575 | /* Ok, we're all right, we can now create a kernel translation for |
576 | * a 4K or 64K page from r16 -> r15. | 576 | * a 4K or 64K page from r16 -> r15. |
@@ -802,24 +802,24 @@ htw_tlb_miss: | |||
802 | rldicl r11,r16,64-(PGDIR_SHIFT-3),64-PGD_INDEX_SIZE-3 | 802 | rldicl r11,r16,64-(PGDIR_SHIFT-3),64-PGD_INDEX_SIZE-3 |
803 | clrrdi r10,r11,3 | 803 | clrrdi r10,r11,3 |
804 | ldx r15,r10,r15 | 804 | ldx r15,r10,r15 |
805 | cmpldi cr0,r15,0 | 805 | cmpdi cr0,r15,0 |
806 | beq htw_tlb_miss_fault | 806 | bge htw_tlb_miss_fault |
807 | 807 | ||
808 | #ifndef CONFIG_PPC_64K_PAGES | 808 | #ifndef CONFIG_PPC_64K_PAGES |
809 | /* Get to PUD entry */ | 809 | /* Get to PUD entry */ |
810 | rldicl r11,r16,64-(PUD_SHIFT-3),64-PUD_INDEX_SIZE-3 | 810 | rldicl r11,r16,64-(PUD_SHIFT-3),64-PUD_INDEX_SIZE-3 |
811 | clrrdi r10,r11,3 | 811 | clrrdi r10,r11,3 |
812 | ldx r15,r10,r15 | 812 | ldx r15,r10,r15 |
813 | cmpldi cr0,r15,0 | 813 | cmpdi cr0,r15,0 |
814 | beq htw_tlb_miss_fault | 814 | bge htw_tlb_miss_fault |
815 | #endif /* CONFIG_PPC_64K_PAGES */ | 815 | #endif /* CONFIG_PPC_64K_PAGES */ |
816 | 816 | ||
817 | /* Get to PMD entry */ | 817 | /* Get to PMD entry */ |
818 | rldicl r11,r16,64-(PMD_SHIFT-3),64-PMD_INDEX_SIZE-3 | 818 | rldicl r11,r16,64-(PMD_SHIFT-3),64-PMD_INDEX_SIZE-3 |
819 | clrrdi r10,r11,3 | 819 | clrrdi r10,r11,3 |
820 | ldx r15,r10,r15 | 820 | ldx r15,r10,r15 |
821 | cmpldi cr0,r15,0 | 821 | cmpdi cr0,r15,0 |
822 | beq htw_tlb_miss_fault | 822 | bge htw_tlb_miss_fault |
823 | 823 | ||
824 | /* Ok, we're all right, we can now create an indirect entry for | 824 | /* Ok, we're all right, we can now create an indirect entry for |
825 | * a 1M or 256M page. | 825 | * a 1M or 256M page. |
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index d32ec643c231..6c2eabf707b7 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c | |||
@@ -36,14 +36,49 @@ | |||
36 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
37 | #include <linux/memblock.h> | 37 | #include <linux/memblock.h> |
38 | #include <linux/of_fdt.h> | 38 | #include <linux/of_fdt.h> |
39 | #include <linux/hugetlb.h> | ||
39 | 40 | ||
40 | #include <asm/tlbflush.h> | 41 | #include <asm/tlbflush.h> |
41 | #include <asm/tlb.h> | 42 | #include <asm/tlb.h> |
42 | #include <asm/code-patching.h> | 43 | #include <asm/code-patching.h> |
44 | #include <asm/hugetlb.h> | ||
43 | 45 | ||
44 | #include "mmu_decl.h" | 46 | #include "mmu_decl.h" |
45 | 47 | ||
46 | #ifdef CONFIG_PPC_BOOK3E | 48 | /* |
49 | * This struct lists the sw-supported page sizes. The hardawre MMU may support | ||
50 | * other sizes not listed here. The .ind field is only used on MMUs that have | ||
51 | * indirect page table entries. | ||
52 | */ | ||
53 | #ifdef CONFIG_PPC_BOOK3E_MMU | ||
54 | #ifdef CONFIG_FSL_BOOKE | ||
55 | struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { | ||
56 | [MMU_PAGE_4K] = { | ||
57 | .shift = 12, | ||
58 | .enc = BOOK3E_PAGESZ_4K, | ||
59 | }, | ||
60 | [MMU_PAGE_4M] = { | ||
61 | .shift = 22, | ||
62 | .enc = BOOK3E_PAGESZ_4M, | ||
63 | }, | ||
64 | [MMU_PAGE_16M] = { | ||
65 | .shift = 24, | ||
66 | .enc = BOOK3E_PAGESZ_16M, | ||
67 | }, | ||
68 | [MMU_PAGE_64M] = { | ||
69 | .shift = 26, | ||
70 | .enc = BOOK3E_PAGESZ_64M, | ||
71 | }, | ||
72 | [MMU_PAGE_256M] = { | ||
73 | .shift = 28, | ||
74 | .enc = BOOK3E_PAGESZ_256M, | ||
75 | }, | ||
76 | [MMU_PAGE_1G] = { | ||
77 | .shift = 30, | ||
78 | .enc = BOOK3E_PAGESZ_1GB, | ||
79 | }, | ||
80 | }; | ||
81 | #else | ||
47 | struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { | 82 | struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { |
48 | [MMU_PAGE_4K] = { | 83 | [MMU_PAGE_4K] = { |
49 | .shift = 12, | 84 | .shift = 12, |
@@ -77,6 +112,8 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { | |||
77 | .enc = BOOK3E_PAGESZ_1GB, | 112 | .enc = BOOK3E_PAGESZ_1GB, |
78 | }, | 113 | }, |
79 | }; | 114 | }; |
115 | #endif /* CONFIG_FSL_BOOKE */ | ||
116 | |||
80 | static inline int mmu_get_tsize(int psize) | 117 | static inline int mmu_get_tsize(int psize) |
81 | { | 118 | { |
82 | return mmu_psize_defs[psize].enc; | 119 | return mmu_psize_defs[psize].enc; |
@@ -87,7 +124,7 @@ static inline int mmu_get_tsize(int psize) | |||
87 | /* This isn't used on !Book3E for now */ | 124 | /* This isn't used on !Book3E for now */ |
88 | return 0; | 125 | return 0; |
89 | } | 126 | } |
90 | #endif | 127 | #endif /* CONFIG_PPC_BOOK3E_MMU */ |
91 | 128 | ||
92 | /* The variables below are currently only used on 64-bit Book3E | 129 | /* The variables below are currently only used on 64-bit Book3E |
93 | * though this will probably be made common with other nohash | 130 | * though this will probably be made common with other nohash |
@@ -266,6 +303,11 @@ void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr, | |||
266 | 303 | ||
267 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) | 304 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) |
268 | { | 305 | { |
306 | #ifdef CONFIG_HUGETLB_PAGE | ||
307 | if (is_vm_hugetlb_page(vma)) | ||
308 | flush_hugetlb_page(vma, vmaddr); | ||
309 | #endif | ||
310 | |||
269 | __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr, | 311 | __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr, |
270 | mmu_get_tsize(mmu_virtual_psize), 0); | 312 | mmu_get_tsize(mmu_virtual_psize), 0); |
271 | } | 313 | } |
@@ -600,13 +642,28 @@ void __cpuinit early_init_mmu_secondary(void) | |||
600 | void setup_initial_memory_limit(phys_addr_t first_memblock_base, | 642 | void setup_initial_memory_limit(phys_addr_t first_memblock_base, |
601 | phys_addr_t first_memblock_size) | 643 | phys_addr_t first_memblock_size) |
602 | { | 644 | { |
603 | /* On Embedded 64-bit, we adjust the RMA size to match | 645 | /* On non-FSL Embedded 64-bit, we adjust the RMA size to match |
604 | * the bolted TLB entry. We know for now that only 1G | 646 | * the bolted TLB entry. We know for now that only 1G |
605 | * entries are supported though that may eventually | 647 | * entries are supported though that may eventually |
606 | * change. We crop it to the size of the first MEMBLOCK to | 648 | * change. |
649 | * | ||
650 | * on FSL Embedded 64-bit, we adjust the RMA size to match the | ||
651 | * first bolted TLB entry size. We still limit max to 1G even if | ||
652 | * the TLB could cover more. This is due to what the early init | ||
653 | * code is setup to do. | ||
654 | * | ||
655 | * We crop it to the size of the first MEMBLOCK to | ||
607 | * avoid going over total available memory just in case... | 656 | * avoid going over total available memory just in case... |
608 | */ | 657 | */ |
609 | ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000); | 658 | #ifdef CONFIG_PPC_FSL_BOOK3E |
659 | if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { | ||
660 | unsigned long linear_sz; | ||
661 | linear_sz = calc_cam_sz(first_memblock_size, PAGE_OFFSET, | ||
662 | first_memblock_base); | ||
663 | ppc64_rma_size = min_t(u64, linear_sz, 0x40000000); | ||
664 | } else | ||
665 | #endif | ||
666 | ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000); | ||
610 | 667 | ||
611 | /* Finally limit subsequent allocations */ | 668 | /* Finally limit subsequent allocations */ |
612 | memblock_set_current_limit(first_memblock_base + ppc64_rma_size); | 669 | memblock_set_current_limit(first_memblock_base + ppc64_rma_size); |
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig index b5d87067a58b..8f9c3e245cff 100644 --- a/arch/powerpc/platforms/40x/Kconfig +++ b/arch/powerpc/platforms/40x/Kconfig | |||
@@ -32,14 +32,6 @@ config EP405 | |||
32 | help | 32 | help |
33 | This option enables support for the EP405/EP405PC boards. | 33 | This option enables support for the EP405/EP405PC boards. |
34 | 34 | ||
35 | config HCU4 | ||
36 | bool "Hcu4" | ||
37 | depends on 40x | ||
38 | default n | ||
39 | select 405GPR | ||
40 | help | ||
41 | This option enables support for the Nestal Maschinen HCU4 board. | ||
42 | |||
43 | config HOTFOOT | 35 | config HOTFOOT |
44 | bool "Hotfoot" | 36 | bool "Hotfoot" |
45 | depends on 40x | 37 | depends on 40x |
diff --git a/arch/powerpc/platforms/40x/Makefile b/arch/powerpc/platforms/40x/Makefile index 56e89004c468..88c22de0c850 100644 --- a/arch/powerpc/platforms/40x/Makefile +++ b/arch/powerpc/platforms/40x/Makefile | |||
@@ -1,4 +1,3 @@ | |||
1 | obj-$(CONFIG_HCU4) += hcu4.o | ||
2 | obj-$(CONFIG_WALNUT) += walnut.o | 1 | obj-$(CONFIG_WALNUT) += walnut.o |
3 | obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD) += virtex.o | 2 | obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD) += virtex.o |
4 | obj-$(CONFIG_EP405) += ep405.o | 3 | obj-$(CONFIG_EP405) += ep405.o |
diff --git a/arch/powerpc/platforms/40x/hcu4.c b/arch/powerpc/platforms/40x/hcu4.c deleted file mode 100644 index 60b2afecab75..000000000000 --- a/arch/powerpc/platforms/40x/hcu4.c +++ /dev/null | |||
@@ -1,61 +0,0 @@ | |||
1 | /* | ||
2 | * Architecture- / platform-specific boot-time initialization code for | ||
3 | * IBM PowerPC 4xx based boards. Adapted from original | ||
4 | * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek | ||
5 | * <dan@net4x.com>. | ||
6 | * | ||
7 | * Copyright(c) 1999-2000 Grant Erickson <grant@lcse.umn.edu> | ||
8 | * | ||
9 | * Rewritten and ported to the merged powerpc tree: | ||
10 | * Copyright 2007 IBM Corporation | ||
11 | * Josh Boyer <jwboyer@linux.vnet.ibm.com> | ||
12 | * | ||
13 | * 2002 (c) MontaVista, Software, Inc. This file is licensed under | ||
14 | * the terms of the GNU General Public License version 2. This program | ||
15 | * is licensed "as is" without any warranty of any kind, whether express | ||
16 | * or implied. | ||
17 | */ | ||
18 | |||
19 | #include <linux/init.h> | ||
20 | #include <linux/of_platform.h> | ||
21 | |||
22 | #include <asm/machdep.h> | ||
23 | #include <asm/prom.h> | ||
24 | #include <asm/udbg.h> | ||
25 | #include <asm/time.h> | ||
26 | #include <asm/uic.h> | ||
27 | #include <asm/ppc4xx.h> | ||
28 | |||
29 | static __initdata struct of_device_id hcu4_of_bus[] = { | ||
30 | { .compatible = "ibm,plb3", }, | ||
31 | { .compatible = "ibm,opb", }, | ||
32 | { .compatible = "ibm,ebc", }, | ||
33 | {}, | ||
34 | }; | ||
35 | |||
36 | static int __init hcu4_device_probe(void) | ||
37 | { | ||
38 | of_platform_bus_probe(NULL, hcu4_of_bus, NULL); | ||
39 | return 0; | ||
40 | } | ||
41 | machine_device_initcall(hcu4, hcu4_device_probe); | ||
42 | |||
43 | static int __init hcu4_probe(void) | ||
44 | { | ||
45 | unsigned long root = of_get_flat_dt_root(); | ||
46 | |||
47 | if (!of_flat_dt_is_compatible(root, "netstal,hcu4")) | ||
48 | return 0; | ||
49 | |||
50 | return 1; | ||
51 | } | ||
52 | |||
53 | define_machine(hcu4) { | ||
54 | .name = "HCU4", | ||
55 | .probe = hcu4_probe, | ||
56 | .progress = udbg_progress, | ||
57 | .init_IRQ = uic_init_tree, | ||
58 | .get_irq = uic_get_irq, | ||
59 | .restart = ppc4xx_reset_system, | ||
60 | .calibrate_decr = generic_calibrate_decr, | ||
61 | }; | ||
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig index 27b0651221d1..b3ebce1aec07 100644 --- a/arch/powerpc/platforms/512x/Kconfig +++ b/arch/powerpc/platforms/512x/Kconfig | |||
@@ -6,6 +6,7 @@ config PPC_MPC512x | |||
6 | select PPC_CLOCK | 6 | select PPC_CLOCK |
7 | select PPC_PCI_CHOICE | 7 | select PPC_PCI_CHOICE |
8 | select FSL_PCI if PCI | 8 | select FSL_PCI if PCI |
9 | select ARCH_WANT_OPTIONAL_GPIOLIB | ||
9 | 10 | ||
10 | config MPC5121_ADS | 11 | config MPC5121_ADS |
11 | bool "Freescale MPC5121E ADS" | 12 | bool "Freescale MPC5121E ADS" |
diff --git a/arch/powerpc/platforms/82xx/km82xx.c b/arch/powerpc/platforms/82xx/km82xx.c index 428c5e0a0e75..3661bcdc326a 100644 --- a/arch/powerpc/platforms/82xx/km82xx.c +++ b/arch/powerpc/platforms/82xx/km82xx.c | |||
@@ -49,6 +49,9 @@ struct cpm_pin { | |||
49 | }; | 49 | }; |
50 | 50 | ||
51 | static __initdata struct cpm_pin km82xx_pins[] = { | 51 | static __initdata struct cpm_pin km82xx_pins[] = { |
52 | /* SMC1 */ | ||
53 | {2, 4, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
54 | {2, 5, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, | ||
52 | 55 | ||
53 | /* SMC2 */ | 56 | /* SMC2 */ |
54 | {0, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | 57 | {0, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, |
@@ -137,6 +140,7 @@ static void __init init_ioports(void) | |||
137 | } | 140 | } |
138 | 141 | ||
139 | cpm2_smc_clk_setup(CPM_CLK_SMC2, CPM_BRG8); | 142 | cpm2_smc_clk_setup(CPM_CLK_SMC2, CPM_BRG8); |
143 | cpm2_smc_clk_setup(CPM_CLK_SMC1, CPM_BRG7); | ||
140 | cpm2_clk_setup(CPM_CLK_SCC1, CPM_CLK11, CPM_CLK_RX); | 144 | cpm2_clk_setup(CPM_CLK_SCC1, CPM_CLK11, CPM_CLK_RX); |
141 | cpm2_clk_setup(CPM_CLK_SCC1, CPM_CLK11, CPM_CLK_TX); | 145 | cpm2_clk_setup(CPM_CLK_SCC1, CPM_CLK11, CPM_CLK_TX); |
142 | cpm2_clk_setup(CPM_CLK_SCC3, CPM_CLK5, CPM_CLK_RTX); | 146 | cpm2_clk_setup(CPM_CLK_SCC3, CPM_CLK5, CPM_CLK_RTX); |
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig index 73f4135f3a1a..670a033264c0 100644 --- a/arch/powerpc/platforms/83xx/Kconfig +++ b/arch/powerpc/platforms/83xx/Kconfig | |||
@@ -114,18 +114,21 @@ config KMETER1 | |||
114 | 114 | ||
115 | endif | 115 | endif |
116 | 116 | ||
117 | # used for usb | 117 | # used for usb & gpio |
118 | config PPC_MPC831x | 118 | config PPC_MPC831x |
119 | bool | 119 | bool |
120 | select ARCH_WANT_OPTIONAL_GPIOLIB | ||
120 | 121 | ||
121 | # used for math-emu | 122 | # used for math-emu |
122 | config PPC_MPC832x | 123 | config PPC_MPC832x |
123 | bool | 124 | bool |
124 | 125 | ||
125 | # used for usb | 126 | # used for usb & gpio |
126 | config PPC_MPC834x | 127 | config PPC_MPC834x |
127 | bool | 128 | bool |
129 | select ARCH_WANT_OPTIONAL_GPIOLIB | ||
128 | 130 | ||
129 | # used for usb | 131 | # used for usb & gpio |
130 | config PPC_MPC837x | 132 | config PPC_MPC837x |
131 | bool | 133 | bool |
134 | select ARCH_WANT_OPTIONAL_GPIOLIB | ||
diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index 70798ac911ef..ef6537b8ed33 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/of.h> | 21 | #include <linux/of.h> |
22 | #include <linux/of_gpio.h> | 22 | #include <linux/of_gpio.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/kthread.h> | ||
25 | #include <linux/reboot.h> | ||
24 | #include <asm/prom.h> | 26 | #include <asm/prom.h> |
25 | #include <asm/machdep.h> | 27 | #include <asm/machdep.h> |
26 | 28 | ||
@@ -30,6 +32,7 @@ | |||
30 | */ | 32 | */ |
31 | #define MCU_REG_CTRL 0x20 | 33 | #define MCU_REG_CTRL 0x20 |
32 | #define MCU_CTRL_POFF 0x40 | 34 | #define MCU_CTRL_POFF 0x40 |
35 | #define MCU_CTRL_BTN 0x80 | ||
33 | 36 | ||
34 | #define MCU_NUM_GPIO 2 | 37 | #define MCU_NUM_GPIO 2 |
35 | 38 | ||
@@ -42,13 +45,55 @@ struct mcu { | |||
42 | 45 | ||
43 | static struct mcu *glob_mcu; | 46 | static struct mcu *glob_mcu; |
44 | 47 | ||
48 | struct task_struct *shutdown_thread; | ||
49 | static int shutdown_thread_fn(void *data) | ||
50 | { | ||
51 | int ret; | ||
52 | struct mcu *mcu = glob_mcu; | ||
53 | |||
54 | while (!kthread_should_stop()) { | ||
55 | ret = i2c_smbus_read_byte_data(mcu->client, MCU_REG_CTRL); | ||
56 | if (ret < 0) | ||
57 | pr_err("MCU status reg read failed.\n"); | ||
58 | mcu->reg_ctrl = ret; | ||
59 | |||
60 | |||
61 | if (mcu->reg_ctrl & MCU_CTRL_BTN) { | ||
62 | i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL, | ||
63 | mcu->reg_ctrl & ~MCU_CTRL_BTN); | ||
64 | |||
65 | ctrl_alt_del(); | ||
66 | } | ||
67 | |||
68 | set_current_state(TASK_INTERRUPTIBLE); | ||
69 | schedule_timeout(HZ); | ||
70 | } | ||
71 | |||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static ssize_t show_status(struct device *d, | ||
76 | struct device_attribute *attr, char *buf) | ||
77 | { | ||
78 | int ret; | ||
79 | struct mcu *mcu = glob_mcu; | ||
80 | |||
81 | ret = i2c_smbus_read_byte_data(mcu->client, MCU_REG_CTRL); | ||
82 | if (ret < 0) | ||
83 | return -ENODEV; | ||
84 | mcu->reg_ctrl = ret; | ||
85 | |||
86 | return sprintf(buf, "%02x\n", ret); | ||
87 | } | ||
88 | static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); | ||
89 | |||
45 | static void mcu_power_off(void) | 90 | static void mcu_power_off(void) |
46 | { | 91 | { |
47 | struct mcu *mcu = glob_mcu; | 92 | struct mcu *mcu = glob_mcu; |
48 | 93 | ||
49 | pr_info("Sending power-off request to the MCU...\n"); | 94 | pr_info("Sending power-off request to the MCU...\n"); |
50 | mutex_lock(&mcu->lock); | 95 | mutex_lock(&mcu->lock); |
51 | i2c_smbus_write_byte_data(glob_mcu->client, MCU_REG_CTRL, | 96 | i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL, |
52 | mcu->reg_ctrl | MCU_CTRL_POFF); | 97 | mcu->reg_ctrl | MCU_CTRL_POFF); |
53 | mutex_unlock(&mcu->lock); | 98 | mutex_unlock(&mcu->lock); |
54 | } | 99 | } |
@@ -130,6 +175,13 @@ static int __devinit mcu_probe(struct i2c_client *client, | |||
130 | dev_info(&client->dev, "will provide power-off service\n"); | 175 | dev_info(&client->dev, "will provide power-off service\n"); |
131 | } | 176 | } |
132 | 177 | ||
178 | if (device_create_file(&client->dev, &dev_attr_status)) | ||
179 | dev_err(&client->dev, | ||
180 | "couldn't create device file for status\n"); | ||
181 | |||
182 | shutdown_thread = kthread_run(shutdown_thread_fn, NULL, | ||
183 | "mcu-i2c-shdn"); | ||
184 | |||
133 | return 0; | 185 | return 0; |
134 | err: | 186 | err: |
135 | kfree(mcu); | 187 | kfree(mcu); |
@@ -141,6 +193,10 @@ static int __devexit mcu_remove(struct i2c_client *client) | |||
141 | struct mcu *mcu = i2c_get_clientdata(client); | 193 | struct mcu *mcu = i2c_get_clientdata(client); |
142 | int ret; | 194 | int ret; |
143 | 195 | ||
196 | kthread_stop(shutdown_thread); | ||
197 | |||
198 | device_remove_file(&client->dev, &dev_attr_status); | ||
199 | |||
144 | if (glob_mcu == mcu) { | 200 | if (glob_mcu == mcu) { |
145 | ppc_md.power_off = NULL; | 201 | ppc_md.power_off = NULL; |
146 | glob_mcu = NULL; | 202 | glob_mcu = NULL; |
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index 12f5932dadc9..45023e26aea3 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig | |||
@@ -171,17 +171,18 @@ config SBC8560 | |||
171 | help | 171 | help |
172 | This option enables support for the Wind River SBC8560 board | 172 | This option enables support for the Wind River SBC8560 board |
173 | 173 | ||
174 | config P2040_RDB | 174 | config P2041_RDB |
175 | bool "Freescale P2040 RDB" | 175 | bool "Freescale P2041 RDB" |
176 | select DEFAULT_UIMAGE | 176 | select DEFAULT_UIMAGE |
177 | select PPC_E500MC | 177 | select PPC_E500MC |
178 | select PHYS_64BIT | 178 | select PHYS_64BIT |
179 | select SWIOTLB | 179 | select SWIOTLB |
180 | select MPC8xxx_GPIO | 180 | select ARCH_REQUIRE_GPIOLIB |
181 | select GPIO_MPC8XXX | ||
181 | select HAS_RAPIDIO | 182 | select HAS_RAPIDIO |
182 | select PPC_EPAPR_HV_PIC | 183 | select PPC_EPAPR_HV_PIC |
183 | help | 184 | help |
184 | This option enables support for the P2040 RDB board | 185 | This option enables support for the P2041 RDB board |
185 | 186 | ||
186 | config P3041_DS | 187 | config P3041_DS |
187 | bool "Freescale P3041 DS" | 188 | bool "Freescale P3041 DS" |
@@ -189,19 +190,33 @@ config P3041_DS | |||
189 | select PPC_E500MC | 190 | select PPC_E500MC |
190 | select PHYS_64BIT | 191 | select PHYS_64BIT |
191 | select SWIOTLB | 192 | select SWIOTLB |
192 | select MPC8xxx_GPIO | 193 | select ARCH_REQUIRE_GPIOLIB |
194 | select GPIO_MPC8XXX | ||
193 | select HAS_RAPIDIO | 195 | select HAS_RAPIDIO |
194 | select PPC_EPAPR_HV_PIC | 196 | select PPC_EPAPR_HV_PIC |
195 | help | 197 | help |
196 | This option enables support for the P3041 DS board | 198 | This option enables support for the P3041 DS board |
197 | 199 | ||
200 | config P3060_QDS | ||
201 | bool "Freescale P3060 QDS" | ||
202 | select DEFAULT_UIMAGE | ||
203 | select PPC_E500MC | ||
204 | select PHYS_64BIT | ||
205 | select SWIOTLB | ||
206 | select MPC8xxx_GPIO | ||
207 | select HAS_RAPIDIO | ||
208 | select PPC_EPAPR_HV_PIC | ||
209 | help | ||
210 | This option enables support for the P3060 QDS board | ||
211 | |||
198 | config P4080_DS | 212 | config P4080_DS |
199 | bool "Freescale P4080 DS" | 213 | bool "Freescale P4080 DS" |
200 | select DEFAULT_UIMAGE | 214 | select DEFAULT_UIMAGE |
201 | select PPC_E500MC | 215 | select PPC_E500MC |
202 | select PHYS_64BIT | 216 | select PHYS_64BIT |
203 | select SWIOTLB | 217 | select SWIOTLB |
204 | select MPC8xxx_GPIO | 218 | select ARCH_REQUIRE_GPIOLIB |
219 | select GPIO_MPC8XXX | ||
205 | select HAS_RAPIDIO | 220 | select HAS_RAPIDIO |
206 | select PPC_EPAPR_HV_PIC | 221 | select PPC_EPAPR_HV_PIC |
207 | help | 222 | help |
@@ -216,7 +231,8 @@ config P5020_DS | |||
216 | select PPC_E500MC | 231 | select PPC_E500MC |
217 | select PHYS_64BIT | 232 | select PHYS_64BIT |
218 | select SWIOTLB | 233 | select SWIOTLB |
219 | select MPC8xxx_GPIO | 234 | select ARCH_REQUIRE_GPIOLIB |
235 | select GPIO_MPC8XXX | ||
220 | select HAS_RAPIDIO | 236 | select HAS_RAPIDIO |
221 | select PPC_EPAPR_HV_PIC | 237 | select PPC_EPAPR_HV_PIC |
222 | help | 238 | help |
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index a971b32c5c0a..bc5acb95917a 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile | |||
@@ -13,8 +13,9 @@ obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o | |||
13 | obj-$(CONFIG_P1010_RDB) += p1010rdb.o | 13 | obj-$(CONFIG_P1010_RDB) += p1010rdb.o |
14 | obj-$(CONFIG_P1022_DS) += p1022_ds.o | 14 | obj-$(CONFIG_P1022_DS) += p1022_ds.o |
15 | obj-$(CONFIG_P1023_RDS) += p1023_rds.o | 15 | obj-$(CONFIG_P1023_RDS) += p1023_rds.o |
16 | obj-$(CONFIG_P2040_RDB) += p2040_rdb.o corenet_ds.o | 16 | obj-$(CONFIG_P2041_RDB) += p2041_rdb.o corenet_ds.o |
17 | obj-$(CONFIG_P3041_DS) += p3041_ds.o corenet_ds.o | 17 | obj-$(CONFIG_P3041_DS) += p3041_ds.o corenet_ds.o |
18 | obj-$(CONFIG_P3060_QDS) += p3060_qds.o corenet_ds.o | ||
18 | obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o | 19 | obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o |
19 | obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o | 20 | obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o |
20 | obj-$(CONFIG_STX_GP3) += stx_gp3.o | 21 | obj-$(CONFIG_STX_GP3) += stx_gp3.o |
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index c01c7277888c..fda15716fada 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c | |||
@@ -129,17 +129,20 @@ static void p1022ds_set_gamma_table(enum fsl_diu_monitor_port port, | |||
129 | */ | 129 | */ |
130 | static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port) | 130 | static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port) |
131 | { | 131 | { |
132 | struct device_node *pixis_node; | 132 | struct device_node *np; |
133 | void __iomem *pixis; | 133 | void __iomem *pixis; |
134 | u8 __iomem *brdcfg1; | 134 | u8 __iomem *brdcfg1; |
135 | 135 | ||
136 | pixis_node = of_find_compatible_node(NULL, NULL, "fsl,p1022ds-pixis"); | 136 | np = of_find_compatible_node(NULL, NULL, "fsl,p1022ds-fpga"); |
137 | if (!pixis_node) { | 137 | if (!np) |
138 | /* older device trees used "fsl,p1022ds-pixis" */ | ||
139 | np = of_find_compatible_node(NULL, NULL, "fsl,p1022ds-pixis"); | ||
140 | if (!np) { | ||
138 | pr_err("p1022ds: missing ngPIXIS node\n"); | 141 | pr_err("p1022ds: missing ngPIXIS node\n"); |
139 | return; | 142 | return; |
140 | } | 143 | } |
141 | 144 | ||
142 | pixis = of_iomap(pixis_node, 0); | 145 | pixis = of_iomap(np, 0); |
143 | if (!pixis) { | 146 | if (!pixis) { |
144 | pr_err("p1022ds: could not map ngPIXIS registers\n"); | 147 | pr_err("p1022ds: could not map ngPIXIS registers\n"); |
145 | return; | 148 | return; |
diff --git a/arch/powerpc/platforms/85xx/p2040_rdb.c b/arch/powerpc/platforms/85xx/p2041_rdb.c index 32b56ac73dfb..eda6ed5683e1 100644 --- a/arch/powerpc/platforms/85xx/p2040_rdb.c +++ b/arch/powerpc/platforms/85xx/p2041_rdb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * P2040 RDB Setup | 2 | * P2041 RDB Setup |
3 | * | 3 | * |
4 | * Copyright 2011 Freescale Semiconductor Inc. | 4 | * Copyright 2011 Freescale Semiconductor Inc. |
5 | * | 5 | * |
@@ -35,18 +35,18 @@ | |||
35 | /* | 35 | /* |
36 | * Called very early, device-tree isn't unflattened | 36 | * Called very early, device-tree isn't unflattened |
37 | */ | 37 | */ |
38 | static int __init p2040_rdb_probe(void) | 38 | static int __init p2041_rdb_probe(void) |
39 | { | 39 | { |
40 | unsigned long root = of_get_flat_dt_root(); | 40 | unsigned long root = of_get_flat_dt_root(); |
41 | #ifdef CONFIG_SMP | 41 | #ifdef CONFIG_SMP |
42 | extern struct smp_ops_t smp_85xx_ops; | 42 | extern struct smp_ops_t smp_85xx_ops; |
43 | #endif | 43 | #endif |
44 | 44 | ||
45 | if (of_flat_dt_is_compatible(root, "fsl,P2040RDB")) | 45 | if (of_flat_dt_is_compatible(root, "fsl,P2041RDB")) |
46 | return 1; | 46 | return 1; |
47 | 47 | ||
48 | /* Check if we're running under the Freescale hypervisor */ | 48 | /* Check if we're running under the Freescale hypervisor */ |
49 | if (of_flat_dt_is_compatible(root, "fsl,P2040RDB-hv")) { | 49 | if (of_flat_dt_is_compatible(root, "fsl,P2041RDB-hv")) { |
50 | ppc_md.init_IRQ = ehv_pic_init; | 50 | ppc_md.init_IRQ = ehv_pic_init; |
51 | ppc_md.get_irq = ehv_pic_get_irq; | 51 | ppc_md.get_irq = ehv_pic_get_irq; |
52 | ppc_md.restart = fsl_hv_restart; | 52 | ppc_md.restart = fsl_hv_restart; |
@@ -66,9 +66,9 @@ static int __init p2040_rdb_probe(void) | |||
66 | return 0; | 66 | return 0; |
67 | } | 67 | } |
68 | 68 | ||
69 | define_machine(p2040_rdb) { | 69 | define_machine(p2041_rdb) { |
70 | .name = "P2040 RDB", | 70 | .name = "P2041 RDB", |
71 | .probe = p2040_rdb_probe, | 71 | .probe = p2041_rdb_probe, |
72 | .setup_arch = corenet_ds_setup_arch, | 72 | .setup_arch = corenet_ds_setup_arch, |
73 | .init_IRQ = corenet_ds_pic_init, | 73 | .init_IRQ = corenet_ds_pic_init, |
74 | #ifdef CONFIG_PCI | 74 | #ifdef CONFIG_PCI |
@@ -81,8 +81,8 @@ define_machine(p2040_rdb) { | |||
81 | .power_save = e500_idle, | 81 | .power_save = e500_idle, |
82 | }; | 82 | }; |
83 | 83 | ||
84 | machine_device_initcall(p2040_rdb, corenet_ds_publish_devices); | 84 | machine_device_initcall(p2041_rdb, corenet_ds_publish_devices); |
85 | 85 | ||
86 | #ifdef CONFIG_SWIOTLB | 86 | #ifdef CONFIG_SWIOTLB |
87 | machine_arch_initcall(p2040_rdb, swiotlb_setup_bus_notifier); | 87 | machine_arch_initcall(p2041_rdb, swiotlb_setup_bus_notifier); |
88 | #endif | 88 | #endif |
diff --git a/arch/powerpc/platforms/85xx/p3060_qds.c b/arch/powerpc/platforms/85xx/p3060_qds.c new file mode 100644 index 000000000000..01dcf44871e9 --- /dev/null +++ b/arch/powerpc/platforms/85xx/p3060_qds.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * P3060 QDS Setup | ||
3 | * | ||
4 | * Copyright 2011 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/phy.h> | ||
15 | #include <asm/machdep.h> | ||
16 | #include <asm/udbg.h> | ||
17 | #include <asm/mpic.h> | ||
18 | #include <linux/of_platform.h> | ||
19 | #include <sysdev/fsl_soc.h> | ||
20 | #include <sysdev/fsl_pci.h> | ||
21 | #include <asm/ehv_pic.h> | ||
22 | #include "corenet_ds.h" | ||
23 | |||
24 | /* | ||
25 | * Called very early, device-tree isn't unflattened | ||
26 | */ | ||
27 | static int __init p3060_qds_probe(void) | ||
28 | { | ||
29 | unsigned long root = of_get_flat_dt_root(); | ||
30 | #ifdef CONFIG_SMP | ||
31 | extern struct smp_ops_t smp_85xx_ops; | ||
32 | #endif | ||
33 | |||
34 | if (of_flat_dt_is_compatible(root, "fsl,P3060QDS")) | ||
35 | return 1; | ||
36 | |||
37 | /* Check if we're running under the Freescale hypervisor */ | ||
38 | if (of_flat_dt_is_compatible(root, "fsl,P3060QDS-hv")) { | ||
39 | ppc_md.init_IRQ = ehv_pic_init; | ||
40 | ppc_md.get_irq = ehv_pic_get_irq; | ||
41 | ppc_md.restart = fsl_hv_restart; | ||
42 | ppc_md.power_off = fsl_hv_halt; | ||
43 | ppc_md.halt = fsl_hv_halt; | ||
44 | #ifdef CONFIG_SMP | ||
45 | /* | ||
46 | * Disable the timebase sync operations because we can't write | ||
47 | * to the timebase registers under the hypervisor. | ||
48 | */ | ||
49 | smp_85xx_ops.give_timebase = NULL; | ||
50 | smp_85xx_ops.take_timebase = NULL; | ||
51 | #endif | ||
52 | return 1; | ||
53 | } | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | define_machine(p3060_qds) { | ||
59 | .name = "P3060 QDS", | ||
60 | .probe = p3060_qds_probe, | ||
61 | .setup_arch = corenet_ds_setup_arch, | ||
62 | .init_IRQ = corenet_ds_pic_init, | ||
63 | #ifdef CONFIG_PCI | ||
64 | .pcibios_fixup_bus = fsl_pcibios_fixup_bus, | ||
65 | #endif | ||
66 | .get_irq = mpic_get_coreint_irq, | ||
67 | .restart = fsl_rstcr_restart, | ||
68 | .calibrate_decr = generic_calibrate_decr, | ||
69 | .progress = udbg_progress, | ||
70 | .power_save = e500_idle, | ||
71 | }; | ||
72 | |||
73 | machine_device_initcall(p3060_qds, declare_of_platform_devices); | ||
74 | |||
75 | #ifdef CONFIG_SWIOTLB | ||
76 | machine_arch_initcall(p3060_qds, swiotlb_setup_bus_notifier); | ||
77 | #endif | ||
diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c index 09ced7221750..cebd786dc334 100644 --- a/arch/powerpc/platforms/85xx/sbc8560.c +++ b/arch/powerpc/platforms/85xx/sbc8560.c | |||
@@ -283,7 +283,7 @@ static int __init sbc8560_bdrstcr_init(void) | |||
283 | 283 | ||
284 | of_address_to_resource(np, 0, &res); | 284 | of_address_to_resource(np, 0, &res); |
285 | 285 | ||
286 | printk(KERN_INFO "sbc8560: Found BRSTCR at i/o 0x%x\n", res.start); | 286 | printk(KERN_INFO "sbc8560: Found BRSTCR at %pR\n", &res); |
287 | 287 | ||
288 | brstcr = ioremap(res.start, resource_size(&res)); | 288 | brstcr = ioremap(res.start, resource_size(&res)); |
289 | if(!brstcr) | 289 | if(!brstcr) |
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 5b9b901f6443..2df4785ffd4e 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c | |||
@@ -48,10 +48,11 @@ smp_85xx_kick_cpu(int nr) | |||
48 | const u64 *cpu_rel_addr; | 48 | const u64 *cpu_rel_addr; |
49 | __iomem u32 *bptr_vaddr; | 49 | __iomem u32 *bptr_vaddr; |
50 | struct device_node *np; | 50 | struct device_node *np; |
51 | int n = 0; | 51 | int n = 0, hw_cpu = get_hard_smp_processor_id(nr); |
52 | int ioremappable; | 52 | int ioremappable; |
53 | 53 | ||
54 | WARN_ON (nr < 0 || nr >= NR_CPUS); | 54 | WARN_ON(nr < 0 || nr >= NR_CPUS); |
55 | WARN_ON(hw_cpu < 0 || hw_cpu >= NR_CPUS); | ||
55 | 56 | ||
56 | pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr); | 57 | pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr); |
57 | 58 | ||
@@ -79,7 +80,7 @@ smp_85xx_kick_cpu(int nr) | |||
79 | 80 | ||
80 | local_irq_save(flags); | 81 | local_irq_save(flags); |
81 | 82 | ||
82 | out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr); | 83 | out_be32(bptr_vaddr + BOOT_ENTRY_PIR, hw_cpu); |
83 | #ifdef CONFIG_PPC32 | 84 | #ifdef CONFIG_PPC32 |
84 | out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start)); | 85 | out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start)); |
85 | 86 | ||
@@ -88,7 +89,7 @@ smp_85xx_kick_cpu(int nr) | |||
88 | (ulong)(bptr_vaddr + SIZE_BOOT_ENTRY)); | 89 | (ulong)(bptr_vaddr + SIZE_BOOT_ENTRY)); |
89 | 90 | ||
90 | /* Wait a bit for the CPU to ack. */ | 91 | /* Wait a bit for the CPU to ack. */ |
91 | while ((__secondary_hold_acknowledge != nr) && (++n < 1000)) | 92 | while ((__secondary_hold_acknowledge != hw_cpu) && (++n < 1000)) |
92 | mdelay(1); | 93 | mdelay(1); |
93 | #else | 94 | #else |
94 | smp_generic_kick_cpu(nr); | 95 | smp_generic_kick_cpu(nr); |
@@ -206,7 +207,7 @@ static void mpc85xx_smp_machine_kexec(struct kimage *image) | |||
206 | if ( !timeout ) | 207 | if ( !timeout ) |
207 | printk(KERN_ERR "Unable to bring down secondary cpu(s)"); | 208 | printk(KERN_ERR "Unable to bring down secondary cpu(s)"); |
208 | 209 | ||
209 | for (i = 0; i < num_cpus; i++) | 210 | for_each_online_cpu(i) |
210 | { | 211 | { |
211 | if ( i == smp_processor_id() ) continue; | 212 | if ( i == smp_processor_id() ) continue; |
212 | mpic_reset_core(i); | 213 | mpic_reset_core(i); |
@@ -243,6 +244,7 @@ void __init mpc85xx_smp_init(void) | |||
243 | * If left NULL, .message_pass defaults to | 244 | * If left NULL, .message_pass defaults to |
244 | * smp_muxed_ipi_message_pass | 245 | * smp_muxed_ipi_message_pass |
245 | */ | 246 | */ |
247 | smp_85xx_ops.message_pass = NULL; | ||
246 | smp_85xx_ops.cause_ipi = doorbell_cause_ipi; | 248 | smp_85xx_ops.cause_ipi = doorbell_cause_ipi; |
247 | } | 249 | } |
248 | 250 | ||
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig index a0b5638c5dc8..8d6599d54ea6 100644 --- a/arch/powerpc/platforms/86xx/Kconfig +++ b/arch/powerpc/platforms/86xx/Kconfig | |||
@@ -4,6 +4,7 @@ menuconfig PPC_86xx | |||
4 | depends on 6xx | 4 | depends on 6xx |
5 | select FSL_SOC | 5 | select FSL_SOC |
6 | select ALTIVEC | 6 | select ALTIVEC |
7 | select ARCH_WANT_OPTIONAL_GPIOLIB | ||
7 | help | 8 | help |
8 | The Freescale E600 SoCs have 74xx cores. | 9 | The Freescale E600 SoCs have 74xx cores. |
9 | 10 | ||
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index b9ba86191aed..e4588721ef34 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | menu "Platform support" | 1 | menu "Platform support" |
2 | 2 | ||
3 | source "arch/powerpc/platforms/powernv/Kconfig" | ||
3 | source "arch/powerpc/platforms/pseries/Kconfig" | 4 | source "arch/powerpc/platforms/pseries/Kconfig" |
4 | source "arch/powerpc/platforms/iseries/Kconfig" | 5 | source "arch/powerpc/platforms/iseries/Kconfig" |
5 | source "arch/powerpc/platforms/chrp/Kconfig" | 6 | source "arch/powerpc/platforms/chrp/Kconfig" |
@@ -333,16 +334,6 @@ config OF_RTC | |||
333 | 334 | ||
334 | source "arch/powerpc/sysdev/bestcomm/Kconfig" | 335 | source "arch/powerpc/sysdev/bestcomm/Kconfig" |
335 | 336 | ||
336 | config MPC8xxx_GPIO | ||
337 | bool "MPC512x/MPC8xxx GPIO support" | ||
338 | depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \ | ||
339 | FSL_SOC_BOOKE || PPC_86xx | ||
340 | select GENERIC_GPIO | ||
341 | select ARCH_REQUIRE_GPIOLIB | ||
342 | help | ||
343 | Say Y here if you're going to use hardware that connects to the | ||
344 | MPC512x/831x/834x/837x/8572/8610 GPIOs. | ||
345 | |||
346 | config SIMPLE_GPIO | 337 | config SIMPLE_GPIO |
347 | bool "Support for simple, memory-mapped GPIO controllers" | 338 | bool "Support for simple, memory-mapped GPIO controllers" |
348 | depends on PPC | 339 | depends on PPC |
@@ -355,7 +346,7 @@ config SIMPLE_GPIO | |||
355 | on-board peripherals. | 346 | on-board peripherals. |
356 | 347 | ||
357 | config MCU_MPC8349EMITX | 348 | config MCU_MPC8349EMITX |
358 | tristate "MPC8349E-mITX MCU driver" | 349 | bool "MPC8349E-mITX MCU driver" |
359 | depends on I2C && PPC_83xx | 350 | depends on I2C && PPC_83xx |
360 | select GENERIC_GPIO | 351 | select GENERIC_GPIO |
361 | select ARCH_REQUIRE_GPIOLIB | 352 | select ARCH_REQUIRE_GPIOLIB |
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index e06e39589a09..a85990c886e9 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype | |||
@@ -69,6 +69,7 @@ config PPC_BOOK3S_64 | |||
69 | bool "Server processors" | 69 | bool "Server processors" |
70 | select PPC_FPU | 70 | select PPC_FPU |
71 | select PPC_HAVE_PMU_SUPPORT | 71 | select PPC_HAVE_PMU_SUPPORT |
72 | select SYS_SUPPORTS_HUGETLBFS | ||
72 | 73 | ||
73 | config PPC_BOOK3E_64 | 74 | config PPC_BOOK3E_64 |
74 | bool "Embedded processors" | 75 | bool "Embedded processors" |
@@ -173,6 +174,7 @@ config BOOKE | |||
173 | config FSL_BOOKE | 174 | config FSL_BOOKE |
174 | bool | 175 | bool |
175 | depends on (E200 || E500) && PPC32 | 176 | depends on (E200 || E500) && PPC32 |
177 | select SYS_SUPPORTS_HUGETLBFS if PHYS_64BIT | ||
176 | default y | 178 | default y |
177 | 179 | ||
178 | # this is for common code between PPC32 & PPC64 FSL BOOKE | 180 | # this is for common code between PPC32 & PPC64 FSL BOOKE |
@@ -296,7 +298,7 @@ config PPC_BOOK3E_MMU | |||
296 | 298 | ||
297 | config PPC_MM_SLICES | 299 | config PPC_MM_SLICES |
298 | bool | 300 | bool |
299 | default y if HUGETLB_PAGE || (PPC_STD_MMU_64 && PPC_64K_PAGES) | 301 | default y if (PPC64 && HUGETLB_PAGE) || (PPC_STD_MMU_64 && PPC_64K_PAGES) |
300 | default n | 302 | default n |
301 | 303 | ||
302 | config VIRT_CPU_ACCOUNTING | 304 | config VIRT_CPU_ACCOUNTING |
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 73e2116cfeed..2635a22bade2 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile | |||
@@ -14,6 +14,7 @@ obj-$(CONFIG_PPC_82xx) += 82xx/ | |||
14 | obj-$(CONFIG_PPC_83xx) += 83xx/ | 14 | obj-$(CONFIG_PPC_83xx) += 83xx/ |
15 | obj-$(CONFIG_FSL_SOC_BOOKE) += 85xx/ | 15 | obj-$(CONFIG_FSL_SOC_BOOKE) += 85xx/ |
16 | obj-$(CONFIG_PPC_86xx) += 86xx/ | 16 | obj-$(CONFIG_PPC_86xx) += 86xx/ |
17 | obj-$(CONFIG_PPC_POWERNV) += powernv/ | ||
17 | obj-$(CONFIG_PPC_PSERIES) += pseries/ | 18 | obj-$(CONFIG_PPC_PSERIES) += pseries/ |
18 | obj-$(CONFIG_PPC_ISERIES) += iseries/ | 19 | obj-$(CONFIG_PPC_ISERIES) += iseries/ |
19 | obj-$(CONFIG_PPC_MAPLE) += maple/ | 20 | obj-$(CONFIG_PPC_MAPLE) += maple/ |
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 26a067122a54..fc46fcac3921 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
@@ -1159,6 +1159,26 @@ static int __init setup_iommu_fixed(char *str) | |||
1159 | } | 1159 | } |
1160 | __setup("iommu_fixed=", setup_iommu_fixed); | 1160 | __setup("iommu_fixed=", setup_iommu_fixed); |
1161 | 1161 | ||
1162 | static u64 cell_dma_get_required_mask(struct device *dev) | ||
1163 | { | ||
1164 | struct dma_map_ops *dma_ops; | ||
1165 | |||
1166 | if (!dev->dma_mask) | ||
1167 | return 0; | ||
1168 | |||
1169 | if (!iommu_fixed_disabled && | ||
1170 | cell_iommu_get_fixed_address(dev) != OF_BAD_ADDR) | ||
1171 | return DMA_BIT_MASK(64); | ||
1172 | |||
1173 | dma_ops = get_dma_ops(dev); | ||
1174 | if (dma_ops->get_required_mask) | ||
1175 | return dma_ops->get_required_mask(dev); | ||
1176 | |||
1177 | WARN_ONCE(1, "no get_required_mask in %p ops", dma_ops); | ||
1178 | |||
1179 | return DMA_BIT_MASK(64); | ||
1180 | } | ||
1181 | |||
1162 | static int __init cell_iommu_init(void) | 1182 | static int __init cell_iommu_init(void) |
1163 | { | 1183 | { |
1164 | struct device_node *np; | 1184 | struct device_node *np; |
@@ -1175,6 +1195,7 @@ static int __init cell_iommu_init(void) | |||
1175 | 1195 | ||
1176 | /* Setup various ppc_md. callbacks */ | 1196 | /* Setup various ppc_md. callbacks */ |
1177 | ppc_md.pci_dma_dev_setup = cell_pci_dma_dev_setup; | 1197 | ppc_md.pci_dma_dev_setup = cell_pci_dma_dev_setup; |
1198 | ppc_md.dma_get_required_mask = cell_dma_get_required_mask; | ||
1178 | ppc_md.tce_build = tce_build_cell; | 1199 | ppc_md.tce_build = tce_build_cell; |
1179 | ppc_md.tce_free = tce_free_cell; | 1200 | ppc_md.tce_free = tce_free_cell; |
1180 | 1201 | ||
diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig new file mode 100644 index 000000000000..74fea5c21839 --- /dev/null +++ b/arch/powerpc/platforms/powernv/Kconfig | |||
@@ -0,0 +1,16 @@ | |||
1 | config PPC_POWERNV | ||
2 | depends on PPC64 && PPC_BOOK3S | ||
3 | bool "IBM PowerNV (Non-Virtualized) platform support" | ||
4 | select PPC_NATIVE | ||
5 | select PPC_XICS | ||
6 | select PPC_ICP_NATIVE | ||
7 | select PPC_P7_NAP | ||
8 | select PPC_PCI_CHOICE if EMBEDDED | ||
9 | default y | ||
10 | |||
11 | config PPC_POWERNV_RTAS | ||
12 | depends on PPC_POWERNV | ||
13 | bool "Support for RTAS based PowerNV platforms such as BML" | ||
14 | default y | ||
15 | select PPC_ICS_RTAS | ||
16 | select PPC_RTAS | ||
diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile new file mode 100644 index 000000000000..31853008b418 --- /dev/null +++ b/arch/powerpc/platforms/powernv/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | obj-y += setup.o opal-takeover.o opal-wrappers.o opal.o | ||
2 | obj-y += opal-rtc.o opal-nvram.o | ||
3 | |||
4 | obj-$(CONFIG_SMP) += smp.o | ||
5 | obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o | ||
diff --git a/arch/powerpc/platforms/powernv/opal-nvram.c b/arch/powerpc/platforms/powernv/opal-nvram.c new file mode 100644 index 000000000000..3f83e1ae26ac --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-nvram.c | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | * PowerNV nvram code. | ||
3 | * | ||
4 | * Copyright 2011 IBM Corp. | ||
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 | #define DEBUG | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/of.h> | ||
17 | |||
18 | #include <asm/opal.h> | ||
19 | #include <asm/machdep.h> | ||
20 | |||
21 | static unsigned int nvram_size; | ||
22 | |||
23 | static ssize_t opal_nvram_size(void) | ||
24 | { | ||
25 | return nvram_size; | ||
26 | } | ||
27 | |||
28 | static ssize_t opal_nvram_read(char *buf, size_t count, loff_t *index) | ||
29 | { | ||
30 | s64 rc; | ||
31 | int off; | ||
32 | |||
33 | if (*index >= nvram_size) | ||
34 | return 0; | ||
35 | off = *index; | ||
36 | if ((off + count) > nvram_size) | ||
37 | count = nvram_size - off; | ||
38 | rc = opal_read_nvram(__pa(buf), count, off); | ||
39 | if (rc != OPAL_SUCCESS) | ||
40 | return -EIO; | ||
41 | *index += count; | ||
42 | return count; | ||
43 | } | ||
44 | |||
45 | static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index) | ||
46 | { | ||
47 | s64 rc = OPAL_BUSY; | ||
48 | int off; | ||
49 | |||
50 | if (*index >= nvram_size) | ||
51 | return 0; | ||
52 | off = *index; | ||
53 | if ((off + count) > nvram_size) | ||
54 | count = nvram_size - off; | ||
55 | |||
56 | while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { | ||
57 | rc = opal_write_nvram(__pa(buf), count, off); | ||
58 | if (rc == OPAL_BUSY_EVENT) | ||
59 | opal_poll_events(NULL); | ||
60 | } | ||
61 | *index += count; | ||
62 | return count; | ||
63 | } | ||
64 | |||
65 | void __init opal_nvram_init(void) | ||
66 | { | ||
67 | struct device_node *np; | ||
68 | const u32 *nbytes_p; | ||
69 | |||
70 | np = of_find_compatible_node(NULL, NULL, "ibm,opal-nvram"); | ||
71 | if (np == NULL) | ||
72 | return; | ||
73 | |||
74 | nbytes_p = of_get_property(np, "#bytes", NULL); | ||
75 | if (!nbytes_p) { | ||
76 | of_node_put(np); | ||
77 | return; | ||
78 | } | ||
79 | nvram_size = *nbytes_p; | ||
80 | |||
81 | printk(KERN_INFO "OPAL nvram setup, %u bytes\n", nvram_size); | ||
82 | of_node_put(np); | ||
83 | |||
84 | ppc_md.nvram_read = opal_nvram_read; | ||
85 | ppc_md.nvram_write = opal_nvram_write; | ||
86 | ppc_md.nvram_size = opal_nvram_size; | ||
87 | } | ||
88 | |||
diff --git a/arch/powerpc/platforms/powernv/opal-rtc.c b/arch/powerpc/platforms/powernv/opal-rtc.c new file mode 100644 index 000000000000..2aa7641aac9b --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-rtc.c | |||
@@ -0,0 +1,97 @@ | |||
1 | /* | ||
2 | * PowerNV Real Time Clock. | ||
3 | * | ||
4 | * Copyright 2011 IBM Corp. | ||
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 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/time.h> | ||
15 | #include <linux/bcd.h> | ||
16 | #include <linux/rtc.h> | ||
17 | #include <linux/delay.h> | ||
18 | |||
19 | #include <asm/opal.h> | ||
20 | #include <asm/firmware.h> | ||
21 | |||
22 | static void opal_to_tm(u32 y_m_d, u64 h_m_s_ms, struct rtc_time *tm) | ||
23 | { | ||
24 | tm->tm_year = ((bcd2bin(y_m_d >> 24) * 100) + | ||
25 | bcd2bin((y_m_d >> 16) & 0xff)) - 1900; | ||
26 | tm->tm_mon = bcd2bin((y_m_d >> 8) & 0xff) - 1; | ||
27 | tm->tm_mday = bcd2bin(y_m_d & 0xff); | ||
28 | tm->tm_hour = bcd2bin((h_m_s_ms >> 56) & 0xff); | ||
29 | tm->tm_min = bcd2bin((h_m_s_ms >> 48) & 0xff); | ||
30 | tm->tm_sec = bcd2bin((h_m_s_ms >> 40) & 0xff); | ||
31 | |||
32 | GregorianDay(tm); | ||
33 | } | ||
34 | |||
35 | unsigned long __init opal_get_boot_time(void) | ||
36 | { | ||
37 | struct rtc_time tm; | ||
38 | u32 y_m_d; | ||
39 | u64 h_m_s_ms; | ||
40 | long rc = OPAL_BUSY; | ||
41 | |||
42 | while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { | ||
43 | rc = opal_rtc_read(&y_m_d, &h_m_s_ms); | ||
44 | if (rc == OPAL_BUSY_EVENT) | ||
45 | opal_poll_events(NULL); | ||
46 | else | ||
47 | mdelay(10); | ||
48 | } | ||
49 | if (rc != OPAL_SUCCESS) | ||
50 | return 0; | ||
51 | opal_to_tm(y_m_d, h_m_s_ms, &tm); | ||
52 | return mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, | ||
53 | tm.tm_hour, tm.tm_min, tm.tm_sec); | ||
54 | } | ||
55 | |||
56 | void opal_get_rtc_time(struct rtc_time *tm) | ||
57 | { | ||
58 | long rc = OPAL_BUSY; | ||
59 | u32 y_m_d; | ||
60 | u64 h_m_s_ms; | ||
61 | |||
62 | while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { | ||
63 | rc = opal_rtc_read(&y_m_d, &h_m_s_ms); | ||
64 | if (rc == OPAL_BUSY_EVENT) | ||
65 | opal_poll_events(NULL); | ||
66 | else | ||
67 | mdelay(10); | ||
68 | } | ||
69 | if (rc != OPAL_SUCCESS) | ||
70 | return; | ||
71 | opal_to_tm(y_m_d, h_m_s_ms, tm); | ||
72 | } | ||
73 | |||
74 | int opal_set_rtc_time(struct rtc_time *tm) | ||
75 | { | ||
76 | long rc = OPAL_BUSY; | ||
77 | u32 y_m_d = 0; | ||
78 | u64 h_m_s_ms = 0; | ||
79 | |||
80 | y_m_d |= ((u32)bin2bcd((tm->tm_year + 1900) / 100)) << 24; | ||
81 | y_m_d |= ((u32)bin2bcd((tm->tm_year + 1900) % 100)) << 16; | ||
82 | y_m_d |= ((u32)bin2bcd((tm->tm_mon + 1))) << 8; | ||
83 | y_m_d |= ((u32)bin2bcd(tm->tm_mday)); | ||
84 | |||
85 | h_m_s_ms |= ((u64)bin2bcd(tm->tm_hour)) << 56; | ||
86 | h_m_s_ms |= ((u64)bin2bcd(tm->tm_min)) << 48; | ||
87 | h_m_s_ms |= ((u64)bin2bcd(tm->tm_sec)) << 40; | ||
88 | |||
89 | while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { | ||
90 | rc = opal_rtc_write(y_m_d, h_m_s_ms); | ||
91 | if (rc == OPAL_BUSY_EVENT) | ||
92 | opal_poll_events(NULL); | ||
93 | else | ||
94 | mdelay(10); | ||
95 | } | ||
96 | return rc == OPAL_SUCCESS ? 0 : -EIO; | ||
97 | } | ||
diff --git a/arch/powerpc/platforms/powernv/opal-takeover.S b/arch/powerpc/platforms/powernv/opal-takeover.S new file mode 100644 index 000000000000..77b48b2b9309 --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-takeover.S | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * PowerNV OPAL takeover assembly code, for use by prom_init.c | ||
3 | * | ||
4 | * Copyright 2011 IBM Corp. | ||
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 <asm/ppc_asm.h> | ||
13 | #include <asm/hvcall.h> | ||
14 | #include <asm/asm-offsets.h> | ||
15 | #include <asm/opal.h> | ||
16 | |||
17 | #define STK_PARAM(i) (48 + ((i)-3)*8) | ||
18 | |||
19 | #define H_HAL_TAKEOVER 0x5124 | ||
20 | #define H_HAL_TAKEOVER_QUERY_MAGIC -1 | ||
21 | |||
22 | .text | ||
23 | _GLOBAL(opal_query_takeover) | ||
24 | mfcr r0 | ||
25 | stw r0,8(r1) | ||
26 | std r3,STK_PARAM(r3)(r1) | ||
27 | std r4,STK_PARAM(r4)(r1) | ||
28 | li r3,H_HAL_TAKEOVER | ||
29 | li r4,H_HAL_TAKEOVER_QUERY_MAGIC | ||
30 | HVSC | ||
31 | ld r10,STK_PARAM(r3)(r1) | ||
32 | std r4,0(r10) | ||
33 | ld r10,STK_PARAM(r4)(r1) | ||
34 | std r5,0(r10) | ||
35 | lwz r0,8(r1) | ||
36 | mtcrf 0xff,r0 | ||
37 | blr | ||
38 | |||
39 | _GLOBAL(opal_do_takeover) | ||
40 | mfcr r0 | ||
41 | stw r0,8(r1) | ||
42 | mflr r0 | ||
43 | std r0,16(r1) | ||
44 | bl __opal_do_takeover | ||
45 | ld r0,16(r1) | ||
46 | mtlr r0 | ||
47 | lwz r0,8(r1) | ||
48 | mtcrf 0xff,r0 | ||
49 | blr | ||
50 | |||
51 | __opal_do_takeover: | ||
52 | ld r4,0(r3) | ||
53 | ld r5,0x8(r3) | ||
54 | ld r6,0x10(r3) | ||
55 | ld r7,0x18(r3) | ||
56 | ld r8,0x20(r3) | ||
57 | ld r9,0x28(r3) | ||
58 | ld r10,0x30(r3) | ||
59 | ld r11,0x38(r3) | ||
60 | li r3,H_HAL_TAKEOVER | ||
61 | HVSC | ||
62 | blr | ||
63 | |||
64 | .globl opal_secondary_entry | ||
65 | opal_secondary_entry: | ||
66 | mr r31,r3 | ||
67 | mfmsr r11 | ||
68 | li r12,(MSR_SF | MSR_ISF)@highest | ||
69 | sldi r12,r12,48 | ||
70 | or r11,r11,r12 | ||
71 | mtmsrd r11 | ||
72 | isync | ||
73 | mfspr r4,SPRN_PIR | ||
74 | std r4,0(r3) | ||
75 | 1: HMT_LOW | ||
76 | ld r4,8(r3) | ||
77 | cmpli cr0,r4,0 | ||
78 | beq 1b | ||
79 | HMT_MEDIUM | ||
80 | 1: addi r3,r31,16 | ||
81 | bl __opal_do_takeover | ||
82 | b 1b | ||
83 | |||
84 | _GLOBAL(opal_enter_rtas) | ||
85 | mflr r0 | ||
86 | std r0,16(r1) | ||
87 | stdu r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */ | ||
88 | |||
89 | /* Because PROM is running in 32b mode, it clobbers the high order half | ||
90 | * of all registers that it saves. We therefore save those registers | ||
91 | * PROM might touch to the stack. (r0, r3-r13 are caller saved) | ||
92 | */ | ||
93 | SAVE_GPR(2, r1) | ||
94 | SAVE_GPR(13, r1) | ||
95 | SAVE_8GPRS(14, r1) | ||
96 | SAVE_10GPRS(22, r1) | ||
97 | mfcr r10 | ||
98 | mfmsr r11 | ||
99 | std r10,_CCR(r1) | ||
100 | std r11,_MSR(r1) | ||
101 | |||
102 | /* Get the PROM entrypoint */ | ||
103 | mtlr r5 | ||
104 | |||
105 | /* Switch MSR to 32 bits mode | ||
106 | */ | ||
107 | li r12,1 | ||
108 | rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG) | ||
109 | andc r11,r11,r12 | ||
110 | li r12,1 | ||
111 | rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG) | ||
112 | andc r11,r11,r12 | ||
113 | mtmsrd r11 | ||
114 | isync | ||
115 | |||
116 | /* Enter RTAS here... */ | ||
117 | blrl | ||
118 | |||
119 | /* Just make sure that r1 top 32 bits didn't get | ||
120 | * corrupt by OF | ||
121 | */ | ||
122 | rldicl r1,r1,0,32 | ||
123 | |||
124 | /* Restore the MSR (back to 64 bits) */ | ||
125 | ld r0,_MSR(r1) | ||
126 | MTMSRD(r0) | ||
127 | isync | ||
128 | |||
129 | /* Restore other registers */ | ||
130 | REST_GPR(2, r1) | ||
131 | REST_GPR(13, r1) | ||
132 | REST_8GPRS(14, r1) | ||
133 | REST_10GPRS(22, r1) | ||
134 | ld r4,_CCR(r1) | ||
135 | mtcr r4 | ||
136 | |||
137 | addi r1,r1,PROM_FRAME_SIZE | ||
138 | ld r0,16(r1) | ||
139 | mtlr r0 | ||
140 | blr | ||
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S new file mode 100644 index 000000000000..4a3f46d8533e --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * PowerNV OPAL API wrappers | ||
3 | * | ||
4 | * Copyright 2011 IBM Corp. | ||
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 <asm/ppc_asm.h> | ||
13 | #include <asm/hvcall.h> | ||
14 | #include <asm/asm-offsets.h> | ||
15 | #include <asm/opal.h> | ||
16 | |||
17 | /* TODO: | ||
18 | * | ||
19 | * - Trace irqs in/off (needs saving/restoring all args, argh...) | ||
20 | * - Get r11 feed up by Dave so I can have better register usage | ||
21 | */ | ||
22 | #define OPAL_CALL(name, token) \ | ||
23 | _GLOBAL(name); \ | ||
24 | mflr r0; \ | ||
25 | mfcr r12; \ | ||
26 | std r0,16(r1); \ | ||
27 | std r12,8(r1); \ | ||
28 | std r1,PACAR1(r13); \ | ||
29 | li r0,0; \ | ||
30 | mfmsr r12; \ | ||
31 | ori r0,r0,MSR_EE; \ | ||
32 | std r12,PACASAVEDMSR(r13); \ | ||
33 | andc r12,r12,r0; \ | ||
34 | mtmsrd r12,1; \ | ||
35 | LOAD_REG_ADDR(r0,.opal_return); \ | ||
36 | mtlr r0; \ | ||
37 | li r0,MSR_DR|MSR_IR; \ | ||
38 | andc r12,r12,r0; \ | ||
39 | li r0,token; \ | ||
40 | mtspr SPRN_HSRR1,r12; \ | ||
41 | LOAD_REG_ADDR(r11,opal); \ | ||
42 | ld r12,8(r11); \ | ||
43 | ld r2,0(r11); \ | ||
44 | mtspr SPRN_HSRR0,r12; \ | ||
45 | hrfid | ||
46 | |||
47 | _STATIC(opal_return) | ||
48 | ld r2,PACATOC(r13); | ||
49 | ld r4,8(r1); | ||
50 | ld r5,16(r1); | ||
51 | ld r6,PACASAVEDMSR(r13); | ||
52 | mtspr SPRN_SRR0,r5; | ||
53 | mtspr SPRN_SRR1,r6; | ||
54 | mtcr r4; | ||
55 | rfid | ||
56 | |||
57 | OPAL_CALL(opal_console_write, OPAL_CONSOLE_WRITE); | ||
58 | OPAL_CALL(opal_console_read, OPAL_CONSOLE_READ); | ||
59 | OPAL_CALL(opal_console_write_buffer_space, OPAL_CONSOLE_WRITE_BUFFER_SPACE); | ||
60 | OPAL_CALL(opal_rtc_read, OPAL_RTC_READ); | ||
61 | OPAL_CALL(opal_rtc_write, OPAL_RTC_WRITE); | ||
62 | OPAL_CALL(opal_cec_power_down, OPAL_CEC_POWER_DOWN); | ||
63 | OPAL_CALL(opal_cec_reboot, OPAL_CEC_REBOOT); | ||
64 | OPAL_CALL(opal_read_nvram, OPAL_READ_NVRAM); | ||
65 | OPAL_CALL(opal_write_nvram, OPAL_WRITE_NVRAM); | ||
66 | OPAL_CALL(opal_handle_interrupt, OPAL_HANDLE_INTERRUPT); | ||
67 | OPAL_CALL(opal_poll_events, OPAL_POLL_EVENTS); | ||
68 | OPAL_CALL(opal_pci_set_hub_tce_memory, OPAL_PCI_SET_HUB_TCE_MEMORY); | ||
69 | OPAL_CALL(opal_pci_set_phb_tce_memory, OPAL_PCI_SET_PHB_TCE_MEMORY); | ||
70 | OPAL_CALL(opal_pci_config_read_byte, OPAL_PCI_CONFIG_READ_BYTE); | ||
71 | OPAL_CALL(opal_pci_config_read_half_word, OPAL_PCI_CONFIG_READ_HALF_WORD); | ||
72 | OPAL_CALL(opal_pci_config_read_word, OPAL_PCI_CONFIG_READ_WORD); | ||
73 | OPAL_CALL(opal_pci_config_write_byte, OPAL_PCI_CONFIG_WRITE_BYTE); | ||
74 | OPAL_CALL(opal_pci_config_write_half_word, OPAL_PCI_CONFIG_WRITE_HALF_WORD); | ||
75 | OPAL_CALL(opal_pci_config_write_word, OPAL_PCI_CONFIG_WRITE_WORD); | ||
76 | OPAL_CALL(opal_set_xive, OPAL_SET_XIVE); | ||
77 | OPAL_CALL(opal_get_xive, OPAL_GET_XIVE); | ||
78 | OPAL_CALL(opal_register_exception_handler, OPAL_REGISTER_OPAL_EXCEPTION_HANDLER); | ||
79 | OPAL_CALL(opal_pci_eeh_freeze_status, OPAL_PCI_EEH_FREEZE_STATUS); | ||
80 | OPAL_CALL(opal_pci_eeh_freeze_clear, OPAL_PCI_EEH_FREEZE_CLEAR); | ||
81 | OPAL_CALL(opal_pci_shpc, OPAL_PCI_SHPC); | ||
82 | OPAL_CALL(opal_pci_phb_mmio_enable, OPAL_PCI_PHB_MMIO_ENABLE); | ||
83 | OPAL_CALL(opal_pci_set_phb_mem_window, OPAL_PCI_SET_PHB_MEM_WINDOW); | ||
84 | OPAL_CALL(opal_pci_map_pe_mmio_window, OPAL_PCI_MAP_PE_MMIO_WINDOW); | ||
85 | OPAL_CALL(opal_pci_set_phb_table_memory, OPAL_PCI_SET_PHB_TABLE_MEMORY); | ||
86 | OPAL_CALL(opal_pci_set_pe, OPAL_PCI_SET_PE); | ||
87 | OPAL_CALL(opal_pci_set_peltv, OPAL_PCI_SET_PELTV); | ||
88 | OPAL_CALL(opal_pci_set_mve, OPAL_PCI_SET_MVE); | ||
89 | OPAL_CALL(opal_pci_set_mve_enable, OPAL_PCI_SET_MVE_ENABLE); | ||
90 | OPAL_CALL(opal_pci_get_xive_reissue, OPAL_PCI_GET_XIVE_REISSUE); | ||
91 | OPAL_CALL(opal_pci_set_xive_reissue, OPAL_PCI_SET_XIVE_REISSUE); | ||
92 | OPAL_CALL(opal_pci_set_xive_pe, OPAL_PCI_SET_XIVE_PE); | ||
93 | OPAL_CALL(opal_get_xive_source, OPAL_GET_XIVE_SOURCE); | ||
94 | OPAL_CALL(opal_get_msi_32, OPAL_GET_MSI_32); | ||
95 | OPAL_CALL(opal_get_msi_64, OPAL_GET_MSI_64); | ||
96 | OPAL_CALL(opal_start_cpu, OPAL_START_CPU); | ||
97 | OPAL_CALL(opal_query_cpu_status, OPAL_QUERY_CPU_STATUS); | ||
98 | OPAL_CALL(opal_write_oppanel, OPAL_WRITE_OPPANEL); | ||
99 | OPAL_CALL(opal_pci_map_pe_dma_window, OPAL_PCI_MAP_PE_DMA_WINDOW); | ||
100 | OPAL_CALL(opal_pci_map_pe_dma_window_real, OPAL_PCI_MAP_PE_DMA_WINDOW_REAL); | ||
101 | OPAL_CALL(opal_pci_reset, OPAL_PCI_RESET); | ||
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c new file mode 100644 index 000000000000..aaa0dba49471 --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal.c | |||
@@ -0,0 +1,322 @@ | |||
1 | /* | ||
2 | * PowerNV OPAL high level interfaces | ||
3 | * | ||
4 | * Copyright 2011 IBM Corp. | ||
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 | #undef DEBUG | ||
13 | |||
14 | #include <linux/types.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/of_platform.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <asm/opal.h> | ||
19 | #include <asm/firmware.h> | ||
20 | |||
21 | #include "powernv.h" | ||
22 | |||
23 | struct opal { | ||
24 | u64 base; | ||
25 | u64 entry; | ||
26 | } opal; | ||
27 | |||
28 | static struct device_node *opal_node; | ||
29 | static DEFINE_SPINLOCK(opal_write_lock); | ||
30 | extern u64 opal_mc_secondary_handler[]; | ||
31 | |||
32 | int __init early_init_dt_scan_opal(unsigned long node, | ||
33 | const char *uname, int depth, void *data) | ||
34 | { | ||
35 | const void *basep, *entryp; | ||
36 | unsigned long basesz, entrysz; | ||
37 | u64 glue; | ||
38 | |||
39 | if (depth != 1 || strcmp(uname, "ibm,opal") != 0) | ||
40 | return 0; | ||
41 | |||
42 | basep = of_get_flat_dt_prop(node, "opal-base-address", &basesz); | ||
43 | entryp = of_get_flat_dt_prop(node, "opal-entry-address", &entrysz); | ||
44 | |||
45 | if (!basep || !entryp) | ||
46 | return 1; | ||
47 | |||
48 | opal.base = of_read_number(basep, basesz/4); | ||
49 | opal.entry = of_read_number(entryp, entrysz/4); | ||
50 | |||
51 | pr_debug("OPAL Base = 0x%llx (basep=%p basesz=%ld)\n", | ||
52 | opal.base, basep, basesz); | ||
53 | pr_debug("OPAL Entry = 0x%llx (entryp=%p basesz=%ld)\n", | ||
54 | opal.entry, entryp, entrysz); | ||
55 | |||
56 | powerpc_firmware_features |= FW_FEATURE_OPAL; | ||
57 | if (of_flat_dt_is_compatible(node, "ibm,opal-v2")) { | ||
58 | powerpc_firmware_features |= FW_FEATURE_OPALv2; | ||
59 | printk("OPAL V2 detected !\n"); | ||
60 | } else { | ||
61 | printk("OPAL V1 detected !\n"); | ||
62 | } | ||
63 | |||
64 | /* Hookup some exception handlers. We use the fwnmi area at 0x7000 | ||
65 | * to provide the glue space to OPAL | ||
66 | */ | ||
67 | glue = 0x7000; | ||
68 | opal_register_exception_handler(OPAL_MACHINE_CHECK_HANDLER, | ||
69 | __pa(opal_mc_secondary_handler[0]), | ||
70 | glue); | ||
71 | glue += 128; | ||
72 | opal_register_exception_handler(OPAL_HYPERVISOR_MAINTENANCE_HANDLER, | ||
73 | 0, glue); | ||
74 | glue += 128; | ||
75 | opal_register_exception_handler(OPAL_SOFTPATCH_HANDLER, 0, glue); | ||
76 | |||
77 | return 1; | ||
78 | } | ||
79 | |||
80 | int opal_get_chars(uint32_t vtermno, char *buf, int count) | ||
81 | { | ||
82 | s64 len, rc; | ||
83 | u64 evt; | ||
84 | |||
85 | if (!opal.entry) | ||
86 | return -ENODEV; | ||
87 | opal_poll_events(&evt); | ||
88 | if ((evt & OPAL_EVENT_CONSOLE_INPUT) == 0) | ||
89 | return 0; | ||
90 | len = count; | ||
91 | rc = opal_console_read(vtermno, &len, buf); | ||
92 | if (rc == OPAL_SUCCESS) | ||
93 | return len; | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | int opal_put_chars(uint32_t vtermno, const char *data, int total_len) | ||
98 | { | ||
99 | int written = 0; | ||
100 | s64 len, rc; | ||
101 | unsigned long flags; | ||
102 | u64 evt; | ||
103 | |||
104 | if (!opal.entry) | ||
105 | return -ENODEV; | ||
106 | |||
107 | /* We want put_chars to be atomic to avoid mangling of hvsi | ||
108 | * packets. To do that, we first test for room and return | ||
109 | * -EAGAIN if there isn't enough. | ||
110 | * | ||
111 | * Unfortunately, opal_console_write_buffer_space() doesn't | ||
112 | * appear to work on opal v1, so we just assume there is | ||
113 | * enough room and be done with it | ||
114 | */ | ||
115 | spin_lock_irqsave(&opal_write_lock, flags); | ||
116 | if (firmware_has_feature(FW_FEATURE_OPALv2)) { | ||
117 | rc = opal_console_write_buffer_space(vtermno, &len); | ||
118 | if (rc || len < total_len) { | ||
119 | spin_unlock_irqrestore(&opal_write_lock, flags); | ||
120 | /* Closed -> drop characters */ | ||
121 | if (rc) | ||
122 | return total_len; | ||
123 | opal_poll_events(&evt); | ||
124 | return -EAGAIN; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | /* We still try to handle partial completions, though they | ||
129 | * should no longer happen. | ||
130 | */ | ||
131 | rc = OPAL_BUSY; | ||
132 | while(total_len > 0 && (rc == OPAL_BUSY || | ||
133 | rc == OPAL_BUSY_EVENT || rc == OPAL_SUCCESS)) { | ||
134 | len = total_len; | ||
135 | rc = opal_console_write(vtermno, &len, data); | ||
136 | if (rc == OPAL_SUCCESS) { | ||
137 | total_len -= len; | ||
138 | data += len; | ||
139 | written += len; | ||
140 | } | ||
141 | /* This is a bit nasty but we need that for the console to | ||
142 | * flush when there aren't any interrupts. We will clean | ||
143 | * things a bit later to limit that to synchronous path | ||
144 | * such as the kernel console and xmon/udbg | ||
145 | */ | ||
146 | do | ||
147 | opal_poll_events(&evt); | ||
148 | while(rc == OPAL_SUCCESS && (evt & OPAL_EVENT_CONSOLE_OUTPUT)); | ||
149 | } | ||
150 | spin_unlock_irqrestore(&opal_write_lock, flags); | ||
151 | return written; | ||
152 | } | ||
153 | |||
154 | int opal_machine_check(struct pt_regs *regs) | ||
155 | { | ||
156 | struct opal_machine_check_event *opal_evt = get_paca()->opal_mc_evt; | ||
157 | struct opal_machine_check_event evt; | ||
158 | const char *level, *sevstr, *subtype; | ||
159 | static const char *opal_mc_ue_types[] = { | ||
160 | "Indeterminate", | ||
161 | "Instruction fetch", | ||
162 | "Page table walk ifetch", | ||
163 | "Load/Store", | ||
164 | "Page table walk Load/Store", | ||
165 | }; | ||
166 | static const char *opal_mc_slb_types[] = { | ||
167 | "Indeterminate", | ||
168 | "Parity", | ||
169 | "Multihit", | ||
170 | }; | ||
171 | static const char *opal_mc_erat_types[] = { | ||
172 | "Indeterminate", | ||
173 | "Parity", | ||
174 | "Multihit", | ||
175 | }; | ||
176 | static const char *opal_mc_tlb_types[] = { | ||
177 | "Indeterminate", | ||
178 | "Parity", | ||
179 | "Multihit", | ||
180 | }; | ||
181 | |||
182 | /* Copy the event structure and release the original */ | ||
183 | evt = *opal_evt; | ||
184 | opal_evt->in_use = 0; | ||
185 | |||
186 | /* Print things out */ | ||
187 | if (evt.version != OpalMCE_V1) { | ||
188 | pr_err("Machine Check Exception, Unknown event version %d !\n", | ||
189 | evt.version); | ||
190 | return 0; | ||
191 | } | ||
192 | switch(evt.severity) { | ||
193 | case OpalMCE_SEV_NO_ERROR: | ||
194 | level = KERN_INFO; | ||
195 | sevstr = "Harmless"; | ||
196 | break; | ||
197 | case OpalMCE_SEV_WARNING: | ||
198 | level = KERN_WARNING; | ||
199 | sevstr = ""; | ||
200 | break; | ||
201 | case OpalMCE_SEV_ERROR_SYNC: | ||
202 | level = KERN_ERR; | ||
203 | sevstr = "Severe"; | ||
204 | break; | ||
205 | case OpalMCE_SEV_FATAL: | ||
206 | default: | ||
207 | level = KERN_ERR; | ||
208 | sevstr = "Fatal"; | ||
209 | break; | ||
210 | } | ||
211 | |||
212 | printk("%s%s Machine check interrupt [%s]\n", level, sevstr, | ||
213 | evt.disposition == OpalMCE_DISPOSITION_RECOVERED ? | ||
214 | "Recovered" : "[Not recovered"); | ||
215 | printk("%s Initiator: %s\n", level, | ||
216 | evt.initiator == OpalMCE_INITIATOR_CPU ? "CPU" : "Unknown"); | ||
217 | switch(evt.error_type) { | ||
218 | case OpalMCE_ERROR_TYPE_UE: | ||
219 | subtype = evt.u.ue_error.ue_error_type < | ||
220 | ARRAY_SIZE(opal_mc_ue_types) ? | ||
221 | opal_mc_ue_types[evt.u.ue_error.ue_error_type] | ||
222 | : "Unknown"; | ||
223 | printk("%s Error type: UE [%s]\n", level, subtype); | ||
224 | if (evt.u.ue_error.effective_address_provided) | ||
225 | printk("%s Effective address: %016llx\n", | ||
226 | level, evt.u.ue_error.effective_address); | ||
227 | if (evt.u.ue_error.physical_address_provided) | ||
228 | printk("%s Physial address: %016llx\n", | ||
229 | level, evt.u.ue_error.physical_address); | ||
230 | break; | ||
231 | case OpalMCE_ERROR_TYPE_SLB: | ||
232 | subtype = evt.u.slb_error.slb_error_type < | ||
233 | ARRAY_SIZE(opal_mc_slb_types) ? | ||
234 | opal_mc_slb_types[evt.u.slb_error.slb_error_type] | ||
235 | : "Unknown"; | ||
236 | printk("%s Error type: SLB [%s]\n", level, subtype); | ||
237 | if (evt.u.slb_error.effective_address_provided) | ||
238 | printk("%s Effective address: %016llx\n", | ||
239 | level, evt.u.slb_error.effective_address); | ||
240 | break; | ||
241 | case OpalMCE_ERROR_TYPE_ERAT: | ||
242 | subtype = evt.u.erat_error.erat_error_type < | ||
243 | ARRAY_SIZE(opal_mc_erat_types) ? | ||
244 | opal_mc_erat_types[evt.u.erat_error.erat_error_type] | ||
245 | : "Unknown"; | ||
246 | printk("%s Error type: ERAT [%s]\n", level, subtype); | ||
247 | if (evt.u.erat_error.effective_address_provided) | ||
248 | printk("%s Effective address: %016llx\n", | ||
249 | level, evt.u.erat_error.effective_address); | ||
250 | break; | ||
251 | case OpalMCE_ERROR_TYPE_TLB: | ||
252 | subtype = evt.u.tlb_error.tlb_error_type < | ||
253 | ARRAY_SIZE(opal_mc_tlb_types) ? | ||
254 | opal_mc_tlb_types[evt.u.tlb_error.tlb_error_type] | ||
255 | : "Unknown"; | ||
256 | printk("%s Error type: TLB [%s]\n", level, subtype); | ||
257 | if (evt.u.tlb_error.effective_address_provided) | ||
258 | printk("%s Effective address: %016llx\n", | ||
259 | level, evt.u.tlb_error.effective_address); | ||
260 | break; | ||
261 | default: | ||
262 | case OpalMCE_ERROR_TYPE_UNKNOWN: | ||
263 | printk("%s Error type: Unknown\n", level); | ||
264 | break; | ||
265 | } | ||
266 | return evt.severity == OpalMCE_SEV_FATAL ? 0 : 1; | ||
267 | } | ||
268 | |||
269 | static irqreturn_t opal_interrupt(int irq, void *data) | ||
270 | { | ||
271 | uint64_t events; | ||
272 | |||
273 | opal_handle_interrupt(virq_to_hw(irq), &events); | ||
274 | |||
275 | /* XXX TODO: Do something with the events */ | ||
276 | |||
277 | return IRQ_HANDLED; | ||
278 | } | ||
279 | |||
280 | static int __init opal_init(void) | ||
281 | { | ||
282 | struct device_node *np, *consoles; | ||
283 | const u32 *irqs; | ||
284 | int rc, i, irqlen; | ||
285 | |||
286 | opal_node = of_find_node_by_path("/ibm,opal"); | ||
287 | if (!opal_node) { | ||
288 | pr_warn("opal: Node not found\n"); | ||
289 | return -ENODEV; | ||
290 | } | ||
291 | if (firmware_has_feature(FW_FEATURE_OPALv2)) | ||
292 | consoles = of_find_node_by_path("/ibm,opal/consoles"); | ||
293 | else | ||
294 | consoles = of_node_get(opal_node); | ||
295 | |||
296 | /* Register serial ports */ | ||
297 | for_each_child_of_node(consoles, np) { | ||
298 | if (strcmp(np->name, "serial")) | ||
299 | continue; | ||
300 | of_platform_device_create(np, NULL, NULL); | ||
301 | } | ||
302 | of_node_put(consoles); | ||
303 | |||
304 | /* Find all OPAL interrupts and request them */ | ||
305 | irqs = of_get_property(opal_node, "opal-interrupts", &irqlen); | ||
306 | pr_debug("opal: Found %d interrupts reserved for OPAL\n", | ||
307 | irqs ? (irqlen / 4) : 0); | ||
308 | for (i = 0; irqs && i < (irqlen / 4); i++, irqs++) { | ||
309 | unsigned int hwirq = be32_to_cpup(irqs); | ||
310 | unsigned int irq = irq_create_mapping(NULL, hwirq); | ||
311 | if (irq == NO_IRQ) { | ||
312 | pr_warning("opal: Failed to map irq 0x%x\n", hwirq); | ||
313 | continue; | ||
314 | } | ||
315 | rc = request_irq(irq, opal_interrupt, 0, "opal", NULL); | ||
316 | if (rc) | ||
317 | pr_warning("opal: Error %d requesting irq %d" | ||
318 | " (0x%x)\n", rc, irq, hwirq); | ||
319 | } | ||
320 | return 0; | ||
321 | } | ||
322 | subsys_initcall(opal_init); | ||
diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c new file mode 100644 index 000000000000..4c80f7c77d56 --- /dev/null +++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c | |||
@@ -0,0 +1,234 @@ | |||
1 | /* | ||
2 | * Support PCI/PCIe on PowerNV platforms | ||
3 | * | ||
4 | * Currently supports only P5IOC2 | ||
5 | * | ||
6 | * Copyright 2011 Benjamin Herrenschmidt, IBM Corp. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the License, or (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/string.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/bootmem.h> | ||
20 | #include <linux/irq.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/msi.h> | ||
23 | |||
24 | #include <asm/sections.h> | ||
25 | #include <asm/io.h> | ||
26 | #include <asm/prom.h> | ||
27 | #include <asm/pci-bridge.h> | ||
28 | #include <asm/machdep.h> | ||
29 | #include <asm/ppc-pci.h> | ||
30 | #include <asm/opal.h> | ||
31 | #include <asm/iommu.h> | ||
32 | #include <asm/tce.h> | ||
33 | #include <asm/abs_addr.h> | ||
34 | |||
35 | #include "powernv.h" | ||
36 | #include "pci.h" | ||
37 | |||
38 | /* For now, use a fixed amount of TCE memory for each p5ioc2 | ||
39 | * hub, 16M will do | ||
40 | */ | ||
41 | #define P5IOC2_TCE_MEMORY 0x01000000 | ||
42 | |||
43 | #ifdef CONFIG_PCI_MSI | ||
44 | static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | ||
45 | unsigned int hwirq, unsigned int is_64, | ||
46 | struct msi_msg *msg) | ||
47 | { | ||
48 | if (WARN_ON(!is_64)) | ||
49 | return -ENXIO; | ||
50 | msg->data = hwirq - phb->msi_base; | ||
51 | msg->address_hi = 0x10000000; | ||
52 | msg->address_lo = 0; | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) | ||
58 | { | ||
59 | unsigned int bmap_size; | ||
60 | const __be32 *prop = of_get_property(phb->hose->dn, | ||
61 | "ibm,opal-msi-ranges", NULL); | ||
62 | if (!prop) | ||
63 | return; | ||
64 | |||
65 | /* Don't do MSI's on p5ioc2 PCI-X are they are not properly | ||
66 | * verified in HW | ||
67 | */ | ||
68 | if (of_device_is_compatible(phb->hose->dn, "ibm,p5ioc2-pcix")) | ||
69 | return; | ||
70 | phb->msi_base = be32_to_cpup(prop); | ||
71 | phb->msi_count = be32_to_cpup(prop + 1); | ||
72 | bmap_size = BITS_TO_LONGS(phb->msi_count) * sizeof(unsigned long); | ||
73 | phb->msi_map = zalloc_maybe_bootmem(bmap_size, GFP_KERNEL); | ||
74 | if (!phb->msi_map) { | ||
75 | pr_err("PCI %d: Failed to allocate MSI bitmap !\n", | ||
76 | phb->hose->global_number); | ||
77 | return; | ||
78 | } | ||
79 | phb->msi_setup = pnv_pci_p5ioc2_msi_setup; | ||
80 | phb->msi32_support = 0; | ||
81 | pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n", | ||
82 | phb->msi_count, phb->msi_base); | ||
83 | } | ||
84 | #else | ||
85 | static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) { } | ||
86 | #endif /* CONFIG_PCI_MSI */ | ||
87 | |||
88 | static void __devinit pnv_pci_p5ioc2_dma_dev_setup(struct pnv_phb *phb, | ||
89 | struct pci_dev *pdev) | ||
90 | { | ||
91 | if (phb->p5ioc2.iommu_table.it_map == NULL) | ||
92 | iommu_init_table(&phb->p5ioc2.iommu_table, phb->hose->node); | ||
93 | |||
94 | set_iommu_table_base(&pdev->dev, &phb->p5ioc2.iommu_table); | ||
95 | } | ||
96 | |||
97 | static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, | ||
98 | void *tce_mem, u64 tce_size) | ||
99 | { | ||
100 | struct pnv_phb *phb; | ||
101 | const u64 *prop64; | ||
102 | u64 phb_id; | ||
103 | int64_t rc; | ||
104 | static int primary = 1; | ||
105 | |||
106 | pr_info(" Initializing p5ioc2 PHB %s\n", np->full_name); | ||
107 | |||
108 | prop64 = of_get_property(np, "ibm,opal-phbid", NULL); | ||
109 | if (!prop64) { | ||
110 | pr_err(" Missing \"ibm,opal-phbid\" property !\n"); | ||
111 | return; | ||
112 | } | ||
113 | phb_id = be64_to_cpup(prop64); | ||
114 | pr_devel(" PHB-ID : 0x%016llx\n", phb_id); | ||
115 | pr_devel(" TCE AT : 0x%016lx\n", __pa(tce_mem)); | ||
116 | pr_devel(" TCE SZ : 0x%016llx\n", tce_size); | ||
117 | |||
118 | rc = opal_pci_set_phb_tce_memory(phb_id, __pa(tce_mem), tce_size); | ||
119 | if (rc != OPAL_SUCCESS) { | ||
120 | pr_err(" Failed to set TCE memory, OPAL error %lld\n", rc); | ||
121 | return; | ||
122 | } | ||
123 | |||
124 | phb = alloc_bootmem(sizeof(struct pnv_phb)); | ||
125 | if (phb) { | ||
126 | memset(phb, 0, sizeof(struct pnv_phb)); | ||
127 | phb->hose = pcibios_alloc_controller(np); | ||
128 | } | ||
129 | if (!phb || !phb->hose) { | ||
130 | pr_err(" Failed to allocate PCI controller\n"); | ||
131 | return; | ||
132 | } | ||
133 | |||
134 | spin_lock_init(&phb->lock); | ||
135 | phb->hose->first_busno = 0; | ||
136 | phb->hose->last_busno = 0xff; | ||
137 | phb->hose->private_data = phb; | ||
138 | phb->opal_id = phb_id; | ||
139 | phb->type = PNV_PHB_P5IOC2; | ||
140 | |||
141 | phb->regs = of_iomap(np, 0); | ||
142 | |||
143 | if (phb->regs == NULL) | ||
144 | pr_err(" Failed to map registers !\n"); | ||
145 | else { | ||
146 | pr_devel(" P_BUID = 0x%08x\n", in_be32(phb->regs + 0x100)); | ||
147 | pr_devel(" P_IOSZ = 0x%08x\n", in_be32(phb->regs + 0x1b0)); | ||
148 | pr_devel(" P_IO_ST = 0x%08x\n", in_be32(phb->regs + 0x1e0)); | ||
149 | pr_devel(" P_MEM1_H = 0x%08x\n", in_be32(phb->regs + 0x1a0)); | ||
150 | pr_devel(" P_MEM1_L = 0x%08x\n", in_be32(phb->regs + 0x190)); | ||
151 | pr_devel(" P_MSZ1_L = 0x%08x\n", in_be32(phb->regs + 0x1c0)); | ||
152 | pr_devel(" P_MEM_ST = 0x%08x\n", in_be32(phb->regs + 0x1d0)); | ||
153 | pr_devel(" P_MEM2_H = 0x%08x\n", in_be32(phb->regs + 0x2c0)); | ||
154 | pr_devel(" P_MEM2_L = 0x%08x\n", in_be32(phb->regs + 0x2b0)); | ||
155 | pr_devel(" P_MSZ2_H = 0x%08x\n", in_be32(phb->regs + 0x2d0)); | ||
156 | pr_devel(" P_MSZ2_L = 0x%08x\n", in_be32(phb->regs + 0x2e0)); | ||
157 | } | ||
158 | |||
159 | /* Interpret the "ranges" property */ | ||
160 | /* This also maps the I/O region and sets isa_io/mem_base */ | ||
161 | pci_process_bridge_OF_ranges(phb->hose, np, primary); | ||
162 | primary = 0; | ||
163 | |||
164 | phb->hose->ops = &pnv_pci_ops; | ||
165 | |||
166 | /* Setup MSI support */ | ||
167 | pnv_pci_init_p5ioc2_msis(phb); | ||
168 | |||
169 | /* Setup TCEs */ | ||
170 | phb->dma_dev_setup = pnv_pci_p5ioc2_dma_dev_setup; | ||
171 | pnv_pci_setup_iommu_table(&phb->p5ioc2.iommu_table, | ||
172 | tce_mem, tce_size, 0); | ||
173 | } | ||
174 | |||
175 | void __init pnv_pci_init_p5ioc2_hub(struct device_node *np) | ||
176 | { | ||
177 | struct device_node *phbn; | ||
178 | const u64 *prop64; | ||
179 | u64 hub_id; | ||
180 | void *tce_mem; | ||
181 | uint64_t tce_per_phb; | ||
182 | int64_t rc; | ||
183 | int phb_count = 0; | ||
184 | |||
185 | pr_info("Probing p5ioc2 IO-Hub %s\n", np->full_name); | ||
186 | |||
187 | prop64 = of_get_property(np, "ibm,opal-hubid", NULL); | ||
188 | if (!prop64) { | ||
189 | pr_err(" Missing \"ibm,opal-hubid\" property !\n"); | ||
190 | return; | ||
191 | } | ||
192 | hub_id = be64_to_cpup(prop64); | ||
193 | pr_info(" HUB-ID : 0x%016llx\n", hub_id); | ||
194 | |||
195 | /* Currently allocate 16M of TCE memory for every Hub | ||
196 | * | ||
197 | * XXX TODO: Make it chip local if possible | ||
198 | */ | ||
199 | tce_mem = __alloc_bootmem(P5IOC2_TCE_MEMORY, P5IOC2_TCE_MEMORY, | ||
200 | __pa(MAX_DMA_ADDRESS)); | ||
201 | if (!tce_mem) { | ||
202 | pr_err(" Failed to allocate TCE Memory !\n"); | ||
203 | return; | ||
204 | } | ||
205 | pr_debug(" TCE : 0x%016lx..0x%016lx\n", | ||
206 | __pa(tce_mem), __pa(tce_mem) + P5IOC2_TCE_MEMORY - 1); | ||
207 | rc = opal_pci_set_hub_tce_memory(hub_id, __pa(tce_mem), | ||
208 | P5IOC2_TCE_MEMORY); | ||
209 | if (rc != OPAL_SUCCESS) { | ||
210 | pr_err(" Failed to allocate TCE memory, OPAL error %lld\n", rc); | ||
211 | return; | ||
212 | } | ||
213 | |||
214 | /* Count child PHBs */ | ||
215 | for_each_child_of_node(np, phbn) { | ||
216 | if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") || | ||
217 | of_device_is_compatible(phbn, "ibm,p5ioc2-pciex")) | ||
218 | phb_count++; | ||
219 | } | ||
220 | |||
221 | /* Calculate how much TCE space we can give per PHB */ | ||
222 | tce_per_phb = __rounddown_pow_of_two(P5IOC2_TCE_MEMORY / phb_count); | ||
223 | pr_info(" Allocating %lld MB of TCE memory per PHB\n", | ||
224 | tce_per_phb >> 20); | ||
225 | |||
226 | /* Initialize PHBs */ | ||
227 | for_each_child_of_node(np, phbn) { | ||
228 | if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") || | ||
229 | of_device_is_compatible(phbn, "ibm,p5ioc2-pciex")) { | ||
230 | pnv_pci_init_p5ioc2_phb(phbn, tce_mem, tce_per_phb); | ||
231 | tce_mem += tce_per_phb; | ||
232 | } | ||
233 | } | ||
234 | } | ||
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c new file mode 100644 index 000000000000..85bb66d7f933 --- /dev/null +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -0,0 +1,427 @@ | |||
1 | /* | ||
2 | * Support PCI/PCIe on PowerNV platforms | ||
3 | * | ||
4 | * Currently supports only P5IOC2 | ||
5 | * | ||
6 | * Copyright 2011 Benjamin Herrenschmidt, IBM Corp. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the License, or (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/string.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/bootmem.h> | ||
20 | #include <linux/irq.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/msi.h> | ||
23 | |||
24 | #include <asm/sections.h> | ||
25 | #include <asm/io.h> | ||
26 | #include <asm/prom.h> | ||
27 | #include <asm/pci-bridge.h> | ||
28 | #include <asm/machdep.h> | ||
29 | #include <asm/ppc-pci.h> | ||
30 | #include <asm/opal.h> | ||
31 | #include <asm/iommu.h> | ||
32 | #include <asm/tce.h> | ||
33 | #include <asm/abs_addr.h> | ||
34 | |||
35 | #include "powernv.h" | ||
36 | #include "pci.h" | ||
37 | |||
38 | /* Delay in usec */ | ||
39 | #define PCI_RESET_DELAY_US 3000000 | ||
40 | |||
41 | #define cfg_dbg(fmt...) do { } while(0) | ||
42 | //#define cfg_dbg(fmt...) printk(fmt) | ||
43 | |||
44 | #ifdef CONFIG_PCI_MSI | ||
45 | static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type) | ||
46 | { | ||
47 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | ||
48 | struct pnv_phb *phb = hose->private_data; | ||
49 | |||
50 | return (phb && phb->msi_map) ? 0 : -ENODEV; | ||
51 | } | ||
52 | |||
53 | static unsigned int pnv_get_one_msi(struct pnv_phb *phb) | ||
54 | { | ||
55 | unsigned int id; | ||
56 | |||
57 | spin_lock(&phb->lock); | ||
58 | id = find_next_zero_bit(phb->msi_map, phb->msi_count, phb->msi_next); | ||
59 | if (id >= phb->msi_count && phb->msi_next) | ||
60 | id = find_next_zero_bit(phb->msi_map, phb->msi_count, 0); | ||
61 | if (id >= phb->msi_count) { | ||
62 | spin_unlock(&phb->lock); | ||
63 | return 0; | ||
64 | } | ||
65 | __set_bit(id, phb->msi_map); | ||
66 | spin_unlock(&phb->lock); | ||
67 | return id + phb->msi_base; | ||
68 | } | ||
69 | |||
70 | static void pnv_put_msi(struct pnv_phb *phb, unsigned int hwirq) | ||
71 | { | ||
72 | unsigned int id; | ||
73 | |||
74 | if (WARN_ON(hwirq < phb->msi_base || | ||
75 | hwirq >= (phb->msi_base + phb->msi_count))) | ||
76 | return; | ||
77 | id = hwirq - phb->msi_base; | ||
78 | spin_lock(&phb->lock); | ||
79 | __clear_bit(id, phb->msi_map); | ||
80 | spin_unlock(&phb->lock); | ||
81 | } | ||
82 | |||
83 | static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | ||
84 | { | ||
85 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | ||
86 | struct pnv_phb *phb = hose->private_data; | ||
87 | struct msi_desc *entry; | ||
88 | struct msi_msg msg; | ||
89 | unsigned int hwirq, virq; | ||
90 | int rc; | ||
91 | |||
92 | if (WARN_ON(!phb)) | ||
93 | return -ENODEV; | ||
94 | |||
95 | list_for_each_entry(entry, &pdev->msi_list, list) { | ||
96 | if (!entry->msi_attrib.is_64 && !phb->msi32_support) { | ||
97 | pr_warn("%s: Supports only 64-bit MSIs\n", | ||
98 | pci_name(pdev)); | ||
99 | return -ENXIO; | ||
100 | } | ||
101 | hwirq = pnv_get_one_msi(phb); | ||
102 | if (!hwirq) { | ||
103 | pr_warn("%s: Failed to find a free MSI\n", | ||
104 | pci_name(pdev)); | ||
105 | return -ENOSPC; | ||
106 | } | ||
107 | virq = irq_create_mapping(NULL, hwirq); | ||
108 | if (virq == NO_IRQ) { | ||
109 | pr_warn("%s: Failed to map MSI to linux irq\n", | ||
110 | pci_name(pdev)); | ||
111 | pnv_put_msi(phb, hwirq); | ||
112 | return -ENOMEM; | ||
113 | } | ||
114 | rc = phb->msi_setup(phb, pdev, hwirq, entry->msi_attrib.is_64, | ||
115 | &msg); | ||
116 | if (rc) { | ||
117 | pr_warn("%s: Failed to setup MSI\n", pci_name(pdev)); | ||
118 | irq_dispose_mapping(virq); | ||
119 | pnv_put_msi(phb, hwirq); | ||
120 | return rc; | ||
121 | } | ||
122 | irq_set_msi_desc(virq, entry); | ||
123 | write_msi_msg(virq, &msg); | ||
124 | } | ||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static void pnv_teardown_msi_irqs(struct pci_dev *pdev) | ||
129 | { | ||
130 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | ||
131 | struct pnv_phb *phb = hose->private_data; | ||
132 | struct msi_desc *entry; | ||
133 | |||
134 | if (WARN_ON(!phb)) | ||
135 | return; | ||
136 | |||
137 | list_for_each_entry(entry, &pdev->msi_list, list) { | ||
138 | if (entry->irq == NO_IRQ) | ||
139 | continue; | ||
140 | irq_set_msi_desc(entry->irq, NULL); | ||
141 | pnv_put_msi(phb, virq_to_hw(entry->irq)); | ||
142 | irq_dispose_mapping(entry->irq); | ||
143 | } | ||
144 | } | ||
145 | #endif /* CONFIG_PCI_MSI */ | ||
146 | |||
147 | static void pnv_pci_config_check_eeh(struct pnv_phb *phb, struct pci_bus *bus, | ||
148 | u32 bdfn) | ||
149 | { | ||
150 | s64 rc; | ||
151 | u8 fstate; | ||
152 | u16 pcierr; | ||
153 | u32 pe_no; | ||
154 | |||
155 | /* Get PE# if we support IODA */ | ||
156 | pe_no = phb->bdfn_to_pe ? phb->bdfn_to_pe(phb, bus, bdfn & 0xff) : 0; | ||
157 | |||
158 | /* Read freeze status */ | ||
159 | rc = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, &fstate, &pcierr, | ||
160 | NULL); | ||
161 | if (rc) { | ||
162 | pr_warning("PCI %d: Failed to read EEH status for PE#%d," | ||
163 | " err %lld\n", phb->hose->global_number, pe_no, rc); | ||
164 | return; | ||
165 | } | ||
166 | cfg_dbg(" -> EEH check, bdfn=%04x PE%d fstate=%x\n", | ||
167 | bdfn, pe_no, fstate); | ||
168 | if (fstate != 0) { | ||
169 | rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no, | ||
170 | OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); | ||
171 | if (rc) { | ||
172 | pr_warning("PCI %d: Failed to clear EEH freeze state" | ||
173 | " for PE#%d, err %lld\n", | ||
174 | phb->hose->global_number, pe_no, rc); | ||
175 | } | ||
176 | } | ||
177 | } | ||
178 | |||
179 | static int pnv_pci_read_config(struct pci_bus *bus, | ||
180 | unsigned int devfn, | ||
181 | int where, int size, u32 *val) | ||
182 | { | ||
183 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
184 | struct pnv_phb *phb = hose->private_data; | ||
185 | u32 bdfn = (((uint64_t)bus->number) << 8) | devfn; | ||
186 | s64 rc; | ||
187 | |||
188 | if (hose == NULL) | ||
189 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
190 | |||
191 | switch (size) { | ||
192 | case 1: { | ||
193 | u8 v8; | ||
194 | rc = opal_pci_config_read_byte(phb->opal_id, bdfn, where, &v8); | ||
195 | *val = (rc == OPAL_SUCCESS) ? v8 : 0xff; | ||
196 | break; | ||
197 | } | ||
198 | case 2: { | ||
199 | u16 v16; | ||
200 | rc = opal_pci_config_read_half_word(phb->opal_id, bdfn, where, | ||
201 | &v16); | ||
202 | *val = (rc == OPAL_SUCCESS) ? v16 : 0xffff; | ||
203 | break; | ||
204 | } | ||
205 | case 4: { | ||
206 | u32 v32; | ||
207 | rc = opal_pci_config_read_word(phb->opal_id, bdfn, where, &v32); | ||
208 | *val = (rc == OPAL_SUCCESS) ? v32 : 0xffffffff; | ||
209 | break; | ||
210 | } | ||
211 | default: | ||
212 | return PCIBIOS_FUNC_NOT_SUPPORTED; | ||
213 | } | ||
214 | cfg_dbg("pnv_pci_read_config bus: %x devfn: %x +%x/%x -> %08x\n", | ||
215 | bus->number, devfn, where, size, *val); | ||
216 | |||
217 | /* Check if the PHB got frozen due to an error (no response) */ | ||
218 | pnv_pci_config_check_eeh(phb, bus, bdfn); | ||
219 | |||
220 | return PCIBIOS_SUCCESSFUL; | ||
221 | } | ||
222 | |||
223 | static int pnv_pci_write_config(struct pci_bus *bus, | ||
224 | unsigned int devfn, | ||
225 | int where, int size, u32 val) | ||
226 | { | ||
227 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
228 | struct pnv_phb *phb = hose->private_data; | ||
229 | u32 bdfn = (((uint64_t)bus->number) << 8) | devfn; | ||
230 | |||
231 | if (hose == NULL) | ||
232 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
233 | |||
234 | cfg_dbg("pnv_pci_write_config bus: %x devfn: %x +%x/%x -> %08x\n", | ||
235 | bus->number, devfn, where, size, val); | ||
236 | switch (size) { | ||
237 | case 1: | ||
238 | opal_pci_config_write_byte(phb->opal_id, bdfn, where, val); | ||
239 | break; | ||
240 | case 2: | ||
241 | opal_pci_config_write_half_word(phb->opal_id, bdfn, where, val); | ||
242 | break; | ||
243 | case 4: | ||
244 | opal_pci_config_write_word(phb->opal_id, bdfn, where, val); | ||
245 | break; | ||
246 | default: | ||
247 | return PCIBIOS_FUNC_NOT_SUPPORTED; | ||
248 | } | ||
249 | /* Check if the PHB got frozen due to an error (no response) */ | ||
250 | pnv_pci_config_check_eeh(phb, bus, bdfn); | ||
251 | |||
252 | return PCIBIOS_SUCCESSFUL; | ||
253 | } | ||
254 | |||
255 | struct pci_ops pnv_pci_ops = { | ||
256 | .read = pnv_pci_read_config, | ||
257 | .write = pnv_pci_write_config, | ||
258 | }; | ||
259 | |||
260 | static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, | ||
261 | unsigned long uaddr, enum dma_data_direction direction, | ||
262 | struct dma_attrs *attrs) | ||
263 | { | ||
264 | u64 proto_tce; | ||
265 | u64 *tcep; | ||
266 | u64 rpn; | ||
267 | |||
268 | proto_tce = TCE_PCI_READ; // Read allowed | ||
269 | |||
270 | if (direction != DMA_TO_DEVICE) | ||
271 | proto_tce |= TCE_PCI_WRITE; | ||
272 | |||
273 | tcep = ((u64 *)tbl->it_base) + index; | ||
274 | |||
275 | while (npages--) { | ||
276 | /* can't move this out since we might cross LMB boundary */ | ||
277 | rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; | ||
278 | *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; | ||
279 | |||
280 | uaddr += TCE_PAGE_SIZE; | ||
281 | tcep++; | ||
282 | } | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static void pnv_tce_free(struct iommu_table *tbl, long index, long npages) | ||
287 | { | ||
288 | u64 *tcep = ((u64 *)tbl->it_base) + index; | ||
289 | |||
290 | while (npages--) | ||
291 | *(tcep++) = 0; | ||
292 | } | ||
293 | |||
294 | void pnv_pci_setup_iommu_table(struct iommu_table *tbl, | ||
295 | void *tce_mem, u64 tce_size, | ||
296 | u64 dma_offset) | ||
297 | { | ||
298 | tbl->it_blocksize = 16; | ||
299 | tbl->it_base = (unsigned long)tce_mem; | ||
300 | tbl->it_offset = dma_offset >> IOMMU_PAGE_SHIFT; | ||
301 | tbl->it_index = 0; | ||
302 | tbl->it_size = tce_size >> 3; | ||
303 | tbl->it_busno = 0; | ||
304 | tbl->it_type = TCE_PCI; | ||
305 | } | ||
306 | |||
307 | static struct iommu_table * __devinit | ||
308 | pnv_pci_setup_bml_iommu(struct pci_controller *hose) | ||
309 | { | ||
310 | struct iommu_table *tbl; | ||
311 | const __be64 *basep; | ||
312 | const __be32 *sizep; | ||
313 | |||
314 | basep = of_get_property(hose->dn, "linux,tce-base", NULL); | ||
315 | sizep = of_get_property(hose->dn, "linux,tce-size", NULL); | ||
316 | if (basep == NULL || sizep == NULL) { | ||
317 | pr_err("PCI: %s has missing tce entries !\n", hose->dn->full_name); | ||
318 | return NULL; | ||
319 | } | ||
320 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, hose->node); | ||
321 | if (WARN_ON(!tbl)) | ||
322 | return NULL; | ||
323 | pnv_pci_setup_iommu_table(tbl, __va(be64_to_cpup(basep)), | ||
324 | be32_to_cpup(sizep), 0); | ||
325 | iommu_init_table(tbl, hose->node); | ||
326 | return tbl; | ||
327 | } | ||
328 | |||
329 | static void __devinit pnv_pci_dma_fallback_setup(struct pci_controller *hose, | ||
330 | struct pci_dev *pdev) | ||
331 | { | ||
332 | struct device_node *np = pci_bus_to_OF_node(hose->bus); | ||
333 | struct pci_dn *pdn; | ||
334 | |||
335 | if (np == NULL) | ||
336 | return; | ||
337 | pdn = PCI_DN(np); | ||
338 | if (!pdn->iommu_table) | ||
339 | pdn->iommu_table = pnv_pci_setup_bml_iommu(hose); | ||
340 | if (!pdn->iommu_table) | ||
341 | return; | ||
342 | set_iommu_table_base(&pdev->dev, pdn->iommu_table); | ||
343 | } | ||
344 | |||
345 | static void __devinit pnv_pci_dma_dev_setup(struct pci_dev *pdev) | ||
346 | { | ||
347 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | ||
348 | struct pnv_phb *phb = hose->private_data; | ||
349 | |||
350 | /* If we have no phb structure, try to setup a fallback based on | ||
351 | * the device-tree (RTAS PCI for example) | ||
352 | */ | ||
353 | if (phb && phb->dma_dev_setup) | ||
354 | phb->dma_dev_setup(phb, pdev); | ||
355 | else | ||
356 | pnv_pci_dma_fallback_setup(hose, pdev); | ||
357 | } | ||
358 | |||
359 | static int pnv_pci_probe_mode(struct pci_bus *bus) | ||
360 | { | ||
361 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
362 | const __be64 *tstamp; | ||
363 | u64 now, target; | ||
364 | |||
365 | |||
366 | /* We hijack this as a way to ensure we have waited long | ||
367 | * enough since the reset was lifted on the PCI bus | ||
368 | */ | ||
369 | if (bus != hose->bus) | ||
370 | return PCI_PROBE_NORMAL; | ||
371 | tstamp = of_get_property(hose->dn, "reset-clear-timestamp", NULL); | ||
372 | if (!tstamp || !*tstamp) | ||
373 | return PCI_PROBE_NORMAL; | ||
374 | |||
375 | now = mftb() / tb_ticks_per_usec; | ||
376 | target = (be64_to_cpup(tstamp) / tb_ticks_per_usec) | ||
377 | + PCI_RESET_DELAY_US; | ||
378 | |||
379 | pr_devel("pci %04d: Reset target: 0x%llx now: 0x%llx\n", | ||
380 | hose->global_number, target, now); | ||
381 | |||
382 | if (now < target) | ||
383 | msleep((target - now + 999) / 1000); | ||
384 | |||
385 | return PCI_PROBE_NORMAL; | ||
386 | } | ||
387 | |||
388 | void __init pnv_pci_init(void) | ||
389 | { | ||
390 | struct device_node *np; | ||
391 | |||
392 | pci_set_flags(PCI_CAN_SKIP_ISA_ALIGN); | ||
393 | |||
394 | /* We do not want to just probe */ | ||
395 | pci_probe_only = 0; | ||
396 | |||
397 | /* OPAL absent, try POPAL first then RTAS detection of PHBs */ | ||
398 | if (!firmware_has_feature(FW_FEATURE_OPAL)) { | ||
399 | #ifdef CONFIG_PPC_POWERNV_RTAS | ||
400 | init_pci_config_tokens(); | ||
401 | find_and_init_phbs(); | ||
402 | #endif /* CONFIG_PPC_POWERNV_RTAS */ | ||
403 | } else { | ||
404 | /* OPAL is here, do our normal stuff */ | ||
405 | |||
406 | /* Look for p5ioc2 IO-Hubs */ | ||
407 | for_each_compatible_node(np, NULL, "ibm,p5ioc2") | ||
408 | pnv_pci_init_p5ioc2_hub(np); | ||
409 | } | ||
410 | |||
411 | /* Setup the linkage between OF nodes and PHBs */ | ||
412 | pci_devs_phb_init(); | ||
413 | |||
414 | /* Configure IOMMU DMA hooks */ | ||
415 | ppc_md.pci_dma_dev_setup = pnv_pci_dma_dev_setup; | ||
416 | ppc_md.tce_build = pnv_tce_build; | ||
417 | ppc_md.tce_free = pnv_tce_free; | ||
418 | ppc_md.pci_probe_mode = pnv_pci_probe_mode; | ||
419 | set_pci_dma_ops(&dma_iommu_ops); | ||
420 | |||
421 | /* Configure MSIs */ | ||
422 | #ifdef CONFIG_PCI_MSI | ||
423 | ppc_md.msi_check_device = pnv_msi_check_device; | ||
424 | ppc_md.setup_msi_irqs = pnv_setup_msi_irqs; | ||
425 | ppc_md.teardown_msi_irqs = pnv_teardown_msi_irqs; | ||
426 | #endif | ||
427 | } | ||
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h new file mode 100644 index 000000000000..d4dbc4950936 --- /dev/null +++ b/arch/powerpc/platforms/powernv/pci.h | |||
@@ -0,0 +1,48 @@ | |||
1 | #ifndef __POWERNV_PCI_H | ||
2 | #define __POWERNV_PCI_H | ||
3 | |||
4 | struct pci_dn; | ||
5 | |||
6 | enum pnv_phb_type { | ||
7 | PNV_PHB_P5IOC2, | ||
8 | PNV_PHB_IODA1, | ||
9 | PNV_PHB_IODA2, | ||
10 | }; | ||
11 | |||
12 | struct pnv_phb { | ||
13 | struct pci_controller *hose; | ||
14 | enum pnv_phb_type type; | ||
15 | u64 opal_id; | ||
16 | void __iomem *regs; | ||
17 | spinlock_t lock; | ||
18 | |||
19 | #ifdef CONFIG_PCI_MSI | ||
20 | unsigned long *msi_map; | ||
21 | unsigned int msi_base; | ||
22 | unsigned int msi_count; | ||
23 | unsigned int msi_next; | ||
24 | unsigned int msi32_support; | ||
25 | #endif | ||
26 | int (*msi_setup)(struct pnv_phb *phb, struct pci_dev *dev, | ||
27 | unsigned int hwirq, unsigned int is_64, | ||
28 | struct msi_msg *msg); | ||
29 | void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev); | ||
30 | void (*fixup_phb)(struct pci_controller *hose); | ||
31 | u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn); | ||
32 | |||
33 | union { | ||
34 | struct { | ||
35 | struct iommu_table iommu_table; | ||
36 | } p5ioc2; | ||
37 | }; | ||
38 | }; | ||
39 | |||
40 | extern struct pci_ops pnv_pci_ops; | ||
41 | |||
42 | extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl, | ||
43 | void *tce_mem, u64 tce_size, | ||
44 | u64 dma_offset); | ||
45 | extern void pnv_pci_init_p5ioc2_hub(struct device_node *np); | ||
46 | |||
47 | |||
48 | #endif /* __POWERNV_PCI_H */ | ||
diff --git a/arch/powerpc/platforms/powernv/powernv.h b/arch/powerpc/platforms/powernv/powernv.h new file mode 100644 index 000000000000..8a9df7f9667e --- /dev/null +++ b/arch/powerpc/platforms/powernv/powernv.h | |||
@@ -0,0 +1,16 @@ | |||
1 | #ifndef _POWERNV_H | ||
2 | #define _POWERNV_H | ||
3 | |||
4 | #ifdef CONFIG_SMP | ||
5 | extern void pnv_smp_init(void); | ||
6 | #else | ||
7 | static inline void pnv_smp_init(void) { } | ||
8 | #endif | ||
9 | |||
10 | #ifdef CONFIG_PCI | ||
11 | extern void pnv_pci_init(void); | ||
12 | #else | ||
13 | static inline void pnv_pci_init(void) { } | ||
14 | #endif | ||
15 | |||
16 | #endif /* _POWERNV_H */ | ||
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c new file mode 100644 index 000000000000..467bd4ac6824 --- /dev/null +++ b/arch/powerpc/platforms/powernv/setup.c | |||
@@ -0,0 +1,196 @@ | |||
1 | /* | ||
2 | * PowerNV setup code. | ||
3 | * | ||
4 | * Copyright 2011 IBM Corp. | ||
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 | #undef DEBUG | ||
13 | |||
14 | #include <linux/cpu.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/sched.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/tty.h> | ||
19 | #include <linux/reboot.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/console.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/irq.h> | ||
24 | #include <linux/seq_file.h> | ||
25 | #include <linux/of.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/bug.h> | ||
28 | |||
29 | #include <asm/machdep.h> | ||
30 | #include <asm/firmware.h> | ||
31 | #include <asm/xics.h> | ||
32 | #include <asm/rtas.h> | ||
33 | #include <asm/opal.h> | ||
34 | #include <asm/xics.h> | ||
35 | |||
36 | #include "powernv.h" | ||
37 | |||
38 | static void __init pnv_setup_arch(void) | ||
39 | { | ||
40 | /* Initialize SMP */ | ||
41 | pnv_smp_init(); | ||
42 | |||
43 | /* Setup PCI */ | ||
44 | pnv_pci_init(); | ||
45 | |||
46 | /* Setup RTC and NVRAM callbacks */ | ||
47 | if (firmware_has_feature(FW_FEATURE_OPAL)) | ||
48 | opal_nvram_init(); | ||
49 | |||
50 | /* Enable NAP mode */ | ||
51 | powersave_nap = 1; | ||
52 | |||
53 | /* XXX PMCS */ | ||
54 | } | ||
55 | |||
56 | static void __init pnv_init_early(void) | ||
57 | { | ||
58 | #ifdef CONFIG_HVC_OPAL | ||
59 | if (firmware_has_feature(FW_FEATURE_OPAL)) | ||
60 | hvc_opal_init_early(); | ||
61 | else | ||
62 | #endif | ||
63 | add_preferred_console("hvc", 0, NULL); | ||
64 | } | ||
65 | |||
66 | static void __init pnv_init_IRQ(void) | ||
67 | { | ||
68 | xics_init(); | ||
69 | |||
70 | WARN_ON(!ppc_md.get_irq); | ||
71 | } | ||
72 | |||
73 | static void pnv_show_cpuinfo(struct seq_file *m) | ||
74 | { | ||
75 | struct device_node *root; | ||
76 | const char *model = ""; | ||
77 | |||
78 | root = of_find_node_by_path("/"); | ||
79 | if (root) | ||
80 | model = of_get_property(root, "model", NULL); | ||
81 | seq_printf(m, "machine\t\t: PowerNV %s\n", model); | ||
82 | if (firmware_has_feature(FW_FEATURE_OPALv2)) | ||
83 | seq_printf(m, "firmware\t: OPAL v2\n"); | ||
84 | else if (firmware_has_feature(FW_FEATURE_OPAL)) | ||
85 | seq_printf(m, "firmware\t: OPAL v1\n"); | ||
86 | else | ||
87 | seq_printf(m, "firmware\t: BML\n"); | ||
88 | of_node_put(root); | ||
89 | } | ||
90 | |||
91 | static void __noreturn pnv_restart(char *cmd) | ||
92 | { | ||
93 | long rc = OPAL_BUSY; | ||
94 | |||
95 | while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { | ||
96 | rc = opal_cec_reboot(); | ||
97 | if (rc == OPAL_BUSY_EVENT) | ||
98 | opal_poll_events(NULL); | ||
99 | else | ||
100 | mdelay(10); | ||
101 | } | ||
102 | for (;;) | ||
103 | opal_poll_events(NULL); | ||
104 | } | ||
105 | |||
106 | static void __noreturn pnv_power_off(void) | ||
107 | { | ||
108 | long rc = OPAL_BUSY; | ||
109 | |||
110 | while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { | ||
111 | rc = opal_cec_power_down(0); | ||
112 | if (rc == OPAL_BUSY_EVENT) | ||
113 | opal_poll_events(NULL); | ||
114 | else | ||
115 | mdelay(10); | ||
116 | } | ||
117 | for (;;) | ||
118 | opal_poll_events(NULL); | ||
119 | } | ||
120 | |||
121 | static void __noreturn pnv_halt(void) | ||
122 | { | ||
123 | pnv_power_off(); | ||
124 | } | ||
125 | |||
126 | static void pnv_progress(char *s, unsigned short hex) | ||
127 | { | ||
128 | } | ||
129 | |||
130 | #ifdef CONFIG_KEXEC | ||
131 | static void pnv_kexec_cpu_down(int crash_shutdown, int secondary) | ||
132 | { | ||
133 | xics_kexec_teardown_cpu(secondary); | ||
134 | } | ||
135 | #endif /* CONFIG_KEXEC */ | ||
136 | |||
137 | static void __init pnv_setup_machdep_opal(void) | ||
138 | { | ||
139 | ppc_md.get_boot_time = opal_get_boot_time; | ||
140 | ppc_md.get_rtc_time = opal_get_rtc_time; | ||
141 | ppc_md.set_rtc_time = opal_set_rtc_time; | ||
142 | ppc_md.restart = pnv_restart; | ||
143 | ppc_md.power_off = pnv_power_off; | ||
144 | ppc_md.halt = pnv_halt; | ||
145 | ppc_md.machine_check_exception = opal_machine_check; | ||
146 | } | ||
147 | |||
148 | #ifdef CONFIG_PPC_POWERNV_RTAS | ||
149 | static void __init pnv_setup_machdep_rtas(void) | ||
150 | { | ||
151 | if (rtas_token("get-time-of-day") != RTAS_UNKNOWN_SERVICE) { | ||
152 | ppc_md.get_boot_time = rtas_get_boot_time; | ||
153 | ppc_md.get_rtc_time = rtas_get_rtc_time; | ||
154 | ppc_md.set_rtc_time = rtas_set_rtc_time; | ||
155 | } | ||
156 | ppc_md.restart = rtas_restart; | ||
157 | ppc_md.power_off = rtas_power_off; | ||
158 | ppc_md.halt = rtas_halt; | ||
159 | } | ||
160 | #endif /* CONFIG_PPC_POWERNV_RTAS */ | ||
161 | |||
162 | static int __init pnv_probe(void) | ||
163 | { | ||
164 | unsigned long root = of_get_flat_dt_root(); | ||
165 | |||
166 | if (!of_flat_dt_is_compatible(root, "ibm,powernv")) | ||
167 | return 0; | ||
168 | |||
169 | hpte_init_native(); | ||
170 | |||
171 | if (firmware_has_feature(FW_FEATURE_OPAL)) | ||
172 | pnv_setup_machdep_opal(); | ||
173 | #ifdef CONFIG_PPC_POWERNV_RTAS | ||
174 | else if (rtas.base) | ||
175 | pnv_setup_machdep_rtas(); | ||
176 | #endif /* CONFIG_PPC_POWERNV_RTAS */ | ||
177 | |||
178 | pr_debug("PowerNV detected !\n"); | ||
179 | |||
180 | return 1; | ||
181 | } | ||
182 | |||
183 | define_machine(powernv) { | ||
184 | .name = "PowerNV", | ||
185 | .probe = pnv_probe, | ||
186 | .init_early = pnv_init_early, | ||
187 | .setup_arch = pnv_setup_arch, | ||
188 | .init_IRQ = pnv_init_IRQ, | ||
189 | .show_cpuinfo = pnv_show_cpuinfo, | ||
190 | .progress = pnv_progress, | ||
191 | .power_save = power7_idle, | ||
192 | .calibrate_decr = generic_calibrate_decr, | ||
193 | #ifdef CONFIG_KEXEC | ||
194 | .kexec_cpu_down = pnv_kexec_cpu_down, | ||
195 | #endif | ||
196 | }; | ||
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c new file mode 100644 index 000000000000..e87736685243 --- /dev/null +++ b/arch/powerpc/platforms/powernv/smp.c | |||
@@ -0,0 +1,182 @@ | |||
1 | /* | ||
2 | * SMP support for PowerNV machines. | ||
3 | * | ||
4 | * Copyright 2011 IBM Corp. | ||
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/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/sched.h> | ||
15 | #include <linux/smp.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/spinlock.h> | ||
20 | #include <linux/cpu.h> | ||
21 | |||
22 | #include <asm/irq.h> | ||
23 | #include <asm/smp.h> | ||
24 | #include <asm/paca.h> | ||
25 | #include <asm/machdep.h> | ||
26 | #include <asm/cputable.h> | ||
27 | #include <asm/firmware.h> | ||
28 | #include <asm/system.h> | ||
29 | #include <asm/rtas.h> | ||
30 | #include <asm/vdso_datapage.h> | ||
31 | #include <asm/cputhreads.h> | ||
32 | #include <asm/xics.h> | ||
33 | #include <asm/opal.h> | ||
34 | |||
35 | #include "powernv.h" | ||
36 | |||
37 | #ifdef DEBUG | ||
38 | #include <asm/udbg.h> | ||
39 | #define DBG(fmt...) udbg_printf(fmt) | ||
40 | #else | ||
41 | #define DBG(fmt...) | ||
42 | #endif | ||
43 | |||
44 | static void __cpuinit pnv_smp_setup_cpu(int cpu) | ||
45 | { | ||
46 | if (cpu != boot_cpuid) | ||
47 | xics_setup_cpu(); | ||
48 | } | ||
49 | |||
50 | static int pnv_smp_cpu_bootable(unsigned int nr) | ||
51 | { | ||
52 | /* Special case - we inhibit secondary thread startup | ||
53 | * during boot if the user requests it. | ||
54 | */ | ||
55 | if (system_state < SYSTEM_RUNNING && cpu_has_feature(CPU_FTR_SMT)) { | ||
56 | if (!smt_enabled_at_boot && cpu_thread_in_core(nr) != 0) | ||
57 | return 0; | ||
58 | if (smt_enabled_at_boot | ||
59 | && cpu_thread_in_core(nr) >= smt_enabled_at_boot) | ||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | return 1; | ||
64 | } | ||
65 | |||
66 | int __devinit pnv_smp_kick_cpu(int nr) | ||
67 | { | ||
68 | unsigned int pcpu = get_hard_smp_processor_id(nr); | ||
69 | unsigned long start_here = __pa(*((unsigned long *) | ||
70 | generic_secondary_smp_init)); | ||
71 | long rc; | ||
72 | |||
73 | BUG_ON(nr < 0 || nr >= NR_CPUS); | ||
74 | |||
75 | /* On OPAL v2 the CPU are still spinning inside OPAL itself, | ||
76 | * get them back now | ||
77 | */ | ||
78 | if (firmware_has_feature(FW_FEATURE_OPALv2)) { | ||
79 | pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", nr, pcpu); | ||
80 | rc = opal_start_cpu(pcpu, start_here); | ||
81 | if (rc != OPAL_SUCCESS) | ||
82 | pr_warn("OPAL Error %ld starting CPU %d\n", | ||
83 | rc, nr); | ||
84 | } | ||
85 | return smp_generic_kick_cpu(nr); | ||
86 | } | ||
87 | |||
88 | #ifdef CONFIG_HOTPLUG_CPU | ||
89 | |||
90 | static int pnv_smp_cpu_disable(void) | ||
91 | { | ||
92 | int cpu = smp_processor_id(); | ||
93 | |||
94 | /* This is identical to pSeries... might consolidate by | ||
95 | * moving migrate_irqs_away to a ppc_md with default to | ||
96 | * the generic fixup_irqs. --BenH. | ||
97 | */ | ||
98 | set_cpu_online(cpu, false); | ||
99 | vdso_data->processorCount--; | ||
100 | if (cpu == boot_cpuid) | ||
101 | boot_cpuid = cpumask_any(cpu_online_mask); | ||
102 | xics_migrate_irqs_away(); | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static void pnv_smp_cpu_kill_self(void) | ||
107 | { | ||
108 | unsigned int cpu; | ||
109 | |||
110 | /* If powersave_nap is enabled, use NAP mode, else just | ||
111 | * spin aimlessly | ||
112 | */ | ||
113 | if (!powersave_nap) { | ||
114 | generic_mach_cpu_die(); | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | /* Standard hot unplug procedure */ | ||
119 | local_irq_disable(); | ||
120 | idle_task_exit(); | ||
121 | current->active_mm = NULL; /* for sanity */ | ||
122 | cpu = smp_processor_id(); | ||
123 | DBG("CPU%d offline\n", cpu); | ||
124 | generic_set_cpu_dead(cpu); | ||
125 | smp_wmb(); | ||
126 | |||
127 | /* We don't want to take decrementer interrupts while we are offline, | ||
128 | * so clear LPCR:PECE1. We keep PECE2 enabled. | ||
129 | */ | ||
130 | mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1); | ||
131 | while (!generic_check_cpu_restart(cpu)) { | ||
132 | power7_idle(); | ||
133 | if (!generic_check_cpu_restart(cpu)) { | ||
134 | DBG("CPU%d Unexpected exit while offline !\n", cpu); | ||
135 | /* We may be getting an IPI, so we re-enable | ||
136 | * interrupts to process it, it will be ignored | ||
137 | * since we aren't online (hopefully) | ||
138 | */ | ||
139 | local_irq_enable(); | ||
140 | local_irq_disable(); | ||
141 | } | ||
142 | } | ||
143 | mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_PECE1); | ||
144 | DBG("CPU%d coming online...\n", cpu); | ||
145 | } | ||
146 | |||
147 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
148 | |||
149 | static struct smp_ops_t pnv_smp_ops = { | ||
150 | .message_pass = smp_muxed_ipi_message_pass, | ||
151 | .cause_ipi = NULL, /* Filled at runtime by xics_smp_probe() */ | ||
152 | .probe = xics_smp_probe, | ||
153 | .kick_cpu = pnv_smp_kick_cpu, | ||
154 | .setup_cpu = pnv_smp_setup_cpu, | ||
155 | .cpu_bootable = pnv_smp_cpu_bootable, | ||
156 | #ifdef CONFIG_HOTPLUG_CPU | ||
157 | .cpu_disable = pnv_smp_cpu_disable, | ||
158 | .cpu_die = generic_cpu_die, | ||
159 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
160 | }; | ||
161 | |||
162 | /* This is called very early during platform setup_arch */ | ||
163 | void __init pnv_smp_init(void) | ||
164 | { | ||
165 | smp_ops = &pnv_smp_ops; | ||
166 | |||
167 | /* XXX We don't yet have a proper entry point from HAL, for | ||
168 | * now we rely on kexec-style entry from BML | ||
169 | */ | ||
170 | |||
171 | #ifdef CONFIG_PPC_RTAS | ||
172 | /* Non-lpar has additional take/give timebase */ | ||
173 | if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { | ||
174 | smp_ops->give_timebase = rtas_give_timebase; | ||
175 | smp_ops->take_timebase = rtas_take_timebase; | ||
176 | } | ||
177 | #endif /* CONFIG_PPC_RTAS */ | ||
178 | |||
179 | #ifdef CONFIG_HOTPLUG_CPU | ||
180 | ppc_md.cpu_die = pnv_smp_cpu_kill_self; | ||
181 | #endif | ||
182 | } | ||
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig index dfe316b161a9..476d9d9b2405 100644 --- a/arch/powerpc/platforms/ps3/Kconfig +++ b/arch/powerpc/platforms/ps3/Kconfig | |||
@@ -148,4 +148,16 @@ config PS3_LPM | |||
148 | profiling support of the Cell processor with programs like | 148 | profiling support of the Cell processor with programs like |
149 | oprofile and perfmon2, then say Y or M, otherwise say N. | 149 | oprofile and perfmon2, then say Y or M, otherwise say N. |
150 | 150 | ||
151 | config PS3GELIC_UDBG | ||
152 | bool "PS3 udbg output via UDP broadcasts on Ethernet" | ||
153 | depends on PPC_PS3 | ||
154 | help | ||
155 | Enables udbg early debugging output by sending broadcast UDP | ||
156 | via the Ethernet port (UDP port number 18194). | ||
157 | |||
158 | This driver uses a trivial implementation and is independent | ||
159 | from the main network driver. | ||
160 | |||
161 | If in doubt, say N here. | ||
162 | |||
151 | endmenu | 163 | endmenu |
diff --git a/arch/powerpc/platforms/ps3/Makefile b/arch/powerpc/platforms/ps3/Makefile index ac1bdf844eca..02b9e636dab7 100644 --- a/arch/powerpc/platforms/ps3/Makefile +++ b/arch/powerpc/platforms/ps3/Makefile | |||
@@ -2,6 +2,7 @@ obj-y += setup.o mm.o time.o hvcall.o htab.o repository.o | |||
2 | obj-y += interrupt.o exports.o os-area.o | 2 | obj-y += interrupt.o exports.o os-area.o |
3 | obj-y += system-bus.o | 3 | obj-y += system-bus.o |
4 | 4 | ||
5 | obj-$(CONFIG_PS3GELIC_UDBG) += gelic_udbg.o | ||
5 | obj-$(CONFIG_SMP) += smp.o | 6 | obj-$(CONFIG_SMP) += smp.o |
6 | obj-$(CONFIG_SPU_BASE) += spu.o | 7 | obj-$(CONFIG_SPU_BASE) += spu.o |
7 | obj-y += device-init.o | 8 | obj-y += device-init.o |
diff --git a/arch/powerpc/platforms/ps3/gelic_udbg.c b/arch/powerpc/platforms/ps3/gelic_udbg.c new file mode 100644 index 000000000000..20b46a19a48f --- /dev/null +++ b/arch/powerpc/platforms/ps3/gelic_udbg.c | |||
@@ -0,0 +1,273 @@ | |||
1 | /* | ||
2 | * udbg debug output routine via GELIC UDP broadcasts | ||
3 | * | ||
4 | * Copyright (C) 2007 Sony Computer Entertainment Inc. | ||
5 | * Copyright 2006, 2007 Sony Corporation | ||
6 | * Copyright (C) 2010 Hector Martin <hector@marcansoft.com> | ||
7 | * Copyright (C) 2011 Andre Heider <a.heider@gmail.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version 2 | ||
12 | * of the License, or (at your option) any later version. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <asm/io.h> | ||
17 | #include <asm/udbg.h> | ||
18 | #include <asm/lv1call.h> | ||
19 | |||
20 | #define GELIC_BUS_ID 1 | ||
21 | #define GELIC_DEVICE_ID 0 | ||
22 | #define GELIC_DEBUG_PORT 18194 | ||
23 | #define GELIC_MAX_MESSAGE_SIZE 1000 | ||
24 | |||
25 | #define GELIC_LV1_GET_MAC_ADDRESS 1 | ||
26 | #define GELIC_LV1_GET_VLAN_ID 4 | ||
27 | #define GELIC_LV1_VLAN_TX_ETHERNET_0 2 | ||
28 | |||
29 | #define GELIC_DESCR_DMA_STAT_MASK 0xf0000000 | ||
30 | #define GELIC_DESCR_DMA_CARDOWNED 0xa0000000 | ||
31 | |||
32 | #define GELIC_DESCR_TX_DMA_IKE 0x00080000 | ||
33 | #define GELIC_DESCR_TX_DMA_NO_CHKSUM 0x00000000 | ||
34 | #define GELIC_DESCR_TX_DMA_FRAME_TAIL 0x00040000 | ||
35 | |||
36 | #define GELIC_DESCR_DMA_CMD_NO_CHKSUM (GELIC_DESCR_DMA_CARDOWNED | \ | ||
37 | GELIC_DESCR_TX_DMA_IKE | \ | ||
38 | GELIC_DESCR_TX_DMA_NO_CHKSUM) | ||
39 | |||
40 | static u64 bus_addr; | ||
41 | |||
42 | struct gelic_descr { | ||
43 | /* as defined by the hardware */ | ||
44 | __be32 buf_addr; | ||
45 | __be32 buf_size; | ||
46 | __be32 next_descr_addr; | ||
47 | __be32 dmac_cmd_status; | ||
48 | __be32 result_size; | ||
49 | __be32 valid_size; /* all zeroes for tx */ | ||
50 | __be32 data_status; | ||
51 | __be32 data_error; /* all zeroes for tx */ | ||
52 | } __attribute__((aligned(32))); | ||
53 | |||
54 | struct debug_block { | ||
55 | struct gelic_descr descr; | ||
56 | u8 pkt[1520]; | ||
57 | } __packed; | ||
58 | |||
59 | struct ethhdr { | ||
60 | u8 dest[6]; | ||
61 | u8 src[6]; | ||
62 | u16 type; | ||
63 | } __packed; | ||
64 | |||
65 | struct vlantag { | ||
66 | u16 vlan; | ||
67 | u16 subtype; | ||
68 | } __packed; | ||
69 | |||
70 | struct iphdr { | ||
71 | u8 ver_len; | ||
72 | u8 dscp_ecn; | ||
73 | u16 total_length; | ||
74 | u16 ident; | ||
75 | u16 frag_off_flags; | ||
76 | u8 ttl; | ||
77 | u8 proto; | ||
78 | u16 checksum; | ||
79 | u32 src; | ||
80 | u32 dest; | ||
81 | } __packed; | ||
82 | |||
83 | struct udphdr { | ||
84 | u16 src; | ||
85 | u16 dest; | ||
86 | u16 len; | ||
87 | u16 checksum; | ||
88 | } __packed; | ||
89 | |||
90 | static __iomem struct ethhdr *h_eth; | ||
91 | static __iomem struct vlantag *h_vlan; | ||
92 | static __iomem struct iphdr *h_ip; | ||
93 | static __iomem struct udphdr *h_udp; | ||
94 | |||
95 | static __iomem char *pmsg; | ||
96 | static __iomem char *pmsgc; | ||
97 | |||
98 | static __iomem struct debug_block dbg __attribute__((aligned(32))); | ||
99 | |||
100 | static int header_size; | ||
101 | |||
102 | static void map_dma_mem(int bus_id, int dev_id, void *start, size_t len, | ||
103 | u64 *real_bus_addr) | ||
104 | { | ||
105 | s64 result; | ||
106 | u64 real_addr = ((u64)start) & 0x0fffffffffffffffUL; | ||
107 | u64 real_end = real_addr + len; | ||
108 | u64 map_start = real_addr & ~0xfff; | ||
109 | u64 map_end = (real_end + 0xfff) & ~0xfff; | ||
110 | u64 bus_addr = 0; | ||
111 | |||
112 | u64 flags = 0xf800000000000000UL; | ||
113 | |||
114 | result = lv1_allocate_device_dma_region(bus_id, dev_id, | ||
115 | map_end - map_start, 12, 0, | ||
116 | &bus_addr); | ||
117 | if (result) | ||
118 | lv1_panic(0); | ||
119 | |||
120 | result = lv1_map_device_dma_region(bus_id, dev_id, map_start, | ||
121 | bus_addr, map_end - map_start, | ||
122 | flags); | ||
123 | if (result) | ||
124 | lv1_panic(0); | ||
125 | |||
126 | *real_bus_addr = bus_addr + real_addr - map_start; | ||
127 | } | ||
128 | |||
129 | static int unmap_dma_mem(int bus_id, int dev_id, u64 bus_addr, size_t len) | ||
130 | { | ||
131 | s64 result; | ||
132 | u64 real_bus_addr; | ||
133 | |||
134 | real_bus_addr = bus_addr & ~0xfff; | ||
135 | len += bus_addr - real_bus_addr; | ||
136 | len = (len + 0xfff) & ~0xfff; | ||
137 | |||
138 | result = lv1_unmap_device_dma_region(bus_id, dev_id, real_bus_addr, | ||
139 | len); | ||
140 | if (result) | ||
141 | return result; | ||
142 | |||
143 | return lv1_free_device_dma_region(bus_id, dev_id, real_bus_addr); | ||
144 | } | ||
145 | |||
146 | static void gelic_debug_init(void) | ||
147 | { | ||
148 | s64 result; | ||
149 | u64 v2; | ||
150 | u64 mac; | ||
151 | u64 vlan_id; | ||
152 | |||
153 | result = lv1_open_device(GELIC_BUS_ID, GELIC_DEVICE_ID, 0); | ||
154 | if (result) | ||
155 | lv1_panic(0); | ||
156 | |||
157 | map_dma_mem(GELIC_BUS_ID, GELIC_DEVICE_ID, &dbg, sizeof(dbg), | ||
158 | &bus_addr); | ||
159 | |||
160 | memset(&dbg, 0, sizeof(dbg)); | ||
161 | |||
162 | dbg.descr.buf_addr = bus_addr + offsetof(struct debug_block, pkt); | ||
163 | |||
164 | wmb(); | ||
165 | |||
166 | result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID, | ||
167 | GELIC_LV1_GET_MAC_ADDRESS, 0, 0, 0, | ||
168 | &mac, &v2); | ||
169 | if (result) | ||
170 | lv1_panic(0); | ||
171 | |||
172 | mac <<= 16; | ||
173 | |||
174 | h_eth = (struct ethhdr *)dbg.pkt; | ||
175 | |||
176 | memset(&h_eth->dest, 0xff, 6); | ||
177 | memcpy(&h_eth->src, &mac, 6); | ||
178 | |||
179 | header_size = sizeof(struct ethhdr); | ||
180 | |||
181 | result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID, | ||
182 | GELIC_LV1_GET_VLAN_ID, | ||
183 | GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0, | ||
184 | &vlan_id, &v2); | ||
185 | if (!result) { | ||
186 | h_eth->type = 0x8100; | ||
187 | |||
188 | header_size += sizeof(struct vlantag); | ||
189 | h_vlan = (struct vlantag *)(h_eth + 1); | ||
190 | h_vlan->vlan = vlan_id; | ||
191 | h_vlan->subtype = 0x0800; | ||
192 | h_ip = (struct iphdr *)(h_vlan + 1); | ||
193 | } else { | ||
194 | h_eth->type = 0x0800; | ||
195 | h_ip = (struct iphdr *)(h_eth + 1); | ||
196 | } | ||
197 | |||
198 | header_size += sizeof(struct iphdr); | ||
199 | h_ip->ver_len = 0x45; | ||
200 | h_ip->ttl = 10; | ||
201 | h_ip->proto = 0x11; | ||
202 | h_ip->src = 0x00000000; | ||
203 | h_ip->dest = 0xffffffff; | ||
204 | |||
205 | header_size += sizeof(struct udphdr); | ||
206 | h_udp = (struct udphdr *)(h_ip + 1); | ||
207 | h_udp->src = GELIC_DEBUG_PORT; | ||
208 | h_udp->dest = GELIC_DEBUG_PORT; | ||
209 | |||
210 | pmsgc = pmsg = (char *)(h_udp + 1); | ||
211 | } | ||
212 | |||
213 | static void gelic_debug_shutdown(void) | ||
214 | { | ||
215 | if (bus_addr) | ||
216 | unmap_dma_mem(GELIC_BUS_ID, GELIC_DEVICE_ID, | ||
217 | bus_addr, sizeof(dbg)); | ||
218 | lv1_close_device(GELIC_BUS_ID, GELIC_DEVICE_ID); | ||
219 | } | ||
220 | |||
221 | static void gelic_sendbuf(int msgsize) | ||
222 | { | ||
223 | u16 *p; | ||
224 | u32 sum; | ||
225 | int i; | ||
226 | |||
227 | dbg.descr.buf_size = header_size + msgsize; | ||
228 | h_ip->total_length = msgsize + sizeof(struct udphdr) + | ||
229 | sizeof(struct iphdr); | ||
230 | h_udp->len = msgsize + sizeof(struct udphdr); | ||
231 | |||
232 | h_ip->checksum = 0; | ||
233 | sum = 0; | ||
234 | p = (u16 *)h_ip; | ||
235 | for (i = 0; i < 5; i++) | ||
236 | sum += *p++; | ||
237 | h_ip->checksum = ~(sum + (sum >> 16)); | ||
238 | |||
239 | dbg.descr.dmac_cmd_status = GELIC_DESCR_DMA_CMD_NO_CHKSUM | | ||
240 | GELIC_DESCR_TX_DMA_FRAME_TAIL; | ||
241 | dbg.descr.result_size = 0; | ||
242 | dbg.descr.data_status = 0; | ||
243 | |||
244 | wmb(); | ||
245 | |||
246 | lv1_net_start_tx_dma(GELIC_BUS_ID, GELIC_DEVICE_ID, bus_addr, 0); | ||
247 | |||
248 | while ((dbg.descr.dmac_cmd_status & GELIC_DESCR_DMA_STAT_MASK) == | ||
249 | GELIC_DESCR_DMA_CARDOWNED) | ||
250 | cpu_relax(); | ||
251 | } | ||
252 | |||
253 | static void ps3gelic_udbg_putc(char ch) | ||
254 | { | ||
255 | *pmsgc++ = ch; | ||
256 | if (ch == '\n' || (pmsgc-pmsg) >= GELIC_MAX_MESSAGE_SIZE) { | ||
257 | gelic_sendbuf(pmsgc-pmsg); | ||
258 | pmsgc = pmsg; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | void __init udbg_init_ps3gelic(void) | ||
263 | { | ||
264 | gelic_debug_init(); | ||
265 | udbg_putc = ps3gelic_udbg_putc; | ||
266 | } | ||
267 | |||
268 | void udbg_shutdown_ps3gelic(void) | ||
269 | { | ||
270 | udbg_putc = NULL; | ||
271 | gelic_debug_shutdown(); | ||
272 | } | ||
273 | EXPORT_SYMBOL(udbg_shutdown_ps3gelic); | ||
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 23083c397528..688141c76e03 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c | |||
@@ -695,12 +695,18 @@ static int ps3_dma_supported(struct device *_dev, u64 mask) | |||
695 | return mask >= DMA_BIT_MASK(32); | 695 | return mask >= DMA_BIT_MASK(32); |
696 | } | 696 | } |
697 | 697 | ||
698 | static u64 ps3_dma_get_required_mask(struct device *_dev) | ||
699 | { | ||
700 | return DMA_BIT_MASK(32); | ||
701 | } | ||
702 | |||
698 | static struct dma_map_ops ps3_sb_dma_ops = { | 703 | static struct dma_map_ops ps3_sb_dma_ops = { |
699 | .alloc_coherent = ps3_alloc_coherent, | 704 | .alloc_coherent = ps3_alloc_coherent, |
700 | .free_coherent = ps3_free_coherent, | 705 | .free_coherent = ps3_free_coherent, |
701 | .map_sg = ps3_sb_map_sg, | 706 | .map_sg = ps3_sb_map_sg, |
702 | .unmap_sg = ps3_sb_unmap_sg, | 707 | .unmap_sg = ps3_sb_unmap_sg, |
703 | .dma_supported = ps3_dma_supported, | 708 | .dma_supported = ps3_dma_supported, |
709 | .get_required_mask = ps3_dma_get_required_mask, | ||
704 | .map_page = ps3_sb_map_page, | 710 | .map_page = ps3_sb_map_page, |
705 | .unmap_page = ps3_unmap_page, | 711 | .unmap_page = ps3_unmap_page, |
706 | }; | 712 | }; |
@@ -711,6 +717,7 @@ static struct dma_map_ops ps3_ioc0_dma_ops = { | |||
711 | .map_sg = ps3_ioc0_map_sg, | 717 | .map_sg = ps3_ioc0_map_sg, |
712 | .unmap_sg = ps3_ioc0_unmap_sg, | 718 | .unmap_sg = ps3_ioc0_unmap_sg, |
713 | .dma_supported = ps3_dma_supported, | 719 | .dma_supported = ps3_dma_supported, |
720 | .get_required_mask = ps3_dma_get_required_mask, | ||
714 | .map_page = ps3_ioc0_map_page, | 721 | .map_page = ps3_ioc0_map_page, |
715 | .unmap_page = ps3_unmap_page, | 722 | .unmap_page = ps3_unmap_page, |
716 | }; | 723 | }; |
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index 05cf4769b88c..c81f6bb9c10f 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig | |||
@@ -15,6 +15,7 @@ config PPC_PSERIES | |||
15 | select PPC_UDBG_16550 | 15 | select PPC_UDBG_16550 |
16 | select PPC_NATIVE | 16 | select PPC_NATIVE |
17 | select PPC_PCI_CHOICE if EXPERT | 17 | select PPC_PCI_CHOICE if EXPERT |
18 | select ZLIB_DEFLATE | ||
18 | default y | 19 | default y |
19 | 20 | ||
20 | config PPC_SPLPAR | 21 | config PPC_SPLPAR |
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index e9be25bc571b..0f1b706506ed 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c | |||
@@ -112,6 +112,7 @@ void dlpar_free_cc_nodes(struct device_node *dn) | |||
112 | dlpar_free_one_cc_node(dn); | 112 | dlpar_free_one_cc_node(dn); |
113 | } | 113 | } |
114 | 114 | ||
115 | #define COMPLETE 0 | ||
115 | #define NEXT_SIBLING 1 | 116 | #define NEXT_SIBLING 1 |
116 | #define NEXT_CHILD 2 | 117 | #define NEXT_CHILD 2 |
117 | #define NEXT_PROPERTY 3 | 118 | #define NEXT_PROPERTY 3 |
@@ -158,6 +159,9 @@ struct device_node *dlpar_configure_connector(u32 drc_index) | |||
158 | spin_unlock(&rtas_data_buf_lock); | 159 | spin_unlock(&rtas_data_buf_lock); |
159 | 160 | ||
160 | switch (rc) { | 161 | switch (rc) { |
162 | case COMPLETE: | ||
163 | break; | ||
164 | |||
161 | case NEXT_SIBLING: | 165 | case NEXT_SIBLING: |
162 | dn = dlpar_parse_cc_node(ccwa); | 166 | dn = dlpar_parse_cc_node(ccwa); |
163 | if (!dn) | 167 | if (!dn) |
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index ada6e07532ec..d42f37d8a440 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
@@ -1338,7 +1338,7 @@ static const struct file_operations proc_eeh_operations = { | |||
1338 | static int __init eeh_init_proc(void) | 1338 | static int __init eeh_init_proc(void) |
1339 | { | 1339 | { |
1340 | if (machine_is(pseries)) | 1340 | if (machine_is(pseries)) |
1341 | proc_create("ppc64/eeh", 0, NULL, &proc_eeh_operations); | 1341 | proc_create("powerpc/eeh", 0, NULL, &proc_eeh_operations); |
1342 | return 0; | 1342 | return 0; |
1343 | } | 1343 | } |
1344 | __initcall(eeh_init_proc); | 1344 | __initcall(eeh_init_proc); |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 01faab9456ca..5905a3b9f7e6 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -939,14 +939,14 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) | |||
939 | if (ret) { | 939 | if (ret) { |
940 | dev_info(&dev->dev, "failed to map direct window for %s: %d\n", | 940 | dev_info(&dev->dev, "failed to map direct window for %s: %d\n", |
941 | dn->full_name, ret); | 941 | dn->full_name, ret); |
942 | goto out_clear_window; | 942 | goto out_free_window; |
943 | } | 943 | } |
944 | 944 | ||
945 | ret = prom_add_property(pdn, win64); | 945 | ret = prom_add_property(pdn, win64); |
946 | if (ret) { | 946 | if (ret) { |
947 | dev_err(&dev->dev, "unable to add dma window property for %s: %d", | 947 | dev_err(&dev->dev, "unable to add dma window property for %s: %d", |
948 | pdn->full_name, ret); | 948 | pdn->full_name, ret); |
949 | goto out_clear_window; | 949 | goto out_free_window; |
950 | } | 950 | } |
951 | 951 | ||
952 | window->device = pdn; | 952 | window->device = pdn; |
@@ -958,6 +958,9 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) | |||
958 | dma_addr = of_read_number(&create.addr_hi, 2); | 958 | dma_addr = of_read_number(&create.addr_hi, 2); |
959 | goto out_unlock; | 959 | goto out_unlock; |
960 | 960 | ||
961 | out_free_window: | ||
962 | kfree(window); | ||
963 | |||
961 | out_clear_window: | 964 | out_clear_window: |
962 | remove_ddw(pdn); | 965 | remove_ddw(pdn); |
963 | 966 | ||
@@ -1077,12 +1080,38 @@ check_mask: | |||
1077 | return 0; | 1080 | return 0; |
1078 | } | 1081 | } |
1079 | 1082 | ||
1083 | static u64 dma_get_required_mask_pSeriesLP(struct device *dev) | ||
1084 | { | ||
1085 | if (!dev->dma_mask) | ||
1086 | return 0; | ||
1087 | |||
1088 | if (!disable_ddw && dev_is_pci(dev)) { | ||
1089 | struct pci_dev *pdev = to_pci_dev(dev); | ||
1090 | struct device_node *dn; | ||
1091 | |||
1092 | dn = pci_device_to_OF_node(pdev); | ||
1093 | |||
1094 | /* search upwards for ibm,dma-window */ | ||
1095 | for (; dn && PCI_DN(dn) && !PCI_DN(dn)->iommu_table; | ||
1096 | dn = dn->parent) | ||
1097 | if (of_get_property(dn, "ibm,dma-window", NULL)) | ||
1098 | break; | ||
1099 | /* if there is a ibm,ddw-applicable property require 64 bits */ | ||
1100 | if (dn && PCI_DN(dn) && | ||
1101 | of_get_property(dn, "ibm,ddw-applicable", NULL)) | ||
1102 | return DMA_BIT_MASK(64); | ||
1103 | } | ||
1104 | |||
1105 | return dma_iommu_ops.get_required_mask(dev); | ||
1106 | } | ||
1107 | |||
1080 | #else /* CONFIG_PCI */ | 1108 | #else /* CONFIG_PCI */ |
1081 | #define pci_dma_bus_setup_pSeries NULL | 1109 | #define pci_dma_bus_setup_pSeries NULL |
1082 | #define pci_dma_dev_setup_pSeries NULL | 1110 | #define pci_dma_dev_setup_pSeries NULL |
1083 | #define pci_dma_bus_setup_pSeriesLP NULL | 1111 | #define pci_dma_bus_setup_pSeriesLP NULL |
1084 | #define pci_dma_dev_setup_pSeriesLP NULL | 1112 | #define pci_dma_dev_setup_pSeriesLP NULL |
1085 | #define dma_set_mask_pSeriesLP NULL | 1113 | #define dma_set_mask_pSeriesLP NULL |
1114 | #define dma_get_required_mask_pSeriesLP NULL | ||
1086 | #endif /* !CONFIG_PCI */ | 1115 | #endif /* !CONFIG_PCI */ |
1087 | 1116 | ||
1088 | static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action, | 1117 | static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action, |
@@ -1186,6 +1215,7 @@ void iommu_init_early_pSeries(void) | |||
1186 | ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeriesLP; | 1215 | ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeriesLP; |
1187 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeriesLP; | 1216 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeriesLP; |
1188 | ppc_md.dma_set_mask = dma_set_mask_pSeriesLP; | 1217 | ppc_md.dma_set_mask = dma_set_mask_pSeriesLP; |
1218 | ppc_md.dma_get_required_mask = dma_get_required_mask_pSeriesLP; | ||
1189 | } else { | 1219 | } else { |
1190 | ppc_md.tce_build = tce_build_pSeries; | 1220 | ppc_md.tce_build = tce_build_pSeries; |
1191 | ppc_md.tce_free = tce_free_pSeries; | 1221 | ppc_md.tce_free = tce_free_pSeries; |
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 00cc3a094885..a76b22844d18 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/kmsg_dump.h> | 20 | #include <linux/kmsg_dump.h> |
21 | #include <linux/ctype.h> | ||
22 | #include <linux/zlib.h> | ||
21 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
22 | #include <asm/nvram.h> | 24 | #include <asm/nvram.h> |
23 | #include <asm/rtas.h> | 25 | #include <asm/rtas.h> |
@@ -78,8 +80,41 @@ static struct kmsg_dumper nvram_kmsg_dumper = { | |||
78 | #define NVRAM_RTAS_READ_TIMEOUT 5 /* seconds */ | 80 | #define NVRAM_RTAS_READ_TIMEOUT 5 /* seconds */ |
79 | static unsigned long last_unread_rtas_event; /* timestamp */ | 81 | static unsigned long last_unread_rtas_event; /* timestamp */ |
80 | 82 | ||
81 | /* We preallocate oops_buf during init to avoid kmalloc during oops/panic. */ | 83 | /* |
82 | static char *oops_buf; | 84 | * For capturing and compressing an oops or panic report... |
85 | |||
86 | * big_oops_buf[] holds the uncompressed text we're capturing. | ||
87 | * | ||
88 | * oops_buf[] holds the compressed text, preceded by a prefix. | ||
89 | * The prefix is just a u16 holding the length of the compressed* text. | ||
90 | * (*Or uncompressed, if compression fails.) oops_buf[] gets written | ||
91 | * to NVRAM. | ||
92 | * | ||
93 | * oops_len points to the prefix. oops_data points to the compressed text. | ||
94 | * | ||
95 | * +- oops_buf | ||
96 | * | +- oops_data | ||
97 | * v v | ||
98 | * +------------+-----------------------------------------------+ | ||
99 | * | length | text | | ||
100 | * | (2 bytes) | (oops_data_sz bytes) | | ||
101 | * +------------+-----------------------------------------------+ | ||
102 | * ^ | ||
103 | * +- oops_len | ||
104 | * | ||
105 | * We preallocate these buffers during init to avoid kmalloc during oops/panic. | ||
106 | */ | ||
107 | static size_t big_oops_buf_sz; | ||
108 | static char *big_oops_buf, *oops_buf; | ||
109 | static u16 *oops_len; | ||
110 | static char *oops_data; | ||
111 | static size_t oops_data_sz; | ||
112 | |||
113 | /* Compression parameters */ | ||
114 | #define COMPR_LEVEL 6 | ||
115 | #define WINDOW_BITS 12 | ||
116 | #define MEM_LEVEL 4 | ||
117 | static struct z_stream_s stream; | ||
83 | 118 | ||
84 | static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index) | 119 | static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index) |
85 | { | 120 | { |
@@ -387,11 +422,44 @@ static void __init nvram_init_oops_partition(int rtas_partition_exists) | |||
387 | sizeof(rtas_log_partition)); | 422 | sizeof(rtas_log_partition)); |
388 | } | 423 | } |
389 | oops_buf = kmalloc(oops_log_partition.size, GFP_KERNEL); | 424 | oops_buf = kmalloc(oops_log_partition.size, GFP_KERNEL); |
425 | if (!oops_buf) { | ||
426 | pr_err("nvram: No memory for %s partition\n", | ||
427 | oops_log_partition.name); | ||
428 | return; | ||
429 | } | ||
430 | oops_len = (u16*) oops_buf; | ||
431 | oops_data = oops_buf + sizeof(u16); | ||
432 | oops_data_sz = oops_log_partition.size - sizeof(u16); | ||
433 | |||
434 | /* | ||
435 | * Figure compression (preceded by elimination of each line's <n> | ||
436 | * severity prefix) will reduce the oops/panic report to at most | ||
437 | * 45% of its original size. | ||
438 | */ | ||
439 | big_oops_buf_sz = (oops_data_sz * 100) / 45; | ||
440 | big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL); | ||
441 | if (big_oops_buf) { | ||
442 | stream.workspace = kmalloc(zlib_deflate_workspacesize( | ||
443 | WINDOW_BITS, MEM_LEVEL), GFP_KERNEL); | ||
444 | if (!stream.workspace) { | ||
445 | pr_err("nvram: No memory for compression workspace; " | ||
446 | "skipping compression of %s partition data\n", | ||
447 | oops_log_partition.name); | ||
448 | kfree(big_oops_buf); | ||
449 | big_oops_buf = NULL; | ||
450 | } | ||
451 | } else { | ||
452 | pr_err("No memory for uncompressed %s data; " | ||
453 | "skipping compression\n", oops_log_partition.name); | ||
454 | stream.workspace = NULL; | ||
455 | } | ||
456 | |||
390 | rc = kmsg_dump_register(&nvram_kmsg_dumper); | 457 | rc = kmsg_dump_register(&nvram_kmsg_dumper); |
391 | if (rc != 0) { | 458 | if (rc != 0) { |
392 | pr_err("nvram: kmsg_dump_register() failed; returned %d\n", rc); | 459 | pr_err("nvram: kmsg_dump_register() failed; returned %d\n", rc); |
393 | kfree(oops_buf); | 460 | kfree(oops_buf); |
394 | return; | 461 | kfree(big_oops_buf); |
462 | kfree(stream.workspace); | ||
395 | } | 463 | } |
396 | } | 464 | } |
397 | 465 | ||
@@ -473,7 +541,83 @@ static int clobbering_unread_rtas_event(void) | |||
473 | NVRAM_RTAS_READ_TIMEOUT); | 541 | NVRAM_RTAS_READ_TIMEOUT); |
474 | } | 542 | } |
475 | 543 | ||
476 | /* our kmsg_dump callback */ | 544 | /* Squeeze out each line's <n> severity prefix. */ |
545 | static size_t elide_severities(char *buf, size_t len) | ||
546 | { | ||
547 | char *in, *out, *buf_end = buf + len; | ||
548 | /* Assume a <n> at the very beginning marks the start of a line. */ | ||
549 | int newline = 1; | ||
550 | |||
551 | in = out = buf; | ||
552 | while (in < buf_end) { | ||
553 | if (newline && in+3 <= buf_end && | ||
554 | *in == '<' && isdigit(in[1]) && in[2] == '>') { | ||
555 | in += 3; | ||
556 | newline = 0; | ||
557 | } else { | ||
558 | newline = (*in == '\n'); | ||
559 | *out++ = *in++; | ||
560 | } | ||
561 | } | ||
562 | return out - buf; | ||
563 | } | ||
564 | |||
565 | /* Derived from logfs_compress() */ | ||
566 | static int nvram_compress(const void *in, void *out, size_t inlen, | ||
567 | size_t outlen) | ||
568 | { | ||
569 | int err, ret; | ||
570 | |||
571 | ret = -EIO; | ||
572 | err = zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS, | ||
573 | MEM_LEVEL, Z_DEFAULT_STRATEGY); | ||
574 | if (err != Z_OK) | ||
575 | goto error; | ||
576 | |||
577 | stream.next_in = in; | ||
578 | stream.avail_in = inlen; | ||
579 | stream.total_in = 0; | ||
580 | stream.next_out = out; | ||
581 | stream.avail_out = outlen; | ||
582 | stream.total_out = 0; | ||
583 | |||
584 | err = zlib_deflate(&stream, Z_FINISH); | ||
585 | if (err != Z_STREAM_END) | ||
586 | goto error; | ||
587 | |||
588 | err = zlib_deflateEnd(&stream); | ||
589 | if (err != Z_OK) | ||
590 | goto error; | ||
591 | |||
592 | if (stream.total_out >= stream.total_in) | ||
593 | goto error; | ||
594 | |||
595 | ret = stream.total_out; | ||
596 | error: | ||
597 | return ret; | ||
598 | } | ||
599 | |||
600 | /* Compress the text from big_oops_buf into oops_buf. */ | ||
601 | static int zip_oops(size_t text_len) | ||
602 | { | ||
603 | int zipped_len = nvram_compress(big_oops_buf, oops_data, text_len, | ||
604 | oops_data_sz); | ||
605 | if (zipped_len < 0) { | ||
606 | pr_err("nvram: compression failed; returned %d\n", zipped_len); | ||
607 | pr_err("nvram: logging uncompressed oops/panic report\n"); | ||
608 | return -1; | ||
609 | } | ||
610 | *oops_len = (u16) zipped_len; | ||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | /* | ||
615 | * This is our kmsg_dump callback, called after an oops or panic report | ||
616 | * has been written to the printk buffer. We want to capture as much | ||
617 | * of the printk buffer as possible. First, capture as much as we can | ||
618 | * that we think will compress sufficiently to fit in the lnx,oops-log | ||
619 | * partition. If that's too much, go back and capture uncompressed text. | ||
620 | */ | ||
477 | static void oops_to_nvram(struct kmsg_dumper *dumper, | 621 | static void oops_to_nvram(struct kmsg_dumper *dumper, |
478 | enum kmsg_dump_reason reason, | 622 | enum kmsg_dump_reason reason, |
479 | const char *old_msgs, unsigned long old_len, | 623 | const char *old_msgs, unsigned long old_len, |
@@ -482,6 +626,8 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, | |||
482 | static unsigned int oops_count = 0; | 626 | static unsigned int oops_count = 0; |
483 | static bool panicking = false; | 627 | static bool panicking = false; |
484 | size_t text_len; | 628 | size_t text_len; |
629 | unsigned int err_type = ERR_TYPE_KERNEL_PANIC_GZ; | ||
630 | int rc = -1; | ||
485 | 631 | ||
486 | switch (reason) { | 632 | switch (reason) { |
487 | case KMSG_DUMP_RESTART: | 633 | case KMSG_DUMP_RESTART: |
@@ -509,8 +655,19 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, | |||
509 | if (clobbering_unread_rtas_event()) | 655 | if (clobbering_unread_rtas_event()) |
510 | return; | 656 | return; |
511 | 657 | ||
512 | text_len = capture_last_msgs(old_msgs, old_len, new_msgs, new_len, | 658 | if (big_oops_buf) { |
513 | oops_buf, oops_log_partition.size); | 659 | text_len = capture_last_msgs(old_msgs, old_len, |
660 | new_msgs, new_len, big_oops_buf, big_oops_buf_sz); | ||
661 | text_len = elide_severities(big_oops_buf, text_len); | ||
662 | rc = zip_oops(text_len); | ||
663 | } | ||
664 | if (rc != 0) { | ||
665 | text_len = capture_last_msgs(old_msgs, old_len, | ||
666 | new_msgs, new_len, oops_data, oops_data_sz); | ||
667 | err_type = ERR_TYPE_KERNEL_PANIC; | ||
668 | *oops_len = (u16) text_len; | ||
669 | } | ||
670 | |||
514 | (void) nvram_write_os_partition(&oops_log_partition, oops_buf, | 671 | (void) nvram_write_os_partition(&oops_log_partition, oops_buf, |
515 | (int) text_len, ERR_TYPE_KERNEL_PANIC, ++oops_count); | 672 | (int) (sizeof(*oops_len) + *oops_len), err_type, ++oops_count); |
516 | } | 673 | } |
diff --git a/arch/powerpc/platforms/wsp/Kconfig b/arch/powerpc/platforms/wsp/Kconfig index c3c48eb62cc1..f4fb837873fb 100644 --- a/arch/powerpc/platforms/wsp/Kconfig +++ b/arch/powerpc/platforms/wsp/Kconfig | |||
@@ -1,5 +1,12 @@ | |||
1 | config PPC_WSP | 1 | config PPC_WSP |
2 | bool | 2 | bool |
3 | select PPC_A2 | ||
4 | select PPC_SCOM | ||
5 | select PPC_XICS | ||
6 | select PPC_ICP_NATIVE | ||
7 | select PCI | ||
8 | select PPC_IO_WORKAROUNDS if PCI | ||
9 | select PPC_INDIRECT_PIO if PCI | ||
3 | default n | 10 | default n |
4 | 11 | ||
5 | menu "WSP platform selection" | 12 | menu "WSP platform selection" |
@@ -7,13 +14,9 @@ menu "WSP platform selection" | |||
7 | 14 | ||
8 | config PPC_PSR2 | 15 | config PPC_PSR2 |
9 | bool "PSR-2 platform" | 16 | bool "PSR-2 platform" |
10 | select PPC_A2 | ||
11 | select GENERIC_TBSYNC | 17 | select GENERIC_TBSYNC |
12 | select PPC_SCOM | ||
13 | select EPAPR_BOOT | 18 | select EPAPR_BOOT |
14 | select PPC_WSP | 19 | select PPC_WSP |
15 | select PPC_XICS | ||
16 | select PPC_ICP_NATIVE | ||
17 | default y | 20 | default y |
18 | 21 | ||
19 | endmenu | 22 | endmenu |
diff --git a/arch/powerpc/platforms/wsp/Makefile b/arch/powerpc/platforms/wsp/Makefile index 095be73d6cd4..a1486b436f02 100644 --- a/arch/powerpc/platforms/wsp/Makefile +++ b/arch/powerpc/platforms/wsp/Makefile | |||
@@ -4,3 +4,5 @@ obj-y += setup.o ics.o | |||
4 | obj-$(CONFIG_PPC_PSR2) += psr2.o opb_pic.o | 4 | obj-$(CONFIG_PPC_PSR2) += psr2.o opb_pic.o |
5 | obj-$(CONFIG_PPC_WSP) += scom_wsp.o | 5 | obj-$(CONFIG_PPC_WSP) += scom_wsp.o |
6 | obj-$(CONFIG_SMP) += smp.o scom_smp.o | 6 | obj-$(CONFIG_SMP) += smp.o scom_smp.o |
7 | obj-$(CONFIG_PCI) += wsp_pci.o | ||
8 | obj-$(CONFIG_PCI_MSI) += msi.o \ No newline at end of file | ||
diff --git a/arch/powerpc/platforms/wsp/ics.c b/arch/powerpc/platforms/wsp/ics.c index e53bd9e7b125..576874392543 100644 --- a/arch/powerpc/platforms/wsp/ics.c +++ b/arch/powerpc/platforms/wsp/ics.c | |||
@@ -710,3 +710,51 @@ void __init wsp_init_irq(void) | |||
710 | /* We need to patch our irq chip's EOI to point to the right ICP */ | 710 | /* We need to patch our irq chip's EOI to point to the right ICP */ |
711 | wsp_irq_chip.irq_eoi = icp_ops->eoi; | 711 | wsp_irq_chip.irq_eoi = icp_ops->eoi; |
712 | } | 712 | } |
713 | |||
714 | #ifdef CONFIG_PCI_MSI | ||
715 | static void wsp_ics_msi_unmask_irq(struct irq_data *d) | ||
716 | { | ||
717 | wsp_chip_unmask_irq(d); | ||
718 | unmask_msi_irq(d); | ||
719 | } | ||
720 | |||
721 | static unsigned int wsp_ics_msi_startup(struct irq_data *d) | ||
722 | { | ||
723 | wsp_ics_msi_unmask_irq(d); | ||
724 | return 0; | ||
725 | } | ||
726 | |||
727 | static void wsp_ics_msi_mask_irq(struct irq_data *d) | ||
728 | { | ||
729 | mask_msi_irq(d); | ||
730 | wsp_chip_mask_irq(d); | ||
731 | } | ||
732 | |||
733 | /* | ||
734 | * we do it this way because we reassinge default EOI handling in | ||
735 | * irq_init() above | ||
736 | */ | ||
737 | static void wsp_ics_eoi(struct irq_data *data) | ||
738 | { | ||
739 | wsp_irq_chip.irq_eoi(data); | ||
740 | } | ||
741 | |||
742 | static struct irq_chip wsp_ics_msi = { | ||
743 | .name = "WSP ICS MSI", | ||
744 | .irq_startup = wsp_ics_msi_startup, | ||
745 | .irq_mask = wsp_ics_msi_mask_irq, | ||
746 | .irq_unmask = wsp_ics_msi_unmask_irq, | ||
747 | .irq_eoi = wsp_ics_eoi, | ||
748 | .irq_set_affinity = wsp_chip_set_affinity | ||
749 | }; | ||
750 | |||
751 | void wsp_ics_set_msi_chip(unsigned int irq) | ||
752 | { | ||
753 | irq_set_chip(irq, &wsp_ics_msi); | ||
754 | } | ||
755 | |||
756 | void wsp_ics_set_std_chip(unsigned int irq) | ||
757 | { | ||
758 | irq_set_chip(irq, &wsp_irq_chip); | ||
759 | } | ||
760 | #endif /* CONFIG_PCI_MSI */ | ||
diff --git a/arch/powerpc/platforms/wsp/ics.h b/arch/powerpc/platforms/wsp/ics.h index e34d53102640..07b644e0cf97 100644 --- a/arch/powerpc/platforms/wsp/ics.h +++ b/arch/powerpc/platforms/wsp/ics.h | |||
@@ -17,4 +17,9 @@ extern void wsp_init_irq(void); | |||
17 | extern int wsp_ics_alloc_irq(struct device_node *dn, int num); | 17 | extern int wsp_ics_alloc_irq(struct device_node *dn, int num); |
18 | extern void wsp_ics_free_irq(struct device_node *dn, unsigned int irq); | 18 | extern void wsp_ics_free_irq(struct device_node *dn, unsigned int irq); |
19 | 19 | ||
20 | #ifdef CONFIG_PCI_MSI | ||
21 | extern void wsp_ics_set_msi_chip(unsigned int irq); | ||
22 | extern void wsp_ics_set_std_chip(unsigned int irq); | ||
23 | #endif /* CONFIG_PCI_MSI */ | ||
24 | |||
20 | #endif /* __ICS_H */ | 25 | #endif /* __ICS_H */ |
diff --git a/arch/powerpc/platforms/wsp/msi.c b/arch/powerpc/platforms/wsp/msi.c new file mode 100644 index 000000000000..380882f27add --- /dev/null +++ b/arch/powerpc/platforms/wsp/msi.c | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Michael Ellerman, IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/pci.h> | ||
12 | #include <linux/msi.h> | ||
13 | #include <linux/irq.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | |||
16 | #include "msi.h" | ||
17 | #include "ics.h" | ||
18 | #include "wsp_pci.h" | ||
19 | |||
20 | /* Magic addresses for 32 & 64-bit MSIs with hardcoded MVE 0 */ | ||
21 | #define MSI_ADDR_32 0xFFFF0000ul | ||
22 | #define MSI_ADDR_64 0x1000000000000000ul | ||
23 | |||
24 | int wsp_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | ||
25 | { | ||
26 | struct pci_controller *phb; | ||
27 | struct msi_desc *entry; | ||
28 | struct msi_msg msg; | ||
29 | unsigned int virq; | ||
30 | int hwirq; | ||
31 | |||
32 | phb = pci_bus_to_host(dev->bus); | ||
33 | if (!phb) | ||
34 | return -ENOENT; | ||
35 | |||
36 | entry = list_first_entry(&dev->msi_list, struct msi_desc, list); | ||
37 | if (entry->msi_attrib.is_64) { | ||
38 | msg.address_lo = 0; | ||
39 | msg.address_hi = MSI_ADDR_64 >> 32; | ||
40 | } else { | ||
41 | msg.address_lo = MSI_ADDR_32; | ||
42 | msg.address_hi = 0; | ||
43 | } | ||
44 | |||
45 | list_for_each_entry(entry, &dev->msi_list, list) { | ||
46 | hwirq = wsp_ics_alloc_irq(phb->dn, 1); | ||
47 | if (hwirq < 0) { | ||
48 | dev_warn(&dev->dev, "wsp_msi: hwirq alloc failed!\n"); | ||
49 | return hwirq; | ||
50 | } | ||
51 | |||
52 | virq = irq_create_mapping(NULL, hwirq); | ||
53 | if (virq == NO_IRQ) { | ||
54 | dev_warn(&dev->dev, "wsp_msi: virq alloc failed!\n"); | ||
55 | return -1; | ||
56 | } | ||
57 | |||
58 | dev_dbg(&dev->dev, "wsp_msi: allocated irq %#x/%#x\n", | ||
59 | hwirq, virq); | ||
60 | |||
61 | wsp_ics_set_msi_chip(virq); | ||
62 | irq_set_msi_desc(virq, entry); | ||
63 | msg.data = hwirq & XIVE_ADDR_MASK; | ||
64 | write_msi_msg(virq, &msg); | ||
65 | } | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | void wsp_teardown_msi_irqs(struct pci_dev *dev) | ||
71 | { | ||
72 | struct pci_controller *phb; | ||
73 | struct msi_desc *entry; | ||
74 | int hwirq; | ||
75 | |||
76 | phb = pci_bus_to_host(dev->bus); | ||
77 | |||
78 | dev_dbg(&dev->dev, "wsp_msi: tearing down msi irqs\n"); | ||
79 | |||
80 | list_for_each_entry(entry, &dev->msi_list, list) { | ||
81 | if (entry->irq == NO_IRQ) | ||
82 | continue; | ||
83 | |||
84 | irq_set_msi_desc(entry->irq, NULL); | ||
85 | wsp_ics_set_std_chip(entry->irq); | ||
86 | |||
87 | hwirq = virq_to_hw(entry->irq); | ||
88 | /* In this order to avoid racing with irq_create_mapping() */ | ||
89 | irq_dispose_mapping(entry->irq); | ||
90 | wsp_ics_free_irq(phb->dn, hwirq); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | void wsp_setup_phb_msi(struct pci_controller *phb) | ||
95 | { | ||
96 | /* Create a single MVE at offset 0 that matches everything */ | ||
97 | out_be64(phb->cfg_data + PCIE_REG_IODA_ADDR, PCIE_REG_IODA_AD_TBL_MVT); | ||
98 | out_be64(phb->cfg_data + PCIE_REG_IODA_DATA0, 1ull << 63); | ||
99 | |||
100 | ppc_md.setup_msi_irqs = wsp_setup_msi_irqs; | ||
101 | ppc_md.teardown_msi_irqs = wsp_teardown_msi_irqs; | ||
102 | } | ||
diff --git a/arch/powerpc/platforms/wsp/msi.h b/arch/powerpc/platforms/wsp/msi.h new file mode 100644 index 000000000000..0ab27b71b24d --- /dev/null +++ b/arch/powerpc/platforms/wsp/msi.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Michael Ellerman, IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #ifndef __WSP_MSI_H | ||
11 | #define __WSP_MSI_H | ||
12 | |||
13 | #ifdef CONFIG_PCI_MSI | ||
14 | extern void wsp_setup_phb_msi(struct pci_controller *phb); | ||
15 | #else | ||
16 | static inline void wsp_setup_phb_msi(struct pci_controller *phb) { } | ||
17 | #endif | ||
18 | |||
19 | #endif /* __WSP_MSI_H */ | ||
diff --git a/arch/powerpc/platforms/wsp/psr2.c b/arch/powerpc/platforms/wsp/psr2.c index 40f28916ff6c..166f2e4b4bee 100644 --- a/arch/powerpc/platforms/wsp/psr2.c +++ b/arch/powerpc/platforms/wsp/psr2.c | |||
@@ -63,6 +63,10 @@ static void __init psr2_setup_arch(void) | |||
63 | #ifdef CONFIG_SMP | 63 | #ifdef CONFIG_SMP |
64 | a2_setup_smp(); | 64 | a2_setup_smp(); |
65 | #endif | 65 | #endif |
66 | #ifdef CONFIG_PCI | ||
67 | wsp_setup_pci(); | ||
68 | #endif | ||
69 | |||
66 | } | 70 | } |
67 | 71 | ||
68 | static int __init psr2_probe(void) | 72 | static int __init psr2_probe(void) |
diff --git a/arch/powerpc/platforms/wsp/wsp.h b/arch/powerpc/platforms/wsp/wsp.h index 7c3e087fd2f2..33479818f62a 100644 --- a/arch/powerpc/platforms/wsp/wsp.h +++ b/arch/powerpc/platforms/wsp/wsp.h | |||
@@ -3,6 +3,9 @@ | |||
3 | 3 | ||
4 | #include <asm/wsp.h> | 4 | #include <asm/wsp.h> |
5 | 5 | ||
6 | /* Devtree compatible strings for major devices */ | ||
7 | #define PCIE_COMPATIBLE "ibm,wsp-pciex" | ||
8 | |||
6 | extern void wsp_setup_pci(void); | 9 | extern void wsp_setup_pci(void); |
7 | extern void scom_init_wsp(void); | 10 | extern void scom_init_wsp(void); |
8 | 11 | ||
diff --git a/arch/powerpc/platforms/wsp/wsp_pci.c b/arch/powerpc/platforms/wsp/wsp_pci.c new file mode 100644 index 000000000000..e0262cd0e2d3 --- /dev/null +++ b/arch/powerpc/platforms/wsp/wsp_pci.c | |||
@@ -0,0 +1,1133 @@ | |||
1 | /* | ||
2 | * Copyright 2010 Ben Herrenschmidt, IBM Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #define DEBUG | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/pci.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/string.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/bootmem.h> | ||
18 | #include <linux/irq.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/debugfs.h> | ||
21 | |||
22 | #include <asm/sections.h> | ||
23 | #include <asm/io.h> | ||
24 | #include <asm/prom.h> | ||
25 | #include <asm/pci-bridge.h> | ||
26 | #include <asm/machdep.h> | ||
27 | #include <asm/ppc-pci.h> | ||
28 | #include <asm/iommu.h> | ||
29 | #include <asm/io-workarounds.h> | ||
30 | |||
31 | #include "wsp.h" | ||
32 | #include "wsp_pci.h" | ||
33 | #include "msi.h" | ||
34 | |||
35 | |||
36 | /* Max number of TVTs for one table. Only 32-bit tables can use | ||
37 | * multiple TVTs and so the max currently supported is thus 8 | ||
38 | * since only 2G of DMA space is supported | ||
39 | */ | ||
40 | #define MAX_TABLE_TVT_COUNT 8 | ||
41 | |||
42 | struct wsp_dma_table { | ||
43 | struct list_head link; | ||
44 | struct iommu_table table; | ||
45 | struct wsp_phb *phb; | ||
46 | struct page *tces[MAX_TABLE_TVT_COUNT]; | ||
47 | }; | ||
48 | |||
49 | /* We support DMA regions from 0...2G in 32bit space (no support for | ||
50 | * 64-bit DMA just yet). Each device gets a separate TCE table (TVT | ||
51 | * entry) with validation enabled (though not supported by SimiCS | ||
52 | * just yet). | ||
53 | * | ||
54 | * To simplify things, we divide this 2G space into N regions based | ||
55 | * on the constant below which could be turned into a tunable eventually | ||
56 | * | ||
57 | * We then assign dynamically those regions to devices as they show up. | ||
58 | * | ||
59 | * We use a bitmap as an allocator for these. | ||
60 | * | ||
61 | * Tables are allocated/created dynamically as devices are discovered, | ||
62 | * multiple TVT entries are used if needed | ||
63 | * | ||
64 | * When 64-bit DMA support is added we should simply use a separate set | ||
65 | * of larger regions (the HW supports 64 TVT entries). We can | ||
66 | * additionally create a bypass region in 64-bit space for performances | ||
67 | * though that would have a cost in term of security. | ||
68 | * | ||
69 | * If you set NUM_DMA32_REGIONS to 1, then a single table is shared | ||
70 | * for all devices and bus/dev/fn validation is disabled | ||
71 | * | ||
72 | * Note that a DMA32 region cannot be smaller than 256M so the max | ||
73 | * supported here for now is 8. We don't yet support sharing regions | ||
74 | * between multiple devices so the max number of devices supported | ||
75 | * is MAX_TABLE_TVT_COUNT. | ||
76 | */ | ||
77 | #define NUM_DMA32_REGIONS 1 | ||
78 | |||
79 | struct wsp_phb { | ||
80 | struct pci_controller *hose; | ||
81 | |||
82 | /* Lock controlling access to the list of dma tables. | ||
83 | * It does -not- protect against dma_* operations on | ||
84 | * those tables, those should be stopped before an entry | ||
85 | * is removed from the list. | ||
86 | * | ||
87 | * The lock is also used for error handling operations | ||
88 | */ | ||
89 | spinlock_t lock; | ||
90 | struct list_head dma_tables; | ||
91 | unsigned long dma32_map; | ||
92 | unsigned long dma32_base; | ||
93 | unsigned int dma32_num_regions; | ||
94 | unsigned long dma32_region_size; | ||
95 | |||
96 | /* Debugfs stuff */ | ||
97 | struct dentry *ddir; | ||
98 | |||
99 | struct list_head all; | ||
100 | }; | ||
101 | static LIST_HEAD(wsp_phbs); | ||
102 | |||
103 | //#define cfg_debug(fmt...) pr_debug(fmt) | ||
104 | #define cfg_debug(fmt...) | ||
105 | |||
106 | |||
107 | static int wsp_pcie_read_config(struct pci_bus *bus, unsigned int devfn, | ||
108 | int offset, int len, u32 *val) | ||
109 | { | ||
110 | struct pci_controller *hose; | ||
111 | int suboff; | ||
112 | u64 addr; | ||
113 | |||
114 | hose = pci_bus_to_host(bus); | ||
115 | if (hose == NULL) | ||
116 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
117 | if (offset >= 0x1000) | ||
118 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
119 | addr = PCIE_REG_CA_ENABLE | | ||
120 | ((u64)bus->number) << PCIE_REG_CA_BUS_SHIFT | | ||
121 | ((u64)devfn) << PCIE_REG_CA_FUNC_SHIFT | | ||
122 | ((u64)offset & ~3) << PCIE_REG_CA_REG_SHIFT; | ||
123 | suboff = offset & 3; | ||
124 | |||
125 | /* | ||
126 | * Note: the caller has already checked that offset is | ||
127 | * suitably aligned and that len is 1, 2 or 4. | ||
128 | */ | ||
129 | |||
130 | switch (len) { | ||
131 | case 1: | ||
132 | addr |= (0x8ul >> suboff) << PCIE_REG_CA_BE_SHIFT; | ||
133 | out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr); | ||
134 | *val = (in_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA) | ||
135 | >> (suboff << 3)) & 0xff; | ||
136 | cfg_debug("read 1 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%02x\n", | ||
137 | bus->number, devfn >> 3, devfn & 7, | ||
138 | offset, suboff, addr, *val); | ||
139 | break; | ||
140 | case 2: | ||
141 | addr |= (0xcul >> suboff) << PCIE_REG_CA_BE_SHIFT; | ||
142 | out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr); | ||
143 | *val = (in_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA) | ||
144 | >> (suboff << 3)) & 0xffff; | ||
145 | cfg_debug("read 2 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%04x\n", | ||
146 | bus->number, devfn >> 3, devfn & 7, | ||
147 | offset, suboff, addr, *val); | ||
148 | break; | ||
149 | default: | ||
150 | addr |= 0xful << PCIE_REG_CA_BE_SHIFT; | ||
151 | out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr); | ||
152 | *val = in_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA); | ||
153 | cfg_debug("read 4 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%08x\n", | ||
154 | bus->number, devfn >> 3, devfn & 7, | ||
155 | offset, suboff, addr, *val); | ||
156 | break; | ||
157 | } | ||
158 | return PCIBIOS_SUCCESSFUL; | ||
159 | } | ||
160 | |||
161 | static int wsp_pcie_write_config(struct pci_bus *bus, unsigned int devfn, | ||
162 | int offset, int len, u32 val) | ||
163 | { | ||
164 | struct pci_controller *hose; | ||
165 | int suboff; | ||
166 | u64 addr; | ||
167 | |||
168 | hose = pci_bus_to_host(bus); | ||
169 | if (hose == NULL) | ||
170 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
171 | if (offset >= 0x1000) | ||
172 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
173 | addr = PCIE_REG_CA_ENABLE | | ||
174 | ((u64)bus->number) << PCIE_REG_CA_BUS_SHIFT | | ||
175 | ((u64)devfn) << PCIE_REG_CA_FUNC_SHIFT | | ||
176 | ((u64)offset & ~3) << PCIE_REG_CA_REG_SHIFT; | ||
177 | suboff = offset & 3; | ||
178 | |||
179 | /* | ||
180 | * Note: the caller has already checked that offset is | ||
181 | * suitably aligned and that len is 1, 2 or 4. | ||
182 | */ | ||
183 | switch (len) { | ||
184 | case 1: | ||
185 | addr |= (0x8ul >> suboff) << PCIE_REG_CA_BE_SHIFT; | ||
186 | val <<= suboff << 3; | ||
187 | out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr); | ||
188 | out_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA, val); | ||
189 | cfg_debug("write 1 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%02x\n", | ||
190 | bus->number, devfn >> 3, devfn & 7, | ||
191 | offset, suboff, addr, val); | ||
192 | break; | ||
193 | case 2: | ||
194 | addr |= (0xcul >> suboff) << PCIE_REG_CA_BE_SHIFT; | ||
195 | val <<= suboff << 3; | ||
196 | out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr); | ||
197 | out_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA, val); | ||
198 | cfg_debug("write 2 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%04x\n", | ||
199 | bus->number, devfn >> 3, devfn & 7, | ||
200 | offset, suboff, addr, val); | ||
201 | break; | ||
202 | default: | ||
203 | addr |= 0xful << PCIE_REG_CA_BE_SHIFT; | ||
204 | out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr); | ||
205 | out_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA, val); | ||
206 | cfg_debug("write 4 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%08x\n", | ||
207 | bus->number, devfn >> 3, devfn & 7, | ||
208 | offset, suboff, addr, val); | ||
209 | break; | ||
210 | } | ||
211 | return PCIBIOS_SUCCESSFUL; | ||
212 | } | ||
213 | |||
214 | static struct pci_ops wsp_pcie_pci_ops = | ||
215 | { | ||
216 | .read = wsp_pcie_read_config, | ||
217 | .write = wsp_pcie_write_config, | ||
218 | }; | ||
219 | |||
220 | #define TCE_SHIFT 12 | ||
221 | #define TCE_PAGE_SIZE (1 << TCE_SHIFT) | ||
222 | #define TCE_PCI_WRITE 0x2 /* write from PCI allowed */ | ||
223 | #define TCE_PCI_READ 0x1 /* read from PCI allowed */ | ||
224 | #define TCE_RPN_MASK 0x3fffffffffful /* 42-bit RPN (4K pages) */ | ||
225 | #define TCE_RPN_SHIFT 12 | ||
226 | |||
227 | //#define dma_debug(fmt...) pr_debug(fmt) | ||
228 | #define dma_debug(fmt...) | ||
229 | |||
230 | static int tce_build_wsp(struct iommu_table *tbl, long index, long npages, | ||
231 | unsigned long uaddr, enum dma_data_direction direction, | ||
232 | struct dma_attrs *attrs) | ||
233 | { | ||
234 | struct wsp_dma_table *ptbl = container_of(tbl, | ||
235 | struct wsp_dma_table, | ||
236 | table); | ||
237 | u64 proto_tce; | ||
238 | u64 *tcep; | ||
239 | u64 rpn; | ||
240 | |||
241 | proto_tce = TCE_PCI_READ; | ||
242 | #ifdef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS | ||
243 | proto_tce |= TCE_PCI_WRITE; | ||
244 | #else | ||
245 | if (direction != DMA_TO_DEVICE) | ||
246 | proto_tce |= TCE_PCI_WRITE; | ||
247 | #endif | ||
248 | |||
249 | /* XXX Make this faster by factoring out the page address for | ||
250 | * within a TCE table | ||
251 | */ | ||
252 | while (npages--) { | ||
253 | /* We don't use it->base as the table can be scattered */ | ||
254 | tcep = (u64 *)page_address(ptbl->tces[index >> 16]); | ||
255 | tcep += (index & 0xffff); | ||
256 | |||
257 | /* can't move this out since we might cross LMB boundary */ | ||
258 | rpn = __pa(uaddr) >> TCE_SHIFT; | ||
259 | *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; | ||
260 | |||
261 | dma_debug("[DMA] TCE %p set to 0x%016llx (dma addr: 0x%lx)\n", | ||
262 | tcep, *tcep, (tbl->it_offset + index) << IOMMU_PAGE_SHIFT); | ||
263 | |||
264 | uaddr += TCE_PAGE_SIZE; | ||
265 | index++; | ||
266 | } | ||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static void tce_free_wsp(struct iommu_table *tbl, long index, long npages) | ||
271 | { | ||
272 | struct wsp_dma_table *ptbl = container_of(tbl, | ||
273 | struct wsp_dma_table, | ||
274 | table); | ||
275 | #ifndef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS | ||
276 | struct pci_controller *hose = ptbl->phb->hose; | ||
277 | #endif | ||
278 | u64 *tcep; | ||
279 | |||
280 | /* XXX Make this faster by factoring out the page address for | ||
281 | * within a TCE table. Also use line-kill option to kill multiple | ||
282 | * TCEs at once | ||
283 | */ | ||
284 | while (npages--) { | ||
285 | /* We don't use it->base as the table can be scattered */ | ||
286 | tcep = (u64 *)page_address(ptbl->tces[index >> 16]); | ||
287 | tcep += (index & 0xffff); | ||
288 | dma_debug("[DMA] TCE %p cleared\n", tcep); | ||
289 | *tcep = 0; | ||
290 | #ifndef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS | ||
291 | /* Don't write there since it would pollute other MMIO accesses */ | ||
292 | out_be64(hose->cfg_data + PCIE_REG_TCE_KILL, | ||
293 | PCIE_REG_TCEKILL_SINGLE | PCIE_REG_TCEKILL_PS_4K | | ||
294 | (__pa(tcep) & PCIE_REG_TCEKILL_ADDR_MASK)); | ||
295 | #endif | ||
296 | index++; | ||
297 | } | ||
298 | } | ||
299 | |||
300 | static struct wsp_dma_table *wsp_pci_create_dma32_table(struct wsp_phb *phb, | ||
301 | unsigned int region, | ||
302 | struct pci_dev *validate) | ||
303 | { | ||
304 | struct pci_controller *hose = phb->hose; | ||
305 | unsigned long size = phb->dma32_region_size; | ||
306 | unsigned long addr = phb->dma32_region_size * region + phb->dma32_base; | ||
307 | struct wsp_dma_table *tbl; | ||
308 | int tvts_per_table, i, tvt, nid; | ||
309 | unsigned long flags; | ||
310 | |||
311 | nid = of_node_to_nid(phb->hose->dn); | ||
312 | |||
313 | /* Calculate how many TVTs are needed */ | ||
314 | tvts_per_table = size / 0x10000000; | ||
315 | if (tvts_per_table == 0) | ||
316 | tvts_per_table = 1; | ||
317 | |||
318 | /* Calculate the base TVT index. We know all tables have the same | ||
319 | * size so we just do a simple multiply here | ||
320 | */ | ||
321 | tvt = region * tvts_per_table; | ||
322 | |||
323 | pr_debug(" Region : %d\n", region); | ||
324 | pr_debug(" DMA range : 0x%08lx..0x%08lx\n", addr, addr + size - 1); | ||
325 | pr_debug(" Number of TVTs : %d\n", tvts_per_table); | ||
326 | pr_debug(" Base TVT : %d\n", tvt); | ||
327 | pr_debug(" Node : %d\n", nid); | ||
328 | |||
329 | tbl = kzalloc_node(sizeof(struct wsp_dma_table), GFP_KERNEL, nid); | ||
330 | if (!tbl) | ||
331 | return ERR_PTR(-ENOMEM); | ||
332 | tbl->phb = phb; | ||
333 | |||
334 | /* Create as many TVTs as needed, each represents 256M at most */ | ||
335 | for (i = 0; i < tvts_per_table; i++) { | ||
336 | u64 tvt_data1, tvt_data0; | ||
337 | |||
338 | /* Allocate table. We use a 4K TCE size for now always so | ||
339 | * one table is always 8 * (258M / 4K) == 512K | ||
340 | */ | ||
341 | tbl->tces[i] = alloc_pages_node(nid, GFP_KERNEL, get_order(0x80000)); | ||
342 | if (tbl->tces[i] == NULL) | ||
343 | goto fail; | ||
344 | memset(page_address(tbl->tces[i]), 0, 0x80000); | ||
345 | |||
346 | pr_debug(" TCE table %d at : %p\n", i, page_address(tbl->tces[i])); | ||
347 | |||
348 | /* Table size. We currently set it to be the whole 256M region */ | ||
349 | tvt_data0 = 2ull << IODA_TVT0_TCE_TABLE_SIZE_SHIFT; | ||
350 | /* IO page size set to 4K */ | ||
351 | tvt_data1 = 1ull << IODA_TVT1_IO_PAGE_SIZE_SHIFT; | ||
352 | /* Shift in the address */ | ||
353 | tvt_data0 |= __pa(page_address(tbl->tces[i])) << IODA_TVT0_TTA_SHIFT; | ||
354 | |||
355 | /* Validation stuff. We only validate fully bus/dev/fn for now | ||
356 | * one day maybe we can group devices but that isn't the case | ||
357 | * at the moment | ||
358 | */ | ||
359 | if (validate) { | ||
360 | tvt_data0 |= IODA_TVT0_BUSNUM_VALID_MASK; | ||
361 | tvt_data0 |= validate->bus->number; | ||
362 | tvt_data1 |= IODA_TVT1_DEVNUM_VALID; | ||
363 | tvt_data1 |= ((u64)PCI_SLOT(validate->devfn)) | ||
364 | << IODA_TVT1_DEVNUM_VALUE_SHIFT; | ||
365 | tvt_data1 |= IODA_TVT1_FUNCNUM_VALID; | ||
366 | tvt_data1 |= ((u64)PCI_FUNC(validate->devfn)) | ||
367 | << IODA_TVT1_FUNCNUM_VALUE_SHIFT; | ||
368 | } | ||
369 | |||
370 | /* XX PE number is always 0 for now */ | ||
371 | |||
372 | /* Program the values using the PHB lock */ | ||
373 | spin_lock_irqsave(&phb->lock, flags); | ||
374 | out_be64(hose->cfg_data + PCIE_REG_IODA_ADDR, | ||
375 | (tvt + i) | PCIE_REG_IODA_AD_TBL_TVT); | ||
376 | out_be64(hose->cfg_data + PCIE_REG_IODA_DATA1, tvt_data1); | ||
377 | out_be64(hose->cfg_data + PCIE_REG_IODA_DATA0, tvt_data0); | ||
378 | spin_unlock_irqrestore(&phb->lock, flags); | ||
379 | } | ||
380 | |||
381 | /* Init bits and pieces */ | ||
382 | tbl->table.it_blocksize = 16; | ||
383 | tbl->table.it_offset = addr >> IOMMU_PAGE_SHIFT; | ||
384 | tbl->table.it_size = size >> IOMMU_PAGE_SHIFT; | ||
385 | |||
386 | /* | ||
387 | * It's already blank but we clear it anyway. | ||
388 | * Consider an aditiona interface that makes cleaing optional | ||
389 | */ | ||
390 | iommu_init_table(&tbl->table, nid); | ||
391 | |||
392 | list_add(&tbl->link, &phb->dma_tables); | ||
393 | return tbl; | ||
394 | |||
395 | fail: | ||
396 | pr_debug(" Failed to allocate a 256M TCE table !\n"); | ||
397 | for (i = 0; i < tvts_per_table; i++) | ||
398 | if (tbl->tces[i]) | ||
399 | __free_pages(tbl->tces[i], get_order(0x80000)); | ||
400 | kfree(tbl); | ||
401 | return ERR_PTR(-ENOMEM); | ||
402 | } | ||
403 | |||
404 | static void __devinit wsp_pci_dma_dev_setup(struct pci_dev *pdev) | ||
405 | { | ||
406 | struct dev_archdata *archdata = &pdev->dev.archdata; | ||
407 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | ||
408 | struct wsp_phb *phb = hose->private_data; | ||
409 | struct wsp_dma_table *table = NULL; | ||
410 | unsigned long flags; | ||
411 | int i; | ||
412 | |||
413 | /* Don't assign an iommu table to a bridge */ | ||
414 | if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE) | ||
415 | return; | ||
416 | |||
417 | pr_debug("%s: Setting up DMA...\n", pci_name(pdev)); | ||
418 | |||
419 | spin_lock_irqsave(&phb->lock, flags); | ||
420 | |||
421 | /* If only one region, check if it already exist */ | ||
422 | if (phb->dma32_num_regions == 1) { | ||
423 | spin_unlock_irqrestore(&phb->lock, flags); | ||
424 | if (list_empty(&phb->dma_tables)) | ||
425 | table = wsp_pci_create_dma32_table(phb, 0, NULL); | ||
426 | else | ||
427 | table = list_first_entry(&phb->dma_tables, | ||
428 | struct wsp_dma_table, | ||
429 | link); | ||
430 | } else { | ||
431 | /* else find a free region */ | ||
432 | for (i = 0; i < phb->dma32_num_regions && !table; i++) { | ||
433 | if (__test_and_set_bit(i, &phb->dma32_map)) | ||
434 | continue; | ||
435 | spin_unlock_irqrestore(&phb->lock, flags); | ||
436 | table = wsp_pci_create_dma32_table(phb, i, pdev); | ||
437 | } | ||
438 | } | ||
439 | |||
440 | /* Check if we got an error */ | ||
441 | if (IS_ERR(table)) { | ||
442 | pr_err("%s: Failed to create DMA table, err %ld !\n", | ||
443 | pci_name(pdev), PTR_ERR(table)); | ||
444 | return; | ||
445 | } | ||
446 | |||
447 | /* Or a valid table */ | ||
448 | if (table) { | ||
449 | pr_info("%s: Setup iommu: 32-bit DMA region 0x%08lx..0x%08lx\n", | ||
450 | pci_name(pdev), | ||
451 | table->table.it_offset << IOMMU_PAGE_SHIFT, | ||
452 | (table->table.it_offset << IOMMU_PAGE_SHIFT) | ||
453 | + phb->dma32_region_size - 1); | ||
454 | archdata->dma_data.iommu_table_base = &table->table; | ||
455 | return; | ||
456 | } | ||
457 | |||
458 | /* Or no room */ | ||
459 | spin_unlock_irqrestore(&phb->lock, flags); | ||
460 | pr_err("%s: Out of DMA space !\n", pci_name(pdev)); | ||
461 | } | ||
462 | |||
463 | static void __init wsp_pcie_configure_hw(struct pci_controller *hose) | ||
464 | { | ||
465 | u64 val; | ||
466 | int i; | ||
467 | |||
468 | #define DUMP_REG(x) \ | ||
469 | pr_debug("%-30s : 0x%016llx\n", #x, in_be64(hose->cfg_data + x)) | ||
470 | |||
471 | #ifdef CONFIG_WSP_DD1_WORKAROUND_BAD_PCIE_CLASS | ||
472 | /* WSP DD1 has a bogus class code by default in the PCI-E | ||
473 | * root complex's built-in P2P bridge */ | ||
474 | val = in_be64(hose->cfg_data + PCIE_REG_SYS_CFG1); | ||
475 | pr_debug("PCI-E SYS_CFG1 : 0x%llx\n", val); | ||
476 | out_be64(hose->cfg_data + PCIE_REG_SYS_CFG1, | ||
477 | (val & ~PCIE_REG_SYS_CFG1_CLASS_CODE) | (PCI_CLASS_BRIDGE_PCI << 8)); | ||
478 | pr_debug("PCI-E SYS_CFG1 : 0x%llx\n", in_be64(hose->cfg_data + PCIE_REG_SYS_CFG1)); | ||
479 | #endif /* CONFIG_WSP_DD1_WORKAROUND_BAD_PCIE_CLASS */ | ||
480 | |||
481 | #ifdef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS | ||
482 | /* XXX Disable TCE caching, it doesn't work on DD1 */ | ||
483 | out_be64(hose->cfg_data + 0xe50, | ||
484 | in_be64(hose->cfg_data + 0xe50) | (3ull << 62)); | ||
485 | printk("PCI-E DEBUG CONTROL 5 = 0x%llx\n", in_be64(hose->cfg_data + 0xe50)); | ||
486 | #endif | ||
487 | |||
488 | /* Configure M32A and IO. IO is hard wired to be 1M for now */ | ||
489 | out_be64(hose->cfg_data + PCIE_REG_IO_BASE_ADDR, hose->io_base_phys); | ||
490 | out_be64(hose->cfg_data + PCIE_REG_IO_BASE_MASK, | ||
491 | (~(hose->io_resource.end - hose->io_resource.start)) & | ||
492 | 0x3fffffff000ul); | ||
493 | out_be64(hose->cfg_data + PCIE_REG_IO_START_ADDR, 0 | 1); | ||
494 | |||
495 | out_be64(hose->cfg_data + PCIE_REG_M32A_BASE_ADDR, | ||
496 | hose->mem_resources[0].start); | ||
497 | printk("Want to write to M32A_BASE_MASK : 0x%llx\n", | ||
498 | (~(hose->mem_resources[0].end - | ||
499 | hose->mem_resources[0].start)) & 0x3ffffff0000ul); | ||
500 | out_be64(hose->cfg_data + PCIE_REG_M32A_BASE_MASK, | ||
501 | (~(hose->mem_resources[0].end - | ||
502 | hose->mem_resources[0].start)) & 0x3ffffff0000ul); | ||
503 | out_be64(hose->cfg_data + PCIE_REG_M32A_START_ADDR, | ||
504 | (hose->mem_resources[0].start - hose->pci_mem_offset) | 1); | ||
505 | |||
506 | /* Clear all TVT entries | ||
507 | * | ||
508 | * XX Might get TVT count from device-tree | ||
509 | */ | ||
510 | for (i = 0; i < IODA_TVT_COUNT; i++) { | ||
511 | out_be64(hose->cfg_data + PCIE_REG_IODA_ADDR, | ||
512 | PCIE_REG_IODA_AD_TBL_TVT | i); | ||
513 | out_be64(hose->cfg_data + PCIE_REG_IODA_DATA1, 0); | ||
514 | out_be64(hose->cfg_data + PCIE_REG_IODA_DATA0, 0); | ||
515 | } | ||
516 | |||
517 | /* Kill the TCE cache */ | ||
518 | out_be64(hose->cfg_data + PCIE_REG_PHB_CONFIG, | ||
519 | in_be64(hose->cfg_data + PCIE_REG_PHB_CONFIG) | | ||
520 | PCIE_REG_PHBC_64B_TCE_EN); | ||
521 | |||
522 | /* Enable 32 & 64-bit MSIs, IO space and M32A */ | ||
523 | val = PCIE_REG_PHBC_32BIT_MSI_EN | | ||
524 | PCIE_REG_PHBC_IO_EN | | ||
525 | PCIE_REG_PHBC_64BIT_MSI_EN | | ||
526 | PCIE_REG_PHBC_M32A_EN; | ||
527 | if (iommu_is_off) | ||
528 | val |= PCIE_REG_PHBC_DMA_XLATE_BYPASS; | ||
529 | pr_debug("Will write config: 0x%llx\n", val); | ||
530 | out_be64(hose->cfg_data + PCIE_REG_PHB_CONFIG, val); | ||
531 | |||
532 | /* Enable error reporting */ | ||
533 | out_be64(hose->cfg_data + 0xe00, | ||
534 | in_be64(hose->cfg_data + 0xe00) | 0x0008000000000000ull); | ||
535 | |||
536 | /* Mask an error that's generated when doing config space probe | ||
537 | * | ||
538 | * XXX Maybe we should only mask it around config space cycles... that or | ||
539 | * ignore it when we know we had a config space cycle recently ? | ||
540 | */ | ||
541 | out_be64(hose->cfg_data + PCIE_REG_DMA_ERR_STATUS_MASK, 0x8000000000000000ull); | ||
542 | out_be64(hose->cfg_data + PCIE_REG_DMA_ERR1_STATUS_MASK, 0x8000000000000000ull); | ||
543 | |||
544 | /* Enable UTL errors, for now, all of them got to UTL irq 1 | ||
545 | * | ||
546 | * We similarily mask one UTL error caused apparently during normal | ||
547 | * probing. We also mask the link up error | ||
548 | */ | ||
549 | out_be64(hose->cfg_data + PCIE_UTL_SYS_BUS_AGENT_ERR_SEV, 0); | ||
550 | out_be64(hose->cfg_data + PCIE_UTL_RC_ERR_SEVERITY, 0); | ||
551 | out_be64(hose->cfg_data + PCIE_UTL_PCIE_PORT_ERROR_SEV, 0); | ||
552 | out_be64(hose->cfg_data + PCIE_UTL_SYS_BUS_AGENT_IRQ_EN, 0xffffffff00000000ull); | ||
553 | out_be64(hose->cfg_data + PCIE_UTL_PCIE_PORT_IRQ_EN, 0xff5fffff00000000ull); | ||
554 | out_be64(hose->cfg_data + PCIE_UTL_EP_ERR_IRQ_EN, 0xffffffff00000000ull); | ||
555 | |||
556 | DUMP_REG(PCIE_REG_IO_BASE_ADDR); | ||
557 | DUMP_REG(PCIE_REG_IO_BASE_MASK); | ||
558 | DUMP_REG(PCIE_REG_IO_START_ADDR); | ||
559 | DUMP_REG(PCIE_REG_M32A_BASE_ADDR); | ||
560 | DUMP_REG(PCIE_REG_M32A_BASE_MASK); | ||
561 | DUMP_REG(PCIE_REG_M32A_START_ADDR); | ||
562 | DUMP_REG(PCIE_REG_M32B_BASE_ADDR); | ||
563 | DUMP_REG(PCIE_REG_M32B_BASE_MASK); | ||
564 | DUMP_REG(PCIE_REG_M32B_START_ADDR); | ||
565 | DUMP_REG(PCIE_REG_M64_BASE_ADDR); | ||
566 | DUMP_REG(PCIE_REG_M64_BASE_MASK); | ||
567 | DUMP_REG(PCIE_REG_M64_START_ADDR); | ||
568 | DUMP_REG(PCIE_REG_PHB_CONFIG); | ||
569 | } | ||
570 | |||
571 | static void wsp_pci_wait_io_idle(struct wsp_phb *phb, unsigned long port) | ||
572 | { | ||
573 | u64 val; | ||
574 | int i; | ||
575 | |||
576 | for (i = 0; i < 10000; i++) { | ||
577 | val = in_be64(phb->hose->cfg_data + 0xe08); | ||
578 | if ((val & 0x1900000000000000ull) == 0x0100000000000000ull) | ||
579 | return; | ||
580 | udelay(1); | ||
581 | } | ||
582 | pr_warning("PCI IO timeout on domain %d port 0x%lx\n", | ||
583 | phb->hose->global_number, port); | ||
584 | } | ||
585 | |||
586 | #define DEF_PCI_AC_RET_pio(name, ret, at, al, aa) \ | ||
587 | static ret wsp_pci_##name at \ | ||
588 | { \ | ||
589 | struct iowa_bus *bus; \ | ||
590 | struct wsp_phb *phb; \ | ||
591 | unsigned long flags; \ | ||
592 | ret rval; \ | ||
593 | bus = iowa_pio_find_bus(aa); \ | ||
594 | WARN_ON(!bus); \ | ||
595 | phb = bus->private; \ | ||
596 | spin_lock_irqsave(&phb->lock, flags); \ | ||
597 | wsp_pci_wait_io_idle(phb, aa); \ | ||
598 | rval = __do_##name al; \ | ||
599 | spin_unlock_irqrestore(&phb->lock, flags); \ | ||
600 | return rval; \ | ||
601 | } | ||
602 | |||
603 | #define DEF_PCI_AC_NORET_pio(name, at, al, aa) \ | ||
604 | static void wsp_pci_##name at \ | ||
605 | { \ | ||
606 | struct iowa_bus *bus; \ | ||
607 | struct wsp_phb *phb; \ | ||
608 | unsigned long flags; \ | ||
609 | bus = iowa_pio_find_bus(aa); \ | ||
610 | WARN_ON(!bus); \ | ||
611 | phb = bus->private; \ | ||
612 | spin_lock_irqsave(&phb->lock, flags); \ | ||
613 | wsp_pci_wait_io_idle(phb, aa); \ | ||
614 | __do_##name al; \ | ||
615 | spin_unlock_irqrestore(&phb->lock, flags); \ | ||
616 | } | ||
617 | |||
618 | #define DEF_PCI_AC_RET_mem(name, ret, at, al, aa) | ||
619 | #define DEF_PCI_AC_NORET_mem(name, at, al, aa) | ||
620 | |||
621 | #define DEF_PCI_AC_RET(name, ret, at, al, space, aa) \ | ||
622 | DEF_PCI_AC_RET_##space(name, ret, at, al, aa) | ||
623 | |||
624 | #define DEF_PCI_AC_NORET(name, at, al, space, aa) \ | ||
625 | DEF_PCI_AC_NORET_##space(name, at, al, aa) \ | ||
626 | |||
627 | |||
628 | #include <asm/io-defs.h> | ||
629 | |||
630 | #undef DEF_PCI_AC_RET | ||
631 | #undef DEF_PCI_AC_NORET | ||
632 | |||
633 | static struct ppc_pci_io wsp_pci_iops = { | ||
634 | .inb = wsp_pci_inb, | ||
635 | .inw = wsp_pci_inw, | ||
636 | .inl = wsp_pci_inl, | ||
637 | .outb = wsp_pci_outb, | ||
638 | .outw = wsp_pci_outw, | ||
639 | .outl = wsp_pci_outl, | ||
640 | .insb = wsp_pci_insb, | ||
641 | .insw = wsp_pci_insw, | ||
642 | .insl = wsp_pci_insl, | ||
643 | .outsb = wsp_pci_outsb, | ||
644 | .outsw = wsp_pci_outsw, | ||
645 | .outsl = wsp_pci_outsl, | ||
646 | }; | ||
647 | |||
648 | static int __init wsp_setup_one_phb(struct device_node *np) | ||
649 | { | ||
650 | struct pci_controller *hose; | ||
651 | struct wsp_phb *phb; | ||
652 | |||
653 | pr_info("PCI: Setting up PCIe host bridge 0x%s\n", np->full_name); | ||
654 | |||
655 | phb = zalloc_maybe_bootmem(sizeof(struct wsp_phb), GFP_KERNEL); | ||
656 | if (!phb) | ||
657 | return -ENOMEM; | ||
658 | hose = pcibios_alloc_controller(np); | ||
659 | if (!hose) { | ||
660 | /* Can't really free the phb */ | ||
661 | return -ENOMEM; | ||
662 | } | ||
663 | hose->private_data = phb; | ||
664 | phb->hose = hose; | ||
665 | |||
666 | INIT_LIST_HEAD(&phb->dma_tables); | ||
667 | spin_lock_init(&phb->lock); | ||
668 | |||
669 | /* XXX Use bus-range property ? */ | ||
670 | hose->first_busno = 0; | ||
671 | hose->last_busno = 0xff; | ||
672 | |||
673 | /* We use cfg_data as the address for the whole bridge MMIO space | ||
674 | */ | ||
675 | hose->cfg_data = of_iomap(hose->dn, 0); | ||
676 | |||
677 | pr_debug("PCIe registers mapped at 0x%p\n", hose->cfg_data); | ||
678 | |||
679 | /* Get the ranges of the device-tree */ | ||
680 | pci_process_bridge_OF_ranges(hose, np, 0); | ||
681 | |||
682 | /* XXX Force re-assigning of everything for now */ | ||
683 | pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC | | ||
684 | PCI_ENABLE_PROC_DOMAINS); | ||
685 | pci_probe_only = 0; | ||
686 | |||
687 | /* Calculate how the TCE space is divided */ | ||
688 | phb->dma32_base = 0; | ||
689 | phb->dma32_num_regions = NUM_DMA32_REGIONS; | ||
690 | if (phb->dma32_num_regions > MAX_TABLE_TVT_COUNT) { | ||
691 | pr_warning("IOMMU: Clamped to %d DMA32 regions\n", | ||
692 | MAX_TABLE_TVT_COUNT); | ||
693 | phb->dma32_num_regions = MAX_TABLE_TVT_COUNT; | ||
694 | } | ||
695 | phb->dma32_region_size = 0x80000000 / phb->dma32_num_regions; | ||
696 | |||
697 | BUG_ON(!is_power_of_2(phb->dma32_region_size)); | ||
698 | |||
699 | /* Setup config ops */ | ||
700 | hose->ops = &wsp_pcie_pci_ops; | ||
701 | |||
702 | /* Configure the HW */ | ||
703 | wsp_pcie_configure_hw(hose); | ||
704 | |||
705 | /* Instanciate IO workarounds */ | ||
706 | iowa_register_bus(hose, &wsp_pci_iops, NULL, phb); | ||
707 | #ifdef CONFIG_PCI_MSI | ||
708 | wsp_setup_phb_msi(hose); | ||
709 | #endif | ||
710 | |||
711 | /* Add to global list */ | ||
712 | list_add(&phb->all, &wsp_phbs); | ||
713 | |||
714 | return 0; | ||
715 | } | ||
716 | |||
717 | void __init wsp_setup_pci(void) | ||
718 | { | ||
719 | struct device_node *np; | ||
720 | int rc; | ||
721 | |||
722 | /* Find host bridges */ | ||
723 | for_each_compatible_node(np, "pciex", PCIE_COMPATIBLE) { | ||
724 | rc = wsp_setup_one_phb(np); | ||
725 | if (rc) | ||
726 | pr_err("Failed to setup PCIe bridge %s, rc=%d\n", | ||
727 | np->full_name, rc); | ||
728 | } | ||
729 | |||
730 | /* Establish device-tree linkage */ | ||
731 | pci_devs_phb_init(); | ||
732 | |||
733 | /* Set DMA ops to use TCEs */ | ||
734 | if (iommu_is_off) { | ||
735 | pr_info("PCI-E: Disabled TCEs, using direct DMA\n"); | ||
736 | set_pci_dma_ops(&dma_direct_ops); | ||
737 | } else { | ||
738 | ppc_md.pci_dma_dev_setup = wsp_pci_dma_dev_setup; | ||
739 | ppc_md.tce_build = tce_build_wsp; | ||
740 | ppc_md.tce_free = tce_free_wsp; | ||
741 | set_pci_dma_ops(&dma_iommu_ops); | ||
742 | } | ||
743 | } | ||
744 | |||
745 | #define err_debug(fmt...) pr_debug(fmt) | ||
746 | //#define err_debug(fmt...) | ||
747 | |||
748 | static int __init wsp_pci_get_err_irq_no_dt(struct device_node *np) | ||
749 | { | ||
750 | const u32 *prop; | ||
751 | int hw_irq; | ||
752 | |||
753 | /* Ok, no interrupts property, let's try to find our child P2P */ | ||
754 | np = of_get_next_child(np, NULL); | ||
755 | if (np == NULL) | ||
756 | return 0; | ||
757 | |||
758 | /* Grab it's interrupt map */ | ||
759 | prop = of_get_property(np, "interrupt-map", NULL); | ||
760 | if (prop == NULL) | ||
761 | return 0; | ||
762 | |||
763 | /* Grab one of the interrupts in there, keep the low 4 bits */ | ||
764 | hw_irq = prop[5] & 0xf; | ||
765 | |||
766 | /* 0..4 for PHB 0 and 5..9 for PHB 1 */ | ||
767 | if (hw_irq < 5) | ||
768 | hw_irq = 4; | ||
769 | else | ||
770 | hw_irq = 9; | ||
771 | hw_irq |= prop[5] & ~0xf; | ||
772 | |||
773 | err_debug("PCI: Using 0x%x as error IRQ for %s\n", | ||
774 | hw_irq, np->parent->full_name); | ||
775 | return irq_create_mapping(NULL, hw_irq); | ||
776 | } | ||
777 | |||
778 | static const struct { | ||
779 | u32 offset; | ||
780 | const char *name; | ||
781 | } wsp_pci_regs[] = { | ||
782 | #define DREG(x) { PCIE_REG_##x, #x } | ||
783 | #define DUTL(x) { PCIE_UTL_##x, "UTL_" #x } | ||
784 | /* Architected registers except CONFIG_ and IODA | ||
785 | * to avoid side effects | ||
786 | */ | ||
787 | DREG(DMA_CHAN_STATUS), | ||
788 | DREG(CPU_LOADSTORE_STATUS), | ||
789 | DREG(LOCK0), | ||
790 | DREG(LOCK1), | ||
791 | DREG(PHB_CONFIG), | ||
792 | DREG(IO_BASE_ADDR), | ||
793 | DREG(IO_BASE_MASK), | ||
794 | DREG(IO_START_ADDR), | ||
795 | DREG(M32A_BASE_ADDR), | ||
796 | DREG(M32A_BASE_MASK), | ||
797 | DREG(M32A_START_ADDR), | ||
798 | DREG(M32B_BASE_ADDR), | ||
799 | DREG(M32B_BASE_MASK), | ||
800 | DREG(M32B_START_ADDR), | ||
801 | DREG(M64_BASE_ADDR), | ||
802 | DREG(M64_BASE_MASK), | ||
803 | DREG(M64_START_ADDR), | ||
804 | DREG(TCE_KILL), | ||
805 | DREG(LOCK2), | ||
806 | DREG(PHB_GEN_CAP), | ||
807 | DREG(PHB_TCE_CAP), | ||
808 | DREG(PHB_IRQ_CAP), | ||
809 | DREG(PHB_EEH_CAP), | ||
810 | DREG(PAPR_ERR_INJ_CONTROL), | ||
811 | DREG(PAPR_ERR_INJ_ADDR), | ||
812 | DREG(PAPR_ERR_INJ_MASK), | ||
813 | |||
814 | /* UTL core regs */ | ||
815 | DUTL(SYS_BUS_CONTROL), | ||
816 | DUTL(STATUS), | ||
817 | DUTL(SYS_BUS_AGENT_STATUS), | ||
818 | DUTL(SYS_BUS_AGENT_ERR_SEV), | ||
819 | DUTL(SYS_BUS_AGENT_IRQ_EN), | ||
820 | DUTL(SYS_BUS_BURST_SZ_CONF), | ||
821 | DUTL(REVISION_ID), | ||
822 | DUTL(OUT_POST_HDR_BUF_ALLOC), | ||
823 | DUTL(OUT_POST_DAT_BUF_ALLOC), | ||
824 | DUTL(IN_POST_HDR_BUF_ALLOC), | ||
825 | DUTL(IN_POST_DAT_BUF_ALLOC), | ||
826 | DUTL(OUT_NP_BUF_ALLOC), | ||
827 | DUTL(IN_NP_BUF_ALLOC), | ||
828 | DUTL(PCIE_TAGS_ALLOC), | ||
829 | DUTL(GBIF_READ_TAGS_ALLOC), | ||
830 | |||
831 | DUTL(PCIE_PORT_CONTROL), | ||
832 | DUTL(PCIE_PORT_STATUS), | ||
833 | DUTL(PCIE_PORT_ERROR_SEV), | ||
834 | DUTL(PCIE_PORT_IRQ_EN), | ||
835 | DUTL(RC_STATUS), | ||
836 | DUTL(RC_ERR_SEVERITY), | ||
837 | DUTL(RC_IRQ_EN), | ||
838 | DUTL(EP_STATUS), | ||
839 | DUTL(EP_ERR_SEVERITY), | ||
840 | DUTL(EP_ERR_IRQ_EN), | ||
841 | DUTL(PCI_PM_CTRL1), | ||
842 | DUTL(PCI_PM_CTRL2), | ||
843 | |||
844 | /* PCIe stack regs */ | ||
845 | DREG(SYSTEM_CONFIG1), | ||
846 | DREG(SYSTEM_CONFIG2), | ||
847 | DREG(EP_SYSTEM_CONFIG), | ||
848 | DREG(EP_FLR), | ||
849 | DREG(EP_BAR_CONFIG), | ||
850 | DREG(LINK_CONFIG), | ||
851 | DREG(PM_CONFIG), | ||
852 | DREG(DLP_CONTROL), | ||
853 | DREG(DLP_STATUS), | ||
854 | DREG(ERR_REPORT_CONTROL), | ||
855 | DREG(SLOT_CONTROL1), | ||
856 | DREG(SLOT_CONTROL2), | ||
857 | DREG(UTL_CONFIG), | ||
858 | DREG(BUFFERS_CONFIG), | ||
859 | DREG(ERROR_INJECT), | ||
860 | DREG(SRIOV_CONFIG), | ||
861 | DREG(PF0_SRIOV_STATUS), | ||
862 | DREG(PF1_SRIOV_STATUS), | ||
863 | DREG(PORT_NUMBER), | ||
864 | DREG(POR_SYSTEM_CONFIG), | ||
865 | |||
866 | /* Internal logic regs */ | ||
867 | DREG(PHB_VERSION), | ||
868 | DREG(RESET), | ||
869 | DREG(PHB_CONTROL), | ||
870 | DREG(PHB_TIMEOUT_CONTROL1), | ||
871 | DREG(PHB_QUIESCE_DMA), | ||
872 | DREG(PHB_DMA_READ_TAG_ACTV), | ||
873 | DREG(PHB_TCE_READ_TAG_ACTV), | ||
874 | |||
875 | /* FIR registers */ | ||
876 | DREG(LEM_FIR_ACCUM), | ||
877 | DREG(LEM_FIR_AND_MASK), | ||
878 | DREG(LEM_FIR_OR_MASK), | ||
879 | DREG(LEM_ACTION0), | ||
880 | DREG(LEM_ACTION1), | ||
881 | DREG(LEM_ERROR_MASK), | ||
882 | DREG(LEM_ERROR_AND_MASK), | ||
883 | DREG(LEM_ERROR_OR_MASK), | ||
884 | |||
885 | /* Error traps registers */ | ||
886 | DREG(PHB_ERR_STATUS), | ||
887 | DREG(PHB_ERR_STATUS), | ||
888 | DREG(PHB_ERR1_STATUS), | ||
889 | DREG(PHB_ERR_INJECT), | ||
890 | DREG(PHB_ERR_LEM_ENABLE), | ||
891 | DREG(PHB_ERR_IRQ_ENABLE), | ||
892 | DREG(PHB_ERR_FREEZE_ENABLE), | ||
893 | DREG(PHB_ERR_SIDE_ENABLE), | ||
894 | DREG(PHB_ERR_LOG_0), | ||
895 | DREG(PHB_ERR_LOG_1), | ||
896 | DREG(PHB_ERR_STATUS_MASK), | ||
897 | DREG(PHB_ERR1_STATUS_MASK), | ||
898 | DREG(MMIO_ERR_STATUS), | ||
899 | DREG(MMIO_ERR1_STATUS), | ||
900 | DREG(MMIO_ERR_INJECT), | ||
901 | DREG(MMIO_ERR_LEM_ENABLE), | ||
902 | DREG(MMIO_ERR_IRQ_ENABLE), | ||
903 | DREG(MMIO_ERR_FREEZE_ENABLE), | ||
904 | DREG(MMIO_ERR_SIDE_ENABLE), | ||
905 | DREG(MMIO_ERR_LOG_0), | ||
906 | DREG(MMIO_ERR_LOG_1), | ||
907 | DREG(MMIO_ERR_STATUS_MASK), | ||
908 | DREG(MMIO_ERR1_STATUS_MASK), | ||
909 | DREG(DMA_ERR_STATUS), | ||
910 | DREG(DMA_ERR1_STATUS), | ||
911 | DREG(DMA_ERR_INJECT), | ||
912 | DREG(DMA_ERR_LEM_ENABLE), | ||
913 | DREG(DMA_ERR_IRQ_ENABLE), | ||
914 | DREG(DMA_ERR_FREEZE_ENABLE), | ||
915 | DREG(DMA_ERR_SIDE_ENABLE), | ||
916 | DREG(DMA_ERR_LOG_0), | ||
917 | DREG(DMA_ERR_LOG_1), | ||
918 | DREG(DMA_ERR_STATUS_MASK), | ||
919 | DREG(DMA_ERR1_STATUS_MASK), | ||
920 | |||
921 | /* Debug and Trace registers */ | ||
922 | DREG(PHB_DEBUG_CONTROL0), | ||
923 | DREG(PHB_DEBUG_STATUS0), | ||
924 | DREG(PHB_DEBUG_CONTROL1), | ||
925 | DREG(PHB_DEBUG_STATUS1), | ||
926 | DREG(PHB_DEBUG_CONTROL2), | ||
927 | DREG(PHB_DEBUG_STATUS2), | ||
928 | DREG(PHB_DEBUG_CONTROL3), | ||
929 | DREG(PHB_DEBUG_STATUS3), | ||
930 | DREG(PHB_DEBUG_CONTROL4), | ||
931 | DREG(PHB_DEBUG_STATUS4), | ||
932 | DREG(PHB_DEBUG_CONTROL5), | ||
933 | DREG(PHB_DEBUG_STATUS5), | ||
934 | |||
935 | /* Don't seem to exist ... | ||
936 | DREG(PHB_DEBUG_CONTROL6), | ||
937 | DREG(PHB_DEBUG_STATUS6), | ||
938 | */ | ||
939 | }; | ||
940 | |||
941 | static int wsp_pci_regs_show(struct seq_file *m, void *private) | ||
942 | { | ||
943 | struct wsp_phb *phb = m->private; | ||
944 | struct pci_controller *hose = phb->hose; | ||
945 | int i; | ||
946 | |||
947 | for (i = 0; i < ARRAY_SIZE(wsp_pci_regs); i++) { | ||
948 | /* Skip write-only regs */ | ||
949 | if (wsp_pci_regs[i].offset == 0xc08 || | ||
950 | wsp_pci_regs[i].offset == 0xc10 || | ||
951 | wsp_pci_regs[i].offset == 0xc38 || | ||
952 | wsp_pci_regs[i].offset == 0xc40) | ||
953 | continue; | ||
954 | seq_printf(m, "0x%03x: 0x%016llx %s\n", | ||
955 | wsp_pci_regs[i].offset, | ||
956 | in_be64(hose->cfg_data + wsp_pci_regs[i].offset), | ||
957 | wsp_pci_regs[i].name); | ||
958 | } | ||
959 | return 0; | ||
960 | } | ||
961 | |||
962 | static int wsp_pci_regs_open(struct inode *inode, struct file *file) | ||
963 | { | ||
964 | return single_open(file, wsp_pci_regs_show, inode->i_private); | ||
965 | } | ||
966 | |||
967 | static const struct file_operations wsp_pci_regs_fops = { | ||
968 | .open = wsp_pci_regs_open, | ||
969 | .read = seq_read, | ||
970 | .llseek = seq_lseek, | ||
971 | .release = single_release, | ||
972 | }; | ||
973 | |||
974 | static int wsp_pci_reg_set(void *data, u64 val) | ||
975 | { | ||
976 | out_be64((void __iomem *)data, val); | ||
977 | return 0; | ||
978 | } | ||
979 | |||
980 | static int wsp_pci_reg_get(void *data, u64 *val) | ||
981 | { | ||
982 | *val = in_be64((void __iomem *)data); | ||
983 | return 0; | ||
984 | } | ||
985 | |||
986 | DEFINE_SIMPLE_ATTRIBUTE(wsp_pci_reg_fops, wsp_pci_reg_get, wsp_pci_reg_set, "0x%llx\n"); | ||
987 | |||
988 | static irqreturn_t wsp_pci_err_irq(int irq, void *dev_id) | ||
989 | { | ||
990 | struct wsp_phb *phb = dev_id; | ||
991 | struct pci_controller *hose = phb->hose; | ||
992 | irqreturn_t handled = IRQ_NONE; | ||
993 | struct wsp_pcie_err_log_data ed; | ||
994 | |||
995 | pr_err("PCI: Error interrupt on %s (PHB %d)\n", | ||
996 | hose->dn->full_name, hose->global_number); | ||
997 | again: | ||
998 | memset(&ed, 0, sizeof(ed)); | ||
999 | |||
1000 | /* Read and clear UTL errors */ | ||
1001 | ed.utl_sys_err = in_be64(hose->cfg_data + PCIE_UTL_SYS_BUS_AGENT_STATUS); | ||
1002 | if (ed.utl_sys_err) | ||
1003 | out_be64(hose->cfg_data + PCIE_UTL_SYS_BUS_AGENT_STATUS, ed.utl_sys_err); | ||
1004 | ed.utl_port_err = in_be64(hose->cfg_data + PCIE_UTL_PCIE_PORT_STATUS); | ||
1005 | if (ed.utl_port_err) | ||
1006 | out_be64(hose->cfg_data + PCIE_UTL_PCIE_PORT_STATUS, ed.utl_port_err); | ||
1007 | ed.utl_rc_err = in_be64(hose->cfg_data + PCIE_UTL_RC_STATUS); | ||
1008 | if (ed.utl_rc_err) | ||
1009 | out_be64(hose->cfg_data + PCIE_UTL_RC_STATUS, ed.utl_rc_err); | ||
1010 | |||
1011 | /* Read and clear main trap errors */ | ||
1012 | ed.phb_err = in_be64(hose->cfg_data + PCIE_REG_PHB_ERR_STATUS); | ||
1013 | if (ed.phb_err) { | ||
1014 | ed.phb_err1 = in_be64(hose->cfg_data + PCIE_REG_PHB_ERR1_STATUS); | ||
1015 | ed.phb_log0 = in_be64(hose->cfg_data + PCIE_REG_PHB_ERR_LOG_0); | ||
1016 | ed.phb_log1 = in_be64(hose->cfg_data + PCIE_REG_PHB_ERR_LOG_1); | ||
1017 | out_be64(hose->cfg_data + PCIE_REG_PHB_ERR1_STATUS, 0); | ||
1018 | out_be64(hose->cfg_data + PCIE_REG_PHB_ERR_STATUS, 0); | ||
1019 | } | ||
1020 | ed.mmio_err = in_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_STATUS); | ||
1021 | if (ed.mmio_err) { | ||
1022 | ed.mmio_err1 = in_be64(hose->cfg_data + PCIE_REG_MMIO_ERR1_STATUS); | ||
1023 | ed.mmio_log0 = in_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_LOG_0); | ||
1024 | ed.mmio_log1 = in_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_LOG_1); | ||
1025 | out_be64(hose->cfg_data + PCIE_REG_MMIO_ERR1_STATUS, 0); | ||
1026 | out_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_STATUS, 0); | ||
1027 | } | ||
1028 | ed.dma_err = in_be64(hose->cfg_data + PCIE_REG_DMA_ERR_STATUS); | ||
1029 | if (ed.dma_err) { | ||
1030 | ed.dma_err1 = in_be64(hose->cfg_data + PCIE_REG_DMA_ERR1_STATUS); | ||
1031 | ed.dma_log0 = in_be64(hose->cfg_data + PCIE_REG_DMA_ERR_LOG_0); | ||
1032 | ed.dma_log1 = in_be64(hose->cfg_data + PCIE_REG_DMA_ERR_LOG_1); | ||
1033 | out_be64(hose->cfg_data + PCIE_REG_DMA_ERR1_STATUS, 0); | ||
1034 | out_be64(hose->cfg_data + PCIE_REG_DMA_ERR_STATUS, 0); | ||
1035 | } | ||
1036 | |||
1037 | /* Now print things out */ | ||
1038 | if (ed.phb_err) { | ||
1039 | pr_err(" PHB Error Status : 0x%016llx\n", ed.phb_err); | ||
1040 | pr_err(" PHB First Error Status: 0x%016llx\n", ed.phb_err1); | ||
1041 | pr_err(" PHB Error Log 0 : 0x%016llx\n", ed.phb_log0); | ||
1042 | pr_err(" PHB Error Log 1 : 0x%016llx\n", ed.phb_log1); | ||
1043 | } | ||
1044 | if (ed.mmio_err) { | ||
1045 | pr_err(" MMIO Error Status : 0x%016llx\n", ed.mmio_err); | ||
1046 | pr_err(" MMIO First Error Status: 0x%016llx\n", ed.mmio_err1); | ||
1047 | pr_err(" MMIO Error Log 0 : 0x%016llx\n", ed.mmio_log0); | ||
1048 | pr_err(" MMIO Error Log 1 : 0x%016llx\n", ed.mmio_log1); | ||
1049 | } | ||
1050 | if (ed.dma_err) { | ||
1051 | pr_err(" DMA Error Status : 0x%016llx\n", ed.dma_err); | ||
1052 | pr_err(" DMA First Error Status: 0x%016llx\n", ed.dma_err1); | ||
1053 | pr_err(" DMA Error Log 0 : 0x%016llx\n", ed.dma_log0); | ||
1054 | pr_err(" DMA Error Log 1 : 0x%016llx\n", ed.dma_log1); | ||
1055 | } | ||
1056 | if (ed.utl_sys_err) | ||
1057 | pr_err(" UTL Sys Error Status : 0x%016llx\n", ed.utl_sys_err); | ||
1058 | if (ed.utl_port_err) | ||
1059 | pr_err(" UTL Port Error Status : 0x%016llx\n", ed.utl_port_err); | ||
1060 | if (ed.utl_rc_err) | ||
1061 | pr_err(" UTL RC Error Status : 0x%016llx\n", ed.utl_rc_err); | ||
1062 | |||
1063 | /* Interrupts are caused by the error traps. If we had any error there | ||
1064 | * we loop again in case the UTL buffered some new stuff between | ||
1065 | * going there and going to the traps | ||
1066 | */ | ||
1067 | if (ed.dma_err || ed.mmio_err || ed.phb_err) { | ||
1068 | handled = IRQ_HANDLED; | ||
1069 | goto again; | ||
1070 | } | ||
1071 | return handled; | ||
1072 | } | ||
1073 | |||
1074 | static void __init wsp_setup_pci_err_reporting(struct wsp_phb *phb) | ||
1075 | { | ||
1076 | struct pci_controller *hose = phb->hose; | ||
1077 | int err_irq, i, rc; | ||
1078 | char fname[16]; | ||
1079 | |||
1080 | /* Create a debugfs file for that PHB */ | ||
1081 | sprintf(fname, "phb%d", phb->hose->global_number); | ||
1082 | phb->ddir = debugfs_create_dir(fname, powerpc_debugfs_root); | ||
1083 | |||
1084 | /* Some useful debug output */ | ||
1085 | if (phb->ddir) { | ||
1086 | struct dentry *d = debugfs_create_dir("regs", phb->ddir); | ||
1087 | char tmp[64]; | ||
1088 | |||
1089 | for (i = 0; i < ARRAY_SIZE(wsp_pci_regs); i++) { | ||
1090 | sprintf(tmp, "%03x_%s", wsp_pci_regs[i].offset, | ||
1091 | wsp_pci_regs[i].name); | ||
1092 | debugfs_create_file(tmp, 0600, d, | ||
1093 | hose->cfg_data + wsp_pci_regs[i].offset, | ||
1094 | &wsp_pci_reg_fops); | ||
1095 | } | ||
1096 | debugfs_create_file("all_regs", 0600, phb->ddir, phb, &wsp_pci_regs_fops); | ||
1097 | } | ||
1098 | |||
1099 | /* Find the IRQ number for that PHB */ | ||
1100 | err_irq = irq_of_parse_and_map(hose->dn, 0); | ||
1101 | if (err_irq == 0) | ||
1102 | /* XXX Error IRQ lacking from device-tree */ | ||
1103 | err_irq = wsp_pci_get_err_irq_no_dt(hose->dn); | ||
1104 | if (err_irq == 0) { | ||
1105 | pr_err("PCI: Failed to fetch error interrupt for %s\n", | ||
1106 | hose->dn->full_name); | ||
1107 | return; | ||
1108 | } | ||
1109 | /* Request it */ | ||
1110 | rc = request_irq(err_irq, wsp_pci_err_irq, 0, "wsp_pci error", phb); | ||
1111 | if (rc) { | ||
1112 | pr_err("PCI: Failed to request interrupt for %s\n", | ||
1113 | hose->dn->full_name); | ||
1114 | } | ||
1115 | /* Enable interrupts for all errors for now */ | ||
1116 | out_be64(hose->cfg_data + PCIE_REG_PHB_ERR_IRQ_ENABLE, 0xffffffffffffffffull); | ||
1117 | out_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_IRQ_ENABLE, 0xffffffffffffffffull); | ||
1118 | out_be64(hose->cfg_data + PCIE_REG_DMA_ERR_IRQ_ENABLE, 0xffffffffffffffffull); | ||
1119 | } | ||
1120 | |||
1121 | /* | ||
1122 | * This is called later to hookup with the error interrupt | ||
1123 | */ | ||
1124 | static int __init wsp_setup_pci_late(void) | ||
1125 | { | ||
1126 | struct wsp_phb *phb; | ||
1127 | |||
1128 | list_for_each_entry(phb, &wsp_phbs, all) | ||
1129 | wsp_setup_pci_err_reporting(phb); | ||
1130 | |||
1131 | return 0; | ||
1132 | } | ||
1133 | arch_initcall(wsp_setup_pci_late); | ||
diff --git a/arch/powerpc/platforms/wsp/wsp_pci.h b/arch/powerpc/platforms/wsp/wsp_pci.h new file mode 100644 index 000000000000..52e9bd95250d --- /dev/null +++ b/arch/powerpc/platforms/wsp/wsp_pci.h | |||
@@ -0,0 +1,268 @@ | |||
1 | /* | ||
2 | * Copyright 2010 Ben Herrenschmidt, IBM Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #ifndef __WSP_PCI_H | ||
11 | #define __WSP_PCI_H | ||
12 | |||
13 | /* Architected registers */ | ||
14 | #define PCIE_REG_DMA_CHAN_STATUS 0x110 | ||
15 | #define PCIE_REG_CPU_LOADSTORE_STATUS 0x120 | ||
16 | |||
17 | #define PCIE_REG_CONFIG_DATA 0x130 | ||
18 | #define PCIE_REG_LOCK0 0x138 | ||
19 | #define PCIE_REG_CONFIG_ADDRESS 0x140 | ||
20 | #define PCIE_REG_CA_ENABLE 0x8000000000000000ull | ||
21 | #define PCIE_REG_CA_BUS_MASK 0x0ff0000000000000ull | ||
22 | #define PCIE_REG_CA_BUS_SHIFT (20+32) | ||
23 | #define PCIE_REG_CA_DEV_MASK 0x000f800000000000ull | ||
24 | #define PCIE_REG_CA_DEV_SHIFT (15+32) | ||
25 | #define PCIE_REG_CA_FUNC_MASK 0x0000700000000000ull | ||
26 | #define PCIE_REG_CA_FUNC_SHIFT (12+32) | ||
27 | #define PCIE_REG_CA_REG_MASK 0x00000fff00000000ull | ||
28 | #define PCIE_REG_CA_REG_SHIFT ( 0+32) | ||
29 | #define PCIE_REG_CA_BE_MASK 0x00000000f0000000ull | ||
30 | #define PCIE_REG_CA_BE_SHIFT ( 28) | ||
31 | #define PCIE_REG_LOCK1 0x148 | ||
32 | |||
33 | #define PCIE_REG_PHB_CONFIG 0x160 | ||
34 | #define PCIE_REG_PHBC_64B_TCE_EN 0x2000000000000000ull | ||
35 | #define PCIE_REG_PHBC_MMIO_DMA_FREEZE_EN 0x1000000000000000ull | ||
36 | #define PCIE_REG_PHBC_32BIT_MSI_EN 0x0080000000000000ull | ||
37 | #define PCIE_REG_PHBC_M64_EN 0x0040000000000000ull | ||
38 | #define PCIE_REG_PHBC_IO_EN 0x0008000000000000ull | ||
39 | #define PCIE_REG_PHBC_64BIT_MSI_EN 0x0002000000000000ull | ||
40 | #define PCIE_REG_PHBC_M32A_EN 0x0000800000000000ull | ||
41 | #define PCIE_REG_PHBC_M32B_EN 0x0000400000000000ull | ||
42 | #define PCIE_REG_PHBC_MSI_PE_VALIDATE 0x0000200000000000ull | ||
43 | #define PCIE_REG_PHBC_DMA_XLATE_BYPASS 0x0000100000000000ull | ||
44 | |||
45 | #define PCIE_REG_IO_BASE_ADDR 0x170 | ||
46 | #define PCIE_REG_IO_BASE_MASK 0x178 | ||
47 | #define PCIE_REG_IO_START_ADDR 0x180 | ||
48 | |||
49 | #define PCIE_REG_M32A_BASE_ADDR 0x190 | ||
50 | #define PCIE_REG_M32A_BASE_MASK 0x198 | ||
51 | #define PCIE_REG_M32A_START_ADDR 0x1a0 | ||
52 | |||
53 | #define PCIE_REG_M32B_BASE_ADDR 0x1b0 | ||
54 | #define PCIE_REG_M32B_BASE_MASK 0x1b8 | ||
55 | #define PCIE_REG_M32B_START_ADDR 0x1c0 | ||
56 | |||
57 | #define PCIE_REG_M64_BASE_ADDR 0x1e0 | ||
58 | #define PCIE_REG_M64_BASE_MASK 0x1e8 | ||
59 | #define PCIE_REG_M64_START_ADDR 0x1f0 | ||
60 | |||
61 | #define PCIE_REG_TCE_KILL 0x210 | ||
62 | #define PCIE_REG_TCEKILL_SINGLE 0x8000000000000000ull | ||
63 | #define PCIE_REG_TCEKILL_ADDR_MASK 0x000003fffffffff8ull | ||
64 | #define PCIE_REG_TCEKILL_PS_4K 0 | ||
65 | #define PCIE_REG_TCEKILL_PS_64K 1 | ||
66 | #define PCIE_REG_TCEKILL_PS_16M 2 | ||
67 | #define PCIE_REG_TCEKILL_PS_16G 3 | ||
68 | |||
69 | #define PCIE_REG_IODA_ADDR 0x220 | ||
70 | #define PCIE_REG_IODA_AD_AUTOINC 0x8000000000000000ull | ||
71 | #define PCIE_REG_IODA_AD_TBL_MVT 0x0005000000000000ull | ||
72 | #define PCIE_REG_IODA_AD_TBL_PELT 0x0006000000000000ull | ||
73 | #define PCIE_REG_IODA_AD_TBL_PESTA 0x0007000000000000ull | ||
74 | #define PCIE_REG_IODA_AD_TBL_PESTB 0x0008000000000000ull | ||
75 | #define PCIE_REG_IODA_AD_TBL_TVT 0x0009000000000000ull | ||
76 | #define PCIE_REG_IODA_AD_TBL_TCE 0x000a000000000000ull | ||
77 | #define PCIE_REG_IODA_DATA0 0x228 | ||
78 | #define PCIE_REG_IODA_DATA1 0x230 | ||
79 | |||
80 | #define PCIE_REG_LOCK2 0x240 | ||
81 | |||
82 | #define PCIE_REG_PHB_GEN_CAP 0x250 | ||
83 | #define PCIE_REG_PHB_TCE_CAP 0x258 | ||
84 | #define PCIE_REG_PHB_IRQ_CAP 0x260 | ||
85 | #define PCIE_REG_PHB_EEH_CAP 0x268 | ||
86 | |||
87 | #define PCIE_REG_PAPR_ERR_INJ_CONTROL 0x2b0 | ||
88 | #define PCIE_REG_PAPR_ERR_INJ_ADDR 0x2b8 | ||
89 | #define PCIE_REG_PAPR_ERR_INJ_MASK 0x2c0 | ||
90 | |||
91 | |||
92 | #define PCIE_REG_SYS_CFG1 0x600 | ||
93 | #define PCIE_REG_SYS_CFG1_CLASS_CODE 0x0000000000ffffffull | ||
94 | |||
95 | #define IODA_TVT0_TTA_MASK 0x000fffffffff0000ull | ||
96 | #define IODA_TVT0_TTA_SHIFT 4 | ||
97 | #define IODA_TVT0_BUSNUM_VALID_MASK 0x000000000000e000ull | ||
98 | #define IODA_TVT0_TCE_TABLE_SIZE_MASK 0x0000000000001f00ull | ||
99 | #define IODA_TVT0_TCE_TABLE_SIZE_SHIFT 8 | ||
100 | #define IODA_TVT0_BUSNUM_VALUE_MASK 0x00000000000000ffull | ||
101 | #define IODA_TVT0_BUSNUM_VALID_SHIFT 0 | ||
102 | #define IODA_TVT1_DEVNUM_VALID 0x2000000000000000ull | ||
103 | #define IODA_TVT1_DEVNUM_VALUE_MASK 0x1f00000000000000ull | ||
104 | #define IODA_TVT1_DEVNUM_VALUE_SHIFT 56 | ||
105 | #define IODA_TVT1_FUNCNUM_VALID 0x0008000000000000ull | ||
106 | #define IODA_TVT1_FUNCNUM_VALUE_MASK 0x0007000000000000ull | ||
107 | #define IODA_TVT1_FUNCNUM_VALUE_SHIFT 48 | ||
108 | #define IODA_TVT1_IO_PAGE_SIZE_MASK 0x00001f0000000000ull | ||
109 | #define IODA_TVT1_IO_PAGE_SIZE_SHIFT 40 | ||
110 | #define IODA_TVT1_PE_NUMBER_MASK 0x000000000000003full | ||
111 | #define IODA_TVT1_PE_NUMBER_SHIFT 0 | ||
112 | |||
113 | #define IODA_TVT_COUNT 64 | ||
114 | |||
115 | /* UTL Core registers */ | ||
116 | #define PCIE_UTL_SYS_BUS_CONTROL 0x400 | ||
117 | #define PCIE_UTL_STATUS 0x408 | ||
118 | #define PCIE_UTL_SYS_BUS_AGENT_STATUS 0x410 | ||
119 | #define PCIE_UTL_SYS_BUS_AGENT_ERR_SEV 0x418 | ||
120 | #define PCIE_UTL_SYS_BUS_AGENT_IRQ_EN 0x420 | ||
121 | #define PCIE_UTL_SYS_BUS_BURST_SZ_CONF 0x440 | ||
122 | #define PCIE_UTL_REVISION_ID 0x448 | ||
123 | |||
124 | #define PCIE_UTL_OUT_POST_HDR_BUF_ALLOC 0x4c0 | ||
125 | #define PCIE_UTL_OUT_POST_DAT_BUF_ALLOC 0x4d0 | ||
126 | #define PCIE_UTL_IN_POST_HDR_BUF_ALLOC 0x4e0 | ||
127 | #define PCIE_UTL_IN_POST_DAT_BUF_ALLOC 0x4f0 | ||
128 | #define PCIE_UTL_OUT_NP_BUF_ALLOC 0x500 | ||
129 | #define PCIE_UTL_IN_NP_BUF_ALLOC 0x510 | ||
130 | #define PCIE_UTL_PCIE_TAGS_ALLOC 0x520 | ||
131 | #define PCIE_UTL_GBIF_READ_TAGS_ALLOC 0x530 | ||
132 | |||
133 | #define PCIE_UTL_PCIE_PORT_CONTROL 0x540 | ||
134 | #define PCIE_UTL_PCIE_PORT_STATUS 0x548 | ||
135 | #define PCIE_UTL_PCIE_PORT_ERROR_SEV 0x550 | ||
136 | #define PCIE_UTL_PCIE_PORT_IRQ_EN 0x558 | ||
137 | #define PCIE_UTL_RC_STATUS 0x560 | ||
138 | #define PCIE_UTL_RC_ERR_SEVERITY 0x568 | ||
139 | #define PCIE_UTL_RC_IRQ_EN 0x570 | ||
140 | #define PCIE_UTL_EP_STATUS 0x578 | ||
141 | #define PCIE_UTL_EP_ERR_SEVERITY 0x580 | ||
142 | #define PCIE_UTL_EP_ERR_IRQ_EN 0x588 | ||
143 | |||
144 | #define PCIE_UTL_PCI_PM_CTRL1 0x590 | ||
145 | #define PCIE_UTL_PCI_PM_CTRL2 0x598 | ||
146 | |||
147 | /* PCIe stack registers */ | ||
148 | #define PCIE_REG_SYSTEM_CONFIG1 0x600 | ||
149 | #define PCIE_REG_SYSTEM_CONFIG2 0x608 | ||
150 | #define PCIE_REG_EP_SYSTEM_CONFIG 0x618 | ||
151 | #define PCIE_REG_EP_FLR 0x620 | ||
152 | #define PCIE_REG_EP_BAR_CONFIG 0x628 | ||
153 | #define PCIE_REG_LINK_CONFIG 0x630 | ||
154 | #define PCIE_REG_PM_CONFIG 0x640 | ||
155 | #define PCIE_REG_DLP_CONTROL 0x650 | ||
156 | #define PCIE_REG_DLP_STATUS 0x658 | ||
157 | #define PCIE_REG_ERR_REPORT_CONTROL 0x660 | ||
158 | #define PCIE_REG_SLOT_CONTROL1 0x670 | ||
159 | #define PCIE_REG_SLOT_CONTROL2 0x678 | ||
160 | #define PCIE_REG_UTL_CONFIG 0x680 | ||
161 | #define PCIE_REG_BUFFERS_CONFIG 0x690 | ||
162 | #define PCIE_REG_ERROR_INJECT 0x698 | ||
163 | #define PCIE_REG_SRIOV_CONFIG 0x6a0 | ||
164 | #define PCIE_REG_PF0_SRIOV_STATUS 0x6a8 | ||
165 | #define PCIE_REG_PF1_SRIOV_STATUS 0x6b0 | ||
166 | #define PCIE_REG_PORT_NUMBER 0x700 | ||
167 | #define PCIE_REG_POR_SYSTEM_CONFIG 0x708 | ||
168 | |||
169 | /* PHB internal logic registers */ | ||
170 | #define PCIE_REG_PHB_VERSION 0x800 | ||
171 | #define PCIE_REG_RESET 0x808 | ||
172 | #define PCIE_REG_PHB_CONTROL 0x810 | ||
173 | #define PCIE_REG_PHB_TIMEOUT_CONTROL1 0x878 | ||
174 | #define PCIE_REG_PHB_QUIESCE_DMA 0x888 | ||
175 | #define PCIE_REG_PHB_DMA_READ_TAG_ACTV 0x900 | ||
176 | #define PCIE_REG_PHB_TCE_READ_TAG_ACTV 0x908 | ||
177 | |||
178 | /* FIR registers */ | ||
179 | #define PCIE_REG_LEM_FIR_ACCUM 0xc00 | ||
180 | #define PCIE_REG_LEM_FIR_AND_MASK 0xc08 | ||
181 | #define PCIE_REG_LEM_FIR_OR_MASK 0xc10 | ||
182 | #define PCIE_REG_LEM_ACTION0 0xc18 | ||
183 | #define PCIE_REG_LEM_ACTION1 0xc20 | ||
184 | #define PCIE_REG_LEM_ERROR_MASK 0xc30 | ||
185 | #define PCIE_REG_LEM_ERROR_AND_MASK 0xc38 | ||
186 | #define PCIE_REG_LEM_ERROR_OR_MASK 0xc40 | ||
187 | |||
188 | /* PHB Error registers */ | ||
189 | #define PCIE_REG_PHB_ERR_STATUS 0xc80 | ||
190 | #define PCIE_REG_PHB_ERR1_STATUS 0xc88 | ||
191 | #define PCIE_REG_PHB_ERR_INJECT 0xc90 | ||
192 | #define PCIE_REG_PHB_ERR_LEM_ENABLE 0xc98 | ||
193 | #define PCIE_REG_PHB_ERR_IRQ_ENABLE 0xca0 | ||
194 | #define PCIE_REG_PHB_ERR_FREEZE_ENABLE 0xca8 | ||
195 | #define PCIE_REG_PHB_ERR_SIDE_ENABLE 0xcb8 | ||
196 | #define PCIE_REG_PHB_ERR_LOG_0 0xcc0 | ||
197 | #define PCIE_REG_PHB_ERR_LOG_1 0xcc8 | ||
198 | #define PCIE_REG_PHB_ERR_STATUS_MASK 0xcd0 | ||
199 | #define PCIE_REG_PHB_ERR1_STATUS_MASK 0xcd8 | ||
200 | |||
201 | #define PCIE_REG_MMIO_ERR_STATUS 0xd00 | ||
202 | #define PCIE_REG_MMIO_ERR1_STATUS 0xd08 | ||
203 | #define PCIE_REG_MMIO_ERR_INJECT 0xd10 | ||
204 | #define PCIE_REG_MMIO_ERR_LEM_ENABLE 0xd18 | ||
205 | #define PCIE_REG_MMIO_ERR_IRQ_ENABLE 0xd20 | ||
206 | #define PCIE_REG_MMIO_ERR_FREEZE_ENABLE 0xd28 | ||
207 | #define PCIE_REG_MMIO_ERR_SIDE_ENABLE 0xd38 | ||
208 | #define PCIE_REG_MMIO_ERR_LOG_0 0xd40 | ||
209 | #define PCIE_REG_MMIO_ERR_LOG_1 0xd48 | ||
210 | #define PCIE_REG_MMIO_ERR_STATUS_MASK 0xd50 | ||
211 | #define PCIE_REG_MMIO_ERR1_STATUS_MASK 0xd58 | ||
212 | |||
213 | #define PCIE_REG_DMA_ERR_STATUS 0xd80 | ||
214 | #define PCIE_REG_DMA_ERR1_STATUS 0xd88 | ||
215 | #define PCIE_REG_DMA_ERR_INJECT 0xd90 | ||
216 | #define PCIE_REG_DMA_ERR_LEM_ENABLE 0xd98 | ||
217 | #define PCIE_REG_DMA_ERR_IRQ_ENABLE 0xda0 | ||
218 | #define PCIE_REG_DMA_ERR_FREEZE_ENABLE 0xda8 | ||
219 | #define PCIE_REG_DMA_ERR_SIDE_ENABLE 0xdb8 | ||
220 | #define PCIE_REG_DMA_ERR_LOG_0 0xdc0 | ||
221 | #define PCIE_REG_DMA_ERR_LOG_1 0xdc8 | ||
222 | #define PCIE_REG_DMA_ERR_STATUS_MASK 0xdd0 | ||
223 | #define PCIE_REG_DMA_ERR1_STATUS_MASK 0xdd8 | ||
224 | |||
225 | /* Shortcuts for access to the above using the PHB definitions | ||
226 | * with an offset | ||
227 | */ | ||
228 | #define PCIE_REG_ERR_PHB_OFFSET 0x0 | ||
229 | #define PCIE_REG_ERR_MMIO_OFFSET 0x80 | ||
230 | #define PCIE_REG_ERR_DMA_OFFSET 0x100 | ||
231 | |||
232 | /* Debug and Trace registers */ | ||
233 | #define PCIE_REG_PHB_DEBUG_CONTROL0 0xe00 | ||
234 | #define PCIE_REG_PHB_DEBUG_STATUS0 0xe08 | ||
235 | #define PCIE_REG_PHB_DEBUG_CONTROL1 0xe10 | ||
236 | #define PCIE_REG_PHB_DEBUG_STATUS1 0xe18 | ||
237 | #define PCIE_REG_PHB_DEBUG_CONTROL2 0xe20 | ||
238 | #define PCIE_REG_PHB_DEBUG_STATUS2 0xe28 | ||
239 | #define PCIE_REG_PHB_DEBUG_CONTROL3 0xe30 | ||
240 | #define PCIE_REG_PHB_DEBUG_STATUS3 0xe38 | ||
241 | #define PCIE_REG_PHB_DEBUG_CONTROL4 0xe40 | ||
242 | #define PCIE_REG_PHB_DEBUG_STATUS4 0xe48 | ||
243 | #define PCIE_REG_PHB_DEBUG_CONTROL5 0xe50 | ||
244 | #define PCIE_REG_PHB_DEBUG_STATUS5 0xe58 | ||
245 | #define PCIE_REG_PHB_DEBUG_CONTROL6 0xe60 | ||
246 | #define PCIE_REG_PHB_DEBUG_STATUS6 0xe68 | ||
247 | |||
248 | /* Definition for PCIe errors */ | ||
249 | struct wsp_pcie_err_log_data { | ||
250 | __u64 phb_err; | ||
251 | __u64 phb_err1; | ||
252 | __u64 phb_log0; | ||
253 | __u64 phb_log1; | ||
254 | __u64 mmio_err; | ||
255 | __u64 mmio_err1; | ||
256 | __u64 mmio_log0; | ||
257 | __u64 mmio_log1; | ||
258 | __u64 dma_err; | ||
259 | __u64 dma_err1; | ||
260 | __u64 dma_log0; | ||
261 | __u64 dma_log1; | ||
262 | __u64 utl_sys_err; | ||
263 | __u64 utl_port_err; | ||
264 | __u64 utl_rc_err; | ||
265 | __u64 unused; | ||
266 | }; | ||
267 | |||
268 | #endif /* __WSP_PCI_H */ | ||
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index cf736ca0cf05..84e13253aec5 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile | |||
@@ -18,7 +18,6 @@ obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y) | |||
18 | obj-$(CONFIG_FSL_PMC) += fsl_pmc.o | 18 | obj-$(CONFIG_FSL_PMC) += fsl_pmc.o |
19 | obj-$(CONFIG_FSL_LBC) += fsl_lbc.o | 19 | obj-$(CONFIG_FSL_LBC) += fsl_lbc.o |
20 | obj-$(CONFIG_FSL_GTM) += fsl_gtm.o | 20 | obj-$(CONFIG_FSL_GTM) += fsl_gtm.o |
21 | obj-$(CONFIG_MPC8xxx_GPIO) += mpc8xxx_gpio.o | ||
22 | obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o | 21 | obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o |
23 | obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o | 22 | obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o |
24 | obj-$(CONFIG_FSL_RIO) += fsl_rio.o | 23 | obj-$(CONFIG_FSL_RIO) += fsl_rio.o |
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index d55d0ad0deab..8db10bb90042 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Author: Scott Wood <scottwood@freescale.com> | 4 | * Author: Scott Wood <scottwood@freescale.com> |
5 | * | 5 | * |
6 | * Copyright 2007 Freescale Semiconductor, Inc. | 6 | * Copyright 2007-2008,2010 Freescale Semiconductor, Inc. |
7 | * | 7 | * |
8 | * Some parts derived from commproc.c/cpm2_common.c, which is: | 8 | * Some parts derived from commproc.c/cpm2_common.c, which is: |
9 | * Copyright (c) 1997 Dan error_act (dmalek@jlc.net) | 9 | * Copyright (c) 1997 Dan error_act (dmalek@jlc.net) |
@@ -146,6 +146,7 @@ unsigned long cpm_muram_alloc(unsigned long size, unsigned long align) | |||
146 | spin_lock_irqsave(&cpm_muram_lock, flags); | 146 | spin_lock_irqsave(&cpm_muram_lock, flags); |
147 | cpm_muram_info.alignment = align; | 147 | cpm_muram_info.alignment = align; |
148 | start = rh_alloc(&cpm_muram_info, size, "commproc"); | 148 | start = rh_alloc(&cpm_muram_info, size, "commproc"); |
149 | memset(cpm_muram_addr(start), 0, size); | ||
149 | spin_unlock_irqrestore(&cpm_muram_lock, flags); | 150 | spin_unlock_irqrestore(&cpm_muram_lock, flags); |
150 | 151 | ||
151 | return start; | 152 | return start; |
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 419a77239bd7..e5c344d336ea 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c | |||
@@ -30,7 +30,7 @@ LIST_HEAD(msi_head); | |||
30 | 30 | ||
31 | struct fsl_msi_feature { | 31 | struct fsl_msi_feature { |
32 | u32 fsl_pic_ip; | 32 | u32 fsl_pic_ip; |
33 | u32 msiir_offset; | 33 | u32 msiir_offset; /* Offset of MSIIR, relative to start of MSIR bank */ |
34 | }; | 34 | }; |
35 | 35 | ||
36 | struct fsl_msi_cascade_data { | 36 | struct fsl_msi_cascade_data { |
@@ -126,10 +126,19 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, | |||
126 | { | 126 | { |
127 | struct fsl_msi *msi_data = fsl_msi_data; | 127 | struct fsl_msi *msi_data = fsl_msi_data; |
128 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | 128 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); |
129 | u64 base = fsl_pci_immrbar_base(hose); | 129 | u64 address; /* Physical address of the MSIIR */ |
130 | int len; | ||
131 | const u64 *reg; | ||
132 | |||
133 | /* If the msi-address-64 property exists, then use it */ | ||
134 | reg = of_get_property(hose->dn, "msi-address-64", &len); | ||
135 | if (reg && (len == sizeof(u64))) | ||
136 | address = be64_to_cpup(reg); | ||
137 | else | ||
138 | address = fsl_pci_immrbar_base(hose) + msi_data->msiir_offset; | ||
130 | 139 | ||
131 | msg->address_lo = msi_data->msi_addr_lo + lower_32_bits(base); | 140 | msg->address_lo = lower_32_bits(address); |
132 | msg->address_hi = msi_data->msi_addr_hi + upper_32_bits(base); | 141 | msg->address_hi = upper_32_bits(address); |
133 | 142 | ||
134 | msg->data = hwirq; | 143 | msg->data = hwirq; |
135 | 144 | ||
@@ -296,7 +305,7 @@ static int __devinit fsl_msi_setup_hwirq(struct fsl_msi *msi, | |||
296 | } | 305 | } |
297 | 306 | ||
298 | msi->msi_virqs[irq_index] = virt_msir; | 307 | msi->msi_virqs[irq_index] = virt_msir; |
299 | cascade_data->index = offset + irq_index; | 308 | cascade_data->index = offset; |
300 | cascade_data->msi_data = msi; | 309 | cascade_data->msi_data = msi; |
301 | irq_set_handler_data(virt_msir, cascade_data); | 310 | irq_set_handler_data(virt_msir, cascade_data); |
302 | irq_set_chained_handler(virt_msir, fsl_msi_cascade); | 311 | irq_set_chained_handler(virt_msir, fsl_msi_cascade); |
@@ -359,8 +368,7 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev) | |||
359 | 368 | ||
360 | msi->irqhost->host_data = msi; | 369 | msi->irqhost->host_data = msi; |
361 | 370 | ||
362 | msi->msi_addr_hi = 0x0; | 371 | msi->msiir_offset = features->msiir_offset + (res.start & 0xfffff); |
363 | msi->msi_addr_lo = features->msiir_offset + (res.start & 0xfffff); | ||
364 | 372 | ||
365 | rc = fsl_msi_init_allocator(msi); | 373 | rc = fsl_msi_init_allocator(msi); |
366 | if (rc) { | 374 | if (rc) { |
@@ -376,8 +384,10 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev) | |||
376 | goto error_out; | 384 | goto error_out; |
377 | } | 385 | } |
378 | 386 | ||
379 | if (!p) | 387 | if (!p) { |
380 | p = all_avail; | 388 | p = all_avail; |
389 | len = sizeof(all_avail); | ||
390 | } | ||
381 | 391 | ||
382 | for (irq_index = 0, i = 0; i < len / (2 * sizeof(u32)); i++) { | 392 | for (irq_index = 0, i = 0; i < len / (2 * sizeof(u32)); i++) { |
383 | if (p[i * 2] % IRQS_PER_MSI_REG || | 393 | if (p[i * 2] % IRQS_PER_MSI_REG || |
@@ -393,7 +403,7 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev) | |||
393 | count = p[i * 2 + 1] / IRQS_PER_MSI_REG; | 403 | count = p[i * 2 + 1] / IRQS_PER_MSI_REG; |
394 | 404 | ||
395 | for (j = 0; j < count; j++, irq_index++) { | 405 | for (j = 0; j < count; j++, irq_index++) { |
396 | err = fsl_msi_setup_hwirq(msi, dev, offset, irq_index); | 406 | err = fsl_msi_setup_hwirq(msi, dev, offset + j, irq_index); |
397 | if (err) | 407 | if (err) |
398 | goto error_out; | 408 | goto error_out; |
399 | } | 409 | } |
diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h index 624580c252d7..1313abbc5200 100644 --- a/arch/powerpc/sysdev/fsl_msi.h +++ b/arch/powerpc/sysdev/fsl_msi.h | |||
@@ -28,8 +28,7 @@ struct fsl_msi { | |||
28 | 28 | ||
29 | unsigned long cascade_irq; | 29 | unsigned long cascade_irq; |
30 | 30 | ||
31 | u32 msi_addr_lo; | 31 | u32 msiir_offset; /* Offset of MSIIR, relative to start of CCSR */ |
32 | u32 msi_addr_hi; | ||
33 | void __iomem *msi_regs; | 32 | void __iomem *msi_regs; |
34 | u32 feature; | 33 | u32 feature; |
35 | int msi_virqs[NR_MSI_REG]; | 34 | int msi_virqs[NR_MSI_REG]; |
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c deleted file mode 100644 index fb4963abdf55..000000000000 --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ /dev/null | |||
@@ -1,395 +0,0 @@ | |||
1 | /* | ||
2 | * GPIOs on MPC512x/8349/8572/8610 and compatible | ||
3 | * | ||
4 | * Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk> | ||
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 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/spinlock.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/of_gpio.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/irq.h> | ||
20 | |||
21 | #define MPC8XXX_GPIO_PINS 32 | ||
22 | |||
23 | #define GPIO_DIR 0x00 | ||
24 | #define GPIO_ODR 0x04 | ||
25 | #define GPIO_DAT 0x08 | ||
26 | #define GPIO_IER 0x0c | ||
27 | #define GPIO_IMR 0x10 | ||
28 | #define GPIO_ICR 0x14 | ||
29 | #define GPIO_ICR2 0x18 | ||
30 | |||
31 | struct mpc8xxx_gpio_chip { | ||
32 | struct of_mm_gpio_chip mm_gc; | ||
33 | spinlock_t lock; | ||
34 | |||
35 | /* | ||
36 | * shadowed data register to be able to clear/set output pins in | ||
37 | * open drain mode safely | ||
38 | */ | ||
39 | u32 data; | ||
40 | struct irq_host *irq; | ||
41 | void *of_dev_id_data; | ||
42 | }; | ||
43 | |||
44 | static inline u32 mpc8xxx_gpio2mask(unsigned int gpio) | ||
45 | { | ||
46 | return 1u << (MPC8XXX_GPIO_PINS - 1 - gpio); | ||
47 | } | ||
48 | |||
49 | static inline struct mpc8xxx_gpio_chip * | ||
50 | to_mpc8xxx_gpio_chip(struct of_mm_gpio_chip *mm) | ||
51 | { | ||
52 | return container_of(mm, struct mpc8xxx_gpio_chip, mm_gc); | ||
53 | } | ||
54 | |||
55 | static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm) | ||
56 | { | ||
57 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
58 | |||
59 | mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT); | ||
60 | } | ||
61 | |||
62 | /* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs | ||
63 | * defined as output cannot be determined by reading GPDAT register, | ||
64 | * so we use shadow data register instead. The status of input pins | ||
65 | * is determined by reading GPDAT register. | ||
66 | */ | ||
67 | static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio) | ||
68 | { | ||
69 | u32 val; | ||
70 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
71 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
72 | |||
73 | val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR); | ||
74 | |||
75 | return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio); | ||
76 | } | ||
77 | |||
78 | static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio) | ||
79 | { | ||
80 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
81 | |||
82 | return in_be32(mm->regs + GPIO_DAT) & mpc8xxx_gpio2mask(gpio); | ||
83 | } | ||
84 | |||
85 | static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | ||
86 | { | ||
87 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
88 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
89 | unsigned long flags; | ||
90 | |||
91 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
92 | |||
93 | if (val) | ||
94 | mpc8xxx_gc->data |= mpc8xxx_gpio2mask(gpio); | ||
95 | else | ||
96 | mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(gpio); | ||
97 | |||
98 | out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data); | ||
99 | |||
100 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
101 | } | ||
102 | |||
103 | static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) | ||
104 | { | ||
105 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
106 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
107 | unsigned long flags; | ||
108 | |||
109 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
110 | |||
111 | clrbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio)); | ||
112 | |||
113 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | ||
119 | { | ||
120 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
121 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
122 | unsigned long flags; | ||
123 | |||
124 | mpc8xxx_gpio_set(gc, gpio, val); | ||
125 | |||
126 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
127 | |||
128 | setbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio)); | ||
129 | |||
130 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | ||
136 | { | ||
137 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
138 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
139 | |||
140 | if (mpc8xxx_gc->irq && offset < MPC8XXX_GPIO_PINS) | ||
141 | return irq_create_mapping(mpc8xxx_gc->irq, offset); | ||
142 | else | ||
143 | return -ENXIO; | ||
144 | } | ||
145 | |||
146 | static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc) | ||
147 | { | ||
148 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc); | ||
149 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
150 | unsigned int mask; | ||
151 | |||
152 | mask = in_be32(mm->regs + GPIO_IER) & in_be32(mm->regs + GPIO_IMR); | ||
153 | if (mask) | ||
154 | generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq, | ||
155 | 32 - ffs(mask))); | ||
156 | } | ||
157 | |||
158 | static void mpc8xxx_irq_unmask(struct irq_data *d) | ||
159 | { | ||
160 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | ||
161 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
162 | unsigned long flags; | ||
163 | |||
164 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
165 | |||
166 | setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | ||
167 | |||
168 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
169 | } | ||
170 | |||
171 | static void mpc8xxx_irq_mask(struct irq_data *d) | ||
172 | { | ||
173 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | ||
174 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
175 | unsigned long flags; | ||
176 | |||
177 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
178 | |||
179 | clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | ||
180 | |||
181 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
182 | } | ||
183 | |||
184 | static void mpc8xxx_irq_ack(struct irq_data *d) | ||
185 | { | ||
186 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | ||
187 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
188 | |||
189 | out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | ||
190 | } | ||
191 | |||
192 | static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type) | ||
193 | { | ||
194 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | ||
195 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
196 | unsigned long flags; | ||
197 | |||
198 | switch (flow_type) { | ||
199 | case IRQ_TYPE_EDGE_FALLING: | ||
200 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
201 | setbits32(mm->regs + GPIO_ICR, | ||
202 | mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | ||
203 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
204 | break; | ||
205 | |||
206 | case IRQ_TYPE_EDGE_BOTH: | ||
207 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
208 | clrbits32(mm->regs + GPIO_ICR, | ||
209 | mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | ||
210 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
211 | break; | ||
212 | |||
213 | default: | ||
214 | return -EINVAL; | ||
215 | } | ||
216 | |||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type) | ||
221 | { | ||
222 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | ||
223 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
224 | unsigned long gpio = irqd_to_hwirq(d); | ||
225 | void __iomem *reg; | ||
226 | unsigned int shift; | ||
227 | unsigned long flags; | ||
228 | |||
229 | if (gpio < 16) { | ||
230 | reg = mm->regs + GPIO_ICR; | ||
231 | shift = (15 - gpio) * 2; | ||
232 | } else { | ||
233 | reg = mm->regs + GPIO_ICR2; | ||
234 | shift = (15 - (gpio % 16)) * 2; | ||
235 | } | ||
236 | |||
237 | switch (flow_type) { | ||
238 | case IRQ_TYPE_EDGE_FALLING: | ||
239 | case IRQ_TYPE_LEVEL_LOW: | ||
240 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
241 | clrsetbits_be32(reg, 3 << shift, 2 << shift); | ||
242 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
243 | break; | ||
244 | |||
245 | case IRQ_TYPE_EDGE_RISING: | ||
246 | case IRQ_TYPE_LEVEL_HIGH: | ||
247 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
248 | clrsetbits_be32(reg, 3 << shift, 1 << shift); | ||
249 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
250 | break; | ||
251 | |||
252 | case IRQ_TYPE_EDGE_BOTH: | ||
253 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
254 | clrbits32(reg, 3 << shift); | ||
255 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
256 | break; | ||
257 | |||
258 | default: | ||
259 | return -EINVAL; | ||
260 | } | ||
261 | |||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | static struct irq_chip mpc8xxx_irq_chip = { | ||
266 | .name = "mpc8xxx-gpio", | ||
267 | .irq_unmask = mpc8xxx_irq_unmask, | ||
268 | .irq_mask = mpc8xxx_irq_mask, | ||
269 | .irq_ack = mpc8xxx_irq_ack, | ||
270 | .irq_set_type = mpc8xxx_irq_set_type, | ||
271 | }; | ||
272 | |||
273 | static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq, | ||
274 | irq_hw_number_t hw) | ||
275 | { | ||
276 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data; | ||
277 | |||
278 | if (mpc8xxx_gc->of_dev_id_data) | ||
279 | mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data; | ||
280 | |||
281 | irq_set_chip_data(virq, h->host_data); | ||
282 | irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq); | ||
283 | irq_set_irq_type(virq, IRQ_TYPE_NONE); | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct, | ||
289 | const u32 *intspec, unsigned int intsize, | ||
290 | irq_hw_number_t *out_hwirq, | ||
291 | unsigned int *out_flags) | ||
292 | |||
293 | { | ||
294 | /* interrupt sense values coming from the device tree equal either | ||
295 | * EDGE_FALLING or EDGE_BOTH | ||
296 | */ | ||
297 | *out_hwirq = intspec[0]; | ||
298 | *out_flags = intspec[1]; | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | static struct irq_host_ops mpc8xxx_gpio_irq_ops = { | ||
304 | .map = mpc8xxx_gpio_irq_map, | ||
305 | .xlate = mpc8xxx_gpio_irq_xlate, | ||
306 | }; | ||
307 | |||
308 | static struct of_device_id mpc8xxx_gpio_ids[] __initdata = { | ||
309 | { .compatible = "fsl,mpc8349-gpio", }, | ||
310 | { .compatible = "fsl,mpc8572-gpio", }, | ||
311 | { .compatible = "fsl,mpc8610-gpio", }, | ||
312 | { .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, }, | ||
313 | { .compatible = "fsl,qoriq-gpio", }, | ||
314 | {} | ||
315 | }; | ||
316 | |||
317 | static void __init mpc8xxx_add_controller(struct device_node *np) | ||
318 | { | ||
319 | struct mpc8xxx_gpio_chip *mpc8xxx_gc; | ||
320 | struct of_mm_gpio_chip *mm_gc; | ||
321 | struct gpio_chip *gc; | ||
322 | const struct of_device_id *id; | ||
323 | unsigned hwirq; | ||
324 | int ret; | ||
325 | |||
326 | mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL); | ||
327 | if (!mpc8xxx_gc) { | ||
328 | ret = -ENOMEM; | ||
329 | goto err; | ||
330 | } | ||
331 | |||
332 | spin_lock_init(&mpc8xxx_gc->lock); | ||
333 | |||
334 | mm_gc = &mpc8xxx_gc->mm_gc; | ||
335 | gc = &mm_gc->gc; | ||
336 | |||
337 | mm_gc->save_regs = mpc8xxx_gpio_save_regs; | ||
338 | gc->ngpio = MPC8XXX_GPIO_PINS; | ||
339 | gc->direction_input = mpc8xxx_gpio_dir_in; | ||
340 | gc->direction_output = mpc8xxx_gpio_dir_out; | ||
341 | if (of_device_is_compatible(np, "fsl,mpc8572-gpio")) | ||
342 | gc->get = mpc8572_gpio_get; | ||
343 | else | ||
344 | gc->get = mpc8xxx_gpio_get; | ||
345 | gc->set = mpc8xxx_gpio_set; | ||
346 | gc->to_irq = mpc8xxx_gpio_to_irq; | ||
347 | |||
348 | ret = of_mm_gpiochip_add(np, mm_gc); | ||
349 | if (ret) | ||
350 | goto err; | ||
351 | |||
352 | hwirq = irq_of_parse_and_map(np, 0); | ||
353 | if (hwirq == NO_IRQ) | ||
354 | goto skip_irq; | ||
355 | |||
356 | mpc8xxx_gc->irq = | ||
357 | irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS, | ||
358 | &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS); | ||
359 | if (!mpc8xxx_gc->irq) | ||
360 | goto skip_irq; | ||
361 | |||
362 | id = of_match_node(mpc8xxx_gpio_ids, np); | ||
363 | if (id) | ||
364 | mpc8xxx_gc->of_dev_id_data = id->data; | ||
365 | |||
366 | mpc8xxx_gc->irq->host_data = mpc8xxx_gc; | ||
367 | |||
368 | /* ack and mask all irqs */ | ||
369 | out_be32(mm_gc->regs + GPIO_IER, 0xffffffff); | ||
370 | out_be32(mm_gc->regs + GPIO_IMR, 0); | ||
371 | |||
372 | irq_set_handler_data(hwirq, mpc8xxx_gc); | ||
373 | irq_set_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade); | ||
374 | |||
375 | skip_irq: | ||
376 | return; | ||
377 | |||
378 | err: | ||
379 | pr_err("%s: registration failed with status %d\n", | ||
380 | np->full_name, ret); | ||
381 | kfree(mpc8xxx_gc); | ||
382 | |||
383 | return; | ||
384 | } | ||
385 | |||
386 | static int __init mpc8xxx_add_gpiochips(void) | ||
387 | { | ||
388 | struct device_node *np; | ||
389 | |||
390 | for_each_matching_node(np, mpc8xxx_gpio_ids) | ||
391 | mpc8xxx_add_controller(np); | ||
392 | |||
393 | return 0; | ||
394 | } | ||
395 | arch_initcall(mpc8xxx_add_gpiochips); | ||
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index d5d3ff3d757e..0842c6f8a3e6 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -1285,13 +1285,11 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
1285 | mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) | 1285 | mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) |
1286 | | MPIC_GREG_GCONF_MCK); | 1286 | | MPIC_GREG_GCONF_MCK); |
1287 | 1287 | ||
1288 | /* Read feature register, calculate num CPUs and, for non-ISU | 1288 | /* |
1289 | * MPICs, num sources as well. On ISU MPICs, sources are counted | 1289 | * Read feature register. For non-ISU MPICs, num sources as well. On |
1290 | * as ISUs are added | 1290 | * ISU MPICs, sources are counted as ISUs are added |
1291 | */ | 1291 | */ |
1292 | greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0)); | 1292 | greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0)); |
1293 | mpic->num_cpus = ((greg_feature & MPIC_GREG_FEATURE_LAST_CPU_MASK) | ||
1294 | >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1; | ||
1295 | if (isu_size == 0) { | 1293 | if (isu_size == 0) { |
1296 | if (flags & MPIC_BROKEN_FRR_NIRQS) | 1294 | if (flags & MPIC_BROKEN_FRR_NIRQS) |
1297 | mpic->num_sources = mpic->irq_count; | 1295 | mpic->num_sources = mpic->irq_count; |
@@ -1301,10 +1299,18 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
1301 | >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; | 1299 | >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; |
1302 | } | 1300 | } |
1303 | 1301 | ||
1302 | /* | ||
1303 | * The MPIC driver will crash if there are more cores than we | ||
1304 | * can initialize, so we may as well catch that problem here. | ||
1305 | */ | ||
1306 | BUG_ON(num_possible_cpus() > MPIC_MAX_CPUS); | ||
1307 | |||
1304 | /* Map the per-CPU registers */ | 1308 | /* Map the per-CPU registers */ |
1305 | for (i = 0; i < mpic->num_cpus; i++) { | 1309 | for_each_possible_cpu(i) { |
1306 | mpic_map(mpic, node, paddr, &mpic->cpuregs[i], | 1310 | unsigned int cpu = get_hard_smp_processor_id(i); |
1307 | MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE), | 1311 | |
1312 | mpic_map(mpic, node, paddr, &mpic->cpuregs[cpu], | ||
1313 | MPIC_INFO(CPU_BASE) + cpu * MPIC_INFO(CPU_STRIDE), | ||
1308 | 0x1000); | 1314 | 0x1000); |
1309 | } | 1315 | } |
1310 | 1316 | ||
@@ -1343,7 +1349,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
1343 | } | 1349 | } |
1344 | printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx," | 1350 | printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx," |
1345 | " max %d CPUs\n", | 1351 | " max %d CPUs\n", |
1346 | name, vers, (unsigned long long)paddr, mpic->num_cpus); | 1352 | name, vers, (unsigned long long)paddr, num_possible_cpus()); |
1347 | printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", | 1353 | printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", |
1348 | mpic->isu_size, mpic->isu_shift, mpic->isu_mask); | 1354 | mpic->isu_size, mpic->isu_shift, mpic->isu_mask); |
1349 | 1355 | ||
@@ -1742,6 +1748,7 @@ void mpic_reset_core(int cpu) | |||
1742 | struct mpic *mpic = mpic_primary; | 1748 | struct mpic *mpic = mpic_primary; |
1743 | u32 pir; | 1749 | u32 pir; |
1744 | int cpuid = get_hard_smp_processor_id(cpu); | 1750 | int cpuid = get_hard_smp_processor_id(cpu); |
1751 | int i; | ||
1745 | 1752 | ||
1746 | /* Set target bit for core reset */ | 1753 | /* Set target bit for core reset */ |
1747 | pir = mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); | 1754 | pir = mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); |
@@ -1753,6 +1760,15 @@ void mpic_reset_core(int cpu) | |||
1753 | pir &= ~(1 << cpuid); | 1760 | pir &= ~(1 << cpuid); |
1754 | mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir); | 1761 | mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir); |
1755 | mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); | 1762 | mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); |
1763 | |||
1764 | /* Perform 15 EOI on each reset core to clear pending interrupts. | ||
1765 | * This is required for FSL CoreNet based devices */ | ||
1766 | if (mpic->flags & MPIC_FSL) { | ||
1767 | for (i = 0; i < 15; i++) { | ||
1768 | _mpic_write(mpic->reg_type, &mpic->cpuregs[cpuid], | ||
1769 | MPIC_CPU_EOI, 0); | ||
1770 | } | ||
1771 | } | ||
1756 | } | 1772 | } |
1757 | #endif /* CONFIG_SMP */ | 1773 | #endif /* CONFIG_SMP */ |
1758 | 1774 | ||
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index dbfe96bc878a..862f11b3821e 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c | |||
@@ -834,7 +834,7 @@ static int __init ppc440spe_pciex_core_init(struct device_node *np) | |||
834 | return 3; | 834 | return 3; |
835 | } | 835 | } |
836 | 836 | ||
837 | static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 837 | static int __init ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
838 | { | 838 | { |
839 | u32 val = 1 << 24; | 839 | u32 val = 1 << 24; |
840 | 840 | ||
@@ -872,12 +872,12 @@ static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | |||
872 | return ppc4xx_pciex_port_reset_sdr(port); | 872 | return ppc4xx_pciex_port_reset_sdr(port); |
873 | } | 873 | } |
874 | 874 | ||
875 | static int ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 875 | static int __init ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
876 | { | 876 | { |
877 | return ppc440spe_pciex_init_port_hw(port); | 877 | return ppc440spe_pciex_init_port_hw(port); |
878 | } | 878 | } |
879 | 879 | ||
880 | static int ppc440speB_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 880 | static int __init ppc440speB_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
881 | { | 881 | { |
882 | int rc = ppc440spe_pciex_init_port_hw(port); | 882 | int rc = ppc440spe_pciex_init_port_hw(port); |
883 | 883 | ||
@@ -936,7 +936,7 @@ static int __init ppc460ex_pciex_core_init(struct device_node *np) | |||
936 | return 2; | 936 | return 2; |
937 | } | 937 | } |
938 | 938 | ||
939 | static int ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 939 | static int __init ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
940 | { | 940 | { |
941 | u32 val; | 941 | u32 val; |
942 | u32 utlset1; | 942 | u32 utlset1; |
@@ -1092,6 +1092,10 @@ static int __init ppc460sx_pciex_core_init(struct device_node *np) | |||
1092 | mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000); | 1092 | mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000); |
1093 | mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000); | 1093 | mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000); |
1094 | 1094 | ||
1095 | /* Set HSS PRBS enabled */ | ||
1096 | mtdcri(SDR0, PESDR0_460SX_HSSCTLSET, 0x00001130); | ||
1097 | mtdcri(SDR0, PESDR2_460SX_HSSCTLSET, 0x00001130); | ||
1098 | |||
1095 | udelay(100); | 1099 | udelay(100); |
1096 | 1100 | ||
1097 | /* De-assert PLLRESET */ | 1101 | /* De-assert PLLRESET */ |
@@ -1122,7 +1126,7 @@ static int __init ppc460sx_pciex_core_init(struct device_node *np) | |||
1122 | return 2; | 1126 | return 2; |
1123 | } | 1127 | } |
1124 | 1128 | ||
1125 | static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 1129 | static int __init ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
1126 | { | 1130 | { |
1127 | 1131 | ||
1128 | if (port->endpoint) | 1132 | if (port->endpoint) |
@@ -1132,9 +1136,6 @@ static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | |||
1132 | dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, | 1136 | dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, |
1133 | 0, 0x01000000); | 1137 | 0, 0x01000000); |
1134 | 1138 | ||
1135 | /*Gen-1*/ | ||
1136 | mtdcri(SDR0, port->sdr_base + PESDRn_460SX_RCEI, 0x08000000); | ||
1137 | |||
1138 | dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, | 1139 | dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, |
1139 | (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL), | 1140 | (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL), |
1140 | PESDRx_RCSSET_RSTPYN); | 1141 | PESDRx_RCSSET_RSTPYN); |
@@ -1148,14 +1149,42 @@ static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port) | |||
1148 | { | 1149 | { |
1149 | /* Max 128 Bytes */ | 1150 | /* Max 128 Bytes */ |
1150 | out_be32 (port->utl_base + PEUTL_PBBSZ, 0x00000000); | 1151 | out_be32 (port->utl_base + PEUTL_PBBSZ, 0x00000000); |
1152 | /* Assert VRB and TXE - per datasheet turn off addr validation */ | ||
1153 | out_be32(port->utl_base + PEUTL_PCTL, 0x80800000); | ||
1151 | return 0; | 1154 | return 0; |
1152 | } | 1155 | } |
1153 | 1156 | ||
1157 | static void __init ppc460sx_pciex_check_link(struct ppc4xx_pciex_port *port) | ||
1158 | { | ||
1159 | void __iomem *mbase; | ||
1160 | int attempt = 50; | ||
1161 | |||
1162 | port->link = 0; | ||
1163 | |||
1164 | mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000); | ||
1165 | if (mbase == NULL) { | ||
1166 | printk(KERN_ERR "%s: Can't map internal config space !", | ||
1167 | port->node->full_name); | ||
1168 | goto done; | ||
1169 | } | ||
1170 | |||
1171 | while (attempt && (0 == (in_le32(mbase + PECFG_460SX_DLLSTA) | ||
1172 | & PECFG_460SX_DLLSTA_LINKUP))) { | ||
1173 | attempt--; | ||
1174 | mdelay(10); | ||
1175 | } | ||
1176 | if (attempt) | ||
1177 | port->link = 1; | ||
1178 | done: | ||
1179 | iounmap(mbase); | ||
1180 | |||
1181 | } | ||
1182 | |||
1154 | static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = { | 1183 | static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = { |
1155 | .core_init = ppc460sx_pciex_core_init, | 1184 | .core_init = ppc460sx_pciex_core_init, |
1156 | .port_init_hw = ppc460sx_pciex_init_port_hw, | 1185 | .port_init_hw = ppc460sx_pciex_init_port_hw, |
1157 | .setup_utl = ppc460sx_pciex_init_utl, | 1186 | .setup_utl = ppc460sx_pciex_init_utl, |
1158 | .check_link = ppc4xx_pciex_check_link_sdr, | 1187 | .check_link = ppc460sx_pciex_check_link, |
1159 | }; | 1188 | }; |
1160 | 1189 | ||
1161 | #endif /* CONFIG_44x */ | 1190 | #endif /* CONFIG_44x */ |
@@ -1189,7 +1218,7 @@ static void ppc405ex_pcie_phy_reset(struct ppc4xx_pciex_port *port) | |||
1189 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x00101000); | 1218 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x00101000); |
1190 | } | 1219 | } |
1191 | 1220 | ||
1192 | static int ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 1221 | static int __init ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
1193 | { | 1222 | { |
1194 | u32 val; | 1223 | u32 val; |
1195 | 1224 | ||
@@ -1338,15 +1367,15 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port) | |||
1338 | if (rc != 0) | 1367 | if (rc != 0) |
1339 | return rc; | 1368 | return rc; |
1340 | 1369 | ||
1341 | if (ppc4xx_pciex_hwops->check_link) | ||
1342 | ppc4xx_pciex_hwops->check_link(port); | ||
1343 | |||
1344 | /* | 1370 | /* |
1345 | * Initialize mapping: disable all regions and configure | 1371 | * Initialize mapping: disable all regions and configure |
1346 | * CFG and REG regions based on resources in the device tree | 1372 | * CFG and REG regions based on resources in the device tree |
1347 | */ | 1373 | */ |
1348 | ppc4xx_pciex_port_init_mapping(port); | 1374 | ppc4xx_pciex_port_init_mapping(port); |
1349 | 1375 | ||
1376 | if (ppc4xx_pciex_hwops->check_link) | ||
1377 | ppc4xx_pciex_hwops->check_link(port); | ||
1378 | |||
1350 | /* | 1379 | /* |
1351 | * Map UTL | 1380 | * Map UTL |
1352 | */ | 1381 | */ |
@@ -1360,13 +1389,23 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port) | |||
1360 | ppc4xx_pciex_hwops->setup_utl(port); | 1389 | ppc4xx_pciex_hwops->setup_utl(port); |
1361 | 1390 | ||
1362 | /* | 1391 | /* |
1363 | * Check for VC0 active and assert RDY. | 1392 | * Check for VC0 active or PLL Locked and assert RDY. |
1364 | */ | 1393 | */ |
1365 | if (port->sdr_base) { | 1394 | if (port->sdr_base) { |
1366 | if (port->link && | 1395 | if (of_device_is_compatible(port->node, |
1367 | ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, | 1396 | "ibm,plb-pciex-460sx")){ |
1368 | 1 << 16, 1 << 16, 5000)) { | 1397 | if (port->link && ppc4xx_pciex_wait_on_sdr(port, |
1369 | printk(KERN_INFO "PCIE%d: VC0 not active\n", port->index); | 1398 | PESDRn_RCSSTS, |
1399 | 1 << 12, 1 << 12, 5000)) { | ||
1400 | printk(KERN_INFO "PCIE%d: PLL not locked\n", | ||
1401 | port->index); | ||
1402 | port->link = 0; | ||
1403 | } | ||
1404 | } else if (port->link && | ||
1405 | ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, | ||
1406 | 1 << 16, 1 << 16, 5000)) { | ||
1407 | printk(KERN_INFO "PCIE%d: VC0 not active\n", | ||
1408 | port->index); | ||
1370 | port->link = 0; | 1409 | port->link = 0; |
1371 | } | 1410 | } |
1372 | 1411 | ||
@@ -1573,8 +1612,15 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port, | |||
1573 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah); | 1612 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah); |
1574 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal); | 1613 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal); |
1575 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff); | 1614 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff); |
1576 | /* Note that 3 here means enabled | single region */ | 1615 | /*Enabled and single region */ |
1577 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, sa | 3); | 1616 | if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx")) |
1617 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, | ||
1618 | sa | DCRO_PEGPL_460SX_OMR1MSKL_UOT | ||
1619 | | DCRO_PEGPL_OMRxMSKL_VAL); | ||
1620 | else | ||
1621 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, | ||
1622 | sa | DCRO_PEGPL_OMR1MSKL_UOT | ||
1623 | | DCRO_PEGPL_OMRxMSKL_VAL); | ||
1578 | break; | 1624 | break; |
1579 | case 1: | 1625 | case 1: |
1580 | out_le32(mbase + PECFG_POM1LAH, pciah); | 1626 | out_le32(mbase + PECFG_POM1LAH, pciah); |
@@ -1582,8 +1628,8 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port, | |||
1582 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah); | 1628 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah); |
1583 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal); | 1629 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal); |
1584 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff); | 1630 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff); |
1585 | /* Note that 3 here means enabled | single region */ | 1631 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, |
1586 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, sa | 3); | 1632 | sa | DCRO_PEGPL_OMRxMSKL_VAL); |
1587 | break; | 1633 | break; |
1588 | case 2: | 1634 | case 2: |
1589 | out_le32(mbase + PECFG_POM2LAH, pciah); | 1635 | out_le32(mbase + PECFG_POM2LAH, pciah); |
@@ -1592,7 +1638,9 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port, | |||
1592 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal); | 1638 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal); |
1593 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff); | 1639 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff); |
1594 | /* Note that 3 here means enabled | IO space !!! */ | 1640 | /* Note that 3 here means enabled | IO space !!! */ |
1595 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, sa | 3); | 1641 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, |
1642 | sa | DCRO_PEGPL_OMR3MSKL_IO | ||
1643 | | DCRO_PEGPL_OMRxMSKL_VAL); | ||
1596 | break; | 1644 | break; |
1597 | } | 1645 | } |
1598 | 1646 | ||
@@ -1693,6 +1741,9 @@ static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port, | |||
1693 | if (res->flags & IORESOURCE_PREFETCH) | 1741 | if (res->flags & IORESOURCE_PREFETCH) |
1694 | sa |= 0x8; | 1742 | sa |= 0x8; |
1695 | 1743 | ||
1744 | if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx")) | ||
1745 | sa |= PCI_BASE_ADDRESS_MEM_TYPE_64; | ||
1746 | |||
1696 | out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); | 1747 | out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); |
1697 | out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa)); | 1748 | out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa)); |
1698 | 1749 | ||
@@ -1854,6 +1905,10 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port) | |||
1854 | } | 1905 | } |
1855 | out_le16(mbase + 0x202, val); | 1906 | out_le16(mbase + 0x202, val); |
1856 | 1907 | ||
1908 | /* Enable Bus master, memory, and io space */ | ||
1909 | if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx")) | ||
1910 | out_le16(mbase + 0x204, 0x7); | ||
1911 | |||
1857 | if (!port->endpoint) { | 1912 | if (!port->endpoint) { |
1858 | /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */ | 1913 | /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */ |
1859 | out_le32(mbase + 0x208, 0x06040001); | 1914 | out_le32(mbase + 0x208, 0x06040001); |
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h b/arch/powerpc/sysdev/ppc4xx_pci.h index c39a134e8684..32ce763a375a 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.h +++ b/arch/powerpc/sysdev/ppc4xx_pci.h | |||
@@ -464,6 +464,18 @@ | |||
464 | #define PECFG_POM2LAL 0x390 | 464 | #define PECFG_POM2LAL 0x390 |
465 | #define PECFG_POM2LAH 0x394 | 465 | #define PECFG_POM2LAH 0x394 |
466 | 466 | ||
467 | /* 460sx only */ | ||
468 | #define PECFG_460SX_DLLSTA 0x3f8 | ||
469 | |||
470 | /* 460sx Bit Mappings */ | ||
471 | #define PECFG_460SX_DLLSTA_LINKUP 0x00000010 | ||
472 | #define DCRO_PEGPL_460SX_OMR1MSKL_UOT 0x00000004 | ||
473 | |||
474 | /* PEGPL Bit Mappings */ | ||
475 | #define DCRO_PEGPL_OMRxMSKL_VAL 0x00000001 | ||
476 | #define DCRO_PEGPL_OMR1MSKL_UOT 0x00000002 | ||
477 | #define DCRO_PEGPL_OMR3MSKL_IO 0x00000002 | ||
478 | |||
467 | /* SDR Bit Mappings */ | 479 | /* SDR Bit Mappings */ |
468 | #define PESDRx_RCSSET_HLDPLB 0x10000000 | 480 | #define PESDRx_RCSSET_HLDPLB 0x10000000 |
469 | #define PESDRx_RCSSET_RSTGU 0x01000000 | 481 | #define PESDRx_RCSSET_RSTGU 0x01000000 |
diff --git a/arch/powerpc/sysdev/xics/Makefile b/arch/powerpc/sysdev/xics/Makefile index b75a6059337f..c606aa8ba60a 100644 --- a/arch/powerpc/sysdev/xics/Makefile +++ b/arch/powerpc/sysdev/xics/Makefile | |||
@@ -4,3 +4,4 @@ obj-y += xics-common.o | |||
4 | obj-$(CONFIG_PPC_ICP_NATIVE) += icp-native.o | 4 | obj-$(CONFIG_PPC_ICP_NATIVE) += icp-native.o |
5 | obj-$(CONFIG_PPC_ICP_HV) += icp-hv.o | 5 | obj-$(CONFIG_PPC_ICP_HV) += icp-hv.o |
6 | obj-$(CONFIG_PPC_ICS_RTAS) += ics-rtas.o | 6 | obj-$(CONFIG_PPC_ICS_RTAS) += ics-rtas.o |
7 | obj-$(CONFIG_PPC_POWERNV) += ics-opal.o | ||
diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c index 50e32afe392e..4c79b6fbee1c 100644 --- a/arch/powerpc/sysdev/xics/icp-native.c +++ b/arch/powerpc/sysdev/xics/icp-native.c | |||
@@ -276,7 +276,7 @@ static const struct icp_ops icp_native_ops = { | |||
276 | #endif | 276 | #endif |
277 | }; | 277 | }; |
278 | 278 | ||
279 | int icp_native_init(void) | 279 | int __init icp_native_init(void) |
280 | { | 280 | { |
281 | struct device_node *np; | 281 | struct device_node *np; |
282 | u32 indx = 0; | 282 | u32 indx = 0; |
diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c new file mode 100644 index 000000000000..f7e8609df0d5 --- /dev/null +++ b/arch/powerpc/sysdev/xics/ics-opal.c | |||
@@ -0,0 +1,244 @@ | |||
1 | /* | ||
2 | * ICS backend for OPAL managed interrupts. | ||
3 | * | ||
4 | * Copyright 2011 IBM Corp. | ||
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 | #undef DEBUG | ||
13 | |||
14 | #include <linux/types.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/smp.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/cpu.h> | ||
21 | #include <linux/of.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | #include <linux/msi.h> | ||
24 | |||
25 | #include <asm/prom.h> | ||
26 | #include <asm/smp.h> | ||
27 | #include <asm/machdep.h> | ||
28 | #include <asm/irq.h> | ||
29 | #include <asm/errno.h> | ||
30 | #include <asm/xics.h> | ||
31 | #include <asm/opal.h> | ||
32 | #include <asm/firmware.h> | ||
33 | |||
34 | static int ics_opal_mangle_server(int server) | ||
35 | { | ||
36 | /* No link for now */ | ||
37 | return server << 2; | ||
38 | } | ||
39 | |||
40 | static int ics_opal_unmangle_server(int server) | ||
41 | { | ||
42 | /* No link for now */ | ||
43 | return server >> 2; | ||
44 | } | ||
45 | |||
46 | static void ics_opal_unmask_irq(struct irq_data *d) | ||
47 | { | ||
48 | unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); | ||
49 | int64_t rc; | ||
50 | int server; | ||
51 | |||
52 | pr_devel("ics-hal: unmask virq %d [hw 0x%x]\n", d->irq, hw_irq); | ||
53 | |||
54 | if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS) | ||
55 | return; | ||
56 | |||
57 | server = xics_get_irq_server(d->irq, d->affinity, 0); | ||
58 | server = ics_opal_mangle_server(server); | ||
59 | |||
60 | rc = opal_set_xive(hw_irq, server, DEFAULT_PRIORITY); | ||
61 | if (rc != OPAL_SUCCESS) | ||
62 | pr_err("%s: opal_set_xive(irq=%d [hw 0x%x] server=%x)" | ||
63 | " error %lld\n", | ||
64 | __func__, d->irq, hw_irq, server, rc); | ||
65 | } | ||
66 | |||
67 | static unsigned int ics_opal_startup(struct irq_data *d) | ||
68 | { | ||
69 | #ifdef CONFIG_PCI_MSI | ||
70 | /* | ||
71 | * The generic MSI code returns with the interrupt disabled on the | ||
72 | * card, using the MSI mask bits. Firmware doesn't appear to unmask | ||
73 | * at that level, so we do it here by hand. | ||
74 | */ | ||
75 | if (d->msi_desc) | ||
76 | unmask_msi_irq(d); | ||
77 | #endif | ||
78 | |||
79 | /* unmask it */ | ||
80 | ics_opal_unmask_irq(d); | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static void ics_opal_mask_real_irq(unsigned int hw_irq) | ||
85 | { | ||
86 | int server = ics_opal_mangle_server(xics_default_server); | ||
87 | int64_t rc; | ||
88 | |||
89 | if (hw_irq == XICS_IPI) | ||
90 | return; | ||
91 | |||
92 | /* Have to set XIVE to 0xff to be able to remove a slot */ | ||
93 | rc = opal_set_xive(hw_irq, server, 0xff); | ||
94 | if (rc != OPAL_SUCCESS) | ||
95 | pr_err("%s: opal_set_xive(0xff) irq=%u returned %lld\n", | ||
96 | __func__, hw_irq, rc); | ||
97 | } | ||
98 | |||
99 | static void ics_opal_mask_irq(struct irq_data *d) | ||
100 | { | ||
101 | unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); | ||
102 | |||
103 | pr_devel("ics-hal: mask virq %d [hw 0x%x]\n", d->irq, hw_irq); | ||
104 | |||
105 | if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS) | ||
106 | return; | ||
107 | ics_opal_mask_real_irq(hw_irq); | ||
108 | } | ||
109 | |||
110 | static int ics_opal_set_affinity(struct irq_data *d, | ||
111 | const struct cpumask *cpumask, | ||
112 | bool force) | ||
113 | { | ||
114 | unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); | ||
115 | int16_t server; | ||
116 | int8_t priority; | ||
117 | int64_t rc; | ||
118 | int wanted_server; | ||
119 | |||
120 | if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS) | ||
121 | return -1; | ||
122 | |||
123 | rc = opal_get_xive(hw_irq, &server, &priority); | ||
124 | if (rc != OPAL_SUCCESS) { | ||
125 | pr_err("%s: opal_set_xive(irq=%d [hw 0x%x] server=%x)" | ||
126 | " error %lld\n", | ||
127 | __func__, d->irq, hw_irq, server, rc); | ||
128 | return -1; | ||
129 | } | ||
130 | |||
131 | wanted_server = xics_get_irq_server(d->irq, cpumask, 1); | ||
132 | if (wanted_server < 0) { | ||
133 | char cpulist[128]; | ||
134 | cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask); | ||
135 | pr_warning("%s: No online cpus in the mask %s for irq %d\n", | ||
136 | __func__, cpulist, d->irq); | ||
137 | return -1; | ||
138 | } | ||
139 | server = ics_opal_mangle_server(wanted_server); | ||
140 | |||
141 | pr_devel("ics-hal: set-affinity irq %d [hw 0x%x] server: 0x%x/0x%x\n", | ||
142 | d->irq, hw_irq, wanted_server, server); | ||
143 | |||
144 | rc = opal_set_xive(hw_irq, server, priority); | ||
145 | if (rc != OPAL_SUCCESS) { | ||
146 | pr_err("%s: opal_set_xive(irq=%d [hw 0x%x] server=%x)" | ||
147 | " error %lld\n", | ||
148 | __func__, d->irq, hw_irq, server, rc); | ||
149 | return -1; | ||
150 | } | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static struct irq_chip ics_opal_irq_chip = { | ||
155 | .name = "OPAL ICS", | ||
156 | .irq_startup = ics_opal_startup, | ||
157 | .irq_mask = ics_opal_mask_irq, | ||
158 | .irq_unmask = ics_opal_unmask_irq, | ||
159 | .irq_eoi = NULL, /* Patched at init time */ | ||
160 | .irq_set_affinity = ics_opal_set_affinity | ||
161 | }; | ||
162 | |||
163 | static int ics_opal_map(struct ics *ics, unsigned int virq); | ||
164 | static void ics_opal_mask_unknown(struct ics *ics, unsigned long vec); | ||
165 | static long ics_opal_get_server(struct ics *ics, unsigned long vec); | ||
166 | |||
167 | static int ics_opal_host_match(struct ics *ics, struct device_node *node) | ||
168 | { | ||
169 | return 1; | ||
170 | } | ||
171 | |||
172 | /* Only one global & state struct ics */ | ||
173 | static struct ics ics_hal = { | ||
174 | .map = ics_opal_map, | ||
175 | .mask_unknown = ics_opal_mask_unknown, | ||
176 | .get_server = ics_opal_get_server, | ||
177 | .host_match = ics_opal_host_match, | ||
178 | }; | ||
179 | |||
180 | static int ics_opal_map(struct ics *ics, unsigned int virq) | ||
181 | { | ||
182 | unsigned int hw_irq = (unsigned int)virq_to_hw(virq); | ||
183 | int64_t rc; | ||
184 | int16_t server; | ||
185 | int8_t priority; | ||
186 | |||
187 | if (WARN_ON(hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)) | ||
188 | return -EINVAL; | ||
189 | |||
190 | /* Check if HAL knows about this interrupt */ | ||
191 | rc = opal_get_xive(hw_irq, &server, &priority); | ||
192 | if (rc != OPAL_SUCCESS) | ||
193 | return -ENXIO; | ||
194 | |||
195 | irq_set_chip_and_handler(virq, &ics_opal_irq_chip, handle_fasteoi_irq); | ||
196 | irq_set_chip_data(virq, &ics_hal); | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | static void ics_opal_mask_unknown(struct ics *ics, unsigned long vec) | ||
202 | { | ||
203 | int64_t rc; | ||
204 | int16_t server; | ||
205 | int8_t priority; | ||
206 | |||
207 | /* Check if HAL knows about this interrupt */ | ||
208 | rc = opal_get_xive(vec, &server, &priority); | ||
209 | if (rc != OPAL_SUCCESS) | ||
210 | return; | ||
211 | |||
212 | ics_opal_mask_real_irq(vec); | ||
213 | } | ||
214 | |||
215 | static long ics_opal_get_server(struct ics *ics, unsigned long vec) | ||
216 | { | ||
217 | int64_t rc; | ||
218 | int16_t server; | ||
219 | int8_t priority; | ||
220 | |||
221 | /* Check if HAL knows about this interrupt */ | ||
222 | rc = opal_get_xive(vec, &server, &priority); | ||
223 | if (rc != OPAL_SUCCESS) | ||
224 | return -1; | ||
225 | return ics_opal_unmangle_server(server); | ||
226 | } | ||
227 | |||
228 | int __init ics_opal_init(void) | ||
229 | { | ||
230 | if (!firmware_has_feature(FW_FEATURE_OPAL)) | ||
231 | return -ENODEV; | ||
232 | |||
233 | /* We need to patch our irq chip's EOI to point to the | ||
234 | * right ICP | ||
235 | */ | ||
236 | ics_opal_irq_chip.irq_eoi = icp_ops->eoi; | ||
237 | |||
238 | /* Register ourselves */ | ||
239 | xics_register_ics(&ics_hal); | ||
240 | |||
241 | pr_info("ICS OPAL backend registered\n"); | ||
242 | |||
243 | return 0; | ||
244 | } | ||
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index 445c5a01b766..3d93a8ded0f8 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c | |||
@@ -409,14 +409,10 @@ void __init xics_init(void) | |||
409 | int rc = -1; | 409 | int rc = -1; |
410 | 410 | ||
411 | /* Fist locate ICP */ | 411 | /* Fist locate ICP */ |
412 | #ifdef CONFIG_PPC_ICP_HV | ||
413 | if (firmware_has_feature(FW_FEATURE_LPAR)) | 412 | if (firmware_has_feature(FW_FEATURE_LPAR)) |
414 | rc = icp_hv_init(); | 413 | rc = icp_hv_init(); |
415 | #endif | ||
416 | #ifdef CONFIG_PPC_ICP_NATIVE | ||
417 | if (rc < 0) | 414 | if (rc < 0) |
418 | rc = icp_native_init(); | 415 | rc = icp_native_init(); |
419 | #endif | ||
420 | if (rc < 0) { | 416 | if (rc < 0) { |
421 | pr_warning("XICS: Cannot find a Presentation Controller !\n"); | 417 | pr_warning("XICS: Cannot find a Presentation Controller !\n"); |
422 | return; | 418 | return; |
@@ -429,9 +425,9 @@ void __init xics_init(void) | |||
429 | xics_ipi_chip.irq_eoi = icp_ops->eoi; | 425 | xics_ipi_chip.irq_eoi = icp_ops->eoi; |
430 | 426 | ||
431 | /* Now locate ICS */ | 427 | /* Now locate ICS */ |
432 | #ifdef CONFIG_PPC_ICS_RTAS | ||
433 | rc = ics_rtas_init(); | 428 | rc = ics_rtas_init(); |
434 | #endif | 429 | if (rc < 0) |
430 | rc = ics_opal_init(); | ||
435 | if (rc < 0) | 431 | if (rc < 0) |
436 | pr_warning("XICS: Cannot find a Source Controller !\n"); | 432 | pr_warning("XICS: Cannot find a Source Controller !\n"); |
437 | 433 | ||
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 42541bbcc7fa..13f82f847669 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
@@ -340,8 +340,8 @@ int cpus_are_in_xmon(void) | |||
340 | 340 | ||
341 | static inline int unrecoverable_excp(struct pt_regs *regs) | 341 | static inline int unrecoverable_excp(struct pt_regs *regs) |
342 | { | 342 | { |
343 | #ifdef CONFIG_4xx | 343 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOK3E) |
344 | /* We have no MSR_RI bit on 4xx, so we simply return false */ | 344 | /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */ |
345 | return 0; | 345 | return 0; |
346 | #else | 346 | #else |
347 | return ((regs->msr & MSR_RI) == 0); | 347 | return ((regs->msr & MSR_RI) == 0); |