diff options
Diffstat (limited to 'arch/powerpc')
225 files changed, 6956 insertions, 2335 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index ea5bb045983a..bbbe02197afb 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -114,7 +114,6 @@ config PPC | |||
114 | select USE_GENERIC_SMP_HELPERS if SMP | 114 | select USE_GENERIC_SMP_HELPERS if SMP |
115 | select HAVE_OPROFILE | 115 | select HAVE_OPROFILE |
116 | select HAVE_DEBUG_KMEMLEAK | 116 | select HAVE_DEBUG_KMEMLEAK |
117 | select HAVE_SYSCALL_WRAPPERS if PPC64 | ||
118 | select GENERIC_ATOMIC64 if PPC32 | 117 | select GENERIC_ATOMIC64 if PPC32 |
119 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | 118 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE |
120 | select HAVE_PERF_EVENTS | 119 | select HAVE_PERF_EVENTS |
@@ -428,11 +427,6 @@ config NODES_SHIFT | |||
428 | default "4" | 427 | default "4" |
429 | depends on NEED_MULTIPLE_NODES | 428 | depends on NEED_MULTIPLE_NODES |
430 | 429 | ||
431 | config MAX_ACTIVE_REGIONS | ||
432 | int | ||
433 | default "256" if PPC64 | ||
434 | default "32" | ||
435 | |||
436 | config ARCH_SELECT_MEMORY_MODEL | 430 | config ARCH_SELECT_MEMORY_MODEL |
437 | def_bool y | 431 | def_bool y |
438 | depends on PPC64 | 432 | depends on PPC64 |
@@ -647,14 +641,14 @@ menu "Bus options" | |||
647 | 641 | ||
648 | config ISA | 642 | config ISA |
649 | bool "Support for ISA-bus hardware" | 643 | bool "Support for ISA-bus hardware" |
650 | depends on PPC_PREP || PPC_CHRP | 644 | depends on PPC_CHRP |
651 | select PPC_I8259 | 645 | select PPC_I8259 |
652 | help | 646 | help |
653 | Find out whether you have ISA slots on your motherboard. ISA is the | 647 | Find out whether you have ISA slots on your motherboard. ISA is the |
654 | name of a bus system, i.e. the way the CPU talks to the other stuff | 648 | name of a bus system, i.e. the way the CPU talks to the other stuff |
655 | inside your box. If you have an Apple machine, say N here; if you | 649 | inside your box. If you have an Apple machine, say N here; if you |
656 | have an IBM RS/6000 or pSeries machine or a PReP machine, say Y. If | 650 | have an IBM RS/6000 or pSeries machine, say Y. If you have an |
657 | you have an embedded board, consult your board documentation. | 651 | embedded board, consult your board documentation. |
658 | 652 | ||
659 | config ZONE_DMA | 653 | config ZONE_DMA |
660 | bool | 654 | bool |
@@ -686,7 +680,6 @@ config SBUS | |||
686 | config FSL_SOC | 680 | config FSL_SOC |
687 | bool | 681 | bool |
688 | select HAVE_CAN_FLEXCAN if NET && CAN | 682 | select HAVE_CAN_FLEXCAN if NET && CAN |
689 | select PPC_CLOCK | ||
690 | 683 | ||
691 | config FSL_PCI | 684 | config FSL_PCI |
692 | bool | 685 | bool |
@@ -745,7 +738,6 @@ config PCI | |||
745 | bool "PCI support" if PPC_PCI_CHOICE | 738 | bool "PCI support" if PPC_PCI_CHOICE |
746 | default y if !40x && !CPM2 && !8xx && !PPC_83xx \ | 739 | default y if !40x && !CPM2 && !8xx && !PPC_83xx \ |
747 | && !PPC_85xx && !PPC_86xx && !GAMECUBE_COMMON | 740 | && !PPC_85xx && !PPC_86xx && !GAMECUBE_COMMON |
748 | default PCI_PERMEDIA if !4xx && !CPM2 && !8xx | ||
749 | default PCI_QSPAN if !4xx && !CPM2 && 8xx | 741 | default PCI_QSPAN if !4xx && !CPM2 && 8xx |
750 | select ARCH_SUPPORTS_MSI | 742 | select ARCH_SUPPORTS_MSI |
751 | select GENERIC_PCI_IOMAP | 743 | select GENERIC_PCI_IOMAP |
@@ -775,11 +767,6 @@ config PCI_8260 | |||
775 | select PPC_INDIRECT_PCI | 767 | select PPC_INDIRECT_PCI |
776 | default y | 768 | default y |
777 | 769 | ||
778 | config 8260_PCI9 | ||
779 | bool "Enable workaround for MPC826x erratum PCI 9" | ||
780 | depends on PCI_8260 && !8272 | ||
781 | default y | ||
782 | |||
783 | source "drivers/pci/pcie/Kconfig" | 770 | source "drivers/pci/pcie/Kconfig" |
784 | 771 | ||
785 | source "drivers/pci/Kconfig" | 772 | source "drivers/pci/Kconfig" |
@@ -969,7 +956,7 @@ config TASK_SIZE_BOOL | |||
969 | 956 | ||
970 | config TASK_SIZE | 957 | config TASK_SIZE |
971 | hex "Size of user task space" if TASK_SIZE_BOOL | 958 | hex "Size of user task space" if TASK_SIZE_BOOL |
972 | default "0x80000000" if PPC_PREP || PPC_8xx | 959 | default "0x80000000" if PPC_8xx |
973 | default "0xc0000000" | 960 | default "0xc0000000" |
974 | 961 | ||
975 | config CONSISTENT_SIZE_BOOL | 962 | config CONSISTENT_SIZE_BOOL |
diff --git a/arch/powerpc/boot/dts/ac14xx.dts b/arch/powerpc/boot/dts/ac14xx.dts new file mode 100644 index 000000000000..a27a4609bb42 --- /dev/null +++ b/arch/powerpc/boot/dts/ac14xx.dts | |||
@@ -0,0 +1,392 @@ | |||
1 | /* | ||
2 | * Device Tree Source for the MPC5121e based ac14xx board | ||
3 | * | ||
4 | * Copyright 2012 Anatolij Gustschin <agust@denx.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | |||
13 | /include/ "mpc5121.dtsi" | ||
14 | |||
15 | / { | ||
16 | model = "ac14xx"; | ||
17 | compatible = "ifm,ac14xx", "fsl,mpc5121"; | ||
18 | #address-cells = <1>; | ||
19 | #size-cells = <1>; | ||
20 | |||
21 | aliases { | ||
22 | serial0 = &serial0; | ||
23 | serial1 = &serial7; | ||
24 | spi4 = &spi4; | ||
25 | spi5 = &spi5; | ||
26 | }; | ||
27 | |||
28 | cpus { | ||
29 | PowerPC,5121@0 { | ||
30 | timebase-frequency = <40000000>; /* 40 MHz (csb/4) */ | ||
31 | bus-frequency = <160000000>; /* 160 MHz csb bus */ | ||
32 | clock-frequency = <400000000>; /* 400 MHz ppc core */ | ||
33 | }; | ||
34 | }; | ||
35 | |||
36 | memory { | ||
37 | reg = <0x00000000 0x10000000>; /* 256MB at 0 */ | ||
38 | }; | ||
39 | |||
40 | nfc@40000000 { | ||
41 | status = "disabled"; | ||
42 | }; | ||
43 | |||
44 | localbus@80000020 { | ||
45 | ranges = <0x0 0x0 0xfc000000 0x04000000 /* CS0: NOR flash */ | ||
46 | 0x1 0x0 0xe0000000 0x00010000 /* CS1: FRAM */ | ||
47 | 0x2 0x0 0xe0100000 0x00080000 /* CS2: asi1 */ | ||
48 | 0x3 0x0 0xe0300000 0x00020000 /* CS3: comm */ | ||
49 | 0x5 0x0 0xe0400000 0x00010000 /* CS5: safety */ | ||
50 | 0x6 0x0 0xe0200000 0x00080000>; /* CS6: asi2 */ | ||
51 | |||
52 | flash@0,0 { | ||
53 | compatible = "cfi-flash"; | ||
54 | reg = <0 0x00000000 0x04000000>; | ||
55 | #address-cells = <1>; | ||
56 | #size-cells = <1>; | ||
57 | bank-width = <2>; | ||
58 | device-width = <2>; | ||
59 | |||
60 | partition@0 { | ||
61 | label = "dtb-kernel-production"; | ||
62 | reg = <0x00000000 0x00400000>; | ||
63 | }; | ||
64 | partition@1 { | ||
65 | label = "filesystem-production"; | ||
66 | reg = <0x00400000 0x03400000>; | ||
67 | }; | ||
68 | |||
69 | partition@2 { | ||
70 | label = "recovery"; | ||
71 | reg = <0x03800000 0x00700000>; | ||
72 | }; | ||
73 | |||
74 | partition@3 { | ||
75 | label = "uboot-code"; | ||
76 | reg = <0x03f00000 0x00040000>; | ||
77 | }; | ||
78 | partition@4 { | ||
79 | label = "uboot-env1"; | ||
80 | reg = <0x03f40000 0x00020000>; | ||
81 | }; | ||
82 | partition@5 { | ||
83 | label = "uboot-env2"; | ||
84 | reg = <0x03f60000 0x00020000>; | ||
85 | }; | ||
86 | }; | ||
87 | |||
88 | fram@1,0 { | ||
89 | compatible = "ifm,ac14xx-fram", "linux,uio-pdrv-genirq"; | ||
90 | reg = <1 0x00000000 0x00010000>; | ||
91 | }; | ||
92 | |||
93 | asi@2,0 { | ||
94 | /* masters mapping: CS, CS offset, size */ | ||
95 | reg = <2 0x00000000 0x00080000 | ||
96 | 6 0x00000000 0x00080000>; | ||
97 | #address-cells = <1>; | ||
98 | #size-cells = <1>; | ||
99 | compatible = "ifm,ac14xx-asi-fpga"; | ||
100 | gpios = < | ||
101 | &gpio_pic 26 0 /* prog */ | ||
102 | &gpio_pic 27 0 /* done */ | ||
103 | &gpio_pic 10 0 /* reset */ | ||
104 | >; | ||
105 | |||
106 | master@1 { | ||
107 | interrupts = <20 0x2>; | ||
108 | interrupt-parent = <&gpio_pic>; | ||
109 | chipselect = <2 0x00009000 0x00009100>; | ||
110 | label = "AS-i master 1"; | ||
111 | }; | ||
112 | |||
113 | master@2 { | ||
114 | interrupts = <21 0x2>; | ||
115 | interrupt-parent = <&gpio_pic>; | ||
116 | chipselect = <6 0x00009000 0x00009100>; | ||
117 | label = "AS-i master 2"; | ||
118 | }; | ||
119 | }; | ||
120 | |||
121 | netx@3,0 { | ||
122 | compatible = "ifm,netx"; | ||
123 | reg = <0x3 0x00000000 0x00020000>; | ||
124 | chipselect = <3 0x00101140 0x00203100>; | ||
125 | interrupts = <17 0x8>; | ||
126 | gpios = <&gpio_pic 15 0>; | ||
127 | }; | ||
128 | |||
129 | safety@5,0 { | ||
130 | compatible = "ifm,safety"; | ||
131 | reg = <0x5 0x00000000 0x00010000>; | ||
132 | chipselect = <5 0x00009000 0x00009100>; | ||
133 | interrupts = <22 0x2>; | ||
134 | interrupt-parent = <&gpio_pic>; | ||
135 | gpios = < | ||
136 | &gpio_pic 12 0 /* prog */ | ||
137 | &gpio_pic 11 0 /* done */ | ||
138 | >; | ||
139 | }; | ||
140 | }; | ||
141 | |||
142 | soc@80000000 { | ||
143 | |||
144 | clock@f00 { | ||
145 | compatible = "fsl,mpc5121rev2-clock", "fsl,mpc5121-clock"; | ||
146 | }; | ||
147 | |||
148 | /* | ||
149 | * GPIO PIC: | ||
150 | * interrupts cell = <pin nr, sense> | ||
151 | * sense == 8: Level, low assertion | ||
152 | * sense == 2: Edge, high-to-low change | ||
153 | */ | ||
154 | gpio_pic: gpio@1100 { | ||
155 | gpio-controller; | ||
156 | #gpio-cells = <2>; | ||
157 | interrupt-controller; | ||
158 | #interrupt-cells = <2>; | ||
159 | }; | ||
160 | |||
161 | sdhc@1500 { | ||
162 | cd-gpios = <&gpio_pic 23 0>; /* card detect */ | ||
163 | wp-gpios = <&gpio_pic 24 0>; /* write protect */ | ||
164 | wp-inverted; /* WP active high */ | ||
165 | }; | ||
166 | |||
167 | i2c@1700 { | ||
168 | /* use Fast-mode */ | ||
169 | clock-frequency = <400000>; | ||
170 | |||
171 | at24@30 { | ||
172 | compatible = "at24,24c01"; | ||
173 | reg = <0x30>; | ||
174 | }; | ||
175 | |||
176 | at24@31 { | ||
177 | compatible = "at24,24c01"; | ||
178 | reg = <0x31>; | ||
179 | }; | ||
180 | |||
181 | temp@48 { | ||
182 | compatible = "ad,ad7414"; | ||
183 | reg = <0x48>; | ||
184 | }; | ||
185 | |||
186 | at24@50 { | ||
187 | compatible = "at24,24c01"; | ||
188 | reg = <0x50>; | ||
189 | }; | ||
190 | |||
191 | at24@51 { | ||
192 | compatible = "at24,24c01"; | ||
193 | reg = <0x51>; | ||
194 | }; | ||
195 | |||
196 | at24@52 { | ||
197 | compatible = "at24,24c01"; | ||
198 | reg = <0x52>; | ||
199 | }; | ||
200 | |||
201 | at24@53 { | ||
202 | compatible = "at24,24c01"; | ||
203 | reg = <0x53>; | ||
204 | }; | ||
205 | |||
206 | at24@54 { | ||
207 | compatible = "at24,24c01"; | ||
208 | reg = <0x54>; | ||
209 | }; | ||
210 | |||
211 | at24@55 { | ||
212 | compatible = "at24,24c01"; | ||
213 | reg = <0x55>; | ||
214 | }; | ||
215 | |||
216 | at24@56 { | ||
217 | compatible = "at24,24c01"; | ||
218 | reg = <0x56>; | ||
219 | }; | ||
220 | |||
221 | at24@57 { | ||
222 | compatible = "at24,24c01"; | ||
223 | reg = <0x57>; | ||
224 | }; | ||
225 | |||
226 | rtc@68 { | ||
227 | compatible = "stm,m41t00"; | ||
228 | reg = <0x68>; | ||
229 | }; | ||
230 | }; | ||
231 | |||
232 | axe_pic: axe-base@2000 { | ||
233 | compatible = "fsl,mpc5121-axe-base"; | ||
234 | reg = <0x2000 0x100>; | ||
235 | interrupts = <42 0x8>; | ||
236 | interrupt-controller; | ||
237 | #interrupt-cells = <2>; | ||
238 | }; | ||
239 | |||
240 | axe-app { | ||
241 | compatible = "fsl,mpc5121-axe-app"; | ||
242 | interrupt-parent = <&axe_pic>; | ||
243 | interrupts = < | ||
244 | /* soft interrupts */ | ||
245 | 0 0x0 1 0x0 2 0x0 3 0x0 | ||
246 | 4 0x0 5 0x0 6 0x0 7 0x0 | ||
247 | /* fifo interrupts */ | ||
248 | 8 0x0 9 0x0 10 0x0 11 0x0 | ||
249 | >; | ||
250 | }; | ||
251 | |||
252 | display@2100 { | ||
253 | edid = [00 FF FF FF FF FF FF 00 14 94 00 00 00 00 00 00 | ||
254 | 0A 12 01 03 80 1C 23 78 CA 88 FF 94 52 54 8E 27 | ||
255 | 1E 4C 50 00 00 00 01 01 01 01 01 01 01 01 01 01 | ||
256 | 01 01 01 01 01 01 FB 00 B0 14 00 DC 05 00 08 04 | ||
257 | 21 00 1C 23 00 00 00 18 00 00 00 FD 00 38 3C 1F | ||
258 | 3C 01 0A 20 20 20 20 20 20 20 00 00 00 FC 00 45 | ||
259 | 54 30 31 38 30 30 33 44 4D 55 0A 0A 00 00 00 10 | ||
260 | 00 41 30 30 30 30 30 30 30 30 30 30 30 31 00 D5]; | ||
261 | }; | ||
262 | |||
263 | can@2300 { | ||
264 | status = "disabled"; | ||
265 | }; | ||
266 | |||
267 | can@2380 { | ||
268 | status = "disabled"; | ||
269 | }; | ||
270 | |||
271 | viu@2400 { | ||
272 | status = "disabled"; | ||
273 | }; | ||
274 | |||
275 | mdio@2800 { | ||
276 | phy0: ethernet-phy@1f { | ||
277 | compatible = "smsc,lan8700"; | ||
278 | reg = <0x1f>; | ||
279 | }; | ||
280 | }; | ||
281 | |||
282 | enet: ethernet@2800 { | ||
283 | phy-handle = <&phy0>; | ||
284 | }; | ||
285 | |||
286 | usb@3000 { | ||
287 | status = "disabled"; | ||
288 | }; | ||
289 | |||
290 | usb@4000 { | ||
291 | status = "disabled"; | ||
292 | }; | ||
293 | |||
294 | /* PSC3 serial port A, aka ttyPSC0 */ | ||
295 | serial0: psc@11300 { | ||
296 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
297 | fsl,rx-fifo-size = <512>; | ||
298 | fsl,tx-fifo-size = <512>; | ||
299 | }; | ||
300 | |||
301 | /* PSC4 in SPI mode */ | ||
302 | spi4: psc@11400 { | ||
303 | compatible = "fsl,mpc5121-psc-spi", "fsl,mpc5121-psc"; | ||
304 | fsl,rx-fifo-size = <768>; | ||
305 | fsl,tx-fifo-size = <768>; | ||
306 | #address-cells = <1>; | ||
307 | #size-cells = <0>; | ||
308 | num-cs = <1>; | ||
309 | cs-gpios = <&gpio_pic 25 0>; | ||
310 | |||
311 | flash: m25p128@0 { | ||
312 | compatible = "st,m25p128"; | ||
313 | spi-max-frequency = <20000000>; | ||
314 | reg = <0>; | ||
315 | #address-cells = <1>; | ||
316 | #size-cells = <1>; | ||
317 | |||
318 | partition@0 { | ||
319 | label = "spi-flash0"; | ||
320 | reg = <0x00000000 0x01000000>; | ||
321 | }; | ||
322 | }; | ||
323 | }; | ||
324 | |||
325 | /* PSC5 in SPI mode */ | ||
326 | spi5: psc@11500 { | ||
327 | compatible = "fsl,mpc5121-psc-spi", "fsl,mpc5121-psc"; | ||
328 | fsl,mode = "spi-master"; | ||
329 | fsl,rx-fifo-size = <128>; | ||
330 | fsl,tx-fifo-size = <128>; | ||
331 | #address-cells = <1>; | ||
332 | #size-cells = <0>; | ||
333 | |||
334 | lcd@0 { | ||
335 | compatible = "ilitek,ili922x"; | ||
336 | reg = <0>; | ||
337 | spi-max-frequency = <100000>; | ||
338 | spi-cpol; | ||
339 | spi-cpha; | ||
340 | }; | ||
341 | }; | ||
342 | |||
343 | /* PSC7 serial port C, aka ttyPSC2 */ | ||
344 | serial7: psc@11700 { | ||
345 | compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||
346 | fsl,rx-fifo-size = <512>; | ||
347 | fsl,tx-fifo-size = <512>; | ||
348 | }; | ||
349 | |||
350 | matrix_keypad@0 { | ||
351 | compatible = "gpio-matrix-keypad"; | ||
352 | debounce-delay-ms = <5>; | ||
353 | col-scan-delay-us = <1>; | ||
354 | gpio-activelow; | ||
355 | col-gpios-binary; | ||
356 | col-switch-delay-ms = <200>; | ||
357 | |||
358 | col-gpios = <&gpio_pic 1 0>; /* pin1 */ | ||
359 | |||
360 | row-gpios = <&gpio_pic 2 0 /* pin2 */ | ||
361 | &gpio_pic 3 0 /* pin3 */ | ||
362 | &gpio_pic 4 0>; /* pin4 */ | ||
363 | |||
364 | linux,keymap = <0x0000006e /* FN LEFT */ | ||
365 | 0x01000067 /* UP */ | ||
366 | 0x02000066 /* FN RIGHT */ | ||
367 | 0x00010069 /* LEFT */ | ||
368 | 0x0101006a /* DOWN */ | ||
369 | 0x0201006c>; /* RIGHT */ | ||
370 | }; | ||
371 | }; | ||
372 | |||
373 | leds { | ||
374 | compatible = "gpio-leds"; | ||
375 | |||
376 | backlight { | ||
377 | label = "backlight"; | ||
378 | gpios = <&gpio_pic 0 0>; | ||
379 | default-state = "keep"; | ||
380 | }; | ||
381 | green { | ||
382 | label = "green"; | ||
383 | gpios = <&gpio_pic 18 0>; | ||
384 | default-state = "keep"; | ||
385 | }; | ||
386 | red { | ||
387 | label = "red"; | ||
388 | gpios = <&gpio_pic 19 0>; | ||
389 | default-state = "keep"; | ||
390 | }; | ||
391 | }; | ||
392 | }; | ||
diff --git a/arch/powerpc/boot/dts/b4420qds.dts b/arch/powerpc/boot/dts/b4420qds.dts new file mode 100644 index 000000000000..923156d03b30 --- /dev/null +++ b/arch/powerpc/boot/dts/b4420qds.dts | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * B4420DS Device Tree Source | ||
3 | * | ||
4 | * Copyright 2012 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 | ||
32 | * this software, even if advised of the possibility of such damage. | ||
33 | */ | ||
34 | |||
35 | /include/ "fsl/b4420si-pre.dtsi" | ||
36 | /include/ "b4qds.dts" | ||
37 | |||
38 | / { | ||
39 | model = "fsl,B4420QDS"; | ||
40 | compatible = "fsl,B4420QDS"; | ||
41 | |||
42 | ifc: localbus@ffe124000 { | ||
43 | board-control@3,0 { | ||
44 | compatible = "fsl,b4420qds-fpga", "fsl,fpga-qixis"; | ||
45 | }; | ||
46 | }; | ||
47 | |||
48 | }; | ||
49 | |||
50 | /include/ "fsl/b4420si-post.dtsi" | ||
diff --git a/arch/powerpc/boot/dts/b4860qds.dts b/arch/powerpc/boot/dts/b4860qds.dts new file mode 100644 index 000000000000..78907f38bb77 --- /dev/null +++ b/arch/powerpc/boot/dts/b4860qds.dts | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * B4860DS Device Tree Source | ||
3 | * | ||
4 | * Copyright 2012 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/ "fsl/b4860si-pre.dtsi" | ||
36 | /include/ "b4qds.dts" | ||
37 | |||
38 | / { | ||
39 | model = "fsl,B4860QDS"; | ||
40 | compatible = "fsl,B4860QDS"; | ||
41 | |||
42 | ifc: localbus@ffe124000 { | ||
43 | board-control@3,0 { | ||
44 | compatible = "fsl,b4860qds-fpga", "fsl,fpga-qixis"; | ||
45 | }; | ||
46 | }; | ||
47 | |||
48 | rio: rapidio@ffe0c0000 { | ||
49 | reg = <0xf 0xfe0c0000 0 0x11000>; | ||
50 | |||
51 | port1 { | ||
52 | ranges = <0 0 0xc 0x20000000 0 0x10000000>; | ||
53 | }; | ||
54 | port2 { | ||
55 | ranges = <0 0 0xc 0x30000000 0 0x10000000>; | ||
56 | }; | ||
57 | }; | ||
58 | |||
59 | }; | ||
60 | |||
61 | /include/ "fsl/b4860si-post.dtsi" | ||
diff --git a/arch/powerpc/boot/dts/b4qds.dts b/arch/powerpc/boot/dts/b4qds.dts new file mode 100644 index 000000000000..e6d2f8f90544 --- /dev/null +++ b/arch/powerpc/boot/dts/b4qds.dts | |||
@@ -0,0 +1,169 @@ | |||
1 | /* | ||
2 | * B4420DS Device Tree Source | ||
3 | * | ||
4 | * Copyright 2012 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 | ||
32 | * this software, even if advised of the possibility of such damage. | ||
33 | */ | ||
34 | |||
35 | / { | ||
36 | model = "fsl,B4QDS"; | ||
37 | compatible = "fsl,B4QDS"; | ||
38 | #address-cells = <2>; | ||
39 | #size-cells = <2>; | ||
40 | interrupt-parent = <&mpic>; | ||
41 | |||
42 | ifc: localbus@ffe124000 { | ||
43 | reg = <0xf 0xfe124000 0 0x2000>; | ||
44 | ranges = <0 0 0xf 0xe8000000 0x08000000 | ||
45 | 2 0 0xf 0xff800000 0x00010000 | ||
46 | 3 0 0xf 0xffdf0000 0x00008000>; | ||
47 | |||
48 | nor@0,0 { | ||
49 | #address-cells = <1>; | ||
50 | #size-cells = <1>; | ||
51 | compatible = "cfi-flash"; | ||
52 | reg = <0x0 0x0 0x8000000>; | ||
53 | bank-width = <2>; | ||
54 | device-width = <1>; | ||
55 | }; | ||
56 | |||
57 | nand@2,0 { | ||
58 | #address-cells = <1>; | ||
59 | #size-cells = <1>; | ||
60 | compatible = "fsl,ifc-nand"; | ||
61 | reg = <0x2 0x0 0x10000>; | ||
62 | |||
63 | partition@0 { | ||
64 | /* This location must not be altered */ | ||
65 | /* 1MB for u-boot Bootloader Image */ | ||
66 | reg = <0x0 0x00100000>; | ||
67 | label = "NAND U-Boot Image"; | ||
68 | read-only; | ||
69 | }; | ||
70 | |||
71 | partition@100000 { | ||
72 | /* 1MB for DTB Image */ | ||
73 | reg = <0x00100000 0x00100000>; | ||
74 | label = "NAND DTB Image"; | ||
75 | }; | ||
76 | |||
77 | partition@200000 { | ||
78 | /* 10MB for Linux Kernel Image */ | ||
79 | reg = <0x00200000 0x00A00000>; | ||
80 | label = "NAND Linux Kernel Image"; | ||
81 | }; | ||
82 | |||
83 | partition@c00000 { | ||
84 | /* 500MB for Root file System Image */ | ||
85 | reg = <0x00c00000 0x1F400000>; | ||
86 | label = "NAND RFS Image"; | ||
87 | }; | ||
88 | }; | ||
89 | |||
90 | board-control@3,0 { | ||
91 | compatible = "fsl,b4qds-fpga", "fsl,fpga-qixis"; | ||
92 | reg = <3 0 0x300>; | ||
93 | }; | ||
94 | }; | ||
95 | |||
96 | memory { | ||
97 | device_type = "memory"; | ||
98 | }; | ||
99 | |||
100 | dcsr: dcsr@f00000000 { | ||
101 | ranges = <0x00000000 0xf 0x00000000 0x01052000>; | ||
102 | }; | ||
103 | |||
104 | soc: soc@ffe000000 { | ||
105 | ranges = <0x00000000 0xf 0xfe000000 0x1000000>; | ||
106 | reg = <0xf 0xfe000000 0 0x00001000>; | ||
107 | spi@110000 { | ||
108 | flash@0 { | ||
109 | #address-cells = <1>; | ||
110 | #size-cells = <1>; | ||
111 | compatible = "sst,sst25wf040"; | ||
112 | reg = <0>; | ||
113 | spi-max-frequency = <40000000>; /* input clock */ | ||
114 | }; | ||
115 | }; | ||
116 | |||
117 | sdhc@114000 { | ||
118 | /*Disabled as there is no sdhc connector on B4420QDS board*/ | ||
119 | status = "disabled"; | ||
120 | }; | ||
121 | |||
122 | i2c@118000 { | ||
123 | eeprom@50 { | ||
124 | compatible = "at24,24c64"; | ||
125 | reg = <0x50>; | ||
126 | }; | ||
127 | eeprom@51 { | ||
128 | compatible = "at24,24c256"; | ||
129 | reg = <0x51>; | ||
130 | }; | ||
131 | eeprom@53 { | ||
132 | compatible = "at24,24c256"; | ||
133 | reg = <0x53>; | ||
134 | }; | ||
135 | eeprom@57 { | ||
136 | compatible = "at24,24c256"; | ||
137 | reg = <0x57>; | ||
138 | }; | ||
139 | rtc@68 { | ||
140 | compatible = "dallas,ds3232"; | ||
141 | reg = <0x68>; | ||
142 | }; | ||
143 | }; | ||
144 | |||
145 | usb@210000 { | ||
146 | dr_mode = "host"; | ||
147 | phy_type = "ulpi"; | ||
148 | }; | ||
149 | |||
150 | }; | ||
151 | |||
152 | pci0: pcie@ffe200000 { | ||
153 | reg = <0xf 0xfe200000 0 0x10000>; | ||
154 | ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000 | ||
155 | 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>; | ||
156 | pcie@0 { | ||
157 | ranges = <0x02000000 0 0xe0000000 | ||
158 | 0x02000000 0 0xe0000000 | ||
159 | 0 0x20000000 | ||
160 | |||
161 | 0x01000000 0 0x00000000 | ||
162 | 0x01000000 0 0x00000000 | ||
163 | 0 0x00010000>; | ||
164 | }; | ||
165 | }; | ||
166 | |||
167 | }; | ||
168 | |||
169 | /include/ "fsl/b4si-post.dtsi" | ||
diff --git a/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi new file mode 100644 index 000000000000..5a6615d0ade2 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * B4420 Silicon/SoC Device Tree Source (post include) | ||
3 | * | ||
4 | * Copyright 2012 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 | ||
32 | * this software, even if advised of the possibility of such damage. | ||
33 | */ | ||
34 | |||
35 | /include/ "b4si-post.dtsi" | ||
36 | |||
37 | /* controller at 0x200000 */ | ||
38 | &pci0 { | ||
39 | compatible = "fsl,b4420-pcie", "fsl,qoriq-pcie-v2.4"; | ||
40 | }; | ||
41 | |||
42 | &dcsr { | ||
43 | dcsr-epu@0 { | ||
44 | compatible = "fsl,b4420-dcsr-epu", "fsl,dcsr-epu"; | ||
45 | }; | ||
46 | dcsr-npc { | ||
47 | compatible = "fsl,b4420-dcsr-cnpc", "fsl,dcsr-cnpc"; | ||
48 | }; | ||
49 | dcsr-dpaa@9000 { | ||
50 | compatible = "fsl,b4420-dcsr-dpaa", "fsl,dcsr-dpaa"; | ||
51 | }; | ||
52 | dcsr-ocn@11000 { | ||
53 | compatible = "fsl,b4420-dcsr-ocn", "fsl,dcsr-ocn"; | ||
54 | }; | ||
55 | dcsr-nal@18000 { | ||
56 | compatible = "fsl,b4420-dcsr-nal", "fsl,dcsr-nal"; | ||
57 | }; | ||
58 | dcsr-rcpm@22000 { | ||
59 | compatible = "fsl,b4420-dcsr-rcpm", "fsl,dcsr-rcpm"; | ||
60 | }; | ||
61 | dcsr-snpc@30000 { | ||
62 | compatible = "fsl,b4420-dcsr-snpc", "fsl,dcsr-snpc"; | ||
63 | }; | ||
64 | dcsr-snpc@31000 { | ||
65 | compatible = "fsl,b4420-dcsr-snpc", "fsl,dcsr-snpc"; | ||
66 | }; | ||
67 | dcsr-cpu-sb-proxy@108000 { | ||
68 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
69 | cpu-handle = <&cpu1>; | ||
70 | reg = <0x108000 0x1000 0x109000 0x1000>; | ||
71 | }; | ||
72 | }; | ||
73 | |||
74 | &soc { | ||
75 | cpc: l3-cache-controller@10000 { | ||
76 | compatible = "fsl,b4420-l3-cache-controller", "cache"; | ||
77 | }; | ||
78 | |||
79 | corenet-cf@18000 { | ||
80 | compatible = "fsl,b4420-corenet-cf"; | ||
81 | }; | ||
82 | |||
83 | guts: global-utilities@e0000 { | ||
84 | compatible = "fsl,b4420-device-config", "fsl,qoriq-device-config-2.0"; | ||
85 | }; | ||
86 | |||
87 | clockgen: global-utilities@e1000 { | ||
88 | compatible = "fsl,b4420-clockgen", "fsl,qoriq-clockgen-2.0"; | ||
89 | }; | ||
90 | |||
91 | rcpm: global-utilities@e2000 { | ||
92 | compatible = "fsl,b4420-rcpm", "fsl,qoriq-rcpm-2.0"; | ||
93 | }; | ||
94 | |||
95 | L2: l2-cache-controller@c20000 { | ||
96 | compatible = "fsl,b4420-l2-cache-controller"; | ||
97 | }; | ||
98 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi b/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi new file mode 100644 index 000000000000..7b4426e0a5a5 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * B4420 Silicon/SoC Device Tree Source (pre include) | ||
3 | * | ||
4 | * Copyright 2012 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 | ||
32 | * this software, even if advised of the possibility of such damage. | ||
33 | */ | ||
34 | |||
35 | /dts-v1/; | ||
36 | |||
37 | / { | ||
38 | compatible = "fsl,B4420"; | ||
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 | dma0 = &dma0; | ||
53 | dma1 = &dma1; | ||
54 | sdhc = &sdhc; | ||
55 | }; | ||
56 | |||
57 | |||
58 | cpus { | ||
59 | #address-cells = <1>; | ||
60 | #size-cells = <0>; | ||
61 | |||
62 | cpu0: PowerPC,e6500@0 { | ||
63 | device_type = "cpu"; | ||
64 | reg = <0 1>; | ||
65 | next-level-cache = <&L2>; | ||
66 | }; | ||
67 | cpu1: PowerPC,e6500@2 { | ||
68 | device_type = "cpu"; | ||
69 | reg = <2 3>; | ||
70 | next-level-cache = <&L2>; | ||
71 | }; | ||
72 | }; | ||
73 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi new file mode 100644 index 000000000000..e5cf6c81dd66 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi | |||
@@ -0,0 +1,142 @@ | |||
1 | /* | ||
2 | * B4860 Silicon/SoC Device Tree Source (post include) | ||
3 | * | ||
4 | * Copyright 2012 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/ "b4si-post.dtsi" | ||
36 | |||
37 | /* controller at 0x200000 */ | ||
38 | &pci0 { | ||
39 | compatible = "fsl,b4860-pcie", "fsl,qoriq-pcie-v2.4"; | ||
40 | }; | ||
41 | |||
42 | &rio { | ||
43 | compatible = "fsl,srio"; | ||
44 | interrupts = <16 2 1 11>; | ||
45 | #address-cells = <2>; | ||
46 | #size-cells = <2>; | ||
47 | fsl,iommu-parent = <&pamu0>; | ||
48 | ranges; | ||
49 | |||
50 | port1 { | ||
51 | #address-cells = <2>; | ||
52 | #size-cells = <2>; | ||
53 | cell-index = <1>; | ||
54 | fsl,liodn-reg = <&guts 0x510>; /* RIO1LIODNR */ | ||
55 | }; | ||
56 | |||
57 | port2 { | ||
58 | #address-cells = <2>; | ||
59 | #size-cells = <2>; | ||
60 | cell-index = <2>; | ||
61 | fsl,liodn-reg = <&guts 0x514>; /* RIO2LIODNR */ | ||
62 | }; | ||
63 | }; | ||
64 | |||
65 | &dcsr { | ||
66 | dcsr-epu@0 { | ||
67 | compatible = "fsl,b4860-dcsr-epu", "fsl,dcsr-epu"; | ||
68 | }; | ||
69 | dcsr-npc { | ||
70 | compatible = "fsl,b4860-dcsr-cnpc", "fsl,dcsr-cnpc"; | ||
71 | }; | ||
72 | dcsr-dpaa@9000 { | ||
73 | compatible = "fsl,b4860-dcsr-dpaa", "fsl,dcsr-dpaa"; | ||
74 | }; | ||
75 | dcsr-ocn@11000 { | ||
76 | compatible = "fsl,b4860-dcsr-ocn", "fsl,dcsr-ocn"; | ||
77 | }; | ||
78 | dcsr-ddr@13000 { | ||
79 | compatible = "fsl,dcsr-ddr"; | ||
80 | dev-handle = <&ddr2>; | ||
81 | reg = <0x13000 0x1000>; | ||
82 | }; | ||
83 | dcsr-nal@18000 { | ||
84 | compatible = "fsl,b4860-dcsr-nal", "fsl,dcsr-nal"; | ||
85 | }; | ||
86 | dcsr-rcpm@22000 { | ||
87 | compatible = "fsl,b4860-dcsr-rcpm", "fsl,dcsr-rcpm"; | ||
88 | }; | ||
89 | dcsr-snpc@30000 { | ||
90 | compatible = "fsl,b4860-dcsr-snpc", "fsl,dcsr-snpc"; | ||
91 | }; | ||
92 | dcsr-snpc@31000 { | ||
93 | compatible = "fsl,b4860-dcsr-snpc", "fsl,dcsr-snpc"; | ||
94 | }; | ||
95 | dcsr-cpu-sb-proxy@108000 { | ||
96 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
97 | cpu-handle = <&cpu1>; | ||
98 | reg = <0x108000 0x1000 0x109000 0x1000>; | ||
99 | }; | ||
100 | dcsr-cpu-sb-proxy@110000 { | ||
101 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
102 | cpu-handle = <&cpu2>; | ||
103 | reg = <0x110000 0x1000 0x111000 0x1000>; | ||
104 | }; | ||
105 | dcsr-cpu-sb-proxy@118000 { | ||
106 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
107 | cpu-handle = <&cpu3>; | ||
108 | reg = <0x118000 0x1000 0x119000 0x1000>; | ||
109 | }; | ||
110 | }; | ||
111 | |||
112 | &soc { | ||
113 | ddr2: memory-controller@9000 { | ||
114 | compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; | ||
115 | reg = <0x9000 0x1000>; | ||
116 | interrupts = <16 2 1 9>; | ||
117 | }; | ||
118 | |||
119 | cpc: l3-cache-controller@10000 { | ||
120 | compatible = "fsl,b4860-l3-cache-controller", "cache"; | ||
121 | }; | ||
122 | |||
123 | corenet-cf@18000 { | ||
124 | compatible = "fsl,b4860-corenet-cf"; | ||
125 | }; | ||
126 | |||
127 | guts: global-utilities@e0000 { | ||
128 | compatible = "fsl,b4860-device-config", "fsl,qoriq-device-config-2.0"; | ||
129 | }; | ||
130 | |||
131 | clockgen: global-utilities@e1000 { | ||
132 | compatible = "fsl,b4860-clockgen", "fsl,qoriq-clockgen-2.0"; | ||
133 | }; | ||
134 | |||
135 | rcpm: global-utilities@e2000 { | ||
136 | compatible = "fsl,b4860-rcpm", "fsl,qoriq-rcpm-2.0"; | ||
137 | }; | ||
138 | |||
139 | L2: l2-cache-controller@c20000 { | ||
140 | compatible = "fsl,b4860-l2-cache-controller"; | ||
141 | }; | ||
142 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi b/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi new file mode 100644 index 000000000000..5263fa46a3fb --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | * B4860 Silicon/SoC Device Tree Source (pre include) | ||
3 | * | ||
4 | * Copyright 2012 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,B4860"; | ||
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 | dma0 = &dma0; | ||
53 | dma1 = &dma1; | ||
54 | sdhc = &sdhc; | ||
55 | }; | ||
56 | |||
57 | |||
58 | cpus { | ||
59 | #address-cells = <1>; | ||
60 | #size-cells = <0>; | ||
61 | |||
62 | cpu0: PowerPC,e6500@0 { | ||
63 | device_type = "cpu"; | ||
64 | reg = <0 1>; | ||
65 | next-level-cache = <&L2>; | ||
66 | }; | ||
67 | cpu1: PowerPC,e6500@2 { | ||
68 | device_type = "cpu"; | ||
69 | reg = <2 3>; | ||
70 | next-level-cache = <&L2>; | ||
71 | }; | ||
72 | cpu2: PowerPC,e6500@4 { | ||
73 | device_type = "cpu"; | ||
74 | reg = <4 5>; | ||
75 | next-level-cache = <&L2>; | ||
76 | }; | ||
77 | cpu3: PowerPC,e6500@6 { | ||
78 | device_type = "cpu"; | ||
79 | reg = <6 7>; | ||
80 | next-level-cache = <&L2>; | ||
81 | }; | ||
82 | }; | ||
83 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi new file mode 100644 index 000000000000..73991547c69b --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi | |||
@@ -0,0 +1,268 @@ | |||
1 | /* | ||
2 | * B4420 Silicon/SoC Device Tree Source (post include) | ||
3 | * | ||
4 | * Copyright 2012 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 | ||
32 | * this software, even if advised of the possibility of such damage. | ||
33 | */ | ||
34 | |||
35 | &ifc { | ||
36 | #address-cells = <2>; | ||
37 | #size-cells = <1>; | ||
38 | compatible = "fsl,ifc", "simple-bus"; | ||
39 | interrupts = <25 2 0 0>; | ||
40 | }; | ||
41 | |||
42 | /* controller at 0x200000 */ | ||
43 | &pci0 { | ||
44 | compatible = "fsl,b4-pcie", "fsl,qoriq-pcie-v2.4"; | ||
45 | device_type = "pci"; | ||
46 | #size-cells = <2>; | ||
47 | #address-cells = <3>; | ||
48 | bus-range = <0x0 0xff>; | ||
49 | interrupts = <20 2 0 0>; | ||
50 | fsl,iommu-parent = <&pamu0>; | ||
51 | pcie@0 { | ||
52 | #interrupt-cells = <1>; | ||
53 | #size-cells = <2>; | ||
54 | #address-cells = <3>; | ||
55 | device_type = "pci"; | ||
56 | reg = <0 0 0 0 0>; | ||
57 | interrupts = <20 2 0 0>; | ||
58 | interrupt-map-mask = <0xf800 0 0 7>; | ||
59 | interrupt-map = < | ||
60 | /* IDSEL 0x0 */ | ||
61 | 0000 0 0 1 &mpic 40 1 0 0 | ||
62 | 0000 0 0 2 &mpic 1 1 0 0 | ||
63 | 0000 0 0 3 &mpic 2 1 0 0 | ||
64 | 0000 0 0 4 &mpic 3 1 0 0 | ||
65 | >; | ||
66 | }; | ||
67 | }; | ||
68 | |||
69 | &dcsr { | ||
70 | #address-cells = <1>; | ||
71 | #size-cells = <1>; | ||
72 | compatible = "fsl,dcsr", "simple-bus"; | ||
73 | |||
74 | dcsr-epu@0 { | ||
75 | compatible = "fsl,b4-dcsr-epu", "fsl,dcsr-epu"; | ||
76 | interrupts = <52 2 0 0 | ||
77 | 84 2 0 0 | ||
78 | 85 2 0 0 | ||
79 | 94 2 0 0 | ||
80 | 95 2 0 0>; | ||
81 | reg = <0x0 0x1000>; | ||
82 | }; | ||
83 | dcsr-npc { | ||
84 | compatible = "fsl,b4-dcsr-cnpc", "fsl,dcsr-cnpc"; | ||
85 | reg = <0x1000 0x1000 0x1002000 0x10000>; | ||
86 | }; | ||
87 | dcsr-nxc@2000 { | ||
88 | compatible = "fsl,dcsr-nxc"; | ||
89 | reg = <0x2000 0x1000>; | ||
90 | }; | ||
91 | dcsr-corenet { | ||
92 | compatible = "fsl,dcsr-corenet"; | ||
93 | reg = <0x8000 0x1000 0x1A000 0x1000>; | ||
94 | }; | ||
95 | dcsr-dpaa@9000 { | ||
96 | compatible = "fsl,b4-dcsr-dpaa", "fsl,dcsr-dpaa"; | ||
97 | reg = <0x9000 0x1000>; | ||
98 | }; | ||
99 | dcsr-ocn@11000 { | ||
100 | compatible = "fsl,b4-dcsr-ocn", "fsl,dcsr-ocn"; | ||
101 | reg = <0x11000 0x1000>; | ||
102 | }; | ||
103 | dcsr-ddr@12000 { | ||
104 | compatible = "fsl,dcsr-ddr"; | ||
105 | dev-handle = <&ddr1>; | ||
106 | reg = <0x12000 0x1000>; | ||
107 | }; | ||
108 | dcsr-nal@18000 { | ||
109 | compatible = "fsl,b4-dcsr-nal", "fsl,dcsr-nal"; | ||
110 | reg = <0x18000 0x1000>; | ||
111 | }; | ||
112 | dcsr-rcpm@22000 { | ||
113 | compatible = "fsl,b4-dcsr-rcpm", "fsl,dcsr-rcpm"; | ||
114 | reg = <0x22000 0x1000>; | ||
115 | }; | ||
116 | dcsr-snpc@30000 { | ||
117 | compatible = "fsl,b4-dcsr-snpc", "fsl,dcsr-snpc"; | ||
118 | reg = <0x30000 0x1000 0x1022000 0x10000>; | ||
119 | }; | ||
120 | dcsr-snpc@31000 { | ||
121 | compatible = "fsl,b4-dcsr-snpc", "fsl,dcsr-snpc"; | ||
122 | reg = <0x31000 0x1000 0x1042000 0x10000>; | ||
123 | }; | ||
124 | dcsr-cpu-sb-proxy@100000 { | ||
125 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
126 | cpu-handle = <&cpu0>; | ||
127 | reg = <0x100000 0x1000 0x101000 0x1000>; | ||
128 | }; | ||
129 | }; | ||
130 | |||
131 | &soc { | ||
132 | #address-cells = <1>; | ||
133 | #size-cells = <1>; | ||
134 | device_type = "soc"; | ||
135 | compatible = "simple-bus"; | ||
136 | |||
137 | soc-sram-error { | ||
138 | compatible = "fsl,soc-sram-error"; | ||
139 | interrupts = <16 2 1 2>; | ||
140 | }; | ||
141 | |||
142 | corenet-law@0 { | ||
143 | compatible = "fsl,corenet-law"; | ||
144 | reg = <0x0 0x1000>; | ||
145 | fsl,num-laws = <32>; | ||
146 | }; | ||
147 | |||
148 | ddr1: memory-controller@8000 { | ||
149 | compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; | ||
150 | reg = <0x8000 0x1000>; | ||
151 | interrupts = <16 2 1 8>; | ||
152 | }; | ||
153 | |||
154 | cpc: l3-cache-controller@10000 { | ||
155 | compatible = "fsl,b4-l3-cache-controller", "cache"; | ||
156 | reg = <0x10000 0x1000>; | ||
157 | interrupts = <16 2 1 4>; | ||
158 | }; | ||
159 | |||
160 | corenet-cf@18000 { | ||
161 | compatible = "fsl,b4-corenet-cf"; | ||
162 | reg = <0x18000 0x1000>; | ||
163 | interrupts = <16 2 1 0>; | ||
164 | fsl,ccf-num-csdids = <32>; | ||
165 | fsl,ccf-num-snoopids = <32>; | ||
166 | }; | ||
167 | |||
168 | iommu@20000 { | ||
169 | compatible = "fsl,pamu-v1.0", "fsl,pamu"; | ||
170 | reg = <0x20000 0x4000>; | ||
171 | #address-cells = <1>; | ||
172 | #size-cells = <1>; | ||
173 | interrupts = < | ||
174 | 24 2 0 0 | ||
175 | 16 2 1 1>; | ||
176 | |||
177 | |||
178 | /* PCIe, DMA, SRIO */ | ||
179 | pamu0: pamu@0 { | ||
180 | reg = <0 0x1000>; | ||
181 | fsl,primary-cache-geometry = <8 1>; | ||
182 | fsl,secondary-cache-geometry = <32 2>; | ||
183 | }; | ||
184 | |||
185 | /* AXI2, Maple */ | ||
186 | pamu1: pamu@1000 { | ||
187 | reg = <0x1000 0x1000>; | ||
188 | fsl,primary-cache-geometry = <32 1>; | ||
189 | fsl,secondary-cache-geometry = <32 2>; | ||
190 | }; | ||
191 | |||
192 | /* Q/BMan */ | ||
193 | pamu2: pamu@2000 { | ||
194 | reg = <0x2000 0x1000>; | ||
195 | fsl,primary-cache-geometry = <32 1>; | ||
196 | fsl,secondary-cache-geometry = <32 2>; | ||
197 | }; | ||
198 | |||
199 | /* AXI1, FMAN */ | ||
200 | pamu3: pamu@3000 { | ||
201 | reg = <0x3000 0x1000>; | ||
202 | fsl,primary-cache-geometry = <32 1>; | ||
203 | fsl,secondary-cache-geometry = <32 2>; | ||
204 | }; | ||
205 | }; | ||
206 | |||
207 | /include/ "qoriq-mpic.dtsi" | ||
208 | |||
209 | guts: global-utilities@e0000 { | ||
210 | compatible = "fsl,b4-device-config"; | ||
211 | reg = <0xe0000 0xe00>; | ||
212 | fsl,has-rstcr; | ||
213 | fsl,liodn-bits = <12>; | ||
214 | }; | ||
215 | |||
216 | clockgen: global-utilities@e1000 { | ||
217 | compatible = "fsl,b4-clockgen", "fsl,qoriq-clockgen-2.0"; | ||
218 | reg = <0xe1000 0x1000>; | ||
219 | }; | ||
220 | |||
221 | rcpm: global-utilities@e2000 { | ||
222 | compatible = "fsl,b4-rcpm", "fsl,qoriq-rcpm-2.0"; | ||
223 | reg = <0xe2000 0x1000>; | ||
224 | }; | ||
225 | |||
226 | /include/ "qoriq-dma-0.dtsi" | ||
227 | dma@100300 { | ||
228 | fsl,iommu-parent = <&pamu0>; | ||
229 | fsl,liodn-reg = <&guts 0x580>; /* DMA1LIODNR */ | ||
230 | }; | ||
231 | |||
232 | /include/ "qoriq-dma-1.dtsi" | ||
233 | dma@101300 { | ||
234 | fsl,iommu-parent = <&pamu0>; | ||
235 | fsl,liodn-reg = <&guts 0x584>; /* DMA2LIODNR */ | ||
236 | }; | ||
237 | |||
238 | /include/ "qonverge-usb2-dr-0.dtsi" | ||
239 | usb0: usb@210000 { | ||
240 | compatible = "fsl-usb2-dr-v2.4", "fsl-usb2-dr"; | ||
241 | fsl,iommu-parent = <&pamu1>; | ||
242 | fsl,liodn-reg = <&guts 0x520>; /* USB1LIODNR */ | ||
243 | }; | ||
244 | |||
245 | /include/ "qoriq-espi-0.dtsi" | ||
246 | spi@110000 { | ||
247 | fsl,espi-num-chipselects = <4>; | ||
248 | }; | ||
249 | |||
250 | /include/ "qoriq-esdhc-0.dtsi" | ||
251 | sdhc@114000 { | ||
252 | sdhci,auto-cmd12; | ||
253 | fsl,iommu-parent = <&pamu1>; | ||
254 | fsl,liodn-reg = <&guts 0x530>; /* eSDHCLIODNR */ | ||
255 | }; | ||
256 | |||
257 | /include/ "qoriq-i2c-0.dtsi" | ||
258 | /include/ "qoriq-i2c-1.dtsi" | ||
259 | /include/ "qoriq-duart-0.dtsi" | ||
260 | /include/ "qoriq-duart-1.dtsi" | ||
261 | /include/ "qoriq-sec5.3-0.dtsi" | ||
262 | |||
263 | L2: l2-cache-controller@c20000 { | ||
264 | compatible = "fsl,b4-l2-cache-controller"; | ||
265 | reg = <0xc20000 0x1000>; | ||
266 | next-level-cache = <&cpc>; | ||
267 | }; | ||
268 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/e500mc_power_isa.dtsi b/arch/powerpc/boot/dts/fsl/e500mc_power_isa.dtsi index 870c6535a053..ea145c91cfbd 100644 --- a/arch/powerpc/boot/dts/fsl/e500mc_power_isa.dtsi +++ b/arch/powerpc/boot/dts/fsl/e500mc_power_isa.dtsi | |||
@@ -53,6 +53,7 @@ | |||
53 | power-isa-mmc; // Memory Coherence | 53 | power-isa-mmc; // Memory Coherence |
54 | power-isa-scpm; // Store Conditional Page Mobility | 54 | power-isa-scpm; // Store Conditional Page Mobility |
55 | power-isa-wt; // Wait | 55 | power-isa-wt; // Wait |
56 | fsl,eref-deo; // Data Cache Extended Operations | ||
56 | mmu-type = "power-embedded"; | 57 | mmu-type = "power-embedded"; |
57 | }; | 58 | }; |
58 | }; | 59 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/e5500_power_isa.dtsi b/arch/powerpc/boot/dts/fsl/e5500_power_isa.dtsi index 3230212f7ad5..c254c981ae87 100644 --- a/arch/powerpc/boot/dts/fsl/e5500_power_isa.dtsi +++ b/arch/powerpc/boot/dts/fsl/e5500_power_isa.dtsi | |||
@@ -54,6 +54,7 @@ | |||
54 | power-isa-scpm; // Store Conditional Page Mobility | 54 | power-isa-scpm; // Store Conditional Page Mobility |
55 | power-isa-wt; // Wait | 55 | power-isa-wt; // Wait |
56 | power-isa-64; // 64-bit | 56 | power-isa-64; // 64-bit |
57 | fsl,eref-deo; // Data Cache Extended Operations | ||
57 | mmu-type = "power-embedded"; | 58 | mmu-type = "power-embedded"; |
58 | }; | 59 | }; |
59 | }; | 60 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/e6500_power_isa.dtsi b/arch/powerpc/boot/dts/fsl/e6500_power_isa.dtsi new file mode 100644 index 000000000000..a912dbeff359 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/e6500_power_isa.dtsi | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * e6500 Power ISA Device Tree Source (include) | ||
3 | * | ||
4 | * Copyright 2013 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 | / { | ||
36 | cpus { | ||
37 | power-isa-version = "2.06"; | ||
38 | power-isa-b; // Base | ||
39 | power-isa-e; // Embedded | ||
40 | power-isa-atb; // Alternate Time Base | ||
41 | power-isa-cs; // Cache Specification | ||
42 | power-isa-ds; // Decorated Storage | ||
43 | power-isa-e.ed; // Embedded.Enhanced Debug | ||
44 | power-isa-e.pd; // Embedded.External PID | ||
45 | power-isa-e.hv; // Embedded.Hypervisor | ||
46 | power-isa-e.le; // Embedded.Little-Endian | ||
47 | power-isa-e.pm; // Embedded.Performance Monitor | ||
48 | power-isa-e.pc; // Embedded.Processor Control | ||
49 | power-isa-ecl; // Embedded Cache Locking | ||
50 | power-isa-exp; // External Proxy | ||
51 | power-isa-fp; // Floating Point | ||
52 | power-isa-fp.r; // Floating Point.Record | ||
53 | power-isa-mmc; // Memory Coherence | ||
54 | power-isa-scpm; // Store Conditional Page Mobility | ||
55 | power-isa-wt; // Wait | ||
56 | power-isa-64; // 64-bit | ||
57 | power-isa-e.pt; // Embedded.Page Table | ||
58 | power-isa-e.hv.lrat; // Embedded.Hypervisor.LRAT | ||
59 | power-isa-e.em; // Embedded Multi-Threading | ||
60 | power-isa-v; // Vector (AltiVec) | ||
61 | fsl,eref-er; // Enhanced Reservations (Load and Reserve and Store Cond.) | ||
62 | fsl,eref-deo; // Data Cache Extended Operations | ||
63 | mmu-type = "power-embedded"; | ||
64 | }; | ||
65 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/p1023si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1023si-post.dtsi index 941fa159cefb..f1105bffa915 100644 --- a/arch/powerpc/boot/dts/fsl/p1023si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1023si-post.dtsi | |||
@@ -148,6 +148,7 @@ | |||
148 | 148 | ||
149 | crypto: crypto@300000 { | 149 | crypto: crypto@300000 { |
150 | compatible = "fsl,sec-v4.2", "fsl,sec-v4.0"; | 150 | compatible = "fsl,sec-v4.2", "fsl,sec-v4.0"; |
151 | fsl,sec-era = <3>; | ||
151 | #address-cells = <1>; | 152 | #address-cells = <1>; |
152 | #size-cells = <1>; | 153 | #size-cells = <1>; |
153 | reg = <0x30000 0x10000>; | 154 | reg = <0x30000 0x10000>; |
diff --git a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi index 69ac1acd4349..dc6cc5afd189 100644 --- a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi | |||
@@ -155,7 +155,7 @@ | |||
155 | compatible = "fsl,dcsr", "simple-bus"; | 155 | compatible = "fsl,dcsr", "simple-bus"; |
156 | 156 | ||
157 | dcsr-epu@0 { | 157 | dcsr-epu@0 { |
158 | compatible = "fsl,dcsr-epu"; | 158 | compatible = "fsl,p2041-dcsr-epu", "fsl,dcsr-epu"; |
159 | interrupts = <52 2 0 0 | 159 | interrupts = <52 2 0 0 |
160 | 84 2 0 0 | 160 | 84 2 0 0 |
161 | 85 2 0 0>; | 161 | 85 2 0 0>; |
diff --git a/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi index 9b5a81a4529c..3fa1e22d544a 100644 --- a/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi | |||
@@ -182,7 +182,7 @@ | |||
182 | compatible = "fsl,dcsr", "simple-bus"; | 182 | compatible = "fsl,dcsr", "simple-bus"; |
183 | 183 | ||
184 | dcsr-epu@0 { | 184 | dcsr-epu@0 { |
185 | compatible = "fsl,dcsr-epu"; | 185 | compatible = "fsl,p3041-dcsr-epu", "fsl,dcsr-epu"; |
186 | interrupts = <52 2 0 0 | 186 | interrupts = <52 2 0 0 |
187 | 84 2 0 0 | 187 | 84 2 0 0 |
188 | 85 2 0 0>; | 188 | 85 2 0 0>; |
diff --git a/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi b/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi index 19859ad851eb..34769a7eafea 100644 --- a/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi | |||
@@ -156,7 +156,7 @@ | |||
156 | compatible = "fsl,dcsr", "simple-bus"; | 156 | compatible = "fsl,dcsr", "simple-bus"; |
157 | 157 | ||
158 | dcsr-epu@0 { | 158 | dcsr-epu@0 { |
159 | compatible = "fsl,dcsr-epu"; | 159 | compatible = "fsl,p4080-dcsr-epu", "fsl,dcsr-epu"; |
160 | interrupts = <52 2 0 0 | 160 | interrupts = <52 2 0 0 |
161 | 84 2 0 0 | 161 | 84 2 0 0 |
162 | 85 2 0 0>; | 162 | 85 2 0 0>; |
diff --git a/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi index 9ea77c3513f6..bc3ae5a2252f 100644 --- a/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi | |||
@@ -184,7 +184,7 @@ | |||
184 | compatible = "fsl,dcsr", "simple-bus"; | 184 | compatible = "fsl,dcsr", "simple-bus"; |
185 | 185 | ||
186 | dcsr-epu@0 { | 186 | dcsr-epu@0 { |
187 | compatible = "fsl,dcsr-epu"; | 187 | compatible = "fsl,p5020-dcsr-epu", "fsl,dcsr-epu"; |
188 | interrupts = <52 2 0 0 | 188 | interrupts = <52 2 0 0 |
189 | 84 2 0 0 | 189 | 84 2 0 0 |
190 | 85 2 0 0>; | 190 | 85 2 0 0>; |
diff --git a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi index 97f8c26f9709..a91897f6af09 100644 --- a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi | |||
@@ -129,7 +129,7 @@ | |||
129 | compatible = "fsl,dcsr", "simple-bus"; | 129 | compatible = "fsl,dcsr", "simple-bus"; |
130 | 130 | ||
131 | dcsr-epu@0 { | 131 | dcsr-epu@0 { |
132 | compatible = "fsl,dcsr-epu"; | 132 | compatible = "fsl,p5040-dcsr-epu", "fsl,dcsr-epu"; |
133 | interrupts = <52 2 0 0 | 133 | interrupts = <52 2 0 0 |
134 | 84 2 0 0 | 134 | 84 2 0 0 |
135 | 85 2 0 0>; | 135 | 85 2 0 0>; |
diff --git a/arch/powerpc/boot/dts/fsl/pq3-sec4.4-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-sec4.4-0.dtsi index ffadcb563ada..bb3d8266b5ce 100644 --- a/arch/powerpc/boot/dts/fsl/pq3-sec4.4-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/pq3-sec4.4-0.dtsi | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | crypto@30000 { | 35 | crypto@30000 { |
36 | compatible = "fsl,sec-v4.4", "fsl,sec-v4.0"; | 36 | compatible = "fsl,sec-v4.4", "fsl,sec-v4.0"; |
37 | fsl,sec-era = <3>; | ||
37 | #address-cells = <1>; | 38 | #address-cells = <1>; |
38 | #size-cells = <1>; | 39 | #size-cells = <1>; |
39 | ranges = <0x0 0x30000 0x10000>; | 40 | ranges = <0x0 0x30000 0x10000>; |
diff --git a/arch/powerpc/boot/dts/fsl/qonverge-usb2-dr-0.dtsi b/arch/powerpc/boot/dts/fsl/qonverge-usb2-dr-0.dtsi new file mode 100644 index 000000000000..29dad723091e --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/qonverge-usb2-dr-0.dtsi | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * QorIQ Qonverge USB Host device tree stub [ controller @ offset 0x210000 ] | ||
3 | * | ||
4 | * Copyright 2013 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 | usb@210000 { | ||
36 | compatible = "fsl-usb2-dr"; | ||
37 | reg = <0x210000 0x1000>; | ||
38 | #address-cells = <1>; | ||
39 | #size-cells = <0>; | ||
40 | interrupts = <44 0x2 0 0>; | ||
41 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-gpio-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-gpio-1.dtsi new file mode 100644 index 000000000000..c2f9cdadb604 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/qoriq-gpio-1.dtsi | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * QorIQ GPIO device tree stub [ controller @ offset 0x131000 ] | ||
3 | * | ||
4 | * Copyright 2013 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 | gpio1: gpio@131000 { | ||
36 | compatible = "fsl,qoriq-gpio"; | ||
37 | reg = <0x131000 0x1000>; | ||
38 | interrupts = <54 2 0 0>; | ||
39 | #gpio-cells = <2>; | ||
40 | gpio-controller; | ||
41 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-gpio-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-gpio-2.dtsi new file mode 100644 index 000000000000..33f3ccbac83f --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/qoriq-gpio-2.dtsi | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * QorIQ GPIO device tree stub [ controller @ offset 0x132000 ] | ||
3 | * | ||
4 | * Copyright 2013 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 | gpio2: gpio@132000 { | ||
36 | compatible = "fsl,qoriq-gpio"; | ||
37 | reg = <0x132000 0x1000>; | ||
38 | interrupts = <86 2 0 0>; | ||
39 | #gpio-cells = <2>; | ||
40 | gpio-controller; | ||
41 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-gpio-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-gpio-3.dtsi new file mode 100644 index 000000000000..86954e95ea02 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/qoriq-gpio-3.dtsi | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * QorIQ GPIO device tree stub [ controller @ offset 0x133000 ] | ||
3 | * | ||
4 | * Copyright 2013 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 | gpio3: gpio@133000 { | ||
36 | compatible = "fsl,qoriq-gpio"; | ||
37 | reg = <0x133000 0x1000>; | ||
38 | interrupts = <87 2 0 0>; | ||
39 | #gpio-cells = <2>; | ||
40 | gpio-controller; | ||
41 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-sec4.0-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-sec4.0-0.dtsi index 0cbbac329539..02bee5fcbb9a 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-sec4.0-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-sec4.0-0.dtsi | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | crypto: crypto@300000 { | 35 | crypto: crypto@300000 { |
36 | compatible = "fsl,sec-v4.0"; | 36 | compatible = "fsl,sec-v4.0"; |
37 | fsl,sec-era = <1>; | ||
37 | #address-cells = <1>; | 38 | #address-cells = <1>; |
38 | #size-cells = <1>; | 39 | #size-cells = <1>; |
39 | reg = <0x300000 0x10000>; | 40 | reg = <0x300000 0x10000>; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-sec4.2-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-sec4.2-0.dtsi index 7990e0d3d6f2..7f7574e53323 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-sec4.2-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-sec4.2-0.dtsi | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | crypto: crypto@300000 { | 35 | crypto: crypto@300000 { |
36 | compatible = "fsl,sec-v4.2", "fsl,sec-v4.0"; | 36 | compatible = "fsl,sec-v4.2", "fsl,sec-v4.0"; |
37 | fsl,sec-era = <3>; | ||
37 | #address-cells = <1>; | 38 | #address-cells = <1>; |
38 | #size-cells = <1>; | 39 | #size-cells = <1>; |
39 | reg = <0x300000 0x10000>; | 40 | reg = <0x300000 0x10000>; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-sec4.1-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-sec5.0-0.dtsi index 3308986bba0d..e298efbb0f3e 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-sec4.1-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-sec5.0-0.dtsi | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * QorIQ Sec/Crypto 4.1 device tree stub [ controller @ offset 0x300000 ] | 2 | * QorIQ Sec/Crypto 5.0 device tree stub [ controller @ offset 0x300000 ] |
3 | * | 3 | * |
4 | * Copyright 2011 Freescale Semiconductor Inc. | 4 | * Copyright 2012 Freescale Semiconductor Inc. |
5 | * | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions are met: | 7 | * modification, are permitted provided that the following conditions are met: |
@@ -33,7 +33,8 @@ | |||
33 | */ | 33 | */ |
34 | 34 | ||
35 | crypto: crypto@300000 { | 35 | crypto: crypto@300000 { |
36 | compatible = "fsl,sec-v4.1", "fsl,sec-v4.0"; | 36 | compatible = "fsl,sec-v5.0", "fsl,sec-v4.0"; |
37 | fsl,sec-era = <5>; | ||
37 | #address-cells = <1>; | 38 | #address-cells = <1>; |
38 | #size-cells = <1>; | 39 | #size-cells = <1>; |
39 | reg = <0x300000 0x10000>; | 40 | reg = <0x300000 0x10000>; |
@@ -41,35 +42,35 @@ crypto: crypto@300000 { | |||
41 | interrupts = <92 2 0 0>; | 42 | interrupts = <92 2 0 0>; |
42 | 43 | ||
43 | sec_jr0: jr@1000 { | 44 | sec_jr0: jr@1000 { |
44 | compatible = "fsl,sec-v4.1-job-ring", | 45 | compatible = "fsl,sec-v5.0-job-ring", |
45 | "fsl,sec-v4.0-job-ring"; | 46 | "fsl,sec-v4.0-job-ring"; |
46 | reg = <0x1000 0x1000>; | 47 | reg = <0x1000 0x1000>; |
47 | interrupts = <88 2 0 0>; | 48 | interrupts = <88 2 0 0>; |
48 | }; | 49 | }; |
49 | 50 | ||
50 | sec_jr1: jr@2000 { | 51 | sec_jr1: jr@2000 { |
51 | compatible = "fsl,sec-v4.1-job-ring", | 52 | compatible = "fsl,sec-v5.0-job-ring", |
52 | "fsl,sec-v4.0-job-ring"; | 53 | "fsl,sec-v4.0-job-ring"; |
53 | reg = <0x2000 0x1000>; | 54 | reg = <0x2000 0x1000>; |
54 | interrupts = <89 2 0 0>; | 55 | interrupts = <89 2 0 0>; |
55 | }; | 56 | }; |
56 | 57 | ||
57 | sec_jr2: jr@3000 { | 58 | sec_jr2: jr@3000 { |
58 | compatible = "fsl,sec-v4.1-job-ring", | 59 | compatible = "fsl,sec-v5.0-job-ring", |
59 | "fsl,sec-v4.0-job-ring"; | 60 | "fsl,sec-v4.0-job-ring"; |
60 | reg = <0x3000 0x1000>; | 61 | reg = <0x3000 0x1000>; |
61 | interrupts = <90 2 0 0>; | 62 | interrupts = <90 2 0 0>; |
62 | }; | 63 | }; |
63 | 64 | ||
64 | sec_jr3: jr@4000 { | 65 | sec_jr3: jr@4000 { |
65 | compatible = "fsl,sec-v4.1-job-ring", | 66 | compatible = "fsl,sec-v5.0-job-ring", |
66 | "fsl,sec-v4.0-job-ring"; | 67 | "fsl,sec-v4.0-job-ring"; |
67 | reg = <0x4000 0x1000>; | 68 | reg = <0x4000 0x1000>; |
68 | interrupts = <91 2 0 0>; | 69 | interrupts = <91 2 0 0>; |
69 | }; | 70 | }; |
70 | 71 | ||
71 | rtic@6000 { | 72 | rtic@6000 { |
72 | compatible = "fsl,sec-v4.1-rtic", | 73 | compatible = "fsl,sec-v5.0-rtic", |
73 | "fsl,sec-v4.0-rtic"; | 74 | "fsl,sec-v4.0-rtic"; |
74 | #address-cells = <1>; | 75 | #address-cells = <1>; |
75 | #size-cells = <1>; | 76 | #size-cells = <1>; |
@@ -77,25 +78,25 @@ crypto: crypto@300000 { | |||
77 | ranges = <0x0 0x6100 0xe00>; | 78 | ranges = <0x0 0x6100 0xe00>; |
78 | 79 | ||
79 | rtic_a: rtic-a@0 { | 80 | rtic_a: rtic-a@0 { |
80 | compatible = "fsl,sec-v4.1-rtic-memory", | 81 | compatible = "fsl,sec-v5.0-rtic-memory", |
81 | "fsl,sec-v4.0-rtic-memory"; | 82 | "fsl,sec-v4.0-rtic-memory"; |
82 | reg = <0x00 0x20 0x100 0x80>; | 83 | reg = <0x00 0x20 0x100 0x80>; |
83 | }; | 84 | }; |
84 | 85 | ||
85 | rtic_b: rtic-b@20 { | 86 | rtic_b: rtic-b@20 { |
86 | compatible = "fsl,sec-v4.1-rtic-memory", | 87 | compatible = "fsl,sec-v5.0-rtic-memory", |
87 | "fsl,sec-v4.0-rtic-memory"; | 88 | "fsl,sec-v4.0-rtic-memory"; |
88 | reg = <0x20 0x20 0x200 0x80>; | 89 | reg = <0x20 0x20 0x200 0x80>; |
89 | }; | 90 | }; |
90 | 91 | ||
91 | rtic_c: rtic-c@40 { | 92 | rtic_c: rtic-c@40 { |
92 | compatible = "fsl,sec-v4.1-rtic-memory", | 93 | compatible = "fsl,sec-v5.0-rtic-memory", |
93 | "fsl,sec-v4.0-rtic-memory"; | 94 | "fsl,sec-v4.0-rtic-memory"; |
94 | reg = <0x40 0x20 0x300 0x80>; | 95 | reg = <0x40 0x20 0x300 0x80>; |
95 | }; | 96 | }; |
96 | 97 | ||
97 | rtic_d: rtic-d@60 { | 98 | rtic_d: rtic-d@60 { |
98 | compatible = "fsl,sec-v4.1-rtic-memory", | 99 | compatible = "fsl,sec-v5.0-rtic-memory", |
99 | "fsl,sec-v4.0-rtic-memory"; | 100 | "fsl,sec-v4.0-rtic-memory"; |
100 | reg = <0x60 0x20 0x500 0x80>; | 101 | reg = <0x60 0x20 0x500 0x80>; |
101 | }; | 102 | }; |
@@ -103,7 +104,7 @@ crypto: crypto@300000 { | |||
103 | }; | 104 | }; |
104 | 105 | ||
105 | sec_mon: sec_mon@314000 { | 106 | sec_mon: sec_mon@314000 { |
106 | compatible = "fsl,sec-v4.1-mon", "fsl,sec-v4.0-mon"; | 107 | compatible = "fsl,sec-v5.0-mon", "fsl,sec-v4.0-mon"; |
107 | reg = <0x314000 0x1000>; | 108 | reg = <0x314000 0x1000>; |
108 | interrupts = <93 2 0 0>; | 109 | interrupts = <93 2 0 0>; |
109 | }; | 110 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi index 7b2ab8a8c1f4..33ff09d52e05 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | crypto: crypto@300000 { | 35 | crypto: crypto@300000 { |
36 | compatible = "fsl,sec-v5.2", "fsl,sec-v5.0", "fsl,sec-v4.0"; | 36 | compatible = "fsl,sec-v5.2", "fsl,sec-v5.0", "fsl,sec-v4.0"; |
37 | fsl,sec-era = <5>; | ||
37 | #address-cells = <1>; | 38 | #address-cells = <1>; |
38 | #size-cells = <1>; | 39 | #size-cells = <1>; |
39 | reg = <0x300000 0x10000>; | 40 | reg = <0x300000 0x10000>; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-sec5.3-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-sec5.3-0.dtsi new file mode 100644 index 000000000000..08778221c194 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/qoriq-sec5.3-0.dtsi | |||
@@ -0,0 +1,119 @@ | |||
1 | /* | ||
2 | * QorIQ Sec/Crypto 5.3 device tree stub [ controller @ offset 0x300000 ] | ||
3 | * | ||
4 | * Copyright 2012 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 | crypto: crypto@300000 { | ||
36 | compatible = "fsl,sec-v5.3", "fsl,sec-v5.0", "fsl,sec-v4.0"; | ||
37 | fsl,sec-era = <4>; | ||
38 | #address-cells = <1>; | ||
39 | #size-cells = <1>; | ||
40 | reg = <0x300000 0x10000>; | ||
41 | ranges = <0 0x300000 0x10000>; | ||
42 | interrupts = <92 2 0 0>; | ||
43 | |||
44 | sec_jr0: jr@1000 { | ||
45 | compatible = "fsl,sec-v5.3-job-ring", | ||
46 | "fsl,sec-v5.0-job-ring", | ||
47 | "fsl,sec-v4.0-job-ring"; | ||
48 | reg = <0x1000 0x1000>; | ||
49 | interrupts = <88 2 0 0>; | ||
50 | }; | ||
51 | |||
52 | sec_jr1: jr@2000 { | ||
53 | compatible = "fsl,sec-v5.3-job-ring", | ||
54 | "fsl,sec-v5.0-job-ring", | ||
55 | "fsl,sec-v4.0-job-ring"; | ||
56 | reg = <0x2000 0x1000>; | ||
57 | interrupts = <89 2 0 0>; | ||
58 | }; | ||
59 | |||
60 | sec_jr2: jr@3000 { | ||
61 | compatible = "fsl,sec-v5.3-job-ring", | ||
62 | "fsl,sec-v5.0-job-ring", | ||
63 | "fsl,sec-v4.0-job-ring"; | ||
64 | reg = <0x3000 0x1000>; | ||
65 | interrupts = <90 2 0 0>; | ||
66 | }; | ||
67 | |||
68 | sec_jr3: jr@4000 { | ||
69 | compatible = "fsl,sec-v5.3-job-ring", | ||
70 | "fsl,sec-v5.0-job-ring", | ||
71 | "fsl,sec-v4.0-job-ring"; | ||
72 | reg = <0x4000 0x1000>; | ||
73 | interrupts = <91 2 0 0>; | ||
74 | }; | ||
75 | |||
76 | rtic@6000 { | ||
77 | compatible = "fsl,sec-v5.3-rtic", | ||
78 | "fsl,sec-v5.0-rtic", | ||
79 | "fsl,sec-v4.0-rtic"; | ||
80 | #address-cells = <1>; | ||
81 | #size-cells = <1>; | ||
82 | reg = <0x6000 0x100>; | ||
83 | ranges = <0x0 0x6100 0xe00>; | ||
84 | |||
85 | rtic_a: rtic-a@0 { | ||
86 | compatible = "fsl,sec-v5.3-rtic-memory", | ||
87 | "fsl,sec-v5.0-rtic-memory", | ||
88 | "fsl,sec-v4.0-rtic-memory"; | ||
89 | reg = <0x00 0x20 0x100 0x80>; | ||
90 | }; | ||
91 | |||
92 | rtic_b: rtic-b@20 { | ||
93 | compatible = "fsl,sec-v5.3-rtic-memory", | ||
94 | "fsl,sec-v5.0-rtic-memory", | ||
95 | "fsl,sec-v4.0-rtic-memory"; | ||
96 | reg = <0x20 0x20 0x200 0x80>; | ||
97 | }; | ||
98 | |||
99 | rtic_c: rtic-c@40 { | ||
100 | compatible = "fsl,sec-v5.3-rtic-memory", | ||
101 | "fsl,sec-v5.0-rtic-memory", | ||
102 | "fsl,sec-v4.0-rtic-memory"; | ||
103 | reg = <0x40 0x20 0x300 0x80>; | ||
104 | }; | ||
105 | |||
106 | rtic_d: rtic-d@60 { | ||
107 | compatible = "fsl,sec-v5.3-rtic-memory", | ||
108 | "fsl,sec-v5.0-rtic-memory", | ||
109 | "fsl,sec-v4.0-rtic-memory"; | ||
110 | reg = <0x60 0x20 0x500 0x80>; | ||
111 | }; | ||
112 | }; | ||
113 | }; | ||
114 | |||
115 | sec_mon: sec_mon@314000 { | ||
116 | compatible = "fsl,sec-v5.3-mon", "fsl,sec-v5.0-mon", "fsl,sec-v4.0-mon"; | ||
117 | reg = <0x314000 0x1000>; | ||
118 | interrupts = <93 2 0 0>; | ||
119 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi new file mode 100644 index 000000000000..bd611a9cad32 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi | |||
@@ -0,0 +1,442 @@ | |||
1 | /* | ||
2 | * T4240 Silicon/SoC Device Tree Source (post include) | ||
3 | * | ||
4 | * Copyright 2012 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 | &ifc { | ||
36 | #address-cells = <2>; | ||
37 | #size-cells = <1>; | ||
38 | compatible = "fsl,ifc", "simple-bus"; | ||
39 | interrupts = <25 2 0 0>; | ||
40 | }; | ||
41 | |||
42 | /* controller at 0x240000 */ | ||
43 | &pci0 { | ||
44 | compatible = "fsl,t4240-pcie", "fsl,qoriq-pcie-v3.0"; | ||
45 | device_type = "pci"; | ||
46 | #size-cells = <2>; | ||
47 | #address-cells = <3>; | ||
48 | bus-range = <0x0 0xff>; | ||
49 | interrupts = <20 2 0 0>; | ||
50 | pcie@0 { | ||
51 | #interrupt-cells = <1>; | ||
52 | #size-cells = <2>; | ||
53 | #address-cells = <3>; | ||
54 | device_type = "pci"; | ||
55 | reg = <0 0 0 0 0>; | ||
56 | interrupts = <20 2 0 0>; | ||
57 | interrupt-map-mask = <0xf800 0 0 7>; | ||
58 | interrupt-map = < | ||
59 | /* IDSEL 0x0 */ | ||
60 | 0000 0 0 1 &mpic 40 1 0 0 | ||
61 | 0000 0 0 2 &mpic 1 1 0 0 | ||
62 | 0000 0 0 3 &mpic 2 1 0 0 | ||
63 | 0000 0 0 4 &mpic 3 1 0 0 | ||
64 | >; | ||
65 | }; | ||
66 | }; | ||
67 | |||
68 | /* controller at 0x250000 */ | ||
69 | &pci1 { | ||
70 | compatible = "fsl,t4240-pcie", "fsl,qoriq-pcie-v3.0"; | ||
71 | device_type = "pci"; | ||
72 | #size-cells = <2>; | ||
73 | #address-cells = <3>; | ||
74 | bus-range = <0 0xff>; | ||
75 | interrupts = <21 2 0 0>; | ||
76 | pcie@0 { | ||
77 | #interrupt-cells = <1>; | ||
78 | #size-cells = <2>; | ||
79 | #address-cells = <3>; | ||
80 | device_type = "pci"; | ||
81 | reg = <0 0 0 0 0>; | ||
82 | interrupts = <21 2 0 0>; | ||
83 | interrupt-map-mask = <0xf800 0 0 7>; | ||
84 | interrupt-map = < | ||
85 | /* IDSEL 0x0 */ | ||
86 | 0000 0 0 1 &mpic 41 1 0 0 | ||
87 | 0000 0 0 2 &mpic 5 1 0 0 | ||
88 | 0000 0 0 3 &mpic 6 1 0 0 | ||
89 | 0000 0 0 4 &mpic 7 1 0 0 | ||
90 | >; | ||
91 | }; | ||
92 | }; | ||
93 | |||
94 | /* controller at 0x260000 */ | ||
95 | &pci2 { | ||
96 | compatible = "fsl,t4240-pcie", "fsl,qoriq-pcie-v3.0"; | ||
97 | device_type = "pci"; | ||
98 | #size-cells = <2>; | ||
99 | #address-cells = <3>; | ||
100 | bus-range = <0x0 0xff>; | ||
101 | interrupts = <22 2 0 0>; | ||
102 | pcie@0 { | ||
103 | #interrupt-cells = <1>; | ||
104 | #size-cells = <2>; | ||
105 | #address-cells = <3>; | ||
106 | device_type = "pci"; | ||
107 | reg = <0 0 0 0 0>; | ||
108 | interrupts = <22 2 0 0>; | ||
109 | interrupt-map-mask = <0xf800 0 0 7>; | ||
110 | interrupt-map = < | ||
111 | /* IDSEL 0x0 */ | ||
112 | 0000 0 0 1 &mpic 42 1 0 0 | ||
113 | 0000 0 0 2 &mpic 9 1 0 0 | ||
114 | 0000 0 0 3 &mpic 10 1 0 0 | ||
115 | 0000 0 0 4 &mpic 11 1 0 0 | ||
116 | >; | ||
117 | }; | ||
118 | }; | ||
119 | |||
120 | /* controller at 0x270000 */ | ||
121 | &pci3 { | ||
122 | compatible = "fsl,t4240-pcie", "fsl,qoriq-pcie-v3.0"; | ||
123 | device_type = "pci"; | ||
124 | #size-cells = <2>; | ||
125 | #address-cells = <3>; | ||
126 | bus-range = <0x0 0xff>; | ||
127 | interrupts = <23 2 0 0>; | ||
128 | pcie@0 { | ||
129 | #interrupt-cells = <1>; | ||
130 | #size-cells = <2>; | ||
131 | #address-cells = <3>; | ||
132 | device_type = "pci"; | ||
133 | reg = <0 0 0 0 0>; | ||
134 | interrupts = <23 2 0 0>; | ||
135 | interrupt-map-mask = <0xf800 0 0 7>; | ||
136 | interrupt-map = < | ||
137 | /* IDSEL 0x0 */ | ||
138 | 0000 0 0 1 &mpic 43 1 0 0 | ||
139 | 0000 0 0 2 &mpic 0 1 0 0 | ||
140 | 0000 0 0 3 &mpic 4 1 0 0 | ||
141 | 0000 0 0 4 &mpic 8 1 0 0 | ||
142 | >; | ||
143 | }; | ||
144 | }; | ||
145 | |||
146 | &rio { | ||
147 | compatible = "fsl,srio"; | ||
148 | interrupts = <16 2 1 11>; | ||
149 | #address-cells = <2>; | ||
150 | #size-cells = <2>; | ||
151 | ranges; | ||
152 | |||
153 | port1 { | ||
154 | #address-cells = <2>; | ||
155 | #size-cells = <2>; | ||
156 | cell-index = <1>; | ||
157 | }; | ||
158 | |||
159 | port2 { | ||
160 | #address-cells = <2>; | ||
161 | #size-cells = <2>; | ||
162 | cell-index = <2>; | ||
163 | }; | ||
164 | }; | ||
165 | |||
166 | &dcsr { | ||
167 | #address-cells = <1>; | ||
168 | #size-cells = <1>; | ||
169 | compatible = "fsl,dcsr", "simple-bus"; | ||
170 | |||
171 | dcsr-epu@0 { | ||
172 | compatible = "fsl,t4240-dcsr-epu", "fsl,dcsr-epu"; | ||
173 | interrupts = <52 2 0 0 | ||
174 | 84 2 0 0 | ||
175 | 85 2 0 0 | ||
176 | 94 2 0 0 | ||
177 | 95 2 0 0>; | ||
178 | reg = <0x0 0x1000>; | ||
179 | }; | ||
180 | dcsr-npc { | ||
181 | compatible = "fsl,t4240-dcsr-cnpc", "fsl,dcsr-cnpc"; | ||
182 | reg = <0x1000 0x1000 0x1002000 0x10000>; | ||
183 | }; | ||
184 | dcsr-nxc@2000 { | ||
185 | compatible = "fsl,dcsr-nxc"; | ||
186 | reg = <0x2000 0x1000>; | ||
187 | }; | ||
188 | dcsr-corenet { | ||
189 | compatible = "fsl,dcsr-corenet"; | ||
190 | reg = <0x8000 0x1000 0x1A000 0x1000>; | ||
191 | }; | ||
192 | dcsr-dpaa@9000 { | ||
193 | compatible = "fsl,t4240-dcsr-dpaa", "fsl,dcsr-dpaa"; | ||
194 | reg = <0x9000 0x1000>; | ||
195 | }; | ||
196 | dcsr-ocn@11000 { | ||
197 | compatible = "fsl,t4240-dcsr-ocn", "fsl,dcsr-ocn"; | ||
198 | reg = <0x11000 0x1000>; | ||
199 | }; | ||
200 | dcsr-ddr@12000 { | ||
201 | compatible = "fsl,dcsr-ddr"; | ||
202 | dev-handle = <&ddr1>; | ||
203 | reg = <0x12000 0x1000>; | ||
204 | }; | ||
205 | dcsr-ddr@13000 { | ||
206 | compatible = "fsl,dcsr-ddr"; | ||
207 | dev-handle = <&ddr2>; | ||
208 | reg = <0x13000 0x1000>; | ||
209 | }; | ||
210 | dcsr-ddr@14000 { | ||
211 | compatible = "fsl,dcsr-ddr"; | ||
212 | dev-handle = <&ddr3>; | ||
213 | reg = <0x14000 0x1000>; | ||
214 | }; | ||
215 | dcsr-nal@18000 { | ||
216 | compatible = "fsl,t4240-dcsr-nal", "fsl,dcsr-nal"; | ||
217 | reg = <0x18000 0x1000>; | ||
218 | }; | ||
219 | dcsr-rcpm@22000 { | ||
220 | compatible = "fsl,t4240-dcsr-rcpm", "fsl,dcsr-rcpm"; | ||
221 | reg = <0x22000 0x1000>; | ||
222 | }; | ||
223 | dcsr-snpc@30000 { | ||
224 | compatible = "fsl,t4240-dcsr-snpc", "fsl,dcsr-snpc"; | ||
225 | reg = <0x30000 0x1000 0x1022000 0x10000>; | ||
226 | }; | ||
227 | dcsr-snpc@31000 { | ||
228 | compatible = "fsl,t4240-dcsr-snpc", "fsl,dcsr-snpc"; | ||
229 | reg = <0x31000 0x1000 0x1042000 0x10000>; | ||
230 | }; | ||
231 | dcsr-snpc@32000 { | ||
232 | compatible = "fsl,t4240-dcsr-snpc", "fsl,dcsr-snpc"; | ||
233 | reg = <0x32000 0x1000 0x1062000 0x10000>; | ||
234 | }; | ||
235 | dcsr-cpu-sb-proxy@100000 { | ||
236 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
237 | cpu-handle = <&cpu0>; | ||
238 | reg = <0x100000 0x1000 0x101000 0x1000>; | ||
239 | }; | ||
240 | dcsr-cpu-sb-proxy@108000 { | ||
241 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
242 | cpu-handle = <&cpu1>; | ||
243 | reg = <0x108000 0x1000 0x109000 0x1000>; | ||
244 | }; | ||
245 | dcsr-cpu-sb-proxy@110000 { | ||
246 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
247 | cpu-handle = <&cpu2>; | ||
248 | reg = <0x110000 0x1000 0x111000 0x1000>; | ||
249 | }; | ||
250 | dcsr-cpu-sb-proxy@118000 { | ||
251 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
252 | cpu-handle = <&cpu3>; | ||
253 | reg = <0x118000 0x1000 0x119000 0x1000>; | ||
254 | }; | ||
255 | dcsr-cpu-sb-proxy@120000 { | ||
256 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
257 | cpu-handle = <&cpu4>; | ||
258 | reg = <0x120000 0x1000 0x121000 0x1000>; | ||
259 | }; | ||
260 | dcsr-cpu-sb-proxy@128000 { | ||
261 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
262 | cpu-handle = <&cpu5>; | ||
263 | reg = <0x128000 0x1000 0x129000 0x1000>; | ||
264 | }; | ||
265 | dcsr-cpu-sb-proxy@130000 { | ||
266 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
267 | cpu-handle = <&cpu6>; | ||
268 | reg = <0x130000 0x1000 0x131000 0x1000>; | ||
269 | }; | ||
270 | dcsr-cpu-sb-proxy@138000 { | ||
271 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
272 | cpu-handle = <&cpu7>; | ||
273 | reg = <0x138000 0x1000 0x139000 0x1000>; | ||
274 | }; | ||
275 | dcsr-cpu-sb-proxy@140000 { | ||
276 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
277 | cpu-handle = <&cpu8>; | ||
278 | reg = <0x140000 0x1000 0x141000 0x1000>; | ||
279 | }; | ||
280 | dcsr-cpu-sb-proxy@148000 { | ||
281 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
282 | cpu-handle = <&cpu9>; | ||
283 | reg = <0x148000 0x1000 0x149000 0x1000>; | ||
284 | }; | ||
285 | dcsr-cpu-sb-proxy@150000 { | ||
286 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
287 | cpu-handle = <&cpu10>; | ||
288 | reg = <0x150000 0x1000 0x151000 0x1000>; | ||
289 | }; | ||
290 | dcsr-cpu-sb-proxy@158000 { | ||
291 | compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
292 | cpu-handle = <&cpu11>; | ||
293 | reg = <0x158000 0x1000 0x159000 0x1000>; | ||
294 | }; | ||
295 | }; | ||
296 | |||
297 | &soc { | ||
298 | #address-cells = <1>; | ||
299 | #size-cells = <1>; | ||
300 | device_type = "soc"; | ||
301 | compatible = "simple-bus"; | ||
302 | |||
303 | soc-sram-error { | ||
304 | compatible = "fsl,soc-sram-error"; | ||
305 | interrupts = <16 2 1 29>; | ||
306 | }; | ||
307 | |||
308 | corenet-law@0 { | ||
309 | compatible = "fsl,corenet-law"; | ||
310 | reg = <0x0 0x1000>; | ||
311 | fsl,num-laws = <32>; | ||
312 | }; | ||
313 | |||
314 | ddr1: memory-controller@8000 { | ||
315 | compatible = "fsl,qoriq-memory-controller-v4.7", | ||
316 | "fsl,qoriq-memory-controller"; | ||
317 | reg = <0x8000 0x1000>; | ||
318 | interrupts = <16 2 1 23>; | ||
319 | }; | ||
320 | |||
321 | ddr2: memory-controller@9000 { | ||
322 | compatible = "fsl,qoriq-memory-controller-v4.7", | ||
323 | "fsl,qoriq-memory-controller"; | ||
324 | reg = <0x9000 0x1000>; | ||
325 | interrupts = <16 2 1 22>; | ||
326 | }; | ||
327 | |||
328 | ddr3: memory-controller@a000 { | ||
329 | compatible = "fsl,qoriq-memory-controller-v4.7", | ||
330 | "fsl,qoriq-memory-controller"; | ||
331 | reg = <0xa000 0x1000>; | ||
332 | interrupts = <16 2 1 21>; | ||
333 | }; | ||
334 | |||
335 | cpc: l3-cache-controller@10000 { | ||
336 | compatible = "fsl,t4240-l3-cache-controller", "cache"; | ||
337 | reg = <0x10000 0x1000 | ||
338 | 0x11000 0x1000 | ||
339 | 0x12000 0x1000>; | ||
340 | interrupts = <16 2 1 27 | ||
341 | 16 2 1 26 | ||
342 | 16 2 1 25>; | ||
343 | }; | ||
344 | |||
345 | corenet-cf@18000 { | ||
346 | compatible = "fsl,corenet-cf"; | ||
347 | reg = <0x18000 0x1000>; | ||
348 | interrupts = <16 2 1 31>; | ||
349 | fsl,ccf-num-csdids = <32>; | ||
350 | fsl,ccf-num-snoopids = <32>; | ||
351 | }; | ||
352 | |||
353 | iommu@20000 { | ||
354 | compatible = "fsl,pamu-v1.0", "fsl,pamu"; | ||
355 | reg = <0x20000 0x6000>; | ||
356 | interrupts = < | ||
357 | 24 2 0 0 | ||
358 | 16 2 1 30>; | ||
359 | }; | ||
360 | |||
361 | /include/ "qoriq-mpic.dtsi" | ||
362 | |||
363 | guts: global-utilities@e0000 { | ||
364 | compatible = "fsl,t4240-device-config", "fsl,qoriq-device-config-2.0"; | ||
365 | reg = <0xe0000 0xe00>; | ||
366 | fsl,has-rstcr; | ||
367 | fsl,liodn-bits = <12>; | ||
368 | }; | ||
369 | |||
370 | clockgen: global-utilities@e1000 { | ||
371 | compatible = "fsl,t4240-clockgen", "fsl,qoriq-clockgen-2.0"; | ||
372 | reg = <0xe1000 0x1000>; | ||
373 | }; | ||
374 | |||
375 | rcpm: global-utilities@e2000 { | ||
376 | compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0"; | ||
377 | reg = <0xe2000 0x1000>; | ||
378 | }; | ||
379 | |||
380 | sfp: sfp@e8000 { | ||
381 | compatible = "fsl,t4240-sfp"; | ||
382 | reg = <0xe8000 0x1000>; | ||
383 | }; | ||
384 | |||
385 | serdes: serdes@ea000 { | ||
386 | compatible = "fsl,t4240-serdes"; | ||
387 | reg = <0xea000 0x4000>; | ||
388 | }; | ||
389 | |||
390 | /include/ "qoriq-dma-0.dtsi" | ||
391 | /include/ "qoriq-dma-1.dtsi" | ||
392 | |||
393 | /include/ "qoriq-espi-0.dtsi" | ||
394 | spi@110000 { | ||
395 | fsl,espi-num-chipselects = <4>; | ||
396 | }; | ||
397 | |||
398 | /include/ "qoriq-esdhc-0.dtsi" | ||
399 | sdhc@114000 { | ||
400 | compatible = "fsl,t4240-esdhc", "fsl,esdhc"; | ||
401 | sdhci,auto-cmd12; | ||
402 | }; | ||
403 | /include/ "qoriq-i2c-0.dtsi" | ||
404 | /include/ "qoriq-i2c-1.dtsi" | ||
405 | /include/ "qoriq-duart-0.dtsi" | ||
406 | /include/ "qoriq-duart-1.dtsi" | ||
407 | /include/ "qoriq-gpio-0.dtsi" | ||
408 | /include/ "qoriq-gpio-1.dtsi" | ||
409 | /include/ "qoriq-gpio-2.dtsi" | ||
410 | /include/ "qoriq-gpio-3.dtsi" | ||
411 | /include/ "qoriq-usb2-mph-0.dtsi" | ||
412 | usb0: usb@210000 { | ||
413 | compatible = "fsl-usb2-mph-v2.4", "fsl-usb2-mph"; | ||
414 | phy_type = "utmi"; | ||
415 | port0; | ||
416 | }; | ||
417 | /include/ "qoriq-usb2-dr-0.dtsi" | ||
418 | usb1: usb@211000 { | ||
419 | compatible = "fsl-usb2-dr-v2.4", "fsl-usb2-dr"; | ||
420 | dr_mode = "host"; | ||
421 | phy_type = "utmi"; | ||
422 | }; | ||
423 | /include/ "qoriq-sata2-0.dtsi" | ||
424 | /include/ "qoriq-sata2-1.dtsi" | ||
425 | /include/ "qoriq-sec5.0-0.dtsi" | ||
426 | |||
427 | L2_1: l2-cache-controller@c20000 { | ||
428 | compatible = "fsl,t4240-l2-cache-controller"; | ||
429 | reg = <0xc20000 0x40000>; | ||
430 | next-level-cache = <&cpc>; | ||
431 | }; | ||
432 | L2_2: l2-cache-controller@c60000 { | ||
433 | compatible = "fsl,t4240-l2-cache-controller"; | ||
434 | reg = <0xc60000 0x40000>; | ||
435 | next-level-cache = <&cpc>; | ||
436 | }; | ||
437 | L2_3: l2-cache-controller@ca0000 { | ||
438 | compatible = "fsl,t4240-l2-cache-controller"; | ||
439 | reg = <0xca0000 0x40000>; | ||
440 | next-level-cache = <&cpc>; | ||
441 | }; | ||
442 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi new file mode 100644 index 000000000000..a93c55a88560 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * T4240 Silicon/SoC Device Tree Source (pre include) | ||
3 | * | ||
4 | * Copyright 2012 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 | /include/ "e6500_power_isa.dtsi" | ||
38 | |||
39 | / { | ||
40 | compatible = "fsl,T4240"; | ||
41 | #address-cells = <2>; | ||
42 | #size-cells = <2>; | ||
43 | interrupt-parent = <&mpic>; | ||
44 | |||
45 | aliases { | ||
46 | ccsr = &soc; | ||
47 | dcsr = &dcsr; | ||
48 | |||
49 | serial0 = &serial0; | ||
50 | serial1 = &serial1; | ||
51 | serial2 = &serial2; | ||
52 | serial3 = &serial3; | ||
53 | crypto = &crypto; | ||
54 | pci0 = &pci0; | ||
55 | pci1 = &pci1; | ||
56 | pci2 = &pci2; | ||
57 | pci3 = &pci3; | ||
58 | dma0 = &dma0; | ||
59 | dma1 = &dma1; | ||
60 | sdhc = &sdhc; | ||
61 | }; | ||
62 | |||
63 | cpus { | ||
64 | #address-cells = <1>; | ||
65 | #size-cells = <0>; | ||
66 | |||
67 | cpu0: PowerPC,e6500@0 { | ||
68 | device_type = "cpu"; | ||
69 | reg = <0 1>; | ||
70 | next-level-cache = <&L2_1>; | ||
71 | }; | ||
72 | cpu1: PowerPC,e6500@2 { | ||
73 | device_type = "cpu"; | ||
74 | reg = <2 3>; | ||
75 | next-level-cache = <&L2_1>; | ||
76 | }; | ||
77 | cpu2: PowerPC,e6500@4 { | ||
78 | device_type = "cpu"; | ||
79 | reg = <4 5>; | ||
80 | next-level-cache = <&L2_1>; | ||
81 | }; | ||
82 | cpu3: PowerPC,e6500@6 { | ||
83 | device_type = "cpu"; | ||
84 | reg = <6 7>; | ||
85 | next-level-cache = <&L2_1>; | ||
86 | }; | ||
87 | cpu4: PowerPC,e6500@8 { | ||
88 | device_type = "cpu"; | ||
89 | reg = <8 9>; | ||
90 | next-level-cache = <&L2_2>; | ||
91 | }; | ||
92 | cpu5: PowerPC,e6500@10 { | ||
93 | device_type = "cpu"; | ||
94 | reg = <10 11>; | ||
95 | next-level-cache = <&L2_2>; | ||
96 | }; | ||
97 | cpu6: PowerPC,e6500@12 { | ||
98 | device_type = "cpu"; | ||
99 | reg = <12 13>; | ||
100 | next-level-cache = <&L2_2>; | ||
101 | }; | ||
102 | cpu7: PowerPC,e6500@14 { | ||
103 | device_type = "cpu"; | ||
104 | reg = <14 15>; | ||
105 | next-level-cache = <&L2_2>; | ||
106 | }; | ||
107 | cpu8: PowerPC,e6500@16 { | ||
108 | device_type = "cpu"; | ||
109 | reg = <16 17>; | ||
110 | next-level-cache = <&L2_3>; | ||
111 | }; | ||
112 | cpu9: PowerPC,e6500@18 { | ||
113 | device_type = "cpu"; | ||
114 | reg = <18 19>; | ||
115 | next-level-cache = <&L2_3>; | ||
116 | }; | ||
117 | cpu10: PowerPC,e6500@20 { | ||
118 | device_type = "cpu"; | ||
119 | reg = <20 21>; | ||
120 | next-level-cache = <&L2_3>; | ||
121 | }; | ||
122 | cpu11: PowerPC,e6500@22 { | ||
123 | device_type = "cpu"; | ||
124 | reg = <22 23>; | ||
125 | next-level-cache = <&L2_3>; | ||
126 | }; | ||
127 | }; | ||
128 | }; | ||
diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi b/arch/powerpc/boot/dts/mpc5121.dtsi index 723e292b6b4e..bd14c00e5146 100644 --- a/arch/powerpc/boot/dts/mpc5121.dtsi +++ b/arch/powerpc/boot/dts/mpc5121.dtsi | |||
@@ -152,6 +152,8 @@ | |||
152 | compatible = "fsl,mpc5121-sdhc"; | 152 | compatible = "fsl,mpc5121-sdhc"; |
153 | reg = <0x1500 0x100>; | 153 | reg = <0x1500 0x100>; |
154 | interrupts = <8 0x8>; | 154 | interrupts = <8 0x8>; |
155 | dmas = <&dma0 30>; | ||
156 | dma-names = "rx-tx"; | ||
155 | }; | 157 | }; |
156 | 158 | ||
157 | i2c@1700 { | 159 | i2c@1700 { |
@@ -384,7 +386,7 @@ | |||
384 | interrupts = <40 0x8>; | 386 | interrupts = <40 0x8>; |
385 | }; | 387 | }; |
386 | 388 | ||
387 | dma@14000 { | 389 | dma0: dma@14000 { |
388 | compatible = "fsl,mpc5121-dma"; | 390 | compatible = "fsl,mpc5121-dma"; |
389 | reg = <0x14000 0x1800>; | 391 | reg = <0x14000 0x1800>; |
390 | interrupts = <65 0x8>; | 392 | interrupts = <65 0x8>; |
diff --git a/arch/powerpc/boot/dts/mpc5121ads.dts b/arch/powerpc/boot/dts/mpc5121ads.dts index f269b1382ef7..7d3cb79185cb 100644 --- a/arch/powerpc/boot/dts/mpc5121ads.dts +++ b/arch/powerpc/boot/dts/mpc5121ads.dts | |||
@@ -13,7 +13,7 @@ | |||
13 | 13 | ||
14 | / { | 14 | / { |
15 | model = "mpc5121ads"; | 15 | model = "mpc5121ads"; |
16 | compatible = "fsl,mpc5121ads"; | 16 | compatible = "fsl,mpc5121ads", "fsl,mpc5121"; |
17 | 17 | ||
18 | nfc@40000000 { | 18 | nfc@40000000 { |
19 | /* | 19 | /* |
diff --git a/arch/powerpc/boot/dts/mpc5125twr.dts b/arch/powerpc/boot/dts/mpc5125twr.dts new file mode 100644 index 000000000000..4177b62240c2 --- /dev/null +++ b/arch/powerpc/boot/dts/mpc5125twr.dts | |||
@@ -0,0 +1,233 @@ | |||
1 | /* | ||
2 | * STx/Freescale ADS5125 MPC5125 silicon | ||
3 | * | ||
4 | * Copyright (C) 2009 Freescale Semiconductor Inc. All rights reserved. | ||
5 | * | ||
6 | * Reworked by Matteo Facchinetti (engineering@sirius-es.it) | ||
7 | * Copyright (C) 2013 Sirius Electronic Systems | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | */ | ||
14 | |||
15 | /dts-v1/; | ||
16 | |||
17 | / { | ||
18 | model = "mpc5125twr"; // In BSP "mpc5125ads" | ||
19 | compatible = "fsl,mpc5125ads", "fsl,mpc5125"; | ||
20 | #address-cells = <1>; | ||
21 | #size-cells = <1>; | ||
22 | interrupt-parent = <&ipic>; | ||
23 | |||
24 | aliases { | ||
25 | gpio0 = &gpio0; | ||
26 | gpio1 = &gpio1; | ||
27 | ethernet0 = ð0; | ||
28 | }; | ||
29 | |||
30 | cpus { | ||
31 | #address-cells = <1>; | ||
32 | #size-cells = <0>; | ||
33 | |||
34 | PowerPC,5125@0 { | ||
35 | device_type = "cpu"; | ||
36 | reg = <0>; | ||
37 | d-cache-line-size = <0x20>; // 32 bytes | ||
38 | i-cache-line-size = <0x20>; // 32 bytes | ||
39 | d-cache-size = <0x8000>; // L1, 32K | ||
40 | i-cache-size = <0x8000>; // L1, 32K | ||
41 | timebase-frequency = <49500000>;// 49.5 MHz (csb/4) | ||
42 | bus-frequency = <198000000>; // 198 MHz csb bus | ||
43 | clock-frequency = <396000000>; // 396 MHz ppc core | ||
44 | }; | ||
45 | }; | ||
46 | |||
47 | memory { | ||
48 | device_type = "memory"; | ||
49 | reg = <0x00000000 0x10000000>; // 256MB at 0 | ||
50 | }; | ||
51 | |||
52 | sram@30000000 { | ||
53 | compatible = "fsl,mpc5121-sram"; | ||
54 | reg = <0x30000000 0x08000>; // 32K at 0x30000000 | ||
55 | }; | ||
56 | |||
57 | soc@80000000 { | ||
58 | compatible = "fsl,mpc5121-immr"; | ||
59 | #address-cells = <1>; | ||
60 | #size-cells = <1>; | ||
61 | #interrupt-cells = <2>; | ||
62 | ranges = <0x0 0x80000000 0x400000>; | ||
63 | reg = <0x80000000 0x400000>; | ||
64 | bus-frequency = <66000000>; // 66 MHz ips bus | ||
65 | |||
66 | // IPIC | ||
67 | // interrupts cell = <intr #, sense> | ||
68 | // sense values match linux IORESOURCE_IRQ_* defines: | ||
69 | // sense == 8: Level, low assertion | ||
70 | // sense == 2: Edge, high-to-low change | ||
71 | // | ||
72 | ipic: interrupt-controller@c00 { | ||
73 | compatible = "fsl,mpc5121-ipic", "fsl,ipic"; | ||
74 | interrupt-controller; | ||
75 | #address-cells = <0>; | ||
76 | #interrupt-cells = <2>; | ||
77 | reg = <0xc00 0x100>; | ||
78 | }; | ||
79 | |||
80 | rtc@a00 { // Real time clock | ||
81 | compatible = "fsl,mpc5121-rtc"; | ||
82 | reg = <0xa00 0x100>; | ||
83 | interrupts = <79 0x8 80 0x8>; | ||
84 | }; | ||
85 | |||
86 | reset@e00 { // Reset module | ||
87 | compatible = "fsl,mpc5125-reset"; | ||
88 | reg = <0xe00 0x100>; | ||
89 | }; | ||
90 | |||
91 | clock@f00 { // Clock control | ||
92 | compatible = "fsl,mpc5121-clock"; | ||
93 | reg = <0xf00 0x100>; | ||
94 | }; | ||
95 | |||
96 | pmc@1000{ // Power Management Controller | ||
97 | compatible = "fsl,mpc5121-pmc"; | ||
98 | reg = <0x1000 0x100>; | ||
99 | interrupts = <83 0x2>; | ||
100 | }; | ||
101 | |||
102 | gpio0: gpio@1100 { | ||
103 | compatible = "fsl,mpc5125-gpio"; | ||
104 | reg = <0x1100 0x080>; | ||
105 | interrupts = <78 0x8>; | ||
106 | }; | ||
107 | |||
108 | gpio1: gpio@1180 { | ||
109 | compatible = "fsl,mpc5125-gpio"; | ||
110 | reg = <0x1180 0x080>; | ||
111 | interrupts = <86 0x8>; | ||
112 | }; | ||
113 | |||
114 | can@1300 { // CAN rev.2 | ||
115 | compatible = "fsl,mpc5121-mscan"; | ||
116 | interrupts = <12 0x8>; | ||
117 | reg = <0x1300 0x80>; | ||
118 | }; | ||
119 | |||
120 | can@1380 { | ||
121 | compatible = "fsl,mpc5121-mscan"; | ||
122 | interrupts = <13 0x8>; | ||
123 | reg = <0x1380 0x80>; | ||
124 | }; | ||
125 | |||
126 | sdhc@1500 { | ||
127 | compatible = "fsl,mpc5121-sdhc"; | ||
128 | interrupts = <8 0x8>; | ||
129 | reg = <0x1500 0x100>; | ||
130 | }; | ||
131 | |||
132 | i2c@1700 { | ||
133 | #address-cells = <1>; | ||
134 | #size-cells = <0>; | ||
135 | compatible = "fsl,mpc5121-i2c", "fsl-i2c"; | ||
136 | reg = <0x1700 0x20>; | ||
137 | interrupts = <0x9 0x8>; | ||
138 | }; | ||
139 | |||
140 | i2c@1720 { | ||
141 | #address-cells = <1>; | ||
142 | #size-cells = <0>; | ||
143 | compatible = "fsl,mpc5121-i2c", "fsl-i2c"; | ||
144 | reg = <0x1720 0x20>; | ||
145 | interrupts = <0xa 0x8>; | ||
146 | }; | ||
147 | |||
148 | i2c@1740 { | ||
149 | #address-cells = <1>; | ||
150 | #size-cells = <0>; | ||
151 | compatible = "fsl,mpc5121-i2c", "fsl-i2c"; | ||
152 | reg = <0x1740 0x20>; | ||
153 | interrupts = <0xb 0x8>; | ||
154 | }; | ||
155 | |||
156 | i2ccontrol@1760 { | ||
157 | compatible = "fsl,mpc5121-i2c-ctrl"; | ||
158 | reg = <0x1760 0x8>; | ||
159 | }; | ||
160 | |||
161 | diu@2100 { | ||
162 | compatible = "fsl,mpc5121-diu"; | ||
163 | reg = <0x2100 0x100>; | ||
164 | interrupts = <64 0x8>; | ||
165 | }; | ||
166 | |||
167 | mdio@2800 { | ||
168 | compatible = "fsl,mpc5121-fec-mdio"; | ||
169 | reg = <0x2800 0x800>; | ||
170 | #address-cells = <1>; | ||
171 | #size-cells = <0>; | ||
172 | phy0: ethernet-phy@0 { | ||
173 | reg = <1>; | ||
174 | }; | ||
175 | }; | ||
176 | |||
177 | eth0: ethernet@2800 { | ||
178 | compatible = "fsl,mpc5125-fec"; | ||
179 | reg = <0x2800 0x800>; | ||
180 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
181 | interrupts = <4 0x8>; | ||
182 | phy-handle = < &phy0 >; | ||
183 | phy-connection-type = "rmii"; | ||
184 | }; | ||
185 | |||
186 | // IO control | ||
187 | ioctl@a000 { | ||
188 | compatible = "fsl,mpc5125-ioctl"; | ||
189 | reg = <0xA000 0x1000>; | ||
190 | }; | ||
191 | |||
192 | usb@3000 { | ||
193 | compatible = "fsl,mpc5121-usb2-dr"; | ||
194 | reg = <0x3000 0x400>; | ||
195 | #address-cells = <1>; | ||
196 | #size-cells = <0>; | ||
197 | interrupts = <43 0x8>; | ||
198 | dr_mode = "host"; | ||
199 | phy_type = "ulpi"; | ||
200 | }; | ||
201 | |||
202 | // 5125 PSCs are not 52xx or 5121 PSC compatible | ||
203 | // PSC1 uart0 aka ttyPSC0 | ||
204 | serial@11100 { | ||
205 | compatible = "fsl,mpc5125-psc-uart", "fsl,mpc5125-psc"; | ||
206 | reg = <0x11100 0x100>; | ||
207 | interrupts = <40 0x8>; | ||
208 | fsl,rx-fifo-size = <16>; | ||
209 | fsl,tx-fifo-size = <16>; | ||
210 | }; | ||
211 | |||
212 | // PSC9 uart1 aka ttyPSC1 | ||
213 | serial@11900 { | ||
214 | compatible = "fsl,mpc5125-psc-uart", "fsl,mpc5125-psc"; | ||
215 | reg = <0x11900 0x100>; | ||
216 | interrupts = <40 0x8>; | ||
217 | fsl,rx-fifo-size = <16>; | ||
218 | fsl,tx-fifo-size = <16>; | ||
219 | }; | ||
220 | |||
221 | pscfifo@11f00 { | ||
222 | compatible = "fsl,mpc5121-psc-fifo"; | ||
223 | reg = <0x11f00 0x100>; | ||
224 | interrupts = <40 0x8>; | ||
225 | }; | ||
226 | |||
227 | dma@14000 { | ||
228 | compatible = "fsl,mpc5121-dma"; // BSP name: "mpc512x-dma2" | ||
229 | reg = <0x14000 0x1800>; | ||
230 | interrupts = <65 0x8>; | ||
231 | }; | ||
232 | }; | ||
233 | }; | ||
diff --git a/arch/powerpc/boot/dts/mpc8536ds_36b.dts b/arch/powerpc/boot/dts/mpc8536ds_36b.dts index f8a3b3413176..6c723ee108cd 100644 --- a/arch/powerpc/boot/dts/mpc8536ds_36b.dts +++ b/arch/powerpc/boot/dts/mpc8536ds_36b.dts | |||
@@ -32,7 +32,7 @@ | |||
32 | reg = <0 0 0 0>; // Filled by U-Boot | 32 | reg = <0 0 0 0>; // Filled by U-Boot |
33 | }; | 33 | }; |
34 | 34 | ||
35 | lbc: localbus@ffe05000 { | 35 | lbc: localbus@fffe05000 { |
36 | reg = <0xf 0xffe05000 0 0x1000>; | 36 | reg = <0xf 0xffe05000 0 0x1000>; |
37 | 37 | ||
38 | ranges = <0x0 0x0 0xf 0xe8000000 0x08000000 | 38 | ranges = <0x0 0x0 0xf 0xe8000000 0x08000000 |
@@ -44,7 +44,7 @@ | |||
44 | ranges = <0x0 0xf 0xffe00000 0x100000>; | 44 | ranges = <0x0 0xf 0xffe00000 0x100000>; |
45 | }; | 45 | }; |
46 | 46 | ||
47 | pci0: pci@ffe08000 { | 47 | pci0: pci@fffe08000 { |
48 | reg = <0xf 0xffe08000 0 0x1000>; | 48 | reg = <0xf 0xffe08000 0 0x1000>; |
49 | ranges = <0x02000000 0 0xf0000000 0xc 0x00000000 0 0x10000000 | 49 | ranges = <0x02000000 0 0xf0000000 0xc 0x00000000 0 0x10000000 |
50 | 0x01000000 0 0x00000000 0xf 0xffc00000 0 0x00010000>; | 50 | 0x01000000 0 0x00000000 0xf 0xffc00000 0 0x00010000>; |
@@ -59,7 +59,7 @@ | |||
59 | 0x8800 0 0 4 &mpic 4 1 0 0>; | 59 | 0x8800 0 0 4 &mpic 4 1 0 0>; |
60 | }; | 60 | }; |
61 | 61 | ||
62 | pci1: pcie@ffe09000 { | 62 | pci1: pcie@fffe09000 { |
63 | reg = <0xf 0xffe09000 0 0x1000>; | 63 | reg = <0xf 0xffe09000 0 0x1000>; |
64 | ranges = <0x02000000 0 0xf8000000 0xc 0x18000000 0 0x08000000 | 64 | ranges = <0x02000000 0 0xf8000000 0xc 0x18000000 0 0x08000000 |
65 | 0x01000000 0 0x00000000 0xf 0xffc20000 0 0x00010000>; | 65 | 0x01000000 0 0x00000000 0xf 0xffc20000 0 0x00010000>; |
diff --git a/arch/powerpc/boot/dts/p1021rdb-pc.dtsi b/arch/powerpc/boot/dts/p1021rdb-pc.dtsi index c13abfbbe2e2..d6274c58f496 100644 --- a/arch/powerpc/boot/dts/p1021rdb-pc.dtsi +++ b/arch/powerpc/boot/dts/p1021rdb-pc.dtsi | |||
@@ -62,11 +62,19 @@ | |||
62 | }; | 62 | }; |
63 | 63 | ||
64 | partition@400000 { | 64 | partition@400000 { |
65 | /* 11MB for JFFS2 based Root file System */ | 65 | /* 10.75MB for JFFS2 based Root file System */ |
66 | reg = <0x00400000 0x00b00000>; | 66 | reg = <0x00400000 0x00ac0000>; |
67 | label = "NOR JFFS2 Root File System"; | 67 | label = "NOR JFFS2 Root File System"; |
68 | }; | 68 | }; |
69 | 69 | ||
70 | partition@ec0000 { | ||
71 | /* This location must not be altered */ | ||
72 | /* 256KB for QE ucode firmware*/ | ||
73 | reg = <0x00ec0000 0x00040000>; | ||
74 | label = "NOR QE microcode firmware"; | ||
75 | read-only; | ||
76 | }; | ||
77 | |||
70 | partition@f00000 { | 78 | partition@f00000 { |
71 | /* This location must not be altered */ | 79 | /* This location must not be altered */ |
72 | /* 512KB for u-boot Bootloader Image */ | 80 | /* 512KB for u-boot Bootloader Image */ |
diff --git a/arch/powerpc/boot/dts/p1025rdb_36b.dts b/arch/powerpc/boot/dts/p1025rdb_36b.dts index 4ce4bfa0eda4..06deb6f341ba 100644 --- a/arch/powerpc/boot/dts/p1025rdb_36b.dts +++ b/arch/powerpc/boot/dts/p1025rdb_36b.dts | |||
@@ -82,6 +82,11 @@ | |||
82 | 0x0 0x100000>; | 82 | 0x0 0x100000>; |
83 | }; | 83 | }; |
84 | }; | 84 | }; |
85 | |||
86 | qe: qe@fffe80000 { | ||
87 | status = "disabled"; /* no firmware loaded */ | ||
88 | }; | ||
89 | |||
85 | }; | 90 | }; |
86 | 91 | ||
87 | /include/ "p1025rdb.dtsi" | 92 | /include/ "p1025rdb.dtsi" |
diff --git a/arch/powerpc/boot/dts/pdm360ng.dts b/arch/powerpc/boot/dts/pdm360ng.dts index 0b069477838a..74337403faee 100644 --- a/arch/powerpc/boot/dts/pdm360ng.dts +++ b/arch/powerpc/boot/dts/pdm360ng.dts | |||
@@ -17,7 +17,7 @@ | |||
17 | 17 | ||
18 | / { | 18 | / { |
19 | model = "pdm360ng"; | 19 | model = "pdm360ng"; |
20 | compatible = "ifm,pdm360ng"; | 20 | compatible = "ifm,pdm360ng", "fsl,mpc5121"; |
21 | #address-cells = <1>; | 21 | #address-cells = <1>; |
22 | #size-cells = <1>; | 22 | #size-cells = <1>; |
23 | interrupt-parent = <&ipic>; | 23 | interrupt-parent = <&ipic>; |
diff --git a/arch/powerpc/boot/dts/t4240qds.dts b/arch/powerpc/boot/dts/t4240qds.dts new file mode 100644 index 000000000000..0555976dd0f3 --- /dev/null +++ b/arch/powerpc/boot/dts/t4240qds.dts | |||
@@ -0,0 +1,224 @@ | |||
1 | /* | ||
2 | * T4240QDS Device Tree Source | ||
3 | * | ||
4 | * Copyright 2012 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/ "fsl/t4240si-pre.dtsi" | ||
36 | |||
37 | / { | ||
38 | model = "fsl,T4240QDS"; | ||
39 | compatible = "fsl,T4240QDS"; | ||
40 | #address-cells = <2>; | ||
41 | #size-cells = <2>; | ||
42 | interrupt-parent = <&mpic>; | ||
43 | |||
44 | ifc: localbus@ffe124000 { | ||
45 | reg = <0xf 0xfe124000 0 0x2000>; | ||
46 | ranges = <0 0 0xf 0xe8000000 0x08000000 | ||
47 | 2 0 0xf 0xff800000 0x00010000 | ||
48 | 3 0 0xf 0xffdf0000 0x00008000>; | ||
49 | |||
50 | nor@0,0 { | ||
51 | #address-cells = <1>; | ||
52 | #size-cells = <1>; | ||
53 | compatible = "cfi-flash"; | ||
54 | reg = <0x0 0x0 0x8000000>; | ||
55 | |||
56 | bank-width = <2>; | ||
57 | device-width = <1>; | ||
58 | }; | ||
59 | |||
60 | nand@2,0 { | ||
61 | #address-cells = <1>; | ||
62 | #size-cells = <1>; | ||
63 | compatible = "fsl,ifc-nand"; | ||
64 | reg = <0x2 0x0 0x10000>; | ||
65 | |||
66 | partition@0 { | ||
67 | /* This location must not be altered */ | ||
68 | /* 1MB for u-boot Bootloader Image */ | ||
69 | reg = <0x0 0x00100000>; | ||
70 | label = "NAND U-Boot Image"; | ||
71 | read-only; | ||
72 | }; | ||
73 | |||
74 | partition@100000 { | ||
75 | /* 1MB for DTB Image */ | ||
76 | reg = <0x00100000 0x00100000>; | ||
77 | label = "NAND DTB Image"; | ||
78 | }; | ||
79 | |||
80 | partition@200000 { | ||
81 | /* 10MB for Linux Kernel Image */ | ||
82 | reg = <0x00200000 0x00A00000>; | ||
83 | label = "NAND Linux Kernel Image"; | ||
84 | }; | ||
85 | |||
86 | partition@C00000 { | ||
87 | /* 500MB for Root file System Image */ | ||
88 | reg = <0x00c00000 0x1F400000>; | ||
89 | label = "NAND RFS Image"; | ||
90 | }; | ||
91 | }; | ||
92 | |||
93 | board-control@3,0 { | ||
94 | compatible = "fsl,t4240qds-fpga", "fsl,fpga-qixis"; | ||
95 | reg = <3 0 0x300>; | ||
96 | }; | ||
97 | }; | ||
98 | |||
99 | memory { | ||
100 | device_type = "memory"; | ||
101 | }; | ||
102 | |||
103 | dcsr: dcsr@f00000000 { | ||
104 | ranges = <0x00000000 0xf 0x00000000 0x01072000>; | ||
105 | }; | ||
106 | |||
107 | soc: soc@ffe000000 { | ||
108 | ranges = <0x00000000 0xf 0xfe000000 0x1000000>; | ||
109 | reg = <0xf 0xfe000000 0 0x00001000>; | ||
110 | spi@110000 { | ||
111 | flash@0 { | ||
112 | #address-cells = <1>; | ||
113 | #size-cells = <1>; | ||
114 | compatible = "sst,sst25wf040"; | ||
115 | reg = <0>; | ||
116 | spi-max-frequency = <40000000>; /* input clock */ | ||
117 | }; | ||
118 | }; | ||
119 | |||
120 | i2c@118000 { | ||
121 | eeprom@51 { | ||
122 | compatible = "at24,24c256"; | ||
123 | reg = <0x51>; | ||
124 | }; | ||
125 | eeprom@52 { | ||
126 | compatible = "at24,24c256"; | ||
127 | reg = <0x52>; | ||
128 | }; | ||
129 | eeprom@53 { | ||
130 | compatible = "at24,24c256"; | ||
131 | reg = <0x53>; | ||
132 | }; | ||
133 | eeprom@54 { | ||
134 | compatible = "at24,24c256"; | ||
135 | reg = <0x54>; | ||
136 | }; | ||
137 | eeprom@55 { | ||
138 | compatible = "at24,24c256"; | ||
139 | reg = <0x55>; | ||
140 | }; | ||
141 | eeprom@56 { | ||
142 | compatible = "at24,24c256"; | ||
143 | reg = <0x56>; | ||
144 | }; | ||
145 | rtc@68 { | ||
146 | compatible = "dallas,ds3232"; | ||
147 | reg = <0x68>; | ||
148 | interrupts = <0x1 0x1 0 0>; | ||
149 | }; | ||
150 | }; | ||
151 | }; | ||
152 | |||
153 | pci0: pcie@ffe240000 { | ||
154 | reg = <0xf 0xfe240000 0 0x10000>; | ||
155 | ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000 | ||
156 | 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>; | ||
157 | pcie@0 { | ||
158 | ranges = <0x02000000 0 0xe0000000 | ||
159 | 0x02000000 0 0xe0000000 | ||
160 | 0 0x20000000 | ||
161 | |||
162 | 0x01000000 0 0x00000000 | ||
163 | 0x01000000 0 0x00000000 | ||
164 | 0 0x00010000>; | ||
165 | }; | ||
166 | }; | ||
167 | |||
168 | pci1: pcie@ffe250000 { | ||
169 | reg = <0xf 0xfe250000 0 0x10000>; | ||
170 | ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000 | ||
171 | 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>; | ||
172 | pcie@0 { | ||
173 | ranges = <0x02000000 0 0xe0000000 | ||
174 | 0x02000000 0 0xe0000000 | ||
175 | 0 0x20000000 | ||
176 | |||
177 | 0x01000000 0 0x00000000 | ||
178 | 0x01000000 0 0x00000000 | ||
179 | 0 0x00010000>; | ||
180 | }; | ||
181 | }; | ||
182 | |||
183 | pci2: pcie@ffe260000 { | ||
184 | reg = <0xf 0xfe260000 0 0x1000>; | ||
185 | ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000 | ||
186 | 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>; | ||
187 | pcie@0 { | ||
188 | ranges = <0x02000000 0 0xe0000000 | ||
189 | 0x02000000 0 0xe0000000 | ||
190 | 0 0x20000000 | ||
191 | |||
192 | 0x01000000 0 0x00000000 | ||
193 | 0x01000000 0 0x00000000 | ||
194 | 0 0x00010000>; | ||
195 | }; | ||
196 | }; | ||
197 | |||
198 | pci3: pcie@ffe270000 { | ||
199 | reg = <0xf 0xfe270000 0 0x10000>; | ||
200 | ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000 | ||
201 | 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>; | ||
202 | pcie@0 { | ||
203 | ranges = <0x02000000 0 0xe0000000 | ||
204 | 0x02000000 0 0xe0000000 | ||
205 | 0 0x20000000 | ||
206 | |||
207 | 0x01000000 0 0x00000000 | ||
208 | 0x01000000 0 0x00000000 | ||
209 | 0 0x00010000>; | ||
210 | }; | ||
211 | }; | ||
212 | rio: rapidio@ffe0c0000 { | ||
213 | reg = <0xf 0xfe0c0000 0 0x11000>; | ||
214 | |||
215 | port1 { | ||
216 | ranges = <0 0 0xc 0x20000000 0 0x10000000>; | ||
217 | }; | ||
218 | port2 { | ||
219 | ranges = <0 0 0xc 0x30000000 0 0x10000000>; | ||
220 | }; | ||
221 | }; | ||
222 | }; | ||
223 | |||
224 | /include/ "fsl/t4240si-post.dtsi" | ||
diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig index 3d139fa04050..6c8b020806ff 100644 --- a/arch/powerpc/configs/corenet64_smp_defconfig +++ b/arch/powerpc/configs/corenet64_smp_defconfig | |||
@@ -1,14 +1,13 @@ | |||
1 | CONFIG_PPC64=y | 1 | CONFIG_PPC64=y |
2 | CONFIG_PPC_BOOK3E_64=y | 2 | CONFIG_PPC_BOOK3E_64=y |
3 | # CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set | 3 | CONFIG_ALTIVEC=y |
4 | CONFIG_SMP=y | 4 | CONFIG_SMP=y |
5 | CONFIG_NR_CPUS=2 | 5 | CONFIG_NR_CPUS=24 |
6 | CONFIG_EXPERIMENTAL=y | ||
7 | CONFIG_SYSVIPC=y | 6 | CONFIG_SYSVIPC=y |
8 | CONFIG_BSD_PROCESS_ACCT=y | ||
9 | CONFIG_IRQ_DOMAIN_DEBUG=y | 7 | CONFIG_IRQ_DOMAIN_DEBUG=y |
10 | CONFIG_NO_HZ=y | 8 | CONFIG_NO_HZ=y |
11 | CONFIG_HIGH_RES_TIMERS=y | 9 | CONFIG_HIGH_RES_TIMERS=y |
10 | CONFIG_BSD_PROCESS_ACCT=y | ||
12 | CONFIG_IKCONFIG=y | 11 | CONFIG_IKCONFIG=y |
13 | CONFIG_IKCONFIG_PROC=y | 12 | CONFIG_IKCONFIG_PROC=y |
14 | CONFIG_LOG_BUF_SHIFT=14 | 13 | CONFIG_LOG_BUF_SHIFT=14 |
@@ -22,10 +21,13 @@ CONFIG_MODVERSIONS=y | |||
22 | # CONFIG_BLK_DEV_BSG is not set | 21 | # CONFIG_BLK_DEV_BSG is not set |
23 | CONFIG_PARTITION_ADVANCED=y | 22 | CONFIG_PARTITION_ADVANCED=y |
24 | CONFIG_MAC_PARTITION=y | 23 | CONFIG_MAC_PARTITION=y |
24 | CONFIG_B4_QDS=y | ||
25 | CONFIG_P5020_DS=y | 25 | CONFIG_P5020_DS=y |
26 | CONFIG_P5040_DS=y | 26 | CONFIG_P5040_DS=y |
27 | CONFIG_T4240_QDS=y | ||
27 | # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set | 28 | # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set |
28 | CONFIG_BINFMT_MISC=m | 29 | CONFIG_BINFMT_MISC=m |
30 | CONFIG_FSL_IFC=y | ||
29 | CONFIG_PCIEPORTBUS=y | 31 | CONFIG_PCIEPORTBUS=y |
30 | CONFIG_PCI_MSI=y | 32 | CONFIG_PCI_MSI=y |
31 | CONFIG_RAPIDIO=y | 33 | CONFIG_RAPIDIO=y |
@@ -58,16 +60,33 @@ CONFIG_IP_SCTP=m | |||
58 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 60 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
59 | CONFIG_DEVTMPFS=y | 61 | CONFIG_DEVTMPFS=y |
60 | CONFIG_MTD=y | 62 | CONFIG_MTD=y |
63 | CONFIG_MTD_PARTITIONS=y | ||
64 | CONFIG_MTD_OF_PARTS=y | ||
61 | CONFIG_MTD_CMDLINE_PARTS=y | 65 | CONFIG_MTD_CMDLINE_PARTS=y |
62 | CONFIG_MTD_CHAR=y | 66 | CONFIG_MTD_CHAR=y |
67 | CONFIG_MTD_BLKDEVS=y | ||
63 | CONFIG_MTD_BLOCK=y | 68 | CONFIG_MTD_BLOCK=y |
69 | CONFIG_FTL=y | ||
64 | CONFIG_MTD_CFI=y | 70 | CONFIG_MTD_CFI=y |
71 | CONFIG_MTD_GEN_PROBE=y | ||
72 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
73 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
74 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
75 | CONFIG_MTD_CFI_I1=y | ||
76 | CONFIG_MTD_CFI_I2=y | ||
77 | CONFIG_MTD_CFI_INTELEXT=y | ||
65 | CONFIG_MTD_CFI_AMDSTD=y | 78 | CONFIG_MTD_CFI_AMDSTD=y |
66 | CONFIG_MTD_PHYSMAP_OF=y | 79 | CONFIG_MTD_PHYSMAP_OF=y |
67 | CONFIG_MTD_M25P80=y | 80 | CONFIG_MTD_M25P80=y |
81 | CONFIG_MTD_CFI_UTIL=y | ||
82 | CONFIG_MTD_NAND_ECC=y | ||
68 | CONFIG_MTD_NAND=y | 83 | CONFIG_MTD_NAND=y |
84 | CONFIG_MTD_NAND_IDS=y | ||
69 | CONFIG_MTD_NAND_FSL_ELBC=y | 85 | CONFIG_MTD_NAND_FSL_ELBC=y |
70 | CONFIG_MTD_NAND_FSL_IFC=y | 86 | CONFIG_MTD_NAND_FSL_IFC=y |
87 | CONFIG_MTD_UBI=y | ||
88 | CONFIG_MTD_UBI_WL_THRESHOLD=4096 | ||
89 | CONFIG_MTD_UBI_BEB_RESERVE=1 | ||
71 | CONFIG_PROC_DEVICETREE=y | 90 | CONFIG_PROC_DEVICETREE=y |
72 | CONFIG_BLK_DEV_LOOP=y | 91 | CONFIG_BLK_DEV_LOOP=y |
73 | CONFIG_BLK_DEV_RAM=y | 92 | CONFIG_BLK_DEV_RAM=y |
@@ -78,6 +97,7 @@ CONFIG_SATA_FSL=y | |||
78 | CONFIG_SATA_SIL24=y | 97 | CONFIG_SATA_SIL24=y |
79 | CONFIG_NETDEVICES=y | 98 | CONFIG_NETDEVICES=y |
80 | CONFIG_DUMMY=y | 99 | CONFIG_DUMMY=y |
100 | CONFIG_E1000E=y | ||
81 | CONFIG_INPUT_FF_MEMLESS=m | 101 | CONFIG_INPUT_FF_MEMLESS=m |
82 | # CONFIG_INPUT_MOUSEDEV is not set | 102 | # CONFIG_INPUT_MOUSEDEV is not set |
83 | # CONFIG_INPUT_KEYBOARD is not set | 103 | # CONFIG_INPUT_KEYBOARD is not set |
@@ -121,7 +141,16 @@ CONFIG_NTFS_FS=y | |||
121 | CONFIG_PROC_KCORE=y | 141 | CONFIG_PROC_KCORE=y |
122 | CONFIG_TMPFS=y | 142 | CONFIG_TMPFS=y |
123 | CONFIG_HUGETLBFS=y | 143 | CONFIG_HUGETLBFS=y |
124 | # CONFIG_MISC_FILESYSTEMS is not set | 144 | CONFIG_MISC_FILESYSTEMS=y |
145 | CONFIG_JFFS2_FS=y | ||
146 | CONFIG_JFFS2_FS_DEBUG=1 | ||
147 | CONFIG_JFFS2_FS_WRITEBUFFER=y | ||
148 | CONFIG_JFFS2_ZLIB=y | ||
149 | CONFIG_JFFS2_RTIME=y | ||
150 | CONFIG_UBIFS_FS=y | ||
151 | CONFIG_UBIFS_FS_XATTR=y | ||
152 | CONFIG_UBIFS_FS_LZO=y | ||
153 | CONFIG_UBIFS_FS_ZLIB=y | ||
125 | CONFIG_NFS_FS=y | 154 | CONFIG_NFS_FS=y |
126 | CONFIG_NFS_V4=y | 155 | CONFIG_NFS_V4=y |
127 | CONFIG_ROOT_NFS=y | 156 | CONFIG_ROOT_NFS=y |
@@ -129,6 +158,12 @@ CONFIG_NFSD=m | |||
129 | CONFIG_NLS_ISO8859_1=y | 158 | CONFIG_NLS_ISO8859_1=y |
130 | CONFIG_NLS_UTF8=m | 159 | CONFIG_NLS_UTF8=m |
131 | CONFIG_CRC_T10DIF=y | 160 | CONFIG_CRC_T10DIF=y |
161 | CONFIG_CRC16=y | ||
162 | CONFIG_ZLIB_DEFLATE=y | ||
163 | CONFIG_LZO_COMPRESS=y | ||
164 | CONFIG_LZO_DECOMPRESS=y | ||
165 | CONFIG_CRYPTO_DEFLATE=y | ||
166 | CONFIG_CRYPTO_LZO=y | ||
132 | CONFIG_FRAME_WARN=1024 | 167 | CONFIG_FRAME_WARN=1024 |
133 | CONFIG_MAGIC_SYSRQ=y | 168 | CONFIG_MAGIC_SYSRQ=y |
134 | CONFIG_DEBUG_FS=y | 169 | CONFIG_DEBUG_FS=y |
@@ -140,6 +175,5 @@ CONFIG_CRYPTO_PCBC=m | |||
140 | CONFIG_CRYPTO_MD4=y | 175 | CONFIG_CRYPTO_MD4=y |
141 | CONFIG_CRYPTO_SHA256=y | 176 | CONFIG_CRYPTO_SHA256=y |
142 | CONFIG_CRYPTO_SHA512=y | 177 | CONFIG_CRYPTO_SHA512=y |
143 | CONFIG_CRYPTO_AES=y | ||
144 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 178 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
145 | CONFIG_CRYPTO_DEV_FSL_CAAM=y | 179 | CONFIG_CRYPTO_DEV_FSL_CAAM=y |
diff --git a/arch/powerpc/configs/mpc512x_defconfig b/arch/powerpc/configs/mpc512x_defconfig index 211fcc9ed700..0d0d981442fd 100644 --- a/arch/powerpc/configs/mpc512x_defconfig +++ b/arch/powerpc/configs/mpc512x_defconfig | |||
@@ -13,7 +13,7 @@ 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 | 16 | CONFIG_MPC512x_GENERIC=y |
17 | CONFIG_PDM360NG=y | 17 | CONFIG_PDM360NG=y |
18 | # CONFIG_PPC_PMAC is not set | 18 | # CONFIG_PPC_PMAC is not set |
19 | CONFIG_NO_HZ=y | 19 | CONFIG_NO_HZ=y |
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index cf815e847cdc..5a58882e351e 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig | |||
@@ -1,13 +1,12 @@ | |||
1 | CONFIG_PPC_85xx=y | 1 | CONFIG_PPC_85xx=y |
2 | CONFIG_PHYS_64BIT=y | 2 | CONFIG_PHYS_64BIT=y |
3 | CONFIG_EXPERIMENTAL=y | ||
4 | CONFIG_SYSVIPC=y | 3 | CONFIG_SYSVIPC=y |
5 | CONFIG_POSIX_MQUEUE=y | 4 | CONFIG_POSIX_MQUEUE=y |
6 | CONFIG_BSD_PROCESS_ACCT=y | ||
7 | CONFIG_AUDIT=y | 5 | CONFIG_AUDIT=y |
8 | CONFIG_IRQ_DOMAIN_DEBUG=y | 6 | CONFIG_IRQ_DOMAIN_DEBUG=y |
9 | CONFIG_NO_HZ=y | 7 | CONFIG_NO_HZ=y |
10 | CONFIG_HIGH_RES_TIMERS=y | 8 | CONFIG_HIGH_RES_TIMERS=y |
9 | CONFIG_BSD_PROCESS_ACCT=y | ||
11 | CONFIG_IKCONFIG=y | 10 | CONFIG_IKCONFIG=y |
12 | CONFIG_IKCONFIG_PROC=y | 11 | CONFIG_IKCONFIG_PROC=y |
13 | CONFIG_LOG_BUF_SHIFT=14 | 12 | CONFIG_LOG_BUF_SHIFT=14 |
@@ -48,6 +47,7 @@ CONFIG_HIGHMEM=y | |||
48 | CONFIG_BINFMT_MISC=m | 47 | CONFIG_BINFMT_MISC=m |
49 | CONFIG_MATH_EMULATION=y | 48 | CONFIG_MATH_EMULATION=y |
50 | CONFIG_FORCE_MAX_ZONEORDER=12 | 49 | CONFIG_FORCE_MAX_ZONEORDER=12 |
50 | CONFIG_FSL_IFC=y | ||
51 | CONFIG_PCI=y | 51 | CONFIG_PCI=y |
52 | CONFIG_PCI_MSI=y | 52 | CONFIG_PCI_MSI=y |
53 | CONFIG_RAPIDIO=y | 53 | CONFIG_RAPIDIO=y |
@@ -79,18 +79,33 @@ CONFIG_IP_SCTP=m | |||
79 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 79 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
80 | CONFIG_DEVTMPFS=y | 80 | CONFIG_DEVTMPFS=y |
81 | CONFIG_MTD=y | 81 | CONFIG_MTD=y |
82 | CONFIG_MTD_PARTITIONS=y | ||
83 | CONFIG_MTD_OF_PARTS=y | ||
82 | CONFIG_MTD_CMDLINE_PARTS=y | 84 | CONFIG_MTD_CMDLINE_PARTS=y |
83 | CONFIG_MTD_CHAR=y | 85 | CONFIG_MTD_CHAR=y |
86 | CONFIG_MTD_BLKDEVS=y | ||
84 | CONFIG_MTD_BLOCK=y | 87 | CONFIG_MTD_BLOCK=y |
85 | CONFIG_FTL=y | 88 | CONFIG_FTL=y |
86 | CONFIG_MTD_CFI=y | 89 | CONFIG_MTD_CFI=y |
90 | CONFIG_MTD_GEN_PROBE=y | ||
91 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
92 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
93 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
94 | CONFIG_MTD_CFI_I1=y | ||
95 | CONFIG_MTD_CFI_I2=y | ||
87 | CONFIG_MTD_CFI_INTELEXT=y | 96 | CONFIG_MTD_CFI_INTELEXT=y |
88 | CONFIG_MTD_CFI_AMDSTD=y | 97 | CONFIG_MTD_CFI_AMDSTD=y |
89 | CONFIG_MTD_PHYSMAP_OF=y | 98 | CONFIG_MTD_PHYSMAP_OF=y |
90 | CONFIG_MTD_M25P80=y | 99 | CONFIG_MTD_M25P80=y |
100 | CONFIG_MTD_CFI_UTIL=y | ||
101 | CONFIG_MTD_NAND_ECC=y | ||
91 | CONFIG_MTD_NAND=y | 102 | CONFIG_MTD_NAND=y |
103 | CONFIG_MTD_NAND_IDS=y | ||
92 | CONFIG_MTD_NAND_FSL_ELBC=y | 104 | CONFIG_MTD_NAND_FSL_ELBC=y |
93 | CONFIG_MTD_NAND_FSL_IFC=y | 105 | CONFIG_MTD_NAND_FSL_IFC=y |
106 | CONFIG_MTD_UBI=y | ||
107 | CONFIG_MTD_UBI_WL_THRESHOLD=4096 | ||
108 | CONFIG_MTD_UBI_BEB_RESERVE=1 | ||
94 | CONFIG_PROC_DEVICETREE=y | 109 | CONFIG_PROC_DEVICETREE=y |
95 | CONFIG_BLK_DEV_LOOP=y | 110 | CONFIG_BLK_DEV_LOOP=y |
96 | CONFIG_BLK_DEV_NBD=y | 111 | CONFIG_BLK_DEV_NBD=y |
@@ -106,6 +121,7 @@ CONFIG_SCSI_LOGGING=y | |||
106 | CONFIG_ATA=y | 121 | CONFIG_ATA=y |
107 | CONFIG_SATA_AHCI=y | 122 | CONFIG_SATA_AHCI=y |
108 | CONFIG_SATA_FSL=y | 123 | CONFIG_SATA_FSL=y |
124 | CONFIG_SATA_SIL24=y | ||
109 | CONFIG_PATA_ALI=y | 125 | CONFIG_PATA_ALI=y |
110 | CONFIG_PATA_VIA=y | 126 | CONFIG_PATA_VIA=y |
111 | CONFIG_NETDEVICES=y | 127 | CONFIG_NETDEVICES=y |
@@ -113,6 +129,9 @@ CONFIG_DUMMY=y | |||
113 | CONFIG_FS_ENET=y | 129 | CONFIG_FS_ENET=y |
114 | CONFIG_UCC_GETH=y | 130 | CONFIG_UCC_GETH=y |
115 | CONFIG_GIANFAR=y | 131 | CONFIG_GIANFAR=y |
132 | CONFIG_E1000=y | ||
133 | CONFIG_E1000E=y | ||
134 | CONFIG_IGB=y | ||
116 | CONFIG_MARVELL_PHY=y | 135 | CONFIG_MARVELL_PHY=y |
117 | CONFIG_DAVICOM_PHY=y | 136 | CONFIG_DAVICOM_PHY=y |
118 | CONFIG_CICADA_PHY=y | 137 | CONFIG_CICADA_PHY=y |
@@ -132,7 +151,6 @@ CONFIG_SERIAL_8250_DETECT_IRQ=y | |||
132 | CONFIG_SERIAL_8250_RSA=y | 151 | CONFIG_SERIAL_8250_RSA=y |
133 | CONFIG_SERIAL_QE=m | 152 | CONFIG_SERIAL_QE=m |
134 | CONFIG_NVRAM=y | 153 | CONFIG_NVRAM=y |
135 | CONFIG_I2C=y | ||
136 | CONFIG_I2C_CHARDEV=y | 154 | CONFIG_I2C_CHARDEV=y |
137 | CONFIG_I2C_CPM=m | 155 | CONFIG_I2C_CPM=m |
138 | CONFIG_I2C_MPC=y | 156 | CONFIG_I2C_MPC=y |
@@ -206,6 +224,15 @@ CONFIG_NTFS_FS=y | |||
206 | CONFIG_PROC_KCORE=y | 224 | CONFIG_PROC_KCORE=y |
207 | CONFIG_TMPFS=y | 225 | CONFIG_TMPFS=y |
208 | CONFIG_HUGETLBFS=y | 226 | CONFIG_HUGETLBFS=y |
227 | CONFIG_JFFS2_FS=y | ||
228 | CONFIG_JFFS2_FS_DEBUG=1 | ||
229 | CONFIG_JFFS2_FS_WRITEBUFFER=y | ||
230 | CONFIG_JFFS2_ZLIB=y | ||
231 | CONFIG_JFFS2_RTIME=y | ||
232 | CONFIG_UBIFS_FS=y | ||
233 | CONFIG_UBIFS_FS_XATTR=y | ||
234 | CONFIG_UBIFS_FS_LZO=y | ||
235 | CONFIG_UBIFS_FS_ZLIB=y | ||
209 | CONFIG_ADFS_FS=m | 236 | CONFIG_ADFS_FS=m |
210 | CONFIG_AFFS_FS=m | 237 | CONFIG_AFFS_FS=m |
211 | CONFIG_HFS_FS=m | 238 | CONFIG_HFS_FS=m |
@@ -224,13 +251,18 @@ CONFIG_NFS_V4=y | |||
224 | CONFIG_ROOT_NFS=y | 251 | CONFIG_ROOT_NFS=y |
225 | CONFIG_NFSD=y | 252 | CONFIG_NFSD=y |
226 | CONFIG_CRC_T10DIF=y | 253 | CONFIG_CRC_T10DIF=y |
254 | CONFIG_CRC16=y | ||
255 | CONFIG_ZLIB_DEFLATE=y | ||
256 | CONFIG_LZO_COMPRESS=y | ||
257 | CONFIG_LZO_DECOMPRESS=y | ||
258 | CONFIG_CRYPTO_DEFLATE=y | ||
259 | CONFIG_CRYPTO_LZO=y | ||
227 | CONFIG_DEBUG_FS=y | 260 | CONFIG_DEBUG_FS=y |
228 | CONFIG_DETECT_HUNG_TASK=y | 261 | CONFIG_DETECT_HUNG_TASK=y |
229 | CONFIG_DEBUG_INFO=y | 262 | CONFIG_DEBUG_INFO=y |
230 | CONFIG_CRYPTO_PCBC=m | 263 | CONFIG_CRYPTO_PCBC=m |
231 | CONFIG_CRYPTO_SHA256=y | 264 | CONFIG_CRYPTO_SHA256=y |
232 | CONFIG_CRYPTO_SHA512=y | 265 | CONFIG_CRYPTO_SHA512=y |
233 | CONFIG_CRYPTO_AES=y | ||
234 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 266 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
235 | CONFIG_CRYPTO_DEV_FSL_CAAM=y | 267 | CONFIG_CRYPTO_DEV_FSL_CAAM=y |
236 | CONFIG_CRYPTO_DEV_TALITOS=y | 268 | CONFIG_CRYPTO_DEV_TALITOS=y |
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig index 8d00ea5b8a9f..165e6b32baef 100644 --- a/arch/powerpc/configs/mpc85xx_smp_defconfig +++ b/arch/powerpc/configs/mpc85xx_smp_defconfig | |||
@@ -50,6 +50,7 @@ CONFIG_HIGHMEM=y | |||
50 | CONFIG_BINFMT_MISC=m | 50 | CONFIG_BINFMT_MISC=m |
51 | CONFIG_MATH_EMULATION=y | 51 | CONFIG_MATH_EMULATION=y |
52 | CONFIG_FORCE_MAX_ZONEORDER=12 | 52 | CONFIG_FORCE_MAX_ZONEORDER=12 |
53 | CONFIG_FSL_IFC=y | ||
53 | CONFIG_PCI=y | 54 | CONFIG_PCI=y |
54 | CONFIG_PCI_MSI=y | 55 | CONFIG_PCI_MSI=y |
55 | CONFIG_RAPIDIO=y | 56 | CONFIG_RAPIDIO=y |
@@ -81,18 +82,33 @@ CONFIG_IP_SCTP=m | |||
81 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 82 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
82 | CONFIG_DEVTMPFS=y | 83 | CONFIG_DEVTMPFS=y |
83 | CONFIG_MTD=y | 84 | CONFIG_MTD=y |
85 | CONFIG_MTD_PARTITIONS=y | ||
86 | CONFIG_MTD_OF_PARTS=y | ||
84 | CONFIG_MTD_CMDLINE_PARTS=y | 87 | CONFIG_MTD_CMDLINE_PARTS=y |
85 | CONFIG_MTD_CHAR=y | 88 | CONFIG_MTD_CHAR=y |
89 | CONFIG_MTD_BLKDEVS=y | ||
86 | CONFIG_MTD_BLOCK=y | 90 | CONFIG_MTD_BLOCK=y |
87 | CONFIG_FTL=y | 91 | CONFIG_FTL=y |
88 | CONFIG_MTD_CFI=y | 92 | CONFIG_MTD_CFI=y |
93 | CONFIG_MTD_GEN_PROBE=y | ||
94 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
95 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
96 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
97 | CONFIG_MTD_CFI_I1=y | ||
98 | CONFIG_MTD_CFI_I2=y | ||
89 | CONFIG_MTD_CFI_INTELEXT=y | 99 | CONFIG_MTD_CFI_INTELEXT=y |
90 | CONFIG_MTD_CFI_AMDSTD=y | 100 | CONFIG_MTD_CFI_AMDSTD=y |
91 | CONFIG_MTD_PHYSMAP_OF=y | 101 | CONFIG_MTD_PHYSMAP_OF=y |
92 | CONFIG_MTD_M25P80=y | 102 | CONFIG_MTD_M25P80=y |
103 | CONFIG_MTD_CFI_UTIL=y | ||
104 | CONFIG_MTD_NAND_ECC=y | ||
93 | CONFIG_MTD_NAND=y | 105 | CONFIG_MTD_NAND=y |
106 | CONFIG_MTD_NAND_IDS=y | ||
94 | CONFIG_MTD_NAND_FSL_ELBC=y | 107 | CONFIG_MTD_NAND_FSL_ELBC=y |
95 | CONFIG_MTD_NAND_FSL_IFC=y | 108 | CONFIG_MTD_NAND_FSL_IFC=y |
109 | CONFIG_MTD_UBI=y | ||
110 | CONFIG_MTD_UBI_WL_THRESHOLD=4096 | ||
111 | CONFIG_MTD_UBI_BEB_RESERVE=1 | ||
96 | CONFIG_PROC_DEVICETREE=y | 112 | CONFIG_PROC_DEVICETREE=y |
97 | CONFIG_BLK_DEV_LOOP=y | 113 | CONFIG_BLK_DEV_LOOP=y |
98 | CONFIG_BLK_DEV_NBD=y | 114 | CONFIG_BLK_DEV_NBD=y |
@@ -108,6 +124,7 @@ CONFIG_SCSI_LOGGING=y | |||
108 | CONFIG_ATA=y | 124 | CONFIG_ATA=y |
109 | CONFIG_SATA_AHCI=y | 125 | CONFIG_SATA_AHCI=y |
110 | CONFIG_SATA_FSL=y | 126 | CONFIG_SATA_FSL=y |
127 | CONFIG_SATA_SIL24=y | ||
111 | CONFIG_PATA_ALI=y | 128 | CONFIG_PATA_ALI=y |
112 | CONFIG_NETDEVICES=y | 129 | CONFIG_NETDEVICES=y |
113 | CONFIG_DUMMY=y | 130 | CONFIG_DUMMY=y |
@@ -207,6 +224,15 @@ CONFIG_NTFS_FS=y | |||
207 | CONFIG_PROC_KCORE=y | 224 | CONFIG_PROC_KCORE=y |
208 | CONFIG_TMPFS=y | 225 | CONFIG_TMPFS=y |
209 | CONFIG_HUGETLBFS=y | 226 | CONFIG_HUGETLBFS=y |
227 | CONFIG_JFFS2_FS=y | ||
228 | CONFIG_JFFS2_FS_DEBUG=1 | ||
229 | CONFIG_JFFS2_FS_WRITEBUFFER=y | ||
230 | CONFIG_JFFS2_ZLIB=y | ||
231 | CONFIG_JFFS2_RTIME=y | ||
232 | CONFIG_UBIFS_FS=y | ||
233 | CONFIG_UBIFS_FS_XATTR=y | ||
234 | CONFIG_UBIFS_FS_LZO=y | ||
235 | CONFIG_UBIFS_FS_ZLIB=y | ||
210 | CONFIG_ADFS_FS=m | 236 | CONFIG_ADFS_FS=m |
211 | CONFIG_AFFS_FS=m | 237 | CONFIG_AFFS_FS=m |
212 | CONFIG_HFS_FS=m | 238 | CONFIG_HFS_FS=m |
@@ -225,6 +251,12 @@ CONFIG_NFS_V4=y | |||
225 | CONFIG_ROOT_NFS=y | 251 | CONFIG_ROOT_NFS=y |
226 | CONFIG_NFSD=y | 252 | CONFIG_NFSD=y |
227 | CONFIG_CRC_T10DIF=y | 253 | CONFIG_CRC_T10DIF=y |
254 | CONFIG_CRC16=y | ||
255 | CONFIG_ZLIB_DEFLATE=y | ||
256 | CONFIG_LZO_COMPRESS=y | ||
257 | CONFIG_LZO_DECOMPRESS=y | ||
258 | CONFIG_CRYPTO_DEFLATE=y | ||
259 | CONFIG_CRYPTO_LZO=y | ||
228 | CONFIG_DEBUG_FS=y | 260 | CONFIG_DEBUG_FS=y |
229 | CONFIG_DETECT_HUNG_TASK=y | 261 | CONFIG_DETECT_HUNG_TASK=y |
230 | CONFIG_DEBUG_INFO=y | 262 | CONFIG_DEBUG_INFO=y |
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig index 7a5c15fcc7cf..f79196232917 100644 --- a/arch/powerpc/configs/ps3_defconfig +++ b/arch/powerpc/configs/ps3_defconfig | |||
@@ -3,11 +3,11 @@ CONFIG_TUNE_CELL=y | |||
3 | CONFIG_ALTIVEC=y | 3 | CONFIG_ALTIVEC=y |
4 | CONFIG_SMP=y | 4 | CONFIG_SMP=y |
5 | CONFIG_NR_CPUS=2 | 5 | CONFIG_NR_CPUS=2 |
6 | CONFIG_EXPERIMENTAL=y | ||
7 | CONFIG_SYSVIPC=y | 6 | CONFIG_SYSVIPC=y |
8 | CONFIG_POSIX_MQUEUE=y | 7 | CONFIG_POSIX_MQUEUE=y |
9 | CONFIG_HIGH_RES_TIMERS=y | 8 | CONFIG_HIGH_RES_TIMERS=y |
10 | CONFIG_BLK_DEV_INITRD=y | 9 | CONFIG_BLK_DEV_INITRD=y |
10 | CONFIG_RD_LZMA=y | ||
11 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 11 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
12 | CONFIG_EMBEDDED=y | 12 | CONFIG_EMBEDDED=y |
13 | # CONFIG_PERF_EVENTS is not set | 13 | # CONFIG_PERF_EVENTS is not set |
diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h index 08bd299c75b1..910194e9a1e2 100644 --- a/arch/powerpc/include/asm/bitops.h +++ b/arch/powerpc/include/asm/bitops.h | |||
@@ -53,7 +53,7 @@ | |||
53 | #define smp_mb__after_clear_bit() smp_mb() | 53 | #define smp_mb__after_clear_bit() smp_mb() |
54 | 54 | ||
55 | /* Macro for generating the ***_bits() functions */ | 55 | /* Macro for generating the ***_bits() functions */ |
56 | #define DEFINE_BITOP(fn, op, prefix, postfix) \ | 56 | #define DEFINE_BITOP(fn, op, prefix) \ |
57 | static __inline__ void fn(unsigned long mask, \ | 57 | static __inline__ void fn(unsigned long mask, \ |
58 | volatile unsigned long *_p) \ | 58 | volatile unsigned long *_p) \ |
59 | { \ | 59 | { \ |
@@ -66,16 +66,15 @@ static __inline__ void fn(unsigned long mask, \ | |||
66 | PPC405_ERR77(0,%3) \ | 66 | PPC405_ERR77(0,%3) \ |
67 | PPC_STLCX "%0,0,%3\n" \ | 67 | PPC_STLCX "%0,0,%3\n" \ |
68 | "bne- 1b\n" \ | 68 | "bne- 1b\n" \ |
69 | postfix \ | ||
70 | : "=&r" (old), "+m" (*p) \ | 69 | : "=&r" (old), "+m" (*p) \ |
71 | : "r" (mask), "r" (p) \ | 70 | : "r" (mask), "r" (p) \ |
72 | : "cc", "memory"); \ | 71 | : "cc", "memory"); \ |
73 | } | 72 | } |
74 | 73 | ||
75 | DEFINE_BITOP(set_bits, or, "", "") | 74 | DEFINE_BITOP(set_bits, or, "") |
76 | DEFINE_BITOP(clear_bits, andc, "", "") | 75 | DEFINE_BITOP(clear_bits, andc, "") |
77 | DEFINE_BITOP(clear_bits_unlock, andc, PPC_RELEASE_BARRIER, "") | 76 | DEFINE_BITOP(clear_bits_unlock, andc, PPC_RELEASE_BARRIER) |
78 | DEFINE_BITOP(change_bits, xor, "", "") | 77 | DEFINE_BITOP(change_bits, xor, "") |
79 | 78 | ||
80 | static __inline__ void set_bit(int nr, volatile unsigned long *addr) | 79 | static __inline__ void set_bit(int nr, volatile unsigned long *addr) |
81 | { | 80 | { |
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index fb3245e928ea..fcc54ad159ba 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h | |||
@@ -52,6 +52,7 @@ struct cpu_spec { | |||
52 | char *cpu_name; | 52 | char *cpu_name; |
53 | unsigned long cpu_features; /* Kernel features */ | 53 | unsigned long cpu_features; /* Kernel features */ |
54 | unsigned int cpu_user_features; /* Userland features */ | 54 | unsigned int cpu_user_features; /* Userland features */ |
55 | unsigned int cpu_user_features2; /* Userland features v2 */ | ||
55 | unsigned int mmu_features; /* MMU features */ | 56 | unsigned int mmu_features; /* MMU features */ |
56 | 57 | ||
57 | /* cache line sizes */ | 58 | /* cache line sizes */ |
@@ -151,7 +152,7 @@ extern const char *powerpc_base_platform; | |||
151 | #define CPU_FTR_HVMODE LONG_ASM_CONST(0x0000000100000000) | 152 | #define CPU_FTR_HVMODE LONG_ASM_CONST(0x0000000100000000) |
152 | #define CPU_FTR_ARCH_201 LONG_ASM_CONST(0x0000000200000000) | 153 | #define CPU_FTR_ARCH_201 LONG_ASM_CONST(0x0000000200000000) |
153 | #define CPU_FTR_ARCH_206 LONG_ASM_CONST(0x0000000400000000) | 154 | #define CPU_FTR_ARCH_206 LONG_ASM_CONST(0x0000000400000000) |
154 | #define CPU_FTR_CFAR LONG_ASM_CONST(0x0000000800000000) | 155 | #define CPU_FTR_ARCH_207S LONG_ASM_CONST(0x0000000800000000) |
155 | #define CPU_FTR_IABR LONG_ASM_CONST(0x0000001000000000) | 156 | #define CPU_FTR_IABR LONG_ASM_CONST(0x0000001000000000) |
156 | #define CPU_FTR_MMCRA LONG_ASM_CONST(0x0000002000000000) | 157 | #define CPU_FTR_MMCRA LONG_ASM_CONST(0x0000002000000000) |
157 | #define CPU_FTR_CTRL LONG_ASM_CONST(0x0000004000000000) | 158 | #define CPU_FTR_CTRL LONG_ASM_CONST(0x0000004000000000) |
@@ -172,7 +173,7 @@ extern const char *powerpc_base_platform; | |||
172 | #define CPU_FTR_ICSWX LONG_ASM_CONST(0x0020000000000000) | 173 | #define CPU_FTR_ICSWX LONG_ASM_CONST(0x0020000000000000) |
173 | #define CPU_FTR_VMX_COPY LONG_ASM_CONST(0x0040000000000000) | 174 | #define CPU_FTR_VMX_COPY LONG_ASM_CONST(0x0040000000000000) |
174 | #define CPU_FTR_TM LONG_ASM_CONST(0x0080000000000000) | 175 | #define CPU_FTR_TM LONG_ASM_CONST(0x0080000000000000) |
175 | #define CPU_FTR_BCTAR LONG_ASM_CONST(0x0100000000000000) | 176 | #define CPU_FTR_CFAR LONG_ASM_CONST(0x0100000000000000) |
176 | #define CPU_FTR_HAS_PPR LONG_ASM_CONST(0x0200000000000000) | 177 | #define CPU_FTR_HAS_PPR LONG_ASM_CONST(0x0200000000000000) |
177 | #define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000) | 178 | #define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000) |
178 | 179 | ||
@@ -374,7 +375,7 @@ extern const char *powerpc_base_platform; | |||
374 | #define CPU_FTRS_E6500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ | 375 | #define CPU_FTRS_E6500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ |
375 | CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ | 376 | CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ |
376 | CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ | 377 | CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ |
377 | CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV) | 378 | CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_ALTIVEC_COMP) |
378 | #define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) | 379 | #define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) |
379 | 380 | ||
380 | /* 64-bit CPUs */ | 381 | /* 64-bit CPUs */ |
@@ -421,8 +422,8 @@ extern const char *powerpc_base_platform; | |||
421 | CPU_FTR_DSCR | CPU_FTR_SAO | \ | 422 | CPU_FTR_DSCR | CPU_FTR_SAO | \ |
422 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ | 423 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ |
423 | CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ | 424 | CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ |
424 | CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | CPU_FTR_BCTAR | \ | 425 | CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \ |
425 | CPU_FTR_TM_COMP) | 426 | CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP) |
426 | #define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ | 427 | #define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ |
427 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ | 428 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ |
428 | CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ | 429 | CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
diff --git a/arch/powerpc/include/asm/dma.h b/arch/powerpc/include/asm/dma.h index f6813e919bb2..a5c6d83b5f60 100644 --- a/arch/powerpc/include/asm/dma.h +++ b/arch/powerpc/include/asm/dma.h | |||
@@ -16,10 +16,6 @@ | |||
16 | * | 16 | * |
17 | * None of this really applies for Power Macintoshes. There is | 17 | * None of this really applies for Power Macintoshes. There is |
18 | * basically just enough here to get kernel/dma.c to compile. | 18 | * basically just enough here to get kernel/dma.c to compile. |
19 | * | ||
20 | * There may be some comments or restrictions made here which are | ||
21 | * not valid for the PReP platform. Take what you read | ||
22 | * with a grain of salt. | ||
23 | */ | 19 | */ |
24 | 20 | ||
25 | #include <asm/io.h> | 21 | #include <asm/io.h> |
@@ -57,7 +53,6 @@ | |||
57 | * - page registers for 5-7 don't use data bit 0, represent 128K pages | 53 | * - page registers for 5-7 don't use data bit 0, represent 128K pages |
58 | * - page registers for 0-3 use bit 0, represent 64K pages | 54 | * - page registers for 0-3 use bit 0, represent 64K pages |
59 | * | 55 | * |
60 | * On PReP, DMA transfers are limited to the lower 16MB of _physical_ memory. | ||
61 | * On CHRP, the W83C553F (and VLSI Tollgate?) support full 32 bit addressing. | 56 | * On CHRP, the W83C553F (and VLSI Tollgate?) support full 32 bit addressing. |
62 | * Note that addresses loaded into registers must be _physical_ addresses, | 57 | * Note that addresses loaded into registers must be _physical_ addresses, |
63 | * not logical addresses (which may differ if paging is active). | 58 | * not logical addresses (which may differ if paging is active). |
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h index ac9790fc3836..cc0655a702a7 100644 --- a/arch/powerpc/include/asm/elf.h +++ b/arch/powerpc/include/asm/elf.h | |||
@@ -61,6 +61,7 @@ typedef elf_vrregset_t elf_fpxregset_t; | |||
61 | instruction set this cpu supports. This could be done in userspace, | 61 | instruction set this cpu supports. This could be done in userspace, |
62 | but it's not easy, and we've already done it here. */ | 62 | but it's not easy, and we've already done it here. */ |
63 | # define ELF_HWCAP (cur_cpu_spec->cpu_user_features) | 63 | # define ELF_HWCAP (cur_cpu_spec->cpu_user_features) |
64 | # define ELF_HWCAP2 (cur_cpu_spec->cpu_user_features2) | ||
64 | 65 | ||
65 | /* This yields a string that ld.so will use to load implementation | 66 | /* This yields a string that ld.so will use to load implementation |
66 | specific libraries for optimization. This is more specific in | 67 | specific libraries for optimization. This is more specific in |
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 05e6d2ee1db9..8e5fae8beaf6 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h | |||
@@ -414,7 +414,6 @@ label##_relon_hv: \ | |||
414 | #define SOFTEN_NOTEST_HV(vec) _SOFTEN_TEST(EXC_HV, vec) | 414 | #define SOFTEN_NOTEST_HV(vec) _SOFTEN_TEST(EXC_HV, vec) |
415 | 415 | ||
416 | #define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \ | 416 | #define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \ |
417 | HMT_MEDIUM_PPR_DISCARD; \ | ||
418 | SET_SCRATCH0(r13); /* save r13 */ \ | 417 | SET_SCRATCH0(r13); /* save r13 */ \ |
419 | EXCEPTION_PROLOG_0(PACA_EXGEN); \ | 418 | EXCEPTION_PROLOG_0(PACA_EXGEN); \ |
420 | __EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \ | 419 | __EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \ |
@@ -427,6 +426,7 @@ label##_relon_hv: \ | |||
427 | . = loc; \ | 426 | . = loc; \ |
428 | .globl label##_pSeries; \ | 427 | .globl label##_pSeries; \ |
429 | label##_pSeries: \ | 428 | label##_pSeries: \ |
429 | HMT_MEDIUM_PPR_DISCARD; \ | ||
430 | _MASKABLE_EXCEPTION_PSERIES(vec, label, \ | 430 | _MASKABLE_EXCEPTION_PSERIES(vec, label, \ |
431 | EXC_STD, SOFTEN_TEST_PR) | 431 | EXC_STD, SOFTEN_TEST_PR) |
432 | 432 | ||
diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h index 097dee57a7a9..0df54646f968 100644 --- a/arch/powerpc/include/asm/firmware.h +++ b/arch/powerpc/include/asm/firmware.h | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <asm/feature-fixups.h> | 18 | #include <asm/feature-fixups.h> |
19 | 19 | ||
20 | /* firmware feature bitmask values */ | 20 | /* firmware feature bitmask values */ |
21 | #define FIRMWARE_MAX_FEATURES 63 | ||
22 | 21 | ||
23 | #define FW_FEATURE_PFT ASM_CONST(0x0000000000000001) | 22 | #define FW_FEATURE_PFT ASM_CONST(0x0000000000000001) |
24 | #define FW_FEATURE_TCE ASM_CONST(0x0000000000000002) | 23 | #define FW_FEATURE_TCE ASM_CONST(0x0000000000000002) |
@@ -51,6 +50,8 @@ | |||
51 | #define FW_FEATURE_OPALv2 ASM_CONST(0x0000000020000000) | 50 | #define FW_FEATURE_OPALv2 ASM_CONST(0x0000000020000000) |
52 | #define FW_FEATURE_SET_MODE ASM_CONST(0x0000000040000000) | 51 | #define FW_FEATURE_SET_MODE ASM_CONST(0x0000000040000000) |
53 | #define FW_FEATURE_BEST_ENERGY ASM_CONST(0x0000000080000000) | 52 | #define FW_FEATURE_BEST_ENERGY ASM_CONST(0x0000000080000000) |
53 | #define FW_FEATURE_TYPE1_AFFINITY ASM_CONST(0x0000000100000000) | ||
54 | #define FW_FEATURE_PRRN ASM_CONST(0x0000000200000000) | ||
54 | 55 | ||
55 | #ifndef __ASSEMBLY__ | 56 | #ifndef __ASSEMBLY__ |
56 | 57 | ||
@@ -65,7 +66,8 @@ enum { | |||
65 | FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR | | 66 | FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR | |
66 | FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR | | 67 | FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR | |
67 | FW_FEATURE_CMO | FW_FEATURE_VPHN | FW_FEATURE_XCMO | | 68 | FW_FEATURE_CMO | FW_FEATURE_VPHN | FW_FEATURE_XCMO | |
68 | FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY, | 69 | FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY | |
70 | FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN, | ||
69 | FW_FEATURE_PSERIES_ALWAYS = 0, | 71 | FW_FEATURE_PSERIES_ALWAYS = 0, |
70 | FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2, | 72 | FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2, |
71 | FW_FEATURE_POWERNV_ALWAYS = 0, | 73 | FW_FEATURE_POWERNV_ALWAYS = 0, |
diff --git a/arch/powerpc/include/asm/hardirq.h b/arch/powerpc/include/asm/hardirq.h index 3147a2970125..3bdcfce2c42a 100644 --- a/arch/powerpc/include/asm/hardirq.h +++ b/arch/powerpc/include/asm/hardirq.h | |||
@@ -10,6 +10,9 @@ typedef struct { | |||
10 | unsigned int pmu_irqs; | 10 | unsigned int pmu_irqs; |
11 | unsigned int mce_exceptions; | 11 | unsigned int mce_exceptions; |
12 | unsigned int spurious_irqs; | 12 | unsigned int spurious_irqs; |
13 | #ifdef CONFIG_PPC_DOORBELL | ||
14 | unsigned int doorbell_irqs; | ||
15 | #endif | ||
13 | } ____cacheline_aligned irq_cpustat_t; | 16 | } ____cacheline_aligned irq_cpustat_t; |
14 | 17 | ||
15 | DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); | 18 | DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); |
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 62e11a32c4c2..f2498c8e595d 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h | |||
@@ -3,9 +3,37 @@ | |||
3 | 3 | ||
4 | #ifdef CONFIG_HUGETLB_PAGE | 4 | #ifdef CONFIG_HUGETLB_PAGE |
5 | #include <asm/page.h> | 5 | #include <asm/page.h> |
6 | #include <asm-generic/hugetlb.h> | ||
6 | 7 | ||
7 | extern struct kmem_cache *hugepte_cache; | 8 | extern struct kmem_cache *hugepte_cache; |
8 | 9 | ||
10 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
11 | /* | ||
12 | * This should work for other subarchs too. But right now we use the | ||
13 | * new format only for 64bit book3s | ||
14 | */ | ||
15 | static inline pte_t *hugepd_page(hugepd_t hpd) | ||
16 | { | ||
17 | BUG_ON(!hugepd_ok(hpd)); | ||
18 | /* | ||
19 | * We have only four bits to encode, MMU page size | ||
20 | */ | ||
21 | BUILD_BUG_ON((MMU_PAGE_COUNT - 1) > 0xf); | ||
22 | return (pte_t *)(hpd.pd & ~HUGEPD_SHIFT_MASK); | ||
23 | } | ||
24 | |||
25 | static inline unsigned int hugepd_mmu_psize(hugepd_t hpd) | ||
26 | { | ||
27 | return (hpd.pd & HUGEPD_SHIFT_MASK) >> 2; | ||
28 | } | ||
29 | |||
30 | static inline unsigned int hugepd_shift(hugepd_t hpd) | ||
31 | { | ||
32 | return mmu_psize_to_shift(hugepd_mmu_psize(hpd)); | ||
33 | } | ||
34 | |||
35 | #else | ||
36 | |||
9 | static inline pte_t *hugepd_page(hugepd_t hpd) | 37 | static inline pte_t *hugepd_page(hugepd_t hpd) |
10 | { | 38 | { |
11 | BUG_ON(!hugepd_ok(hpd)); | 39 | BUG_ON(!hugepd_ok(hpd)); |
@@ -17,6 +45,9 @@ static inline unsigned int hugepd_shift(hugepd_t hpd) | |||
17 | return hpd.pd & HUGEPD_SHIFT_MASK; | 45 | return hpd.pd & HUGEPD_SHIFT_MASK; |
18 | } | 46 | } |
19 | 47 | ||
48 | #endif /* CONFIG_PPC_BOOK3S_64 */ | ||
49 | |||
50 | |||
20 | static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, | 51 | static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, |
21 | unsigned pdshift) | 52 | unsigned pdshift) |
22 | { | 53 | { |
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index f94ef4213e9d..dd15e5e37d6d 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h | |||
@@ -15,10 +15,6 @@ | |||
15 | extern int check_legacy_ioport(unsigned long base_port); | 15 | extern int check_legacy_ioport(unsigned long base_port); |
16 | #define I8042_DATA_REG 0x60 | 16 | #define I8042_DATA_REG 0x60 |
17 | #define FDC_BASE 0x3f0 | 17 | #define FDC_BASE 0x3f0 |
18 | /* only relevant for PReP */ | ||
19 | #define _PIDXR 0x279 | ||
20 | #define _PNPWRP 0xa79 | ||
21 | #define PNPBIOS_BASE 0xf000 | ||
22 | 18 | ||
23 | #if defined(CONFIG_PPC64) && defined(CONFIG_PCI) | 19 | #if defined(CONFIG_PPC64) && defined(CONFIG_PCI) |
24 | extern struct pci_dev *isa_bridge_pcidev; | 20 | extern struct pci_dev *isa_bridge_pcidev; |
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h index aabcdba8f6b0..b9dd382cb349 100644 --- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h | |||
@@ -67,6 +67,10 @@ | |||
67 | #define BOOKE_INTERRUPT_HV_SYSCALL 40 | 67 | #define BOOKE_INTERRUPT_HV_SYSCALL 40 |
68 | #define BOOKE_INTERRUPT_HV_PRIV 41 | 68 | #define BOOKE_INTERRUPT_HV_PRIV 41 |
69 | 69 | ||
70 | /* altivec */ | ||
71 | #define BOOKE_INTERRUPT_ALTIVEC_UNAVAIL 42 | ||
72 | #define BOOKE_INTERRUPT_ALTIVEC_ASSIST 43 | ||
73 | |||
70 | /* book3s */ | 74 | /* book3s */ |
71 | 75 | ||
72 | #define BOOK3S_INTERRUPT_SYSTEM_RESET 0x100 | 76 | #define BOOK3S_INTERRUPT_SYSTEM_RESET 0x100 |
diff --git a/arch/powerpc/include/asm/linkage.h b/arch/powerpc/include/asm/linkage.h new file mode 100644 index 000000000000..b36f650a13ff --- /dev/null +++ b/arch/powerpc/include/asm/linkage.h | |||
@@ -0,0 +1,13 @@ | |||
1 | #ifndef _ASM_POWERPC_LINKAGE_H | ||
2 | #define _ASM_POWERPC_LINKAGE_H | ||
3 | |||
4 | #ifdef CONFIG_PPC64 | ||
5 | #define cond_syscall(x) \ | ||
6 | asm ("\t.weak " #x "\n\t.set " #x ", sys_ni_syscall\n" \ | ||
7 | "\t.weak ." #x "\n\t.set ." #x ", .sys_ni_syscall\n") | ||
8 | #define SYSCALL_ALIAS(alias, name) \ | ||
9 | asm ("\t.globl " #alias "\n\t.set " #alias ", " #name "\n" \ | ||
10 | "\t.globl ." #alias "\n\t.set ." #alias ", ." #name) | ||
11 | #endif | ||
12 | |||
13 | #endif /* _ASM_POWERPC_LINKAGE_H */ | ||
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 3d6b4100dac1..3f3f691be2e7 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h | |||
@@ -50,7 +50,8 @@ struct machdep_calls { | |||
50 | unsigned long prpn, | 50 | unsigned long prpn, |
51 | unsigned long rflags, | 51 | unsigned long rflags, |
52 | unsigned long vflags, | 52 | unsigned long vflags, |
53 | int psize, int ssize); | 53 | int psize, int apsize, |
54 | int ssize); | ||
54 | long (*hpte_remove)(unsigned long hpte_group); | 55 | long (*hpte_remove)(unsigned long hpte_group); |
55 | void (*hpte_removebolted)(unsigned long ea, | 56 | void (*hpte_removebolted)(unsigned long ea, |
56 | int psize, int ssize); | 57 | int psize, int ssize); |
diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/mmu-book3e.h index 99d43e0c1e4a..936db360790a 100644 --- a/arch/powerpc/include/asm/mmu-book3e.h +++ b/arch/powerpc/include/asm/mmu-book3e.h | |||
@@ -215,6 +215,7 @@ | |||
215 | #define TLBILX_T_CLASS3 7 | 215 | #define TLBILX_T_CLASS3 7 |
216 | 216 | ||
217 | #ifndef __ASSEMBLY__ | 217 | #ifndef __ASSEMBLY__ |
218 | #include <asm/bug.h> | ||
218 | 219 | ||
219 | extern unsigned int tlbcam_index; | 220 | extern unsigned int tlbcam_index; |
220 | 221 | ||
@@ -231,6 +232,10 @@ typedef struct { | |||
231 | u64 high_slices_psize; /* 4 bits per slice for now */ | 232 | u64 high_slices_psize; /* 4 bits per slice for now */ |
232 | u16 user_psize; /* page size index */ | 233 | u16 user_psize; /* page size index */ |
233 | #endif | 234 | #endif |
235 | #ifdef CONFIG_PPC_64K_PAGES | ||
236 | /* for 4K PTE fragment support */ | ||
237 | void *pte_frag; | ||
238 | #endif | ||
234 | } mm_context_t; | 239 | } mm_context_t; |
235 | 240 | ||
236 | /* Page size definitions, common between 32 and 64-bit | 241 | /* Page size definitions, common between 32 and 64-bit |
@@ -250,6 +255,23 @@ struct mmu_psize_def | |||
250 | }; | 255 | }; |
251 | extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; | 256 | extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; |
252 | 257 | ||
258 | static inline int shift_to_mmu_psize(unsigned int shift) | ||
259 | { | ||
260 | int psize; | ||
261 | |||
262 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) | ||
263 | if (mmu_psize_defs[psize].shift == shift) | ||
264 | return psize; | ||
265 | return -1; | ||
266 | } | ||
267 | |||
268 | static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize) | ||
269 | { | ||
270 | if (mmu_psize_defs[mmu_psize].shift) | ||
271 | return mmu_psize_defs[mmu_psize].shift; | ||
272 | BUG(); | ||
273 | } | ||
274 | |||
253 | /* The page sizes use the same names as 64-bit hash but are | 275 | /* The page sizes use the same names as 64-bit hash but are |
254 | * constants | 276 | * constants |
255 | */ | 277 | */ |
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h index b59e06f507ea..2accc9611248 100644 --- a/arch/powerpc/include/asm/mmu-hash64.h +++ b/arch/powerpc/include/asm/mmu-hash64.h | |||
@@ -21,6 +21,7 @@ | |||
21 | * complete pgtable.h but only a portion of it. | 21 | * complete pgtable.h but only a portion of it. |
22 | */ | 22 | */ |
23 | #include <asm/pgtable-ppc64.h> | 23 | #include <asm/pgtable-ppc64.h> |
24 | #include <asm/bug.h> | ||
24 | 25 | ||
25 | /* | 26 | /* |
26 | * Segment table | 27 | * Segment table |
@@ -154,11 +155,29 @@ extern unsigned long htab_hash_mask; | |||
154 | struct mmu_psize_def | 155 | struct mmu_psize_def |
155 | { | 156 | { |
156 | unsigned int shift; /* number of bits */ | 157 | unsigned int shift; /* number of bits */ |
157 | unsigned int penc; /* HPTE encoding */ | 158 | int penc[MMU_PAGE_COUNT]; /* HPTE encoding */ |
158 | unsigned int tlbiel; /* tlbiel supported for that page size */ | 159 | unsigned int tlbiel; /* tlbiel supported for that page size */ |
159 | unsigned long avpnm; /* bits to mask out in AVPN in the HPTE */ | 160 | unsigned long avpnm; /* bits to mask out in AVPN in the HPTE */ |
160 | unsigned long sllp; /* SLB L||LP (exact mask to use in slbmte) */ | 161 | unsigned long sllp; /* SLB L||LP (exact mask to use in slbmte) */ |
161 | }; | 162 | }; |
163 | extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; | ||
164 | |||
165 | static inline int shift_to_mmu_psize(unsigned int shift) | ||
166 | { | ||
167 | int psize; | ||
168 | |||
169 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) | ||
170 | if (mmu_psize_defs[psize].shift == shift) | ||
171 | return psize; | ||
172 | return -1; | ||
173 | } | ||
174 | |||
175 | static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize) | ||
176 | { | ||
177 | if (mmu_psize_defs[mmu_psize].shift) | ||
178 | return mmu_psize_defs[mmu_psize].shift; | ||
179 | BUG(); | ||
180 | } | ||
162 | 181 | ||
163 | #endif /* __ASSEMBLY__ */ | 182 | #endif /* __ASSEMBLY__ */ |
164 | 183 | ||
@@ -181,6 +200,13 @@ struct mmu_psize_def | |||
181 | */ | 200 | */ |
182 | #define VPN_SHIFT 12 | 201 | #define VPN_SHIFT 12 |
183 | 202 | ||
203 | /* | ||
204 | * HPTE Large Page (LP) details | ||
205 | */ | ||
206 | #define LP_SHIFT 12 | ||
207 | #define LP_BITS 8 | ||
208 | #define LP_MASK(i) ((0xFF >> (i)) << LP_SHIFT) | ||
209 | |||
184 | #ifndef __ASSEMBLY__ | 210 | #ifndef __ASSEMBLY__ |
185 | 211 | ||
186 | static inline int segment_shift(int ssize) | 212 | static inline int segment_shift(int ssize) |
@@ -193,7 +219,6 @@ static inline int segment_shift(int ssize) | |||
193 | /* | 219 | /* |
194 | * The current system page and segment sizes | 220 | * The current system page and segment sizes |
195 | */ | 221 | */ |
196 | extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; | ||
197 | extern int mmu_linear_psize; | 222 | extern int mmu_linear_psize; |
198 | extern int mmu_virtual_psize; | 223 | extern int mmu_virtual_psize; |
199 | extern int mmu_vmalloc_psize; | 224 | extern int mmu_vmalloc_psize; |
@@ -237,14 +262,14 @@ static inline unsigned long hpte_encode_avpn(unsigned long vpn, int psize, | |||
237 | 262 | ||
238 | /* | 263 | /* |
239 | * This function sets the AVPN and L fields of the HPTE appropriately | 264 | * This function sets the AVPN and L fields of the HPTE appropriately |
240 | * for the page size | 265 | * using the base page size and actual page size. |
241 | */ | 266 | */ |
242 | static inline unsigned long hpte_encode_v(unsigned long vpn, | 267 | static inline unsigned long hpte_encode_v(unsigned long vpn, int base_psize, |
243 | int psize, int ssize) | 268 | int actual_psize, int ssize) |
244 | { | 269 | { |
245 | unsigned long v; | 270 | unsigned long v; |
246 | v = hpte_encode_avpn(vpn, psize, ssize); | 271 | v = hpte_encode_avpn(vpn, base_psize, ssize); |
247 | if (psize != MMU_PAGE_4K) | 272 | if (actual_psize != MMU_PAGE_4K) |
248 | v |= HPTE_V_LARGE; | 273 | v |= HPTE_V_LARGE; |
249 | return v; | 274 | return v; |
250 | } | 275 | } |
@@ -254,19 +279,17 @@ static inline unsigned long hpte_encode_v(unsigned long vpn, | |||
254 | * for the page size. We assume the pa is already "clean" that is properly | 279 | * for the page size. We assume the pa is already "clean" that is properly |
255 | * aligned for the requested page size | 280 | * aligned for the requested page size |
256 | */ | 281 | */ |
257 | static inline unsigned long hpte_encode_r(unsigned long pa, int psize) | 282 | static inline unsigned long hpte_encode_r(unsigned long pa, int base_psize, |
283 | int actual_psize) | ||
258 | { | 284 | { |
259 | unsigned long r; | ||
260 | |||
261 | /* A 4K page needs no special encoding */ | 285 | /* A 4K page needs no special encoding */ |
262 | if (psize == MMU_PAGE_4K) | 286 | if (actual_psize == MMU_PAGE_4K) |
263 | return pa & HPTE_R_RPN; | 287 | return pa & HPTE_R_RPN; |
264 | else { | 288 | else { |
265 | unsigned int penc = mmu_psize_defs[psize].penc; | 289 | unsigned int penc = mmu_psize_defs[base_psize].penc[actual_psize]; |
266 | unsigned int shift = mmu_psize_defs[psize].shift; | 290 | unsigned int shift = mmu_psize_defs[actual_psize].shift; |
267 | return (pa & ~((1ul << shift) - 1)) | (penc << 12); | 291 | return (pa & ~((1ul << shift) - 1)) | (penc << LP_SHIFT); |
268 | } | 292 | } |
269 | return r; | ||
270 | } | 293 | } |
271 | 294 | ||
272 | /* | 295 | /* |
@@ -319,7 +342,8 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, | |||
319 | unsigned int shift, unsigned int mmu_psize); | 342 | unsigned int shift, unsigned int mmu_psize); |
320 | extern void hash_failure_debug(unsigned long ea, unsigned long access, | 343 | extern void hash_failure_debug(unsigned long ea, unsigned long access, |
321 | unsigned long vsid, unsigned long trap, | 344 | unsigned long vsid, unsigned long trap, |
322 | int ssize, int psize, unsigned long pte); | 345 | int ssize, int psize, int lpsize, |
346 | unsigned long pte); | ||
323 | extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | 347 | extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend, |
324 | unsigned long pstart, unsigned long prot, | 348 | unsigned long pstart, unsigned long prot, |
325 | int psize, int ssize); | 349 | int psize, int ssize); |
@@ -498,6 +522,10 @@ typedef struct { | |||
498 | unsigned long acop; /* mask of enabled coprocessor types */ | 522 | unsigned long acop; /* mask of enabled coprocessor types */ |
499 | unsigned int cop_pid; /* pid value used with coprocessors */ | 523 | unsigned int cop_pid; /* pid value used with coprocessors */ |
500 | #endif /* CONFIG_PPC_ICSWX */ | 524 | #endif /* CONFIG_PPC_ICSWX */ |
525 | #ifdef CONFIG_PPC_64K_PAGES | ||
526 | /* for 4K PTE fragment support */ | ||
527 | void *pte_frag; | ||
528 | #endif | ||
501 | } mm_context_t; | 529 | } mm_context_t; |
502 | 530 | ||
503 | 531 | ||
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index a4b28f165b6c..b6c8b58b1d76 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h | |||
@@ -117,6 +117,7 @@ extern int opal_enter_rtas(struct rtas_args *args, | |||
117 | #define OPAL_SET_SLOT_LED_STATUS 55 | 117 | #define OPAL_SET_SLOT_LED_STATUS 55 |
118 | #define OPAL_GET_EPOW_STATUS 56 | 118 | #define OPAL_GET_EPOW_STATUS 56 |
119 | #define OPAL_SET_SYSTEM_ATTENTION_LED 57 | 119 | #define OPAL_SET_SYSTEM_ATTENTION_LED 57 |
120 | #define OPAL_PCI_MSI_EOI 63 | ||
120 | 121 | ||
121 | #ifndef __ASSEMBLY__ | 122 | #ifndef __ASSEMBLY__ |
122 | 123 | ||
@@ -506,6 +507,7 @@ int64_t opal_pci_get_xive_reissue(uint64_t phb_id, uint32_t xive_number, | |||
506 | uint8_t *p_bit, uint8_t *q_bit); | 507 | uint8_t *p_bit, uint8_t *q_bit); |
507 | int64_t opal_pci_set_xive_reissue(uint64_t phb_id, uint32_t xive_number, | 508 | int64_t opal_pci_set_xive_reissue(uint64_t phb_id, uint32_t xive_number, |
508 | uint8_t p_bit, uint8_t q_bit); | 509 | uint8_t p_bit, uint8_t q_bit); |
510 | int64_t opal_pci_msi_eoi(uint64_t phb_id, uint32_t hw_irq); | ||
509 | int64_t opal_pci_set_xive_pe(uint64_t phb_id, uint32_t pe_number, | 511 | int64_t opal_pci_set_xive_pe(uint64_t phb_id, uint32_t pe_number, |
510 | uint32_t xive_num); | 512 | uint32_t xive_num); |
511 | int64_t opal_get_xive_source(uint64_t phb_id, uint32_t xive_num, | 513 | int64_t opal_get_xive_source(uint64_t phb_id, uint32_t xive_num, |
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index f072e974f8a2..988c812aab5b 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h | |||
@@ -249,6 +249,7 @@ extern long long virt_phys_offset; | |||
249 | #define is_kernel_addr(x) ((x) >= PAGE_OFFSET) | 249 | #define is_kernel_addr(x) ((x) >= PAGE_OFFSET) |
250 | #endif | 250 | #endif |
251 | 251 | ||
252 | #ifndef CONFIG_PPC_BOOK3S_64 | ||
252 | /* | 253 | /* |
253 | * Use the top bit of the higher-level page table entries to indicate whether | 254 | * Use the top bit of the higher-level page table entries to indicate whether |
254 | * the entries we point to contain hugepages. This works because we know that | 255 | * the entries we point to contain hugepages. This works because we know that |
@@ -260,6 +261,7 @@ extern long long virt_phys_offset; | |||
260 | #else | 261 | #else |
261 | #define PD_HUGE 0x80000000 | 262 | #define PD_HUGE 0x80000000 |
262 | #endif | 263 | #endif |
264 | #endif /* CONFIG_PPC_BOOK3S_64 */ | ||
263 | 265 | ||
264 | /* | 266 | /* |
265 | * Some number of bits at the level of the page table that points to | 267 | * Some number of bits at the level of the page table that points to |
@@ -354,14 +356,27 @@ typedef unsigned long pgprot_t; | |||
354 | typedef struct { signed long pd; } hugepd_t; | 356 | typedef struct { signed long pd; } hugepd_t; |
355 | 357 | ||
356 | #ifdef CONFIG_HUGETLB_PAGE | 358 | #ifdef CONFIG_HUGETLB_PAGE |
359 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
360 | static inline int hugepd_ok(hugepd_t hpd) | ||
361 | { | ||
362 | /* | ||
363 | * hugepd pointer, bottom two bits == 00 and next 4 bits | ||
364 | * indicate size of table | ||
365 | */ | ||
366 | return (((hpd.pd & 0x3) == 0x0) && ((hpd.pd & HUGEPD_SHIFT_MASK) != 0)); | ||
367 | } | ||
368 | #else | ||
357 | static inline int hugepd_ok(hugepd_t hpd) | 369 | static inline int hugepd_ok(hugepd_t hpd) |
358 | { | 370 | { |
359 | return (hpd.pd > 0); | 371 | return (hpd.pd > 0); |
360 | } | 372 | } |
373 | #endif | ||
361 | 374 | ||
362 | #define is_hugepd(pdep) (hugepd_ok(*((hugepd_t *)(pdep)))) | 375 | #define is_hugepd(pdep) (hugepd_ok(*((hugepd_t *)(pdep)))) |
376 | int pgd_huge(pgd_t pgd); | ||
363 | #else /* CONFIG_HUGETLB_PAGE */ | 377 | #else /* CONFIG_HUGETLB_PAGE */ |
364 | #define is_hugepd(pdep) 0 | 378 | #define is_hugepd(pdep) 0 |
379 | #define pgd_huge(pgd) 0 | ||
365 | #endif /* CONFIG_HUGETLB_PAGE */ | 380 | #endif /* CONFIG_HUGETLB_PAGE */ |
366 | 381 | ||
367 | struct page; | 382 | struct page; |
@@ -378,7 +393,11 @@ void arch_free_page(struct page *page, int order); | |||
378 | 393 | ||
379 | struct vm_area_struct; | 394 | struct vm_area_struct; |
380 | 395 | ||
396 | #ifdef CONFIG_PPC_64K_PAGES | ||
397 | typedef pte_t *pgtable_t; | ||
398 | #else | ||
381 | typedef struct page *pgtable_t; | 399 | typedef struct page *pgtable_t; |
400 | #endif | ||
382 | 401 | ||
383 | #include <asm-generic/memory_model.h> | 402 | #include <asm-generic/memory_model.h> |
384 | #endif /* __ASSEMBLY__ */ | 403 | #endif /* __ASSEMBLY__ */ |
diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h index cd915d6b093d..88693cef4f3d 100644 --- a/arch/powerpc/include/asm/page_64.h +++ b/arch/powerpc/include/asm/page_64.h | |||
@@ -99,8 +99,7 @@ extern unsigned long slice_get_unmapped_area(unsigned long addr, | |||
99 | unsigned long len, | 99 | unsigned long len, |
100 | unsigned long flags, | 100 | unsigned long flags, |
101 | unsigned int psize, | 101 | unsigned int psize, |
102 | int topdown, | 102 | int topdown); |
103 | int use_cache); | ||
104 | 103 | ||
105 | extern unsigned int get_slice_psize(struct mm_struct *mm, | 104 | extern unsigned int get_slice_psize(struct mm_struct *mm, |
106 | unsigned long addr); | 105 | unsigned long addr); |
diff --git a/arch/powerpc/include/asm/parport.h b/arch/powerpc/include/asm/parport.h index 6dc2577932b1..a452968b29ea 100644 --- a/arch/powerpc/include/asm/parport.h +++ b/arch/powerpc/include/asm/parport.h | |||
@@ -21,9 +21,7 @@ static int parport_pc_find_nonpci_ports (int autoirq, int autodma) | |||
21 | int count = 0; | 21 | int count = 0; |
22 | int virq; | 22 | int virq; |
23 | 23 | ||
24 | for (np = NULL; (np = of_find_compatible_node(np, | 24 | for_each_compatible_node(np, "parallel", "pnpPNP,400") { |
25 | "parallel", | ||
26 | "pnpPNP,400")) != NULL;) { | ||
27 | prop = of_get_property(np, "reg", &propsize); | 25 | prop = of_get_property(np, "reg", &propsize); |
28 | if (!prop || propsize > 6*sizeof(u32)) | 26 | if (!prop || propsize > 6*sizeof(u32)) |
29 | continue; | 27 | continue; |
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 025a130729bc..ffbc5fd549ac 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h | |||
@@ -70,6 +70,8 @@ struct pci_controller { | |||
70 | * BIG_ENDIAN - cfg_addr is a big endian register | 70 | * BIG_ENDIAN - cfg_addr is a big endian register |
71 | * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs on | 71 | * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs on |
72 | * the PLB4. Effectively disable MRM commands by setting this. | 72 | * the PLB4. Effectively disable MRM commands by setting this. |
73 | * FSL_CFG_REG_LINK - Freescale controller version in which the PCIe | ||
74 | * link status is in a RC PCIe cfg register (vs being a SoC register) | ||
73 | */ | 75 | */ |
74 | #define PPC_INDIRECT_TYPE_SET_CFG_TYPE 0x00000001 | 76 | #define PPC_INDIRECT_TYPE_SET_CFG_TYPE 0x00000001 |
75 | #define PPC_INDIRECT_TYPE_EXT_REG 0x00000002 | 77 | #define PPC_INDIRECT_TYPE_EXT_REG 0x00000002 |
@@ -77,6 +79,7 @@ struct pci_controller { | |||
77 | #define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008 | 79 | #define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008 |
78 | #define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010 | 80 | #define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010 |
79 | #define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020 | 81 | #define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020 |
82 | #define PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK 0x00000040 | ||
80 | u32 indirect_type; | 83 | u32 indirect_type; |
81 | /* Currently, we limit ourselves to 1 IO range and 3 mem | 84 | /* Currently, we limit ourselves to 1 IO range and 3 mem |
82 | * ranges since the common pci_bus structure can't handle more | 85 | * ranges since the common pci_bus structure can't handle more |
@@ -90,9 +93,9 @@ struct pci_controller { | |||
90 | 93 | ||
91 | #ifdef CONFIG_PPC64 | 94 | #ifdef CONFIG_PPC64 |
92 | unsigned long buid; | 95 | unsigned long buid; |
96 | #endif /* CONFIG_PPC64 */ | ||
93 | 97 | ||
94 | void *private_data; | 98 | void *private_data; |
95 | #endif /* CONFIG_PPC64 */ | ||
96 | }; | 99 | }; |
97 | 100 | ||
98 | /* These are used for config access before all the PCI probing | 101 | /* These are used for config access before all the PCI probing |
@@ -117,6 +120,12 @@ extern void setup_indirect_pci(struct pci_controller* hose, | |||
117 | resource_size_t cfg_addr, | 120 | resource_size_t cfg_addr, |
118 | resource_size_t cfg_data, u32 flags); | 121 | resource_size_t cfg_data, u32 flags); |
119 | 122 | ||
123 | extern int indirect_read_config(struct pci_bus *bus, unsigned int devfn, | ||
124 | int offset, int len, u32 *val); | ||
125 | |||
126 | extern int indirect_write_config(struct pci_bus *bus, unsigned int devfn, | ||
127 | int offset, int len, u32 val); | ||
128 | |||
120 | static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) | 129 | static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) |
121 | { | 130 | { |
122 | return bus->sysdata; | 131 | return bus->sysdata; |
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h index d0aec72722e9..f265049dd7d6 100644 --- a/arch/powerpc/include/asm/perf_event_server.h +++ b/arch/powerpc/include/asm/perf_event_server.h | |||
@@ -33,6 +33,8 @@ struct power_pmu { | |||
33 | unsigned long *valp); | 33 | unsigned long *valp); |
34 | int (*get_alternatives)(u64 event_id, unsigned int flags, | 34 | int (*get_alternatives)(u64 event_id, unsigned int flags, |
35 | u64 alt[]); | 35 | u64 alt[]); |
36 | u64 (*bhrb_filter_map)(u64 branch_sample_type); | ||
37 | void (*config_bhrb)(u64 pmu_bhrb_filter); | ||
36 | void (*disable_pmc)(unsigned int pmc, unsigned long mmcr[]); | 38 | void (*disable_pmc)(unsigned int pmc, unsigned long mmcr[]); |
37 | int (*limited_pmc_event)(u64 event_id); | 39 | int (*limited_pmc_event)(u64 event_id); |
38 | u32 flags; | 40 | u32 flags; |
@@ -42,6 +44,9 @@ struct power_pmu { | |||
42 | int (*cache_events)[PERF_COUNT_HW_CACHE_MAX] | 44 | int (*cache_events)[PERF_COUNT_HW_CACHE_MAX] |
43 | [PERF_COUNT_HW_CACHE_OP_MAX] | 45 | [PERF_COUNT_HW_CACHE_OP_MAX] |
44 | [PERF_COUNT_HW_CACHE_RESULT_MAX]; | 46 | [PERF_COUNT_HW_CACHE_RESULT_MAX]; |
47 | |||
48 | /* BHRB entries in the PMU */ | ||
49 | int bhrb_nr; | ||
45 | }; | 50 | }; |
46 | 51 | ||
47 | /* | 52 | /* |
@@ -52,6 +57,9 @@ struct power_pmu { | |||
52 | #define PPMU_NO_SIPR 0x00000004 /* no SIPR/HV in MMCRA at all */ | 57 | #define PPMU_NO_SIPR 0x00000004 /* no SIPR/HV in MMCRA at all */ |
53 | #define PPMU_NO_CONT_SAMPLING 0x00000008 /* no continuous sampling */ | 58 | #define PPMU_NO_CONT_SAMPLING 0x00000008 /* no continuous sampling */ |
54 | #define PPMU_SIAR_VALID 0x00000010 /* Processor has SIAR Valid bit */ | 59 | #define PPMU_SIAR_VALID 0x00000010 /* Processor has SIAR Valid bit */ |
60 | #define PPMU_HAS_SSLOT 0x00000020 /* Has sampled slot in MMCRA */ | ||
61 | #define PPMU_HAS_SIER 0x00000040 /* Has SIER */ | ||
62 | #define PPMU_BHRB 0x00000080 /* has BHRB feature enabled */ | ||
55 | 63 | ||
56 | /* | 64 | /* |
57 | * Values for flags to get_alternatives() | 65 | * Values for flags to get_alternatives() |
@@ -65,6 +73,7 @@ extern int register_power_pmu(struct power_pmu *); | |||
65 | struct pt_regs; | 73 | struct pt_regs; |
66 | extern unsigned long perf_misc_flags(struct pt_regs *regs); | 74 | extern unsigned long perf_misc_flags(struct pt_regs *regs); |
67 | extern unsigned long perf_instruction_pointer(struct pt_regs *regs); | 75 | extern unsigned long perf_instruction_pointer(struct pt_regs *regs); |
76 | extern unsigned long int read_bhrb(int n); | ||
68 | 77 | ||
69 | /* | 78 | /* |
70 | * Only override the default definitions in include/linux/perf_event.h | 79 | * Only override the default definitions in include/linux/perf_event.h |
diff --git a/arch/powerpc/include/asm/pgalloc-32.h b/arch/powerpc/include/asm/pgalloc-32.h index 580cf73b96e8..27b2386f738a 100644 --- a/arch/powerpc/include/asm/pgalloc-32.h +++ b/arch/powerpc/include/asm/pgalloc-32.h | |||
@@ -37,6 +37,17 @@ extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); | |||
37 | extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr); | 37 | extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr); |
38 | extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr); | 38 | extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr); |
39 | 39 | ||
40 | static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) | ||
41 | { | ||
42 | free_page((unsigned long)pte); | ||
43 | } | ||
44 | |||
45 | static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage) | ||
46 | { | ||
47 | pgtable_page_dtor(ptepage); | ||
48 | __free_page(ptepage); | ||
49 | } | ||
50 | |||
40 | static inline void pgtable_free(void *table, unsigned index_size) | 51 | static inline void pgtable_free(void *table, unsigned index_size) |
41 | { | 52 | { |
42 | BUG_ON(index_size); /* 32-bit doesn't use this */ | 53 | BUG_ON(index_size); /* 32-bit doesn't use this */ |
@@ -45,4 +56,38 @@ static inline void pgtable_free(void *table, unsigned index_size) | |||
45 | 56 | ||
46 | #define check_pgt_cache() do { } while (0) | 57 | #define check_pgt_cache() do { } while (0) |
47 | 58 | ||
59 | #ifdef CONFIG_SMP | ||
60 | static inline void pgtable_free_tlb(struct mmu_gather *tlb, | ||
61 | void *table, int shift) | ||
62 | { | ||
63 | unsigned long pgf = (unsigned long)table; | ||
64 | BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE); | ||
65 | pgf |= shift; | ||
66 | tlb_remove_table(tlb, (void *)pgf); | ||
67 | } | ||
68 | |||
69 | static inline void __tlb_remove_table(void *_table) | ||
70 | { | ||
71 | void *table = (void *)((unsigned long)_table & ~MAX_PGTABLE_INDEX_SIZE); | ||
72 | unsigned shift = (unsigned long)_table & MAX_PGTABLE_INDEX_SIZE; | ||
73 | |||
74 | pgtable_free(table, shift); | ||
75 | } | ||
76 | #else | ||
77 | static inline void pgtable_free_tlb(struct mmu_gather *tlb, | ||
78 | void *table, int shift) | ||
79 | { | ||
80 | pgtable_free(table, shift); | ||
81 | } | ||
82 | #endif | ||
83 | |||
84 | static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table, | ||
85 | unsigned long address) | ||
86 | { | ||
87 | struct page *page = page_address(table); | ||
88 | |||
89 | tlb_flush_pgtable(tlb, address); | ||
90 | pgtable_page_dtor(page); | ||
91 | pgtable_free_tlb(tlb, page, 0); | ||
92 | } | ||
48 | #endif /* _ASM_POWERPC_PGALLOC_32_H */ | 93 | #endif /* _ASM_POWERPC_PGALLOC_32_H */ |
diff --git a/arch/powerpc/include/asm/pgalloc-64.h b/arch/powerpc/include/asm/pgalloc-64.h index 292725cec2e3..91acb12bac92 100644 --- a/arch/powerpc/include/asm/pgalloc-64.h +++ b/arch/powerpc/include/asm/pgalloc-64.h | |||
@@ -35,7 +35,10 @@ struct vmemmap_backing { | |||
35 | #define MAX_PGTABLE_INDEX_SIZE 0xf | 35 | #define MAX_PGTABLE_INDEX_SIZE 0xf |
36 | 36 | ||
37 | extern struct kmem_cache *pgtable_cache[]; | 37 | extern struct kmem_cache *pgtable_cache[]; |
38 | #define PGT_CACHE(shift) (pgtable_cache[(shift)-1]) | 38 | #define PGT_CACHE(shift) ({ \ |
39 | BUG_ON(!(shift)); \ | ||
40 | pgtable_cache[(shift) - 1]; \ | ||
41 | }) | ||
39 | 42 | ||
40 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) | 43 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) |
41 | { | 44 | { |
@@ -72,8 +75,100 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) | |||
72 | #define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, (unsigned long)(pte)) | 75 | #define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, (unsigned long)(pte)) |
73 | #define pmd_pgtable(pmd) pmd_page(pmd) | 76 | #define pmd_pgtable(pmd) pmd_page(pmd) |
74 | 77 | ||
78 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | ||
79 | unsigned long address) | ||
80 | { | ||
81 | return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO); | ||
82 | } | ||
83 | |||
84 | static inline pgtable_t pte_alloc_one(struct mm_struct *mm, | ||
85 | unsigned long address) | ||
86 | { | ||
87 | struct page *page; | ||
88 | pte_t *pte; | ||
89 | |||
90 | pte = pte_alloc_one_kernel(mm, address); | ||
91 | if (!pte) | ||
92 | return NULL; | ||
93 | page = virt_to_page(pte); | ||
94 | pgtable_page_ctor(page); | ||
95 | return page; | ||
96 | } | ||
97 | |||
98 | static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) | ||
99 | { | ||
100 | free_page((unsigned long)pte); | ||
101 | } | ||
102 | |||
103 | static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage) | ||
104 | { | ||
105 | pgtable_page_dtor(ptepage); | ||
106 | __free_page(ptepage); | ||
107 | } | ||
108 | |||
109 | static inline void pgtable_free(void *table, unsigned index_size) | ||
110 | { | ||
111 | if (!index_size) | ||
112 | free_page((unsigned long)table); | ||
113 | else { | ||
114 | BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE); | ||
115 | kmem_cache_free(PGT_CACHE(index_size), table); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | #ifdef CONFIG_SMP | ||
120 | static inline void pgtable_free_tlb(struct mmu_gather *tlb, | ||
121 | void *table, int shift) | ||
122 | { | ||
123 | unsigned long pgf = (unsigned long)table; | ||
124 | BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE); | ||
125 | pgf |= shift; | ||
126 | tlb_remove_table(tlb, (void *)pgf); | ||
127 | } | ||
128 | |||
129 | static inline void __tlb_remove_table(void *_table) | ||
130 | { | ||
131 | void *table = (void *)((unsigned long)_table & ~MAX_PGTABLE_INDEX_SIZE); | ||
132 | unsigned shift = (unsigned long)_table & MAX_PGTABLE_INDEX_SIZE; | ||
133 | |||
134 | pgtable_free(table, shift); | ||
135 | } | ||
136 | #else /* !CONFIG_SMP */ | ||
137 | static inline void pgtable_free_tlb(struct mmu_gather *tlb, | ||
138 | void *table, int shift) | ||
139 | { | ||
140 | pgtable_free(table, shift); | ||
141 | } | ||
142 | #endif /* CONFIG_SMP */ | ||
143 | |||
144 | static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table, | ||
145 | unsigned long address) | ||
146 | { | ||
147 | struct page *page = page_address(table); | ||
148 | |||
149 | tlb_flush_pgtable(tlb, address); | ||
150 | pgtable_page_dtor(page); | ||
151 | pgtable_free_tlb(tlb, page, 0); | ||
152 | } | ||
153 | |||
154 | #else /* if CONFIG_PPC_64K_PAGES */ | ||
155 | /* | ||
156 | * we support 16 fragments per PTE page. | ||
157 | */ | ||
158 | #define PTE_FRAG_NR 16 | ||
159 | /* | ||
160 | * We use a 2K PTE page fragment and another 2K for storing | ||
161 | * real_pte_t hash index | ||
162 | */ | ||
163 | #define PTE_FRAG_SIZE_SHIFT 12 | ||
164 | #define PTE_FRAG_SIZE (2 * PTRS_PER_PTE * sizeof(pte_t)) | ||
75 | 165 | ||
76 | #else /* CONFIG_PPC_64K_PAGES */ | 166 | extern pte_t *page_table_alloc(struct mm_struct *, unsigned long, int); |
167 | extern void page_table_free(struct mm_struct *, unsigned long *, int); | ||
168 | extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift); | ||
169 | #ifdef CONFIG_SMP | ||
170 | extern void __tlb_remove_table(void *_table); | ||
171 | #endif | ||
77 | 172 | ||
78 | #define pud_populate(mm, pud, pmd) pud_set(pud, (unsigned long)pmd) | 173 | #define pud_populate(mm, pud, pmd) pud_set(pud, (unsigned long)pmd) |
79 | 174 | ||
@@ -83,51 +178,56 @@ static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, | |||
83 | pmd_set(pmd, (unsigned long)pte); | 178 | pmd_set(pmd, (unsigned long)pte); |
84 | } | 179 | } |
85 | 180 | ||
86 | #define pmd_populate(mm, pmd, pte_page) \ | 181 | static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, |
87 | pmd_populate_kernel(mm, pmd, page_address(pte_page)) | 182 | pgtable_t pte_page) |
88 | #define pmd_pgtable(pmd) pmd_page(pmd) | ||
89 | |||
90 | #endif /* CONFIG_PPC_64K_PAGES */ | ||
91 | |||
92 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) | ||
93 | { | 183 | { |
94 | return kmem_cache_alloc(PGT_CACHE(PMD_INDEX_SIZE), | 184 | pmd_set(pmd, (unsigned long)pte_page); |
95 | GFP_KERNEL|__GFP_REPEAT); | ||
96 | } | 185 | } |
97 | 186 | ||
98 | static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) | 187 | static inline pgtable_t pmd_pgtable(pmd_t pmd) |
99 | { | 188 | { |
100 | kmem_cache_free(PGT_CACHE(PMD_INDEX_SIZE), pmd); | 189 | return (pgtable_t)(pmd_val(pmd) & -sizeof(pte_t)*PTRS_PER_PTE); |
101 | } | 190 | } |
102 | 191 | ||
103 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | 192 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, |
104 | unsigned long address) | 193 | unsigned long address) |
105 | { | 194 | { |
106 | return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO); | 195 | return (pte_t *)page_table_alloc(mm, address, 1); |
107 | } | 196 | } |
108 | 197 | ||
109 | static inline pgtable_t pte_alloc_one(struct mm_struct *mm, | 198 | static inline pgtable_t pte_alloc_one(struct mm_struct *mm, |
110 | unsigned long address) | 199 | unsigned long address) |
111 | { | 200 | { |
112 | struct page *page; | 201 | return (pgtable_t)page_table_alloc(mm, address, 0); |
113 | pte_t *pte; | 202 | } |
114 | 203 | ||
115 | pte = pte_alloc_one_kernel(mm, address); | 204 | static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) |
116 | if (!pte) | 205 | { |
117 | return NULL; | 206 | page_table_free(mm, (unsigned long *)pte, 1); |
118 | page = virt_to_page(pte); | ||
119 | pgtable_page_ctor(page); | ||
120 | return page; | ||
121 | } | 207 | } |
122 | 208 | ||
123 | static inline void pgtable_free(void *table, unsigned index_size) | 209 | static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage) |
124 | { | 210 | { |
125 | if (!index_size) | 211 | page_table_free(mm, (unsigned long *)ptepage, 0); |
126 | free_page((unsigned long)table); | 212 | } |
127 | else { | 213 | |
128 | BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE); | 214 | static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table, |
129 | kmem_cache_free(PGT_CACHE(index_size), table); | 215 | unsigned long address) |
130 | } | 216 | { |
217 | tlb_flush_pgtable(tlb, address); | ||
218 | pgtable_free_tlb(tlb, table, 0); | ||
219 | } | ||
220 | #endif /* CONFIG_PPC_64K_PAGES */ | ||
221 | |||
222 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) | ||
223 | { | ||
224 | return kmem_cache_alloc(PGT_CACHE(PMD_INDEX_SIZE), | ||
225 | GFP_KERNEL|__GFP_REPEAT); | ||
226 | } | ||
227 | |||
228 | static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) | ||
229 | { | ||
230 | kmem_cache_free(PGT_CACHE(PMD_INDEX_SIZE), pmd); | ||
131 | } | 231 | } |
132 | 232 | ||
133 | #define __pmd_free_tlb(tlb, pmd, addr) \ | 233 | #define __pmd_free_tlb(tlb, pmd, addr) \ |
diff --git a/arch/powerpc/include/asm/pgalloc.h b/arch/powerpc/include/asm/pgalloc.h index bf301ac62f35..e9a9f60e596d 100644 --- a/arch/powerpc/include/asm/pgalloc.h +++ b/arch/powerpc/include/asm/pgalloc.h | |||
@@ -3,6 +3,7 @@ | |||
3 | #ifdef __KERNEL__ | 3 | #ifdef __KERNEL__ |
4 | 4 | ||
5 | #include <linux/mm.h> | 5 | #include <linux/mm.h> |
6 | #include <asm-generic/tlb.h> | ||
6 | 7 | ||
7 | #ifdef CONFIG_PPC_BOOK3E | 8 | #ifdef CONFIG_PPC_BOOK3E |
8 | extern void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address); | 9 | extern void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address); |
@@ -13,56 +14,11 @@ static inline void tlb_flush_pgtable(struct mmu_gather *tlb, | |||
13 | } | 14 | } |
14 | #endif /* !CONFIG_PPC_BOOK3E */ | 15 | #endif /* !CONFIG_PPC_BOOK3E */ |
15 | 16 | ||
16 | static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) | ||
17 | { | ||
18 | free_page((unsigned long)pte); | ||
19 | } | ||
20 | |||
21 | static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage) | ||
22 | { | ||
23 | pgtable_page_dtor(ptepage); | ||
24 | __free_page(ptepage); | ||
25 | } | ||
26 | |||
27 | #ifdef CONFIG_PPC64 | 17 | #ifdef CONFIG_PPC64 |
28 | #include <asm/pgalloc-64.h> | 18 | #include <asm/pgalloc-64.h> |
29 | #else | 19 | #else |
30 | #include <asm/pgalloc-32.h> | 20 | #include <asm/pgalloc-32.h> |
31 | #endif | 21 | #endif |
32 | 22 | ||
33 | #ifdef CONFIG_SMP | ||
34 | struct mmu_gather; | ||
35 | extern void tlb_remove_table(struct mmu_gather *, void *); | ||
36 | |||
37 | static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift) | ||
38 | { | ||
39 | unsigned long pgf = (unsigned long)table; | ||
40 | BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE); | ||
41 | pgf |= shift; | ||
42 | tlb_remove_table(tlb, (void *)pgf); | ||
43 | } | ||
44 | |||
45 | static inline void __tlb_remove_table(void *_table) | ||
46 | { | ||
47 | void *table = (void *)((unsigned long)_table & ~MAX_PGTABLE_INDEX_SIZE); | ||
48 | unsigned shift = (unsigned long)_table & MAX_PGTABLE_INDEX_SIZE; | ||
49 | |||
50 | pgtable_free(table, shift); | ||
51 | } | ||
52 | #else /* CONFIG_SMP */ | ||
53 | static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, unsigned shift) | ||
54 | { | ||
55 | pgtable_free(table, shift); | ||
56 | } | ||
57 | #endif /* !CONFIG_SMP */ | ||
58 | |||
59 | static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage, | ||
60 | unsigned long address) | ||
61 | { | ||
62 | tlb_flush_pgtable(tlb, address); | ||
63 | pgtable_page_dtor(ptepage); | ||
64 | pgtable_free_tlb(tlb, page_address(ptepage), 0); | ||
65 | } | ||
66 | |||
67 | #endif /* __KERNEL__ */ | 23 | #endif /* __KERNEL__ */ |
68 | #endif /* _ASM_POWERPC_PGALLOC_H */ | 24 | #endif /* _ASM_POWERPC_PGALLOC_H */ |
diff --git a/arch/powerpc/include/asm/pgtable-ppc64-64k.h b/arch/powerpc/include/asm/pgtable-ppc64-64k.h index be4e2878fbc0..45142d640720 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64-64k.h +++ b/arch/powerpc/include/asm/pgtable-ppc64-64k.h | |||
@@ -4,10 +4,10 @@ | |||
4 | #include <asm-generic/pgtable-nopud.h> | 4 | #include <asm-generic/pgtable-nopud.h> |
5 | 5 | ||
6 | 6 | ||
7 | #define PTE_INDEX_SIZE 12 | 7 | #define PTE_INDEX_SIZE 8 |
8 | #define PMD_INDEX_SIZE 12 | 8 | #define PMD_INDEX_SIZE 10 |
9 | #define PUD_INDEX_SIZE 0 | 9 | #define PUD_INDEX_SIZE 0 |
10 | #define PGD_INDEX_SIZE 6 | 10 | #define PGD_INDEX_SIZE 12 |
11 | 11 | ||
12 | #ifndef __ASSEMBLY__ | 12 | #ifndef __ASSEMBLY__ |
13 | #define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE) | 13 | #define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE) |
diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h index 0182c203e411..e3d55f6f24fe 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64.h +++ b/arch/powerpc/include/asm/pgtable-ppc64.h | |||
@@ -167,8 +167,7 @@ | |||
167 | * Find an entry in a page-table-directory. We combine the address region | 167 | * Find an entry in a page-table-directory. We combine the address region |
168 | * (the high order N bits) and the pgd portion of the address. | 168 | * (the high order N bits) and the pgd portion of the address. |
169 | */ | 169 | */ |
170 | /* to avoid overflow in free_pgtables we don't use PTRS_PER_PGD here */ | 170 | #define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1)) |
171 | #define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & 0x1ff) | ||
172 | 171 | ||
173 | #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) | 172 | #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) |
174 | 173 | ||
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h index a9cbd3ba5c33..7aeb9555f6ea 100644 --- a/arch/powerpc/include/asm/pgtable.h +++ b/arch/powerpc/include/asm/pgtable.h | |||
@@ -17,6 +17,12 @@ struct mm_struct; | |||
17 | # include <asm/pgtable-ppc32.h> | 17 | # include <asm/pgtable-ppc32.h> |
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | /* | ||
21 | * We save the slot number & secondary bit in the second half of the | ||
22 | * PTE page. We use the 8 bytes per each pte entry. | ||
23 | */ | ||
24 | #define PTE_PAGE_HIDX_OFFSET (PTRS_PER_PTE * 8) | ||
25 | |||
20 | #ifndef __ASSEMBLY__ | 26 | #ifndef __ASSEMBLY__ |
21 | 27 | ||
22 | #include <asm/tlbflush.h> | 28 | #include <asm/tlbflush.h> |
@@ -212,6 +218,8 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *); | |||
212 | extern int gup_hugepd(hugepd_t *hugepd, unsigned pdshift, unsigned long addr, | 218 | extern int gup_hugepd(hugepd_t *hugepd, unsigned pdshift, unsigned long addr, |
213 | unsigned long end, int write, struct page **pages, int *nr); | 219 | unsigned long end, int write, struct page **pages, int *nr); |
214 | 220 | ||
221 | extern int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, | ||
222 | unsigned long end, int write, struct page **pages, int *nr); | ||
215 | #endif /* __ASSEMBLY__ */ | 223 | #endif /* __ASSEMBLY__ */ |
216 | 224 | ||
217 | #endif /* __KERNEL__ */ | 225 | #endif /* __KERNEL__ */ |
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index 8752bc8e34a3..0c34e4803499 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h | |||
@@ -82,6 +82,8 @@ | |||
82 | #define __REGA0_R31 31 | 82 | #define __REGA0_R31 31 |
83 | 83 | ||
84 | /* sorted alphabetically */ | 84 | /* sorted alphabetically */ |
85 | #define PPC_INST_BHRBE 0x7c00025c | ||
86 | #define PPC_INST_CLRBHRB 0x7c00035c | ||
85 | #define PPC_INST_DCBA 0x7c0005ec | 87 | #define PPC_INST_DCBA 0x7c0005ec |
86 | #define PPC_INST_DCBA_MASK 0xfc0007fe | 88 | #define PPC_INST_DCBA_MASK 0xfc0007fe |
87 | #define PPC_INST_DCBAL 0x7c2005ec | 89 | #define PPC_INST_DCBAL 0x7c2005ec |
@@ -297,6 +299,12 @@ | |||
297 | #define PPC_NAP stringify_in_c(.long PPC_INST_NAP) | 299 | #define PPC_NAP stringify_in_c(.long PPC_INST_NAP) |
298 | #define PPC_SLEEP stringify_in_c(.long PPC_INST_SLEEP) | 300 | #define PPC_SLEEP stringify_in_c(.long PPC_INST_SLEEP) |
299 | 301 | ||
302 | /* BHRB instructions */ | ||
303 | #define PPC_CLRBHRB stringify_in_c(.long PPC_INST_CLRBHRB) | ||
304 | #define PPC_MFBHRBE(r, n) stringify_in_c(.long PPC_INST_BHRBE | \ | ||
305 | __PPC_RT(r) | \ | ||
306 | (((n) & 0x3ff) << 11)) | ||
307 | |||
300 | /* Transactional memory instructions */ | 308 | /* Transactional memory instructions */ |
301 | #define TRECHKPT stringify_in_c(.long PPC_INST_TRECHKPT) | 309 | #define TRECHKPT stringify_in_c(.long PPC_INST_TRECHKPT) |
302 | #define TRECLAIM(r) stringify_in_c(.long PPC_INST_TRECLAIM \ | 310 | #define TRECLAIM(r) stringify_in_c(.long PPC_INST_TRECLAIM \ |
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 7ff9eaa3ea6c..d7e67ca8b4a6 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h | |||
@@ -40,7 +40,7 @@ | |||
40 | * -- BenH. | 40 | * -- BenH. |
41 | */ | 41 | */ |
42 | 42 | ||
43 | /* PREP sub-platform types see residual.h for these */ | 43 | /* PREP sub-platform types. Unused */ |
44 | #define _PREP_Motorola 0x01 /* motorola prep */ | 44 | #define _PREP_Motorola 0x01 /* motorola prep */ |
45 | #define _PREP_Firm 0x02 /* firmworks prep */ | 45 | #define _PREP_Firm 0x02 /* firmworks prep */ |
46 | #define _PREP_IBM 0x00 /* ibm prep */ | 46 | #define _PREP_IBM 0x00 /* ibm prep */ |
@@ -56,13 +56,6 @@ | |||
56 | 56 | ||
57 | extern int _chrp_type; | 57 | extern int _chrp_type; |
58 | 58 | ||
59 | #ifdef CONFIG_PPC_PREP | ||
60 | |||
61 | /* what kind of prep workstation we are */ | ||
62 | extern int _prep_type; | ||
63 | |||
64 | #endif /* CONFIG_PPC_PREP */ | ||
65 | |||
66 | #endif /* defined(__KERNEL__) && defined(CONFIG_PPC32) */ | 59 | #endif /* defined(__KERNEL__) && defined(CONFIG_PPC32) */ |
67 | 60 | ||
68 | /* | 61 | /* |
@@ -288,6 +281,9 @@ struct thread_struct { | |||
288 | #endif | 281 | #endif |
289 | #ifdef CONFIG_PPC_BOOK3S_64 | 282 | #ifdef CONFIG_PPC_BOOK3S_64 |
290 | unsigned long tar; | 283 | unsigned long tar; |
284 | unsigned long ebbrr; | ||
285 | unsigned long ebbhr; | ||
286 | unsigned long bescr; | ||
291 | #endif | 287 | #endif |
292 | }; | 288 | }; |
293 | 289 | ||
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 99c92d5363e4..bc2da154f68b 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h | |||
@@ -74,6 +74,75 @@ struct of_drconf_cell { | |||
74 | #define DRCONF_MEM_AI_INVALID 0x00000040 | 74 | #define DRCONF_MEM_AI_INVALID 0x00000040 |
75 | #define DRCONF_MEM_RESERVED 0x00000080 | 75 | #define DRCONF_MEM_RESERVED 0x00000080 |
76 | 76 | ||
77 | /* | ||
78 | * There are two methods for telling firmware what our capabilities are. | ||
79 | * Newer machines have an "ibm,client-architecture-support" method on the | ||
80 | * root node. For older machines, we have to call the "process-elf-header" | ||
81 | * method in the /packages/elf-loader node, passing it a fake 32-bit | ||
82 | * ELF header containing a couple of PT_NOTE sections that contain | ||
83 | * structures that contain various information. | ||
84 | */ | ||
85 | |||
86 | /* New method - extensible architecture description vector. */ | ||
87 | |||
88 | /* Option vector bits - generic bits in byte 1 */ | ||
89 | #define OV_IGNORE 0x80 /* ignore this vector */ | ||
90 | #define OV_CESSATION_POLICY 0x40 /* halt if unsupported option present*/ | ||
91 | |||
92 | /* Option vector 1: processor architectures supported */ | ||
93 | #define OV1_PPC_2_00 0x80 /* set if we support PowerPC 2.00 */ | ||
94 | #define OV1_PPC_2_01 0x40 /* set if we support PowerPC 2.01 */ | ||
95 | #define OV1_PPC_2_02 0x20 /* set if we support PowerPC 2.02 */ | ||
96 | #define OV1_PPC_2_03 0x10 /* set if we support PowerPC 2.03 */ | ||
97 | #define OV1_PPC_2_04 0x08 /* set if we support PowerPC 2.04 */ | ||
98 | #define OV1_PPC_2_05 0x04 /* set if we support PowerPC 2.05 */ | ||
99 | #define OV1_PPC_2_06 0x02 /* set if we support PowerPC 2.06 */ | ||
100 | #define OV1_PPC_2_07 0x01 /* set if we support PowerPC 2.07 */ | ||
101 | |||
102 | /* Option vector 2: Open Firmware options supported */ | ||
103 | #define OV2_REAL_MODE 0x20 /* set if we want OF in real mode */ | ||
104 | |||
105 | /* Option vector 3: processor options supported */ | ||
106 | #define OV3_FP 0x80 /* floating point */ | ||
107 | #define OV3_VMX 0x40 /* VMX/Altivec */ | ||
108 | #define OV3_DFP 0x20 /* decimal FP */ | ||
109 | |||
110 | /* Option vector 4: IBM PAPR implementation */ | ||
111 | #define OV4_MIN_ENT_CAP 0x01 /* minimum VP entitled capacity */ | ||
112 | |||
113 | /* Option vector 5: PAPR/OF options supported | ||
114 | * These bits are also used in firmware_has_feature() to validate | ||
115 | * the capabilities reported for vector 5 in the device tree so we | ||
116 | * encode the vector index in the define and use the OV5_FEAT() | ||
117 | * and OV5_INDX() macros to extract the desired information. | ||
118 | */ | ||
119 | #define OV5_FEAT(x) ((x) & 0xff) | ||
120 | #define OV5_INDX(x) ((x) >> 8) | ||
121 | #define OV5_LPAR 0x0280 /* logical partitioning supported */ | ||
122 | #define OV5_SPLPAR 0x0240 /* shared-processor LPAR supported */ | ||
123 | /* ibm,dynamic-reconfiguration-memory property supported */ | ||
124 | #define OV5_DRCONF_MEMORY 0x0220 | ||
125 | #define OV5_LARGE_PAGES 0x0210 /* large pages supported */ | ||
126 | #define OV5_DONATE_DEDICATE_CPU 0x0202 /* donate dedicated CPU support */ | ||
127 | #define OV5_MSI 0x0201 /* PCIe/MSI support */ | ||
128 | #define OV5_CMO 0x0480 /* Cooperative Memory Overcommitment */ | ||
129 | #define OV5_XCMO 0x0440 /* Page Coalescing */ | ||
130 | #define OV5_TYPE1_AFFINITY 0x0580 /* Type 1 NUMA affinity */ | ||
131 | #define OV5_PRRN 0x0540 /* Platform Resource Reassignment */ | ||
132 | #define OV5_PFO_HW_RNG 0x0E80 /* PFO Random Number Generator */ | ||
133 | #define OV5_PFO_HW_842 0x0E40 /* PFO Compression Accelerator */ | ||
134 | #define OV5_PFO_HW_ENCR 0x0E20 /* PFO Encryption Accelerator */ | ||
135 | #define OV5_SUB_PROCESSORS 0x0F01 /* 1,2,or 4 Sub-Processors supported */ | ||
136 | |||
137 | /* Option Vector 6: IBM PAPR hints */ | ||
138 | #define OV6_LINUX 0x02 /* Linux is our OS */ | ||
139 | |||
140 | /* | ||
141 | * The architecture vector has an array of PVR mask/value pairs, | ||
142 | * followed by # option vectors - 1, followed by the option vectors. | ||
143 | */ | ||
144 | extern unsigned char ibm_architecture_vec[]; | ||
145 | |||
77 | /* These includes are put at the bottom because they may contain things | 146 | /* These includes are put at the bottom because they may contain things |
78 | * that are overridden by this file. Ideally they shouldn't be included | 147 | * that are overridden by this file. Ideally they shouldn't be included |
79 | * by this file, but there are a bunch of .c files that currently depend | 148 | * by this file, but there are a bunch of .c files that currently depend |
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h index 5f995681bc1d..becc08e6a65c 100644 --- a/arch/powerpc/include/asm/ptrace.h +++ b/arch/powerpc/include/asm/ptrace.h | |||
@@ -92,7 +92,8 @@ static inline long regs_return_value(struct pt_regs *regs) | |||
92 | } while(0) | 92 | } while(0) |
93 | 93 | ||
94 | struct task_struct; | 94 | struct task_struct; |
95 | extern unsigned long ptrace_get_reg(struct task_struct *task, int regno); | 95 | extern int ptrace_get_reg(struct task_struct *task, int regno, |
96 | unsigned long *data); | ||
96 | extern int ptrace_put_reg(struct task_struct *task, int regno, | 97 | extern int ptrace_put_reg(struct task_struct *task, int regno, |
97 | unsigned long data); | 98 | unsigned long data); |
98 | 99 | ||
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 799322433620..a6136515c7f2 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -267,7 +267,17 @@ | |||
267 | #define SPRN_HSRR1 0x13B /* Hypervisor Save/Restore 1 */ | 267 | #define SPRN_HSRR1 0x13B /* Hypervisor Save/Restore 1 */ |
268 | #define SPRN_FSCR 0x099 /* Facility Status & Control Register */ | 268 | #define SPRN_FSCR 0x099 /* Facility Status & Control Register */ |
269 | #define FSCR_TAR (1 << (63-55)) /* Enable Target Address Register */ | 269 | #define FSCR_TAR (1 << (63-55)) /* Enable Target Address Register */ |
270 | #define FSCR_EBB (1 << (63-56)) /* Enable Event Based Branching */ | ||
270 | #define FSCR_DSCR (1 << (63-61)) /* Enable Data Stream Control Register */ | 271 | #define FSCR_DSCR (1 << (63-61)) /* Enable Data Stream Control Register */ |
272 | #define SPRN_HFSCR 0xbe /* HV=1 Facility Status & Control Register */ | ||
273 | #define HFSCR_TAR (1 << (63-55)) /* Enable Target Address Register */ | ||
274 | #define HFSCR_EBB (1 << (63-56)) /* Enable Event Based Branching */ | ||
275 | #define HFSCR_TM (1 << (63-58)) /* Enable Transactional Memory */ | ||
276 | #define HFSCR_PM (1 << (63-60)) /* Enable prob/priv access to PMU SPRs */ | ||
277 | #define HFSCR_BHRB (1 << (63-59)) /* Enable Branch History Rolling Buffer*/ | ||
278 | #define HFSCR_DSCR (1 << (63-61)) /* Enable Data Stream Control Register */ | ||
279 | #define HFSCR_VECVSX (1 << (63-62)) /* Enable VMX/VSX */ | ||
280 | #define HFSCR_FP (1 << (63-63)) /* Enable Floating Point */ | ||
271 | #define SPRN_TAR 0x32f /* Target Address Register */ | 281 | #define SPRN_TAR 0x32f /* Target Address Register */ |
272 | #define SPRN_LPCR 0x13E /* LPAR Control Register */ | 282 | #define SPRN_LPCR 0x13E /* LPAR Control Register */ |
273 | #define LPCR_VPM0 (1ul << (63-0)) | 283 | #define LPCR_VPM0 (1ul << (63-0)) |
@@ -632,6 +642,7 @@ | |||
632 | #define MMCR0_FCWAIT 0x00000002UL /* freeze counter in WAIT state */ | 642 | #define MMCR0_FCWAIT 0x00000002UL /* freeze counter in WAIT state */ |
633 | #define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */ | 643 | #define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */ |
634 | #define SPRN_MMCR1 798 | 644 | #define SPRN_MMCR1 798 |
645 | #define SPRN_MMCR2 769 | ||
635 | #define SPRN_MMCRA 0x312 | 646 | #define SPRN_MMCRA 0x312 |
636 | #define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */ | 647 | #define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */ |
637 | #define MMCRA_SDAR_DCACHE_MISS 0x40000000UL | 648 | #define MMCRA_SDAR_DCACHE_MISS 0x40000000UL |
@@ -650,6 +661,13 @@ | |||
650 | #define POWER7P_MMCRA_SIAR_VALID 0x10000000 /* P7+ SIAR contents valid */ | 661 | #define POWER7P_MMCRA_SIAR_VALID 0x10000000 /* P7+ SIAR contents valid */ |
651 | #define POWER7P_MMCRA_SDAR_VALID 0x08000000 /* P7+ SDAR contents valid */ | 662 | #define POWER7P_MMCRA_SDAR_VALID 0x08000000 /* P7+ SDAR contents valid */ |
652 | 663 | ||
664 | #define SPRN_MMCRH 316 /* Hypervisor monitor mode control register */ | ||
665 | #define SPRN_MMCRS 894 /* Supervisor monitor mode control register */ | ||
666 | #define SPRN_MMCRC 851 /* Core monitor mode control register */ | ||
667 | #define SPRN_EBBHR 804 /* Event based branch handler register */ | ||
668 | #define SPRN_EBBRR 805 /* Event based branch return register */ | ||
669 | #define SPRN_BESCR 806 /* Branch event status and control register */ | ||
670 | |||
653 | #define SPRN_PMC1 787 | 671 | #define SPRN_PMC1 787 |
654 | #define SPRN_PMC2 788 | 672 | #define SPRN_PMC2 788 |
655 | #define SPRN_PMC3 789 | 673 | #define SPRN_PMC3 789 |
@@ -660,6 +678,11 @@ | |||
660 | #define SPRN_PMC8 794 | 678 | #define SPRN_PMC8 794 |
661 | #define SPRN_SIAR 780 | 679 | #define SPRN_SIAR 780 |
662 | #define SPRN_SDAR 781 | 680 | #define SPRN_SDAR 781 |
681 | #define SPRN_SIER 784 | ||
682 | #define SIER_SIPR 0x2000000 /* Sampled MSR_PR */ | ||
683 | #define SIER_SIHV 0x1000000 /* Sampled MSR_HV */ | ||
684 | #define SIER_SIAR_VALID 0x0400000 /* SIAR contents valid */ | ||
685 | #define SIER_SDAR_VALID 0x0200000 /* SDAR contents valid */ | ||
663 | 686 | ||
664 | #define SPRN_PA6T_MMCR0 795 | 687 | #define SPRN_PA6T_MMCR0 795 |
665 | #define PA6T_MMCR0_EN0 0x0000000000000001UL | 688 | #define PA6T_MMCR0_EN0 0x0000000000000001UL |
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index aef00c675905..a8bc2bb4adc9 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h | |||
@@ -143,6 +143,8 @@ struct rtas_suspend_me_data { | |||
143 | #define RTAS_TYPE_PMGM_TIME_ALARM 0x6f | 143 | #define RTAS_TYPE_PMGM_TIME_ALARM 0x6f |
144 | #define RTAS_TYPE_PMGM_CONFIG_CHANGE 0x70 | 144 | #define RTAS_TYPE_PMGM_CONFIG_CHANGE 0x70 |
145 | #define RTAS_TYPE_PMGM_SERVICE_PROC 0x71 | 145 | #define RTAS_TYPE_PMGM_SERVICE_PROC 0x71 |
146 | /* Platform Resource Reassignment Notification */ | ||
147 | #define RTAS_TYPE_PRRN 0xA0 | ||
146 | 148 | ||
147 | /* RTAS check-exception vector offset */ | 149 | /* RTAS check-exception vector offset */ |
148 | #define RTAS_VECTOR_EXTERNAL_INTERRUPT 0x500 | 150 | #define RTAS_VECTOR_EXTERNAL_INTERRUPT 0x500 |
@@ -277,6 +279,10 @@ extern int early_init_dt_scan_rtas(unsigned long node, | |||
277 | 279 | ||
278 | extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal); | 280 | extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal); |
279 | 281 | ||
282 | #ifdef CONFIG_PPC_PSERIES | ||
283 | extern int pseries_devicetree_update(s32 scope); | ||
284 | #endif | ||
285 | |||
280 | #ifdef CONFIG_PPC_RTAS_DAEMON | 286 | #ifdef CONFIG_PPC_RTAS_DAEMON |
281 | extern void rtas_cancel_event_scan(void); | 287 | extern void rtas_cancel_event_scan(void); |
282 | #else | 288 | #else |
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 195ce2ac5691..ffbaabebcdca 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h | |||
@@ -143,6 +143,8 @@ extern void __cpu_die(unsigned int cpu); | |||
143 | /* for UP */ | 143 | /* for UP */ |
144 | #define hard_smp_processor_id() get_hard_smp_processor_id(0) | 144 | #define hard_smp_processor_id() get_hard_smp_processor_id(0) |
145 | #define smp_setup_cpu_maps() | 145 | #define smp_setup_cpu_maps() |
146 | static inline void inhibit_secondary_onlining(void) {} | ||
147 | static inline void uninhibit_secondary_onlining(void) {} | ||
146 | 148 | ||
147 | #endif /* CONFIG_SMP */ | 149 | #endif /* CONFIG_SMP */ |
148 | 150 | ||
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index ebbec52d21bd..43523fe0d8b4 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h | |||
@@ -190,7 +190,7 @@ SYSCALL_SPU(getcwd) | |||
190 | SYSCALL_SPU(capget) | 190 | SYSCALL_SPU(capget) |
191 | SYSCALL_SPU(capset) | 191 | SYSCALL_SPU(capset) |
192 | COMPAT_SYS(sigaltstack) | 192 | COMPAT_SYS(sigaltstack) |
193 | SYSX_SPU(sys_sendfile,compat_sys_sendfile_wrapper,sys_sendfile) | 193 | COMPAT_SYS_SPU(sendfile) |
194 | SYSCALL(ni_syscall) | 194 | SYSCALL(ni_syscall) |
195 | SYSCALL(ni_syscall) | 195 | SYSCALL(ni_syscall) |
196 | PPC_SYS(vfork) | 196 | PPC_SYS(vfork) |
@@ -230,7 +230,7 @@ COMPAT_SYS_SPU(sched_setaffinity) | |||
230 | COMPAT_SYS_SPU(sched_getaffinity) | 230 | COMPAT_SYS_SPU(sched_getaffinity) |
231 | SYSCALL(ni_syscall) | 231 | SYSCALL(ni_syscall) |
232 | SYSCALL(ni_syscall) | 232 | SYSCALL(ni_syscall) |
233 | SYSX(sys_ni_syscall,compat_sys_sendfile64_wrapper,sys_sendfile64) | 233 | SYS32ONLY(sendfile64) |
234 | COMPAT_SYS_SPU(io_setup) | 234 | COMPAT_SYS_SPU(io_setup) |
235 | SYSCALL_SPU(io_destroy) | 235 | SYSCALL_SPU(io_destroy) |
236 | COMPAT_SYS_SPU(io_getevents) | 236 | COMPAT_SYS_SPU(io_getevents) |
@@ -239,7 +239,7 @@ SYSCALL_SPU(io_cancel) | |||
239 | SYSCALL(set_tid_address) | 239 | SYSCALL(set_tid_address) |
240 | SYSX_SPU(sys_fadvise64,ppc32_fadvise64,sys_fadvise64) | 240 | SYSX_SPU(sys_fadvise64,ppc32_fadvise64,sys_fadvise64) |
241 | SYSCALL(exit_group) | 241 | SYSCALL(exit_group) |
242 | SYSX(sys_lookup_dcookie,ppc32_lookup_dcookie,sys_lookup_dcookie) | 242 | COMPAT_SYS(lookup_dcookie) |
243 | SYSCALL_SPU(epoll_create) | 243 | SYSCALL_SPU(epoll_create) |
244 | SYSCALL_SPU(epoll_ctl) | 244 | SYSCALL_SPU(epoll_ctl) |
245 | SYSCALL_SPU(epoll_wait) | 245 | SYSCALL_SPU(epoll_wait) |
@@ -273,8 +273,8 @@ COMPAT_SYS(mq_timedreceive) | |||
273 | COMPAT_SYS(mq_notify) | 273 | COMPAT_SYS(mq_notify) |
274 | COMPAT_SYS(mq_getsetattr) | 274 | COMPAT_SYS(mq_getsetattr) |
275 | COMPAT_SYS(kexec_load) | 275 | COMPAT_SYS(kexec_load) |
276 | COMPAT_SYS(add_key) | 276 | SYSCALL(add_key) |
277 | COMPAT_SYS(request_key) | 277 | SYSCALL(request_key) |
278 | COMPAT_SYS(keyctl) | 278 | COMPAT_SYS(keyctl) |
279 | COMPAT_SYS(waitid) | 279 | COMPAT_SYS(waitid) |
280 | SYSCALL(ioprio_set) | 280 | SYSCALL(ioprio_set) |
diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index 406b7b9a1341..8ceea14d6fe4 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h | |||
@@ -182,8 +182,6 @@ static inline bool test_thread_local_flags(unsigned int flags) | |||
182 | #define is_32bit_task() (1) | 182 | #define is_32bit_task() (1) |
183 | #endif | 183 | #endif |
184 | 184 | ||
185 | #define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) | ||
186 | |||
187 | #endif /* !__ASSEMBLY__ */ | 185 | #endif /* !__ASSEMBLY__ */ |
188 | 186 | ||
189 | #endif /* __KERNEL__ */ | 187 | #endif /* __KERNEL__ */ |
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 852ed1b384f6..161ab662843b 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h | |||
@@ -71,6 +71,7 @@ static inline void sysfs_remove_device_from_node(struct device *dev, | |||
71 | #if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR) | 71 | #if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR) |
72 | extern int start_topology_update(void); | 72 | extern int start_topology_update(void); |
73 | extern int stop_topology_update(void); | 73 | extern int stop_topology_update(void); |
74 | extern int prrn_is_enabled(void); | ||
74 | #else | 75 | #else |
75 | static inline int start_topology_update(void) | 76 | static inline int start_topology_update(void) |
76 | { | 77 | { |
@@ -80,6 +81,10 @@ static inline int stop_topology_update(void) | |||
80 | { | 81 | { |
81 | return 0; | 82 | return 0; |
82 | } | 83 | } |
84 | static inline int prrn_is_enabled(void) | ||
85 | { | ||
86 | return 0; | ||
87 | } | ||
83 | #endif /* CONFIG_NUMA && CONFIG_PPC_SPLPAR */ | 88 | #endif /* CONFIG_NUMA && CONFIG_PPC_SPLPAR */ |
84 | 89 | ||
85 | #include <asm-generic/topology.h> | 90 | #include <asm-generic/topology.h> |
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index 1487f0f12293..3ca819f541bf 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h | |||
@@ -56,11 +56,5 @@ | |||
56 | #define __ARCH_WANT_SYS_VFORK | 56 | #define __ARCH_WANT_SYS_VFORK |
57 | #define __ARCH_WANT_SYS_CLONE | 57 | #define __ARCH_WANT_SYS_CLONE |
58 | 58 | ||
59 | /* | ||
60 | * "Conditional" syscalls | ||
61 | */ | ||
62 | #define cond_syscall(x) \ | ||
63 | asmlinkage long x (void) __attribute__((weak,alias("sys_ni_syscall"))) | ||
64 | |||
65 | #endif /* __ASSEMBLY__ */ | 59 | #endif /* __ASSEMBLY__ */ |
66 | #endif /* _ASM_POWERPC_UNISTD_H_ */ | 60 | #endif /* _ASM_POWERPC_UNISTD_H_ */ |
diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h index b532060d0916..23016020915e 100644 --- a/arch/powerpc/include/asm/uprobes.h +++ b/arch/powerpc/include/asm/uprobes.h | |||
@@ -51,4 +51,5 @@ extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); | |||
51 | extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); | 51 | extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); |
52 | extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data); | 52 | extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data); |
53 | extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs); | 53 | extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs); |
54 | extern unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs); | ||
54 | #endif /* _ASM_UPROBES_H */ | 55 | #endif /* _ASM_UPROBES_H */ |
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h index 4ae9a09c3b89..282d43a0c855 100644 --- a/arch/powerpc/include/asm/xics.h +++ b/arch/powerpc/include/asm/xics.h | |||
@@ -150,6 +150,7 @@ extern void xics_register_ics(struct ics *ics); | |||
150 | extern void xics_teardown_cpu(void); | 150 | extern void xics_teardown_cpu(void); |
151 | extern void xics_kexec_teardown_cpu(int secondary); | 151 | extern void xics_kexec_teardown_cpu(int secondary); |
152 | extern void xics_migrate_irqs_away(void); | 152 | extern void xics_migrate_irqs_away(void); |
153 | extern void icp_native_eoi(struct irq_data *d); | ||
153 | #ifdef CONFIG_SMP | 154 | #ifdef CONFIG_SMP |
154 | extern int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask, | 155 | extern int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask, |
155 | unsigned int strict_check); | 156 | unsigned int strict_check); |
diff --git a/arch/powerpc/include/uapi/asm/linkage.h b/arch/powerpc/include/uapi/asm/linkage.h deleted file mode 100644 index e1c4ac1cc4ba..000000000000 --- a/arch/powerpc/include/uapi/asm/linkage.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef _ASM_POWERPC_LINKAGE_H | ||
2 | #define _ASM_POWERPC_LINKAGE_H | ||
3 | |||
4 | /* Nothing to see here... */ | ||
5 | |||
6 | #endif /* _ASM_POWERPC_LINKAGE_H */ | ||
diff --git a/arch/powerpc/include/uapi/asm/ptrace.h b/arch/powerpc/include/uapi/asm/ptrace.h index 66b9ca4ee94a..77d2ed35b111 100644 --- a/arch/powerpc/include/uapi/asm/ptrace.h +++ b/arch/powerpc/include/uapi/asm/ptrace.h | |||
@@ -211,6 +211,7 @@ struct ppc_debug_info { | |||
211 | #define PPC_DEBUG_FEATURE_INSN_BP_MASK 0x0000000000000002 | 211 | #define PPC_DEBUG_FEATURE_INSN_BP_MASK 0x0000000000000002 |
212 | #define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x0000000000000004 | 212 | #define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x0000000000000004 |
213 | #define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x0000000000000008 | 213 | #define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x0000000000000008 |
214 | #define PPC_DEBUG_FEATURE_DATA_BP_DAWR 0x0000000000000010 | ||
214 | 215 | ||
215 | #ifndef __ASSEMBLY__ | 216 | #ifndef __ASSEMBLY__ |
216 | 217 | ||
diff --git a/arch/powerpc/include/uapi/asm/socket.h b/arch/powerpc/include/uapi/asm/socket.h index a26dcaece509..a36daf3c6f9a 100644 --- a/arch/powerpc/include/uapi/asm/socket.h +++ b/arch/powerpc/include/uapi/asm/socket.h | |||
@@ -79,4 +79,6 @@ | |||
79 | 79 | ||
80 | #define SO_LOCK_FILTER 44 | 80 | #define SO_LOCK_FILTER 44 |
81 | 81 | ||
82 | #define SO_SELECT_ERR_QUEUE 45 | ||
83 | |||
82 | #endif /* _ASM_POWERPC_SOCKET_H */ | 84 | #endif /* _ASM_POWERPC_SOCKET_H */ |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index a791229329cf..b51a97cfedf8 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -124,6 +124,9 @@ int main(void) | |||
124 | 124 | ||
125 | #ifdef CONFIG_PPC_BOOK3S_64 | 125 | #ifdef CONFIG_PPC_BOOK3S_64 |
126 | DEFINE(THREAD_TAR, offsetof(struct thread_struct, tar)); | 126 | DEFINE(THREAD_TAR, offsetof(struct thread_struct, tar)); |
127 | DEFINE(THREAD_BESCR, offsetof(struct thread_struct, bescr)); | ||
128 | DEFINE(THREAD_EBBHR, offsetof(struct thread_struct, ebbhr)); | ||
129 | DEFINE(THREAD_EBBRR, offsetof(struct thread_struct, ebbrr)); | ||
127 | #endif | 130 | #endif |
128 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 131 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
129 | DEFINE(PACATMSCRATCH, offsetof(struct paca_struct, tm_scratch)); | 132 | DEFINE(PACATMSCRATCH, offsetof(struct paca_struct, tm_scratch)); |
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S index dcd881937f7a..0b9af015bedc 100644 --- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S | |||
@@ -53,6 +53,15 @@ _GLOBAL(__e500_dcache_setup) | |||
53 | isync | 53 | isync |
54 | blr | 54 | blr |
55 | 55 | ||
56 | _GLOBAL(__setup_cpu_e6500) | ||
57 | mflr r6 | ||
58 | #ifdef CONFIG_PPC64 | ||
59 | bl .setup_altivec_ivors | ||
60 | #endif | ||
61 | bl __setup_cpu_e5500 | ||
62 | mtlr r6 | ||
63 | blr | ||
64 | |||
56 | #ifdef CONFIG_PPC32 | 65 | #ifdef CONFIG_PPC32 |
57 | _GLOBAL(__setup_cpu_e200) | 66 | _GLOBAL(__setup_cpu_e200) |
58 | /* enable dedicated debug exception handling resources (Debug APU) */ | 67 | /* enable dedicated debug exception handling resources (Debug APU) */ |
@@ -107,6 +116,13 @@ _GLOBAL(__setup_cpu_e5500) | |||
107 | #endif | 116 | #endif |
108 | 117 | ||
109 | #ifdef CONFIG_PPC_BOOK3E_64 | 118 | #ifdef CONFIG_PPC_BOOK3E_64 |
119 | _GLOBAL(__restore_cpu_e6500) | ||
120 | mflr r5 | ||
121 | bl .setup_altivec_ivors | ||
122 | bl __restore_cpu_e5500 | ||
123 | mtlr r5 | ||
124 | blr | ||
125 | |||
110 | _GLOBAL(__restore_cpu_e5500) | 126 | _GLOBAL(__restore_cpu_e5500) |
111 | mflr r4 | 127 | mflr r4 |
112 | bl __e500_icache_setup | 128 | bl __e500_icache_setup |
diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S index ea847abb0d0a..a283b6442b26 100644 --- a/arch/powerpc/kernel/cpu_setup_power.S +++ b/arch/powerpc/kernel/cpu_setup_power.S | |||
@@ -49,6 +49,7 @@ _GLOBAL(__restore_cpu_power7) | |||
49 | _GLOBAL(__setup_cpu_power8) | 49 | _GLOBAL(__setup_cpu_power8) |
50 | mflr r11 | 50 | mflr r11 |
51 | bl __init_FSCR | 51 | bl __init_FSCR |
52 | bl __init_PMU | ||
52 | bl __init_hvmode_206 | 53 | bl __init_hvmode_206 |
53 | mtlr r11 | 54 | mtlr r11 |
54 | beqlr | 55 | beqlr |
@@ -57,22 +58,28 @@ _GLOBAL(__setup_cpu_power8) | |||
57 | mfspr r3,SPRN_LPCR | 58 | mfspr r3,SPRN_LPCR |
58 | oris r3, r3, LPCR_AIL_3@h | 59 | oris r3, r3, LPCR_AIL_3@h |
59 | bl __init_LPCR | 60 | bl __init_LPCR |
61 | bl __init_HFSCR | ||
60 | bl __init_TLB | 62 | bl __init_TLB |
63 | bl __init_PMU_HV | ||
61 | mtlr r11 | 64 | mtlr r11 |
62 | blr | 65 | blr |
63 | 66 | ||
64 | _GLOBAL(__restore_cpu_power8) | 67 | _GLOBAL(__restore_cpu_power8) |
65 | mflr r11 | 68 | mflr r11 |
66 | bl __init_FSCR | 69 | bl __init_FSCR |
70 | bl __init_PMU | ||
67 | mfmsr r3 | 71 | mfmsr r3 |
68 | rldicl. r0,r3,4,63 | 72 | rldicl. r0,r3,4,63 |
73 | mtlr r11 | ||
69 | beqlr | 74 | beqlr |
70 | li r0,0 | 75 | li r0,0 |
71 | mtspr SPRN_LPID,r0 | 76 | mtspr SPRN_LPID,r0 |
72 | mfspr r3,SPRN_LPCR | 77 | mfspr r3,SPRN_LPCR |
73 | oris r3, r3, LPCR_AIL_3@h | 78 | oris r3, r3, LPCR_AIL_3@h |
74 | bl __init_LPCR | 79 | bl __init_LPCR |
80 | bl __init_HFSCR | ||
75 | bl __init_TLB | 81 | bl __init_TLB |
82 | bl __init_PMU_HV | ||
76 | mtlr r11 | 83 | mtlr r11 |
77 | blr | 84 | blr |
78 | 85 | ||
@@ -116,10 +123,17 @@ __init_LPCR: | |||
116 | 123 | ||
117 | __init_FSCR: | 124 | __init_FSCR: |
118 | mfspr r3,SPRN_FSCR | 125 | mfspr r3,SPRN_FSCR |
119 | ori r3,r3,FSCR_TAR|FSCR_DSCR | 126 | ori r3,r3,FSCR_TAR|FSCR_DSCR|FSCR_EBB |
120 | mtspr SPRN_FSCR,r3 | 127 | mtspr SPRN_FSCR,r3 |
121 | blr | 128 | blr |
122 | 129 | ||
130 | __init_HFSCR: | ||
131 | mfspr r3,SPRN_HFSCR | ||
132 | ori r3,r3,HFSCR_TAR|HFSCR_TM|HFSCR_BHRB|HFSCR_PM|\ | ||
133 | HFSCR_DSCR|HFSCR_VECVSX|HFSCR_FP|HFSCR_EBB | ||
134 | mtspr SPRN_HFSCR,r3 | ||
135 | blr | ||
136 | |||
123 | __init_TLB: | 137 | __init_TLB: |
124 | /* Clear the TLB */ | 138 | /* Clear the TLB */ |
125 | li r6,128 | 139 | li r6,128 |
@@ -131,3 +145,18 @@ __init_TLB: | |||
131 | bdnz 2b | 145 | bdnz 2b |
132 | ptesync | 146 | ptesync |
133 | 1: blr | 147 | 1: blr |
148 | |||
149 | __init_PMU_HV: | ||
150 | li r5,0 | ||
151 | mtspr SPRN_MMCRC,r5 | ||
152 | mtspr SPRN_MMCRH,r5 | ||
153 | blr | ||
154 | |||
155 | __init_PMU: | ||
156 | li r5,0 | ||
157 | mtspr SPRN_MMCRS,r5 | ||
158 | mtspr SPRN_MMCRA,r5 | ||
159 | mtspr SPRN_MMCR0,r5 | ||
160 | mtspr SPRN_MMCR1,r5 | ||
161 | mtspr SPRN_MMCR2,r5 | ||
162 | blr | ||
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 19599ef352bc..ae9f433daabf 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -74,7 +74,9 @@ extern void __restore_cpu_a2(void); | |||
74 | #endif /* CONFIG_PPC64 */ | 74 | #endif /* CONFIG_PPC64 */ |
75 | #if defined(CONFIG_E500) | 75 | #if defined(CONFIG_E500) |
76 | extern void __setup_cpu_e5500(unsigned long offset, struct cpu_spec* spec); | 76 | extern void __setup_cpu_e5500(unsigned long offset, struct cpu_spec* spec); |
77 | extern void __setup_cpu_e6500(unsigned long offset, struct cpu_spec* spec); | ||
77 | extern void __restore_cpu_e5500(void); | 78 | extern void __restore_cpu_e5500(void); |
79 | extern void __restore_cpu_e6500(void); | ||
78 | #endif /* CONFIG_E500 */ | 80 | #endif /* CONFIG_E500 */ |
79 | 81 | ||
80 | /* This table only contains "desktop" CPUs, it need to be filled with embedded | 82 | /* This table only contains "desktop" CPUs, it need to be filled with embedded |
@@ -2065,7 +2067,8 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
2065 | .pvr_value = 0x80400000, | 2067 | .pvr_value = 0x80400000, |
2066 | .cpu_name = "e6500", | 2068 | .cpu_name = "e6500", |
2067 | .cpu_features = CPU_FTRS_E6500, | 2069 | .cpu_features = CPU_FTRS_E6500, |
2068 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, | 2070 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU | |
2071 | PPC_FEATURE_HAS_ALTIVEC_COMP, | ||
2069 | .mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS | | 2072 | .mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS | |
2070 | MMU_FTR_USE_TLBILX, | 2073 | MMU_FTR_USE_TLBILX, |
2071 | .icache_bsize = 64, | 2074 | .icache_bsize = 64, |
@@ -2073,9 +2076,9 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
2073 | .num_pmcs = 4, | 2076 | .num_pmcs = 4, |
2074 | .oprofile_cpu_type = "ppc/e6500", | 2077 | .oprofile_cpu_type = "ppc/e6500", |
2075 | .oprofile_type = PPC_OPROFILE_FSL_EMB, | 2078 | .oprofile_type = PPC_OPROFILE_FSL_EMB, |
2076 | .cpu_setup = __setup_cpu_e5500, | 2079 | .cpu_setup = __setup_cpu_e6500, |
2077 | #ifndef CONFIG_PPC32 | 2080 | #ifndef CONFIG_PPC32 |
2078 | .cpu_restore = __restore_cpu_e5500, | 2081 | .cpu_restore = __restore_cpu_e6500, |
2079 | #endif | 2082 | #endif |
2080 | .machine_check = machine_check_e500mc, | 2083 | .machine_check = machine_check_e500mc, |
2081 | .platform = "ppce6500", | 2084 | .platform = "ppce6500", |
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index b3ba5163eae2..9ec3fe174cba 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c | |||
@@ -150,10 +150,7 @@ void crash_free_reserved_phys_range(unsigned long begin, unsigned long end) | |||
150 | if (addr <= rtas_end && ((addr + PAGE_SIZE) > rtas_start)) | 150 | if (addr <= rtas_end && ((addr + PAGE_SIZE) > rtas_start)) |
151 | continue; | 151 | continue; |
152 | 152 | ||
153 | ClearPageReserved(pfn_to_page(addr >> PAGE_SHIFT)); | 153 | free_reserved_page(pfn_to_page(addr >> PAGE_SHIFT)); |
154 | init_page_count(pfn_to_page(addr >> PAGE_SHIFT)); | ||
155 | free_page((unsigned long)__va(addr)); | ||
156 | totalram_pages++; | ||
157 | } | 154 | } |
158 | } | 155 | } |
159 | #endif | 156 | #endif |
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c index 9ebbc24bb23c..d55c76c571f3 100644 --- a/arch/powerpc/kernel/dbell.c +++ b/arch/powerpc/kernel/dbell.c | |||
@@ -41,6 +41,8 @@ void doorbell_exception(struct pt_regs *regs) | |||
41 | 41 | ||
42 | may_hard_irq_enable(); | 42 | may_hard_irq_enable(); |
43 | 43 | ||
44 | __get_cpu_var(irq_stat).doorbell_irqs++; | ||
45 | |||
44 | smp_ipi_demux(); | 46 | smp_ipi_demux(); |
45 | 47 | ||
46 | irq_exit(); | 48 | irq_exit(); |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 256c5bf0adb7..3fe5259e2fea 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -304,7 +304,7 @@ syscall_exit_work: | |||
304 | subi r12,r12,TI_FLAGS | 304 | subi r12,r12,TI_FLAGS |
305 | 305 | ||
306 | 4: /* Anything else left to do? */ | 306 | 4: /* Anything else left to do? */ |
307 | SET_DEFAULT_THREAD_PPR(r3, r9) /* Set thread.ppr = 3 */ | 307 | SET_DEFAULT_THREAD_PPR(r3, r10) /* Set thread.ppr = 3 */ |
308 | andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) | 308 | andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) |
309 | beq .ret_from_except_lite | 309 | beq .ret_from_except_lite |
310 | 310 | ||
@@ -458,7 +458,15 @@ BEGIN_FTR_SECTION | |||
458 | */ | 458 | */ |
459 | mfspr r0,SPRN_TAR | 459 | mfspr r0,SPRN_TAR |
460 | std r0,THREAD_TAR(r3) | 460 | std r0,THREAD_TAR(r3) |
461 | END_FTR_SECTION_IFSET(CPU_FTR_BCTAR) | 461 | |
462 | /* Event based branch registers */ | ||
463 | mfspr r0, SPRN_BESCR | ||
464 | std r0, THREAD_BESCR(r3) | ||
465 | mfspr r0, SPRN_EBBHR | ||
466 | std r0, THREAD_EBBHR(r3) | ||
467 | mfspr r0, SPRN_EBBRR | ||
468 | std r0, THREAD_EBBRR(r3) | ||
469 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | ||
462 | #endif | 470 | #endif |
463 | 471 | ||
464 | #ifdef CONFIG_SMP | 472 | #ifdef CONFIG_SMP |
@@ -545,9 +553,17 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) | |||
545 | 553 | ||
546 | #ifdef CONFIG_PPC_BOOK3S_64 | 554 | #ifdef CONFIG_PPC_BOOK3S_64 |
547 | BEGIN_FTR_SECTION | 555 | BEGIN_FTR_SECTION |
556 | /* Event based branch registers */ | ||
557 | ld r0, THREAD_BESCR(r4) | ||
558 | mtspr SPRN_BESCR, r0 | ||
559 | ld r0, THREAD_EBBHR(r4) | ||
560 | mtspr SPRN_EBBHR, r0 | ||
561 | ld r0, THREAD_EBBRR(r4) | ||
562 | mtspr SPRN_EBBRR, r0 | ||
563 | |||
548 | ld r0,THREAD_TAR(r4) | 564 | ld r0,THREAD_TAR(r4) |
549 | mtspr SPRN_TAR,r0 | 565 | mtspr SPRN_TAR,r0 |
550 | END_FTR_SECTION_IFSET(CPU_FTR_BCTAR) | 566 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) |
551 | #endif | 567 | #endif |
552 | 568 | ||
553 | #ifdef CONFIG_ALTIVEC | 569 | #ifdef CONFIG_ALTIVEC |
@@ -657,7 +673,7 @@ resume_kernel: | |||
657 | /* Clear _TIF_EMULATE_STACK_STORE flag */ | 673 | /* Clear _TIF_EMULATE_STACK_STORE flag */ |
658 | lis r11,_TIF_EMULATE_STACK_STORE@h | 674 | lis r11,_TIF_EMULATE_STACK_STORE@h |
659 | addi r5,r9,TI_FLAGS | 675 | addi r5,r9,TI_FLAGS |
660 | ldarx r4,0,r5 | 676 | 0: ldarx r4,0,r5 |
661 | andc r4,r4,r11 | 677 | andc r4,r4,r11 |
662 | stdcx. r4,0,r5 | 678 | stdcx. r4,0,r5 |
663 | bne- 0b | 679 | bne- 0b |
diff --git a/arch/powerpc/kernel/epapr_hcalls.S b/arch/powerpc/kernel/epapr_hcalls.S index 62c0dc237826..9f1ebf7338f1 100644 --- a/arch/powerpc/kernel/epapr_hcalls.S +++ b/arch/powerpc/kernel/epapr_hcalls.S | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <asm/asm-compat.h> | 17 | #include <asm/asm-compat.h> |
18 | #include <asm/asm-offsets.h> | 18 | #include <asm/asm-offsets.h> |
19 | 19 | ||
20 | #ifndef CONFIG_PPC64 | ||
20 | /* epapr_ev_idle() was derived from e500_idle() */ | 21 | /* epapr_ev_idle() was derived from e500_idle() */ |
21 | _GLOBAL(epapr_ev_idle) | 22 | _GLOBAL(epapr_ev_idle) |
22 | CURRENT_THREAD_INFO(r3, r1) | 23 | CURRENT_THREAD_INFO(r3, r1) |
@@ -42,6 +43,7 @@ epapr_ev_idle_start: | |||
42 | * _TLF_NAPPING. | 43 | * _TLF_NAPPING. |
43 | */ | 44 | */ |
44 | b idle_loop | 45 | b idle_loop |
46 | #endif | ||
45 | 47 | ||
46 | /* Hypercall entry point. Will be patched with device tree instructions. */ | 48 | /* Hypercall entry point. Will be patched with device tree instructions. */ |
47 | .global epapr_hypercall_start | 49 | .global epapr_hypercall_start |
diff --git a/arch/powerpc/kernel/epapr_paravirt.c b/arch/powerpc/kernel/epapr_paravirt.c index f3eab8594d9f..d44a571e45a7 100644 --- a/arch/powerpc/kernel/epapr_paravirt.c +++ b/arch/powerpc/kernel/epapr_paravirt.c | |||
@@ -23,8 +23,10 @@ | |||
23 | #include <asm/code-patching.h> | 23 | #include <asm/code-patching.h> |
24 | #include <asm/machdep.h> | 24 | #include <asm/machdep.h> |
25 | 25 | ||
26 | #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64) | ||
26 | extern void epapr_ev_idle(void); | 27 | extern void epapr_ev_idle(void); |
27 | extern u32 epapr_ev_idle_start[]; | 28 | extern u32 epapr_ev_idle_start[]; |
29 | #endif | ||
28 | 30 | ||
29 | bool epapr_paravirt_enabled; | 31 | bool epapr_paravirt_enabled; |
30 | 32 | ||
@@ -47,11 +49,15 @@ static int __init epapr_paravirt_init(void) | |||
47 | 49 | ||
48 | for (i = 0; i < (len / 4); i++) { | 50 | for (i = 0; i < (len / 4); i++) { |
49 | patch_instruction(epapr_hypercall_start + i, insts[i]); | 51 | patch_instruction(epapr_hypercall_start + i, insts[i]); |
52 | #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64) | ||
50 | patch_instruction(epapr_ev_idle_start + i, insts[i]); | 53 | patch_instruction(epapr_ev_idle_start + i, insts[i]); |
54 | #endif | ||
51 | } | 55 | } |
52 | 56 | ||
57 | #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64) | ||
53 | if (of_get_property(hyper_node, "has-idle", NULL)) | 58 | if (of_get_property(hyper_node, "has-idle", NULL)) |
54 | ppc_md.power_save = epapr_ev_idle; | 59 | ppc_md.power_save = epapr_ev_idle; |
60 | #endif | ||
55 | 61 | ||
56 | epapr_paravirt_enabled = true; | 62 | epapr_paravirt_enabled = true; |
57 | 63 | ||
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index ae54553eacd9..42a756eec9ff 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S | |||
@@ -299,6 +299,8 @@ interrupt_base_book3e: /* fake trap */ | |||
299 | EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */ | 299 | EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */ |
300 | EXCEPTION_STUB(0x1c0, data_tlb_miss) | 300 | EXCEPTION_STUB(0x1c0, data_tlb_miss) |
301 | EXCEPTION_STUB(0x1e0, instruction_tlb_miss) | 301 | EXCEPTION_STUB(0x1e0, instruction_tlb_miss) |
302 | EXCEPTION_STUB(0x200, altivec_unavailable) /* 0x0f20 */ | ||
303 | EXCEPTION_STUB(0x220, altivec_assist) /* 0x1700 */ | ||
302 | EXCEPTION_STUB(0x260, perfmon) | 304 | EXCEPTION_STUB(0x260, perfmon) |
303 | EXCEPTION_STUB(0x280, doorbell) | 305 | EXCEPTION_STUB(0x280, doorbell) |
304 | EXCEPTION_STUB(0x2a0, doorbell_crit) | 306 | EXCEPTION_STUB(0x2a0, doorbell_crit) |
@@ -395,6 +397,45 @@ interrupt_end_book3e: | |||
395 | bl .kernel_fp_unavailable_exception | 397 | bl .kernel_fp_unavailable_exception |
396 | b .ret_from_except | 398 | b .ret_from_except |
397 | 399 | ||
400 | /* Altivec Unavailable Interrupt */ | ||
401 | START_EXCEPTION(altivec_unavailable); | ||
402 | NORMAL_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_ALTIVEC_UNAVAIL, | ||
403 | PROLOG_ADDITION_NONE) | ||
404 | /* we can probably do a shorter exception entry for that one... */ | ||
405 | EXCEPTION_COMMON(0x200, PACA_EXGEN, INTS_KEEP) | ||
406 | #ifdef CONFIG_ALTIVEC | ||
407 | BEGIN_FTR_SECTION | ||
408 | ld r12,_MSR(r1) | ||
409 | andi. r0,r12,MSR_PR; | ||
410 | beq- 1f | ||
411 | bl .load_up_altivec | ||
412 | b fast_exception_return | ||
413 | 1: | ||
414 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | ||
415 | #endif | ||
416 | INTS_DISABLE | ||
417 | bl .save_nvgprs | ||
418 | addi r3,r1,STACK_FRAME_OVERHEAD | ||
419 | bl .altivec_unavailable_exception | ||
420 | b .ret_from_except | ||
421 | |||
422 | /* AltiVec Assist */ | ||
423 | START_EXCEPTION(altivec_assist); | ||
424 | NORMAL_EXCEPTION_PROLOG(0x220, BOOKE_INTERRUPT_ALTIVEC_ASSIST, | ||
425 | PROLOG_ADDITION_NONE) | ||
426 | EXCEPTION_COMMON(0x220, PACA_EXGEN, INTS_DISABLE) | ||
427 | bl .save_nvgprs | ||
428 | addi r3,r1,STACK_FRAME_OVERHEAD | ||
429 | #ifdef CONFIG_ALTIVEC | ||
430 | BEGIN_FTR_SECTION | ||
431 | bl .altivec_assist_exception | ||
432 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | ||
433 | #else | ||
434 | bl .unknown_exception | ||
435 | #endif | ||
436 | b .ret_from_except | ||
437 | |||
438 | |||
398 | /* Decrementer Interrupt */ | 439 | /* Decrementer Interrupt */ |
399 | MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER, | 440 | MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER, |
400 | decrementer, .timer_interrupt, ACK_DEC) | 441 | decrementer, .timer_interrupt, ACK_DEC) |
@@ -807,6 +848,7 @@ fast_exception_return: | |||
807 | BAD_STACK_TRAMPOLINE(0x000) | 848 | BAD_STACK_TRAMPOLINE(0x000) |
808 | BAD_STACK_TRAMPOLINE(0x100) | 849 | BAD_STACK_TRAMPOLINE(0x100) |
809 | BAD_STACK_TRAMPOLINE(0x200) | 850 | BAD_STACK_TRAMPOLINE(0x200) |
851 | BAD_STACK_TRAMPOLINE(0x220) | ||
810 | BAD_STACK_TRAMPOLINE(0x260) | 852 | BAD_STACK_TRAMPOLINE(0x260) |
811 | BAD_STACK_TRAMPOLINE(0x280) | 853 | BAD_STACK_TRAMPOLINE(0x280) |
812 | BAD_STACK_TRAMPOLINE(0x2a0) | 854 | BAD_STACK_TRAMPOLINE(0x2a0) |
@@ -1350,6 +1392,11 @@ _GLOBAL(__setup_base_ivors) | |||
1350 | 1392 | ||
1351 | blr | 1393 | blr |
1352 | 1394 | ||
1395 | _GLOBAL(setup_altivec_ivors) | ||
1396 | SET_IVOR(32, 0x200) /* AltiVec Unavailable */ | ||
1397 | SET_IVOR(33, 0x220) /* AltiVec Assist */ | ||
1398 | blr | ||
1399 | |||
1353 | _GLOBAL(setup_perfmon_ivor) | 1400 | _GLOBAL(setup_perfmon_ivor) |
1354 | SET_IVOR(35, 0x260) /* Performance Monitor */ | 1401 | SET_IVOR(35, 0x260) /* Performance Monitor */ |
1355 | blr | 1402 | blr |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 200afa5bcfb7..e6eba1bf61ad 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -235,6 +235,7 @@ instruction_access_slb_pSeries: | |||
235 | .globl hardware_interrupt_hv; | 235 | .globl hardware_interrupt_hv; |
236 | hardware_interrupt_pSeries: | 236 | hardware_interrupt_pSeries: |
237 | hardware_interrupt_hv: | 237 | hardware_interrupt_hv: |
238 | HMT_MEDIUM_PPR_DISCARD | ||
238 | BEGIN_FTR_SECTION | 239 | BEGIN_FTR_SECTION |
239 | _MASKABLE_EXCEPTION_PSERIES(0x502, hardware_interrupt, | 240 | _MASKABLE_EXCEPTION_PSERIES(0x502, hardware_interrupt, |
240 | EXC_HV, SOFTEN_TEST_HV) | 241 | EXC_HV, SOFTEN_TEST_HV) |
@@ -254,7 +255,11 @@ hardware_interrupt_hv: | |||
254 | STD_EXCEPTION_PSERIES(0x800, 0x800, fp_unavailable) | 255 | STD_EXCEPTION_PSERIES(0x800, 0x800, fp_unavailable) |
255 | KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x800) | 256 | KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x800) |
256 | 257 | ||
257 | MASKABLE_EXCEPTION_PSERIES(0x900, 0x900, decrementer) | 258 | . = 0x900 |
259 | .globl decrementer_pSeries | ||
260 | decrementer_pSeries: | ||
261 | _MASKABLE_EXCEPTION_PSERIES(0x900, decrementer, EXC_STD, SOFTEN_TEST_PR) | ||
262 | |||
258 | STD_EXCEPTION_HV(0x980, 0x982, hdecrementer) | 263 | STD_EXCEPTION_HV(0x980, 0x982, hdecrementer) |
259 | 264 | ||
260 | MASKABLE_EXCEPTION_PSERIES(0xa00, 0xa00, doorbell_super) | 265 | MASKABLE_EXCEPTION_PSERIES(0xa00, 0xa00, doorbell_super) |
@@ -688,9 +693,18 @@ slb_miss_user_pseries: | |||
688 | .align 7 | 693 | .align 7 |
689 | .globl machine_check_common | 694 | .globl machine_check_common |
690 | machine_check_common: | 695 | machine_check_common: |
696 | |||
697 | mfspr r10,SPRN_DAR | ||
698 | std r10,PACA_EXGEN+EX_DAR(r13) | ||
699 | mfspr r10,SPRN_DSISR | ||
700 | stw r10,PACA_EXGEN+EX_DSISR(r13) | ||
691 | EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) | 701 | EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) |
692 | FINISH_NAP | 702 | FINISH_NAP |
693 | DISABLE_INTS | 703 | DISABLE_INTS |
704 | ld r3,PACA_EXGEN+EX_DAR(r13) | ||
705 | lwz r4,PACA_EXGEN+EX_DSISR(r13) | ||
706 | std r3,_DAR(r1) | ||
707 | std r4,_DSISR(r1) | ||
694 | bl .save_nvgprs | 708 | bl .save_nvgprs |
695 | addi r3,r1,STACK_FRAME_OVERHEAD | 709 | addi r3,r1,STACK_FRAME_OVERHEAD |
696 | bl .machine_check_exception | 710 | bl .machine_check_exception |
@@ -797,7 +811,7 @@ hardware_interrupt_relon_hv: | |||
797 | _MASKABLE_RELON_EXCEPTION_PSERIES(0x502, hardware_interrupt, EXC_HV, SOFTEN_TEST_HV) | 811 | _MASKABLE_RELON_EXCEPTION_PSERIES(0x502, hardware_interrupt, EXC_HV, SOFTEN_TEST_HV) |
798 | FTR_SECTION_ELSE | 812 | FTR_SECTION_ELSE |
799 | _MASKABLE_RELON_EXCEPTION_PSERIES(0x500, hardware_interrupt, EXC_STD, SOFTEN_TEST_PR) | 813 | _MASKABLE_RELON_EXCEPTION_PSERIES(0x500, hardware_interrupt, EXC_STD, SOFTEN_TEST_PR) |
800 | ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_206) | 814 | ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) |
801 | STD_RELON_EXCEPTION_PSERIES(0x4600, 0x600, alignment) | 815 | STD_RELON_EXCEPTION_PSERIES(0x4600, 0x600, alignment) |
802 | STD_RELON_EXCEPTION_PSERIES(0x4700, 0x700, program_check) | 816 | STD_RELON_EXCEPTION_PSERIES(0x4700, 0x700, program_check) |
803 | STD_RELON_EXCEPTION_PSERIES(0x4800, 0x800, fp_unavailable) | 817 | STD_RELON_EXCEPTION_PSERIES(0x4800, 0x800, fp_unavailable) |
@@ -870,10 +884,6 @@ tm_unavailable_relon_pSeries_1: | |||
870 | . = 0x5500 | 884 | . = 0x5500 |
871 | b denorm_exception_hv | 885 | b denorm_exception_hv |
872 | #endif | 886 | #endif |
873 | #ifdef CONFIG_HVC_SCOM | ||
874 | STD_RELON_EXCEPTION_HV(0x5600, 0x1600, maintence_interrupt) | ||
875 | KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1600) | ||
876 | #endif /* CONFIG_HVC_SCOM */ | ||
877 | STD_RELON_EXCEPTION_PSERIES(0x5700, 0x1700, altivec_assist) | 887 | STD_RELON_EXCEPTION_PSERIES(0x5700, 0x1700, altivec_assist) |
878 | 888 | ||
879 | /* Other future vectors */ | 889 | /* Other future vectors */ |
@@ -1066,78 +1076,6 @@ unrecov_user_slb: | |||
1066 | #endif /* __DISABLED__ */ | 1076 | #endif /* __DISABLED__ */ |
1067 | 1077 | ||
1068 | 1078 | ||
1069 | /* | ||
1070 | * r13 points to the PACA, r9 contains the saved CR, | ||
1071 | * r12 contain the saved SRR1, SRR0 is still ready for return | ||
1072 | * r3 has the faulting address | ||
1073 | * r9 - r13 are saved in paca->exslb. | ||
1074 | * r3 is saved in paca->slb_r3 | ||
1075 | * We assume we aren't going to take any exceptions during this procedure. | ||
1076 | */ | ||
1077 | _GLOBAL(slb_miss_realmode) | ||
1078 | mflr r10 | ||
1079 | #ifdef CONFIG_RELOCATABLE | ||
1080 | mtctr r11 | ||
1081 | #endif | ||
1082 | |||
1083 | stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ | ||
1084 | std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ | ||
1085 | |||
1086 | bl .slb_allocate_realmode | ||
1087 | |||
1088 | /* All done -- return from exception. */ | ||
1089 | |||
1090 | ld r10,PACA_EXSLB+EX_LR(r13) | ||
1091 | ld r3,PACA_EXSLB+EX_R3(r13) | ||
1092 | lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ | ||
1093 | |||
1094 | mtlr r10 | ||
1095 | |||
1096 | andi. r10,r12,MSR_RI /* check for unrecoverable exception */ | ||
1097 | beq- 2f | ||
1098 | |||
1099 | .machine push | ||
1100 | .machine "power4" | ||
1101 | mtcrf 0x80,r9 | ||
1102 | mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ | ||
1103 | .machine pop | ||
1104 | |||
1105 | RESTORE_PPR_PACA(PACA_EXSLB, r9) | ||
1106 | ld r9,PACA_EXSLB+EX_R9(r13) | ||
1107 | ld r10,PACA_EXSLB+EX_R10(r13) | ||
1108 | ld r11,PACA_EXSLB+EX_R11(r13) | ||
1109 | ld r12,PACA_EXSLB+EX_R12(r13) | ||
1110 | ld r13,PACA_EXSLB+EX_R13(r13) | ||
1111 | rfid | ||
1112 | b . /* prevent speculative execution */ | ||
1113 | |||
1114 | 2: mfspr r11,SPRN_SRR0 | ||
1115 | ld r10,PACAKBASE(r13) | ||
1116 | LOAD_HANDLER(r10,unrecov_slb) | ||
1117 | mtspr SPRN_SRR0,r10 | ||
1118 | ld r10,PACAKMSR(r13) | ||
1119 | mtspr SPRN_SRR1,r10 | ||
1120 | rfid | ||
1121 | b . | ||
1122 | |||
1123 | unrecov_slb: | ||
1124 | EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB) | ||
1125 | DISABLE_INTS | ||
1126 | bl .save_nvgprs | ||
1127 | 1: addi r3,r1,STACK_FRAME_OVERHEAD | ||
1128 | bl .unrecoverable_exception | ||
1129 | b 1b | ||
1130 | |||
1131 | |||
1132 | #ifdef CONFIG_PPC_970_NAP | ||
1133 | power4_fixup_nap: | ||
1134 | andc r9,r9,r10 | ||
1135 | std r9,TI_LOCAL_FLAGS(r11) | ||
1136 | ld r10,_LINK(r1) /* make idle task do the */ | ||
1137 | std r10,_NIP(r1) /* equivalent of a blr */ | ||
1138 | blr | ||
1139 | #endif | ||
1140 | |||
1141 | .align 7 | 1079 | .align 7 |
1142 | .globl alignment_common | 1080 | .globl alignment_common |
1143 | alignment_common: | 1081 | alignment_common: |
@@ -1336,6 +1274,78 @@ _GLOBAL(opal_mc_secondary_handler) | |||
1336 | 1274 | ||
1337 | 1275 | ||
1338 | /* | 1276 | /* |
1277 | * r13 points to the PACA, r9 contains the saved CR, | ||
1278 | * r12 contain the saved SRR1, SRR0 is still ready for return | ||
1279 | * r3 has the faulting address | ||
1280 | * r9 - r13 are saved in paca->exslb. | ||
1281 | * r3 is saved in paca->slb_r3 | ||
1282 | * We assume we aren't going to take any exceptions during this procedure. | ||
1283 | */ | ||
1284 | _GLOBAL(slb_miss_realmode) | ||
1285 | mflr r10 | ||
1286 | #ifdef CONFIG_RELOCATABLE | ||
1287 | mtctr r11 | ||
1288 | #endif | ||
1289 | |||
1290 | stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ | ||
1291 | std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ | ||
1292 | |||
1293 | bl .slb_allocate_realmode | ||
1294 | |||
1295 | /* All done -- return from exception. */ | ||
1296 | |||
1297 | ld r10,PACA_EXSLB+EX_LR(r13) | ||
1298 | ld r3,PACA_EXSLB+EX_R3(r13) | ||
1299 | lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ | ||
1300 | |||
1301 | mtlr r10 | ||
1302 | |||
1303 | andi. r10,r12,MSR_RI /* check for unrecoverable exception */ | ||
1304 | beq- 2f | ||
1305 | |||
1306 | .machine push | ||
1307 | .machine "power4" | ||
1308 | mtcrf 0x80,r9 | ||
1309 | mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ | ||
1310 | .machine pop | ||
1311 | |||
1312 | RESTORE_PPR_PACA(PACA_EXSLB, r9) | ||
1313 | ld r9,PACA_EXSLB+EX_R9(r13) | ||
1314 | ld r10,PACA_EXSLB+EX_R10(r13) | ||
1315 | ld r11,PACA_EXSLB+EX_R11(r13) | ||
1316 | ld r12,PACA_EXSLB+EX_R12(r13) | ||
1317 | ld r13,PACA_EXSLB+EX_R13(r13) | ||
1318 | rfid | ||
1319 | b . /* prevent speculative execution */ | ||
1320 | |||
1321 | 2: mfspr r11,SPRN_SRR0 | ||
1322 | ld r10,PACAKBASE(r13) | ||
1323 | LOAD_HANDLER(r10,unrecov_slb) | ||
1324 | mtspr SPRN_SRR0,r10 | ||
1325 | ld r10,PACAKMSR(r13) | ||
1326 | mtspr SPRN_SRR1,r10 | ||
1327 | rfid | ||
1328 | b . | ||
1329 | |||
1330 | unrecov_slb: | ||
1331 | EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB) | ||
1332 | DISABLE_INTS | ||
1333 | bl .save_nvgprs | ||
1334 | 1: addi r3,r1,STACK_FRAME_OVERHEAD | ||
1335 | bl .unrecoverable_exception | ||
1336 | b 1b | ||
1337 | |||
1338 | |||
1339 | #ifdef CONFIG_PPC_970_NAP | ||
1340 | power4_fixup_nap: | ||
1341 | andc r9,r9,r10 | ||
1342 | std r9,TI_LOCAL_FLAGS(r11) | ||
1343 | ld r10,_LINK(r1) /* make idle task do the */ | ||
1344 | std r10,_NIP(r1) /* equivalent of a blr */ | ||
1345 | blr | ||
1346 | #endif | ||
1347 | |||
1348 | /* | ||
1339 | * Hash table stuff | 1349 | * Hash table stuff |
1340 | */ | 1350 | */ |
1341 | .align 7 | 1351 | .align 7 |
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c index 06c8202a69cf..2230fd0ca3e4 100644 --- a/arch/powerpc/kernel/fadump.c +++ b/arch/powerpc/kernel/fadump.c | |||
@@ -1045,10 +1045,7 @@ static void fadump_release_memory(unsigned long begin, unsigned long end) | |||
1045 | if (addr <= ra_end && ((addr + PAGE_SIZE) > ra_start)) | 1045 | if (addr <= ra_end && ((addr + PAGE_SIZE) > ra_start)) |
1046 | continue; | 1046 | continue; |
1047 | 1047 | ||
1048 | ClearPageReserved(pfn_to_page(addr >> PAGE_SHIFT)); | 1048 | free_reserved_page(pfn_to_page(addr >> PAGE_SHIFT)); |
1049 | init_page_count(pfn_to_page(addr >> PAGE_SHIFT)); | ||
1050 | free_page((unsigned long)__va(addr)); | ||
1051 | totalram_pages++; | ||
1052 | } | 1049 | } |
1053 | } | 1050 | } |
1054 | 1051 | ||
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 7a2e5e421abf..97e2671cde7f 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S | |||
@@ -769,6 +769,8 @@ finish_tlb_load_47x: | |||
769 | */ | 769 | */ |
770 | DEBUG_CRIT_EXCEPTION | 770 | DEBUG_CRIT_EXCEPTION |
771 | 771 | ||
772 | interrupt_end: | ||
773 | |||
772 | /* | 774 | /* |
773 | * Global functions | 775 | * Global functions |
774 | */ | 776 | */ |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 0886ae6dd5be..b61363d557b5 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -509,6 +509,7 @@ _GLOBAL(copy_and_flush) | |||
509 | sync | 509 | sync |
510 | addi r5,r5,8 | 510 | addi r5,r5,8 |
511 | addi r6,r6,8 | 511 | addi r6,r6,8 |
512 | isync | ||
512 | blr | 513 | blr |
513 | 514 | ||
514 | .align 8 | 515 | .align 8 |
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index 5f051eeb93a2..a620203f7de3 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h | |||
@@ -199,11 +199,6 @@ | |||
199 | .align 5; \ | 199 | .align 5; \ |
200 | label: | 200 | label: |
201 | 201 | ||
202 | #define FINISH_EXCEPTION(func) \ | ||
203 | bl transfer_to_handler_full; \ | ||
204 | .long func; \ | ||
205 | .long ret_from_except_full | ||
206 | |||
207 | #define EXCEPTION(n, intno, label, hdlr, xfer) \ | 202 | #define EXCEPTION(n, intno, label, hdlr, xfer) \ |
208 | START_EXCEPTION(label); \ | 203 | START_EXCEPTION(label); \ |
209 | NORMAL_EXCEPTION_PROLOG(intno); \ | 204 | NORMAL_EXCEPTION_PROLOG(intno); \ |
@@ -286,13 +281,13 @@ label: | |||
286 | andis. r10,r10,(DBSR_IC|DBSR_BT)@h; \ | 281 | andis. r10,r10,(DBSR_IC|DBSR_BT)@h; \ |
287 | beq+ 2f; \ | 282 | beq+ 2f; \ |
288 | \ | 283 | \ |
289 | lis r10,KERNELBASE@h; /* check if exception in vectors */ \ | 284 | lis r10,interrupt_base@h; /* check if exception in vectors */ \ |
290 | ori r10,r10,KERNELBASE@l; \ | 285 | ori r10,r10,interrupt_base@l; \ |
291 | cmplw r12,r10; \ | 286 | cmplw r12,r10; \ |
292 | blt+ 2f; /* addr below exception vectors */ \ | 287 | blt+ 2f; /* addr below exception vectors */ \ |
293 | \ | 288 | \ |
294 | lis r10,DebugDebug@h; \ | 289 | lis r10,interrupt_end@h; \ |
295 | ori r10,r10,DebugDebug@l; \ | 290 | ori r10,r10,interrupt_end@l; \ |
296 | cmplw r12,r10; \ | 291 | cmplw r12,r10; \ |
297 | bgt+ 2f; /* addr above exception vectors */ \ | 292 | bgt+ 2f; /* addr above exception vectors */ \ |
298 | \ | 293 | \ |
@@ -339,13 +334,13 @@ label: | |||
339 | andis. r10,r10,(DBSR_IC|DBSR_BT)@h; \ | 334 | andis. r10,r10,(DBSR_IC|DBSR_BT)@h; \ |
340 | beq+ 2f; \ | 335 | beq+ 2f; \ |
341 | \ | 336 | \ |
342 | lis r10,KERNELBASE@h; /* check if exception in vectors */ \ | 337 | lis r10,interrupt_base@h; /* check if exception in vectors */ \ |
343 | ori r10,r10,KERNELBASE@l; \ | 338 | ori r10,r10,interrupt_base@l; \ |
344 | cmplw r12,r10; \ | 339 | cmplw r12,r10; \ |
345 | blt+ 2f; /* addr below exception vectors */ \ | 340 | blt+ 2f; /* addr below exception vectors */ \ |
346 | \ | 341 | \ |
347 | lis r10,DebugCrit@h; \ | 342 | lis r10,interrupt_end@h; \ |
348 | ori r10,r10,DebugCrit@l; \ | 343 | ori r10,r10,interrupt_end@l; \ |
349 | cmplw r12,r10; \ | 344 | cmplw r12,r10; \ |
350 | bgt+ 2f; /* addr above exception vectors */ \ | 345 | bgt+ 2f; /* addr above exception vectors */ \ |
351 | \ | 346 | \ |
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 6f62a737f607..d10a7cacccd2 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S | |||
@@ -605,6 +605,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV) | |||
605 | /* Embedded Hypervisor Privilege */ | 605 | /* Embedded Hypervisor Privilege */ |
606 | EXCEPTION(0, HV_PRIV, Ehvpriv, unknown_exception, EXC_XFER_EE) | 606 | EXCEPTION(0, HV_PRIV, Ehvpriv, unknown_exception, EXC_XFER_EE) |
607 | 607 | ||
608 | interrupt_end: | ||
609 | |||
608 | /* | 610 | /* |
609 | * Local functions | 611 | * Local functions |
610 | */ | 612 | */ |
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index ea78761aa169..939ea7ef0dc8 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c | |||
@@ -33,11 +33,6 @@ | |||
33 | #include <asm/runlatch.h> | 33 | #include <asm/runlatch.h> |
34 | #include <asm/smp.h> | 34 | #include <asm/smp.h> |
35 | 35 | ||
36 | #ifdef CONFIG_HOTPLUG_CPU | ||
37 | #define cpu_should_die() cpu_is_offline(smp_processor_id()) | ||
38 | #else | ||
39 | #define cpu_should_die() 0 | ||
40 | #endif | ||
41 | 36 | ||
42 | unsigned long cpuidle_disable = IDLE_NO_OVERRIDE; | 37 | unsigned long cpuidle_disable = IDLE_NO_OVERRIDE; |
43 | EXPORT_SYMBOL(cpuidle_disable); | 38 | EXPORT_SYMBOL(cpuidle_disable); |
@@ -50,64 +45,38 @@ static int __init powersave_off(char *arg) | |||
50 | } | 45 | } |
51 | __setup("powersave=off", powersave_off); | 46 | __setup("powersave=off", powersave_off); |
52 | 47 | ||
53 | /* | 48 | #ifdef CONFIG_HOTPLUG_CPU |
54 | * The body of the idle task. | 49 | void arch_cpu_idle_dead(void) |
55 | */ | ||
56 | void cpu_idle(void) | ||
57 | { | 50 | { |
58 | set_thread_flag(TIF_POLLING_NRFLAG); | 51 | sched_preempt_enable_no_resched(); |
59 | while (1) { | 52 | cpu_die(); |
60 | tick_nohz_idle_enter(); | 53 | } |
61 | rcu_idle_enter(); | 54 | #endif |
62 | |||
63 | while (!need_resched() && !cpu_should_die()) { | ||
64 | ppc64_runlatch_off(); | ||
65 | |||
66 | if (ppc_md.power_save) { | ||
67 | clear_thread_flag(TIF_POLLING_NRFLAG); | ||
68 | /* | ||
69 | * smp_mb is so clearing of TIF_POLLING_NRFLAG | ||
70 | * is ordered w.r.t. need_resched() test. | ||
71 | */ | ||
72 | smp_mb(); | ||
73 | local_irq_disable(); | ||
74 | |||
75 | /* Don't trace irqs off for idle */ | ||
76 | stop_critical_timings(); | ||
77 | |||
78 | /* check again after disabling irqs */ | ||
79 | if (!need_resched() && !cpu_should_die()) | ||
80 | ppc_md.power_save(); | ||
81 | |||
82 | start_critical_timings(); | ||
83 | |||
84 | /* Some power_save functions return with | ||
85 | * interrupts enabled, some don't. | ||
86 | */ | ||
87 | if (irqs_disabled()) | ||
88 | local_irq_enable(); | ||
89 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
90 | |||
91 | } else { | ||
92 | /* | ||
93 | * Go into low thread priority and possibly | ||
94 | * low power mode. | ||
95 | */ | ||
96 | HMT_low(); | ||
97 | HMT_very_low(); | ||
98 | } | ||
99 | } | ||
100 | 55 | ||
101 | HMT_medium(); | 56 | void arch_cpu_idle(void) |
102 | ppc64_runlatch_on(); | 57 | { |
103 | rcu_idle_exit(); | 58 | ppc64_runlatch_off(); |
104 | tick_nohz_idle_exit(); | 59 | |
105 | if (cpu_should_die()) { | 60 | if (ppc_md.power_save) { |
106 | sched_preempt_enable_no_resched(); | 61 | ppc_md.power_save(); |
107 | cpu_die(); | 62 | /* |
108 | } | 63 | * Some power_save functions return with |
109 | schedule_preempt_disabled(); | 64 | * interrupts enabled, some don't. |
65 | */ | ||
66 | if (irqs_disabled()) | ||
67 | local_irq_enable(); | ||
68 | } else { | ||
69 | local_irq_enable(); | ||
70 | /* | ||
71 | * Go into low thread priority and possibly | ||
72 | * low power mode. | ||
73 | */ | ||
74 | HMT_low(); | ||
75 | HMT_very_low(); | ||
110 | } | 76 | } |
77 | |||
78 | HMT_medium(); | ||
79 | ppc64_runlatch_on(); | ||
111 | } | 80 | } |
112 | 81 | ||
113 | int powersave_nap; | 82 | int powersave_nap; |
diff --git a/arch/powerpc/kernel/idle_book3e.S b/arch/powerpc/kernel/idle_book3e.S index 4c7cb4008585..bfb73cc209ce 100644 --- a/arch/powerpc/kernel/idle_book3e.S +++ b/arch/powerpc/kernel/idle_book3e.S | |||
@@ -16,11 +16,13 @@ | |||
16 | #include <asm/ppc-opcode.h> | 16 | #include <asm/ppc-opcode.h> |
17 | #include <asm/processor.h> | 17 | #include <asm/processor.h> |
18 | #include <asm/thread_info.h> | 18 | #include <asm/thread_info.h> |
19 | #include <asm/epapr_hcalls.h> | ||
19 | 20 | ||
20 | /* 64-bit version only for now */ | 21 | /* 64-bit version only for now */ |
21 | #ifdef CONFIG_PPC64 | 22 | #ifdef CONFIG_PPC64 |
22 | 23 | ||
23 | _GLOBAL(book3e_idle) | 24 | .macro BOOK3E_IDLE name loop |
25 | _GLOBAL(\name) | ||
24 | /* Save LR for later */ | 26 | /* Save LR for later */ |
25 | mflr r0 | 27 | mflr r0 |
26 | std r0,16(r1) | 28 | std r0,16(r1) |
@@ -67,7 +69,33 @@ _GLOBAL(book3e_idle) | |||
67 | 69 | ||
68 | /* We can now re-enable hard interrupts and go to sleep */ | 70 | /* We can now re-enable hard interrupts and go to sleep */ |
69 | wrteei 1 | 71 | wrteei 1 |
70 | 1: PPC_WAIT(0) | 72 | \loop |
73 | |||
74 | .endm | ||
75 | |||
76 | .macro BOOK3E_IDLE_LOOP | ||
77 | 1: | ||
78 | PPC_WAIT(0) | ||
71 | b 1b | 79 | b 1b |
80 | .endm | ||
81 | |||
82 | /* epapr_ev_idle_start below is patched with the proper hcall | ||
83 | opcodes during kernel initialization */ | ||
84 | .macro EPAPR_EV_IDLE_LOOP | ||
85 | idle_loop: | ||
86 | LOAD_REG_IMMEDIATE(r11, EV_HCALL_TOKEN(EV_IDLE)) | ||
87 | |||
88 | .global epapr_ev_idle_start | ||
89 | epapr_ev_idle_start: | ||
90 | li r3, -1 | ||
91 | nop | ||
92 | nop | ||
93 | nop | ||
94 | b idle_loop | ||
95 | .endm | ||
96 | |||
97 | BOOK3E_IDLE epapr_ev_idle EPAPR_EV_IDLE_LOOP | ||
98 | |||
99 | BOOK3E_IDLE book3e_idle BOOK3E_IDLE_LOOP | ||
72 | 100 | ||
73 | #endif /* CONFIG_PPC64 */ | 101 | #endif /* CONFIG_PPC64 */ |
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 31c4fdc6859c..c0d0dbddfba1 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -102,7 +102,7 @@ static int __init fail_iommu_debugfs(void) | |||
102 | struct dentry *dir = fault_create_debugfs_attr("fail_iommu", | 102 | struct dentry *dir = fault_create_debugfs_attr("fail_iommu", |
103 | NULL, &fail_iommu); | 103 | NULL, &fail_iommu); |
104 | 104 | ||
105 | return IS_ERR(dir) ? PTR_ERR(dir) : 0; | 105 | return PTR_RET(dir); |
106 | } | 106 | } |
107 | late_initcall(fail_iommu_debugfs); | 107 | late_initcall(fail_iommu_debugfs); |
108 | 108 | ||
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 4f97fe345526..5cbcf4d5a808 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -374,6 +374,15 @@ int arch_show_interrupts(struct seq_file *p, int prec) | |||
374 | seq_printf(p, "%10u ", per_cpu(irq_stat, j).mce_exceptions); | 374 | seq_printf(p, "%10u ", per_cpu(irq_stat, j).mce_exceptions); |
375 | seq_printf(p, " Machine check exceptions\n"); | 375 | seq_printf(p, " Machine check exceptions\n"); |
376 | 376 | ||
377 | #ifdef CONFIG_PPC_DOORBELL | ||
378 | if (cpu_has_feature(CPU_FTR_DBELL)) { | ||
379 | seq_printf(p, "%*s: ", prec, "DBL"); | ||
380 | for_each_online_cpu(j) | ||
381 | seq_printf(p, "%10u ", per_cpu(irq_stat, j).doorbell_irqs); | ||
382 | seq_printf(p, " Doorbell interrupts\n"); | ||
383 | } | ||
384 | #endif | ||
385 | |||
377 | return 0; | 386 | return 0; |
378 | } | 387 | } |
379 | 388 | ||
@@ -387,6 +396,9 @@ u64 arch_irq_stat_cpu(unsigned int cpu) | |||
387 | sum += per_cpu(irq_stat, cpu).pmu_irqs; | 396 | sum += per_cpu(irq_stat, cpu).pmu_irqs; |
388 | sum += per_cpu(irq_stat, cpu).mce_exceptions; | 397 | sum += per_cpu(irq_stat, cpu).mce_exceptions; |
389 | sum += per_cpu(irq_stat, cpu).spurious_irqs; | 398 | sum += per_cpu(irq_stat, cpu).spurious_irqs; |
399 | #ifdef CONFIG_PPC_DOORBELL | ||
400 | sum += per_cpu(irq_stat, cpu).doorbell_irqs; | ||
401 | #endif | ||
390 | 402 | ||
391 | return sum; | 403 | return sum; |
392 | } | 404 | } |
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index 5ca82cd4a374..c1eef241017a 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c | |||
@@ -159,7 +159,7 @@ static int kgdb_singlestep(struct pt_regs *regs) | |||
159 | if (user_mode(regs)) | 159 | if (user_mode(regs)) |
160 | return 0; | 160 | return 0; |
161 | 161 | ||
162 | backup_current_thread_info = (struct thread_info *)kmalloc(sizeof(struct thread_info), GFP_KERNEL); | 162 | backup_current_thread_info = kmalloc(sizeof(struct thread_info), GFP_KERNEL); |
163 | /* | 163 | /* |
164 | * On Book E and perhaps other processors, singlestep is handled on | 164 | * On Book E and perhaps other processors, singlestep is handled on |
165 | * the critical exception stack. This causes current_thread_info() | 165 | * the critical exception stack. This causes current_thread_info() |
diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c index a61b133c4f99..6782221d49bd 100644 --- a/arch/powerpc/kernel/kvm.c +++ b/arch/powerpc/kernel/kvm.c | |||
@@ -756,12 +756,7 @@ static __init void kvm_free_tmp(void) | |||
756 | end = (ulong)&kvm_tmp[ARRAY_SIZE(kvm_tmp)] & PAGE_MASK; | 756 | end = (ulong)&kvm_tmp[ARRAY_SIZE(kvm_tmp)] & PAGE_MASK; |
757 | 757 | ||
758 | /* Free the tmp space we don't need */ | 758 | /* Free the tmp space we don't need */ |
759 | for (; start < end; start += PAGE_SIZE) { | 759 | free_reserved_area(start, end, 0, NULL); |
760 | ClearPageReserved(virt_to_page(start)); | ||
761 | init_page_count(virt_to_page(start)); | ||
762 | free_page(start); | ||
763 | totalram_pages++; | ||
764 | } | ||
765 | } | 760 | } |
766 | 761 | ||
767 | static int __init kvm_guest_init(void) | 762 | static int __init kvm_guest_init(void) |
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index f5725bce9ed2..d92f3871e9cf 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c | |||
@@ -41,8 +41,6 @@ | |||
41 | 41 | ||
42 | /* #define LPARCFG_DEBUG */ | 42 | /* #define LPARCFG_DEBUG */ |
43 | 43 | ||
44 | static struct proc_dir_entry *proc_ppc64_lparcfg; | ||
45 | |||
46 | /* | 44 | /* |
47 | * Track sum of all purrs across all processors. This is used to further | 45 | * Track sum of all purrs across all processors. This is used to further |
48 | * calculate usage values by different applications | 46 | * calculate usage values by different applications |
@@ -301,6 +299,7 @@ static void parse_system_parameter_string(struct seq_file *m) | |||
301 | __pa(rtas_data_buf), | 299 | __pa(rtas_data_buf), |
302 | RTAS_DATA_BUF_SIZE); | 300 | RTAS_DATA_BUF_SIZE); |
303 | memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH); | 301 | memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH); |
302 | local_buffer[SPLPAR_MAXLENGTH - 1] = '\0'; | ||
304 | spin_unlock(&rtas_data_buf_lock); | 303 | spin_unlock(&rtas_data_buf_lock); |
305 | 304 | ||
306 | if (call_status != 0) { | 305 | if (call_status != 0) { |
@@ -688,27 +687,22 @@ static const struct file_operations lparcfg_fops = { | |||
688 | 687 | ||
689 | static int __init lparcfg_init(void) | 688 | static int __init lparcfg_init(void) |
690 | { | 689 | { |
691 | struct proc_dir_entry *ent; | ||
692 | umode_t mode = S_IRUSR | S_IRGRP | S_IROTH; | 690 | umode_t mode = S_IRUSR | S_IRGRP | S_IROTH; |
693 | 691 | ||
694 | /* Allow writing if we have FW_FEATURE_SPLPAR */ | 692 | /* Allow writing if we have FW_FEATURE_SPLPAR */ |
695 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) | 693 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) |
696 | mode |= S_IWUSR; | 694 | mode |= S_IWUSR; |
697 | 695 | ||
698 | ent = proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_fops); | 696 | if (!proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_fops)) { |
699 | if (!ent) { | ||
700 | printk(KERN_ERR "Failed to create powerpc/lparcfg\n"); | 697 | printk(KERN_ERR "Failed to create powerpc/lparcfg\n"); |
701 | return -EIO; | 698 | return -EIO; |
702 | } | 699 | } |
703 | |||
704 | proc_ppc64_lparcfg = ent; | ||
705 | return 0; | 700 | return 0; |
706 | } | 701 | } |
707 | 702 | ||
708 | static void __exit lparcfg_cleanup(void) | 703 | static void __exit lparcfg_cleanup(void) |
709 | { | 704 | { |
710 | if (proc_ppc64_lparcfg) | 705 | remove_proc_subtree("powerpc/lparcfg", NULL); |
711 | remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent); | ||
712 | } | 706 | } |
713 | 707 | ||
714 | module_init(lparcfg_init); | 708 | module_init(lparcfg_init); |
diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index bec1e930ed73..48fbc2b97e95 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c | |||
@@ -511,8 +511,7 @@ int __init nvram_scan_partitions(void) | |||
511 | "detected: 0-length partition\n"); | 511 | "detected: 0-length partition\n"); |
512 | goto out; | 512 | goto out; |
513 | } | 513 | } |
514 | tmp_part = (struct nvram_partition *) | 514 | tmp_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL); |
515 | kmalloc(sizeof(struct nvram_partition), GFP_KERNEL); | ||
516 | err = -ENOMEM; | 515 | err = -ENOMEM; |
517 | if (!tmp_part) { | 516 | if (!tmp_part) { |
518 | printk(KERN_ERR "nvram_scan_partitions: kmalloc failed\n"); | 517 | printk(KERN_ERR "nvram_scan_partitions: kmalloc failed\n"); |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index fa12ae42d98c..f325dc923409 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/irq.h> | 30 | #include <linux/irq.h> |
31 | #include <linux/vmalloc.h> | 31 | #include <linux/vmalloc.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/vgaarb.h> | ||
33 | 34 | ||
34 | #include <asm/processor.h> | 35 | #include <asm/processor.h> |
35 | #include <asm/io.h> | 36 | #include <asm/io.h> |
@@ -1023,6 +1024,27 @@ void pcibios_setup_bus_self(struct pci_bus *bus) | |||
1023 | ppc_md.pci_dma_bus_setup(bus); | 1024 | ppc_md.pci_dma_bus_setup(bus); |
1024 | } | 1025 | } |
1025 | 1026 | ||
1027 | void pcibios_setup_device(struct pci_dev *dev) | ||
1028 | { | ||
1029 | /* Fixup NUMA node as it may not be setup yet by the generic | ||
1030 | * code and is needed by the DMA init | ||
1031 | */ | ||
1032 | set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); | ||
1033 | |||
1034 | /* Hook up default DMA ops */ | ||
1035 | set_dma_ops(&dev->dev, pci_dma_ops); | ||
1036 | set_dma_offset(&dev->dev, PCI_DRAM_OFFSET); | ||
1037 | |||
1038 | /* Additional platform DMA/iommu setup */ | ||
1039 | if (ppc_md.pci_dma_dev_setup) | ||
1040 | ppc_md.pci_dma_dev_setup(dev); | ||
1041 | |||
1042 | /* Read default IRQs and fixup if necessary */ | ||
1043 | pci_read_irq_line(dev); | ||
1044 | if (ppc_md.pci_irq_fixup) | ||
1045 | ppc_md.pci_irq_fixup(dev); | ||
1046 | } | ||
1047 | |||
1026 | void pcibios_setup_bus_devices(struct pci_bus *bus) | 1048 | void pcibios_setup_bus_devices(struct pci_bus *bus) |
1027 | { | 1049 | { |
1028 | struct pci_dev *dev; | 1050 | struct pci_dev *dev; |
@@ -1037,23 +1059,7 @@ void pcibios_setup_bus_devices(struct pci_bus *bus) | |||
1037 | if (dev->is_added) | 1059 | if (dev->is_added) |
1038 | continue; | 1060 | continue; |
1039 | 1061 | ||
1040 | /* Fixup NUMA node as it may not be setup yet by the generic | 1062 | pcibios_setup_device(dev); |
1041 | * code and is needed by the DMA init | ||
1042 | */ | ||
1043 | set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); | ||
1044 | |||
1045 | /* Hook up default DMA ops */ | ||
1046 | set_dma_ops(&dev->dev, pci_dma_ops); | ||
1047 | set_dma_offset(&dev->dev, PCI_DRAM_OFFSET); | ||
1048 | |||
1049 | /* Additional platform DMA/iommu setup */ | ||
1050 | if (ppc_md.pci_dma_dev_setup) | ||
1051 | ppc_md.pci_dma_dev_setup(dev); | ||
1052 | |||
1053 | /* Read default IRQs and fixup if necessary */ | ||
1054 | pci_read_irq_line(dev); | ||
1055 | if (ppc_md.pci_irq_fixup) | ||
1056 | ppc_md.pci_irq_fixup(dev); | ||
1057 | } | 1063 | } |
1058 | } | 1064 | } |
1059 | 1065 | ||
@@ -1494,6 +1500,10 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
1494 | if (ppc_md.pcibios_enable_device_hook(dev)) | 1500 | if (ppc_md.pcibios_enable_device_hook(dev)) |
1495 | return -EINVAL; | 1501 | return -EINVAL; |
1496 | 1502 | ||
1503 | /* avoid pcie irq fix up impact on cardbus */ | ||
1504 | if (dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) | ||
1505 | pcibios_setup_device(dev); | ||
1506 | |||
1497 | return pci_enable_resources(dev, mask); | 1507 | return pci_enable_resources(dev, mask); |
1498 | } | 1508 | } |
1499 | 1509 | ||
@@ -1725,3 +1735,15 @@ static void fixup_hide_host_resource_fsl(struct pci_dev *dev) | |||
1725 | } | 1735 | } |
1726 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MOTOROLA, PCI_ANY_ID, fixup_hide_host_resource_fsl); | 1736 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MOTOROLA, PCI_ANY_ID, fixup_hide_host_resource_fsl); |
1727 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, fixup_hide_host_resource_fsl); | 1737 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, fixup_hide_host_resource_fsl); |
1738 | |||
1739 | static void fixup_vga(struct pci_dev *pdev) | ||
1740 | { | ||
1741 | u16 cmd; | ||
1742 | |||
1743 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | ||
1744 | if ((cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) || !vga_default_device()) | ||
1745 | vga_set_default_device(pdev); | ||
1746 | |||
1747 | } | ||
1748 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, | ||
1749 | PCI_CLASS_DISPLAY_VGA, 8, fixup_vga); | ||
diff --git a/arch/powerpc/kernel/proc_powerpc.c b/arch/powerpc/kernel/proc_powerpc.c index f19d0bdc3241..feb8580fdc84 100644 --- a/arch/powerpc/kernel/proc_powerpc.c +++ b/arch/powerpc/kernel/proc_powerpc.c | |||
@@ -32,8 +32,6 @@ | |||
32 | static loff_t page_map_seek( struct file *file, loff_t off, int whence) | 32 | static loff_t page_map_seek( struct file *file, loff_t off, int whence) |
33 | { | 33 | { |
34 | loff_t new; | 34 | loff_t new; |
35 | struct proc_dir_entry *dp = PDE(file_inode(file)); | ||
36 | |||
37 | switch(whence) { | 35 | switch(whence) { |
38 | case 0: | 36 | case 0: |
39 | new = off; | 37 | new = off; |
@@ -42,12 +40,12 @@ static loff_t page_map_seek( struct file *file, loff_t off, int whence) | |||
42 | new = file->f_pos + off; | 40 | new = file->f_pos + off; |
43 | break; | 41 | break; |
44 | case 2: | 42 | case 2: |
45 | new = dp->size + off; | 43 | new = PAGE_SIZE + off; |
46 | break; | 44 | break; |
47 | default: | 45 | default: |
48 | return -EINVAL; | 46 | return -EINVAL; |
49 | } | 47 | } |
50 | if ( new < 0 || new > dp->size ) | 48 | if ( new < 0 || new > PAGE_SIZE ) |
51 | return -EINVAL; | 49 | return -EINVAL; |
52 | return (file->f_pos = new); | 50 | return (file->f_pos = new); |
53 | } | 51 | } |
@@ -55,19 +53,18 @@ static loff_t page_map_seek( struct file *file, loff_t off, int whence) | |||
55 | static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes, | 53 | static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes, |
56 | loff_t *ppos) | 54 | loff_t *ppos) |
57 | { | 55 | { |
58 | struct proc_dir_entry *dp = PDE(file_inode(file)); | 56 | return simple_read_from_buffer(buf, nbytes, ppos, |
59 | return simple_read_from_buffer(buf, nbytes, ppos, dp->data, dp->size); | 57 | PDE_DATA(file_inode(file)), PAGE_SIZE); |
60 | } | 58 | } |
61 | 59 | ||
62 | static int page_map_mmap( struct file *file, struct vm_area_struct *vma ) | 60 | static int page_map_mmap( struct file *file, struct vm_area_struct *vma ) |
63 | { | 61 | { |
64 | struct proc_dir_entry *dp = PDE(file_inode(file)); | 62 | if ((vma->vm_end - vma->vm_start) > PAGE_SIZE) |
65 | |||
66 | if ((vma->vm_end - vma->vm_start) > dp->size) | ||
67 | return -EINVAL; | 63 | return -EINVAL; |
68 | 64 | ||
69 | remap_pfn_range(vma, vma->vm_start, __pa(dp->data) >> PAGE_SHIFT, | 65 | remap_pfn_range(vma, vma->vm_start, |
70 | dp->size, vma->vm_page_prot); | 66 | __pa(PDE_DATA(file_inode(file))) >> PAGE_SHIFT, |
67 | PAGE_SIZE, vma->vm_page_prot); | ||
71 | return 0; | 68 | return 0; |
72 | } | 69 | } |
73 | 70 | ||
@@ -86,7 +83,7 @@ static int __init proc_ppc64_init(void) | |||
86 | &page_map_fops, vdso_data); | 83 | &page_map_fops, vdso_data); |
87 | if (!pde) | 84 | if (!pde) |
88 | return 1; | 85 | return 1; |
89 | pde->size = PAGE_SIZE; | 86 | proc_set_size(pde, PAGE_SIZE); |
90 | 87 | ||
91 | return 0; | 88 | return 0; |
92 | } | 89 | } |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 59dd545fdde1..ceb4e7b62cf4 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -555,10 +555,12 @@ static inline void tm_recheckpoint_new_task(struct task_struct *new) | |||
555 | new->thread.regs->msr |= | 555 | new->thread.regs->msr |= |
556 | (MSR_FP | new->thread.fpexc_mode); | 556 | (MSR_FP | new->thread.fpexc_mode); |
557 | } | 557 | } |
558 | #ifdef CONFIG_ALTIVEC | ||
558 | if (msr & MSR_VEC) { | 559 | if (msr & MSR_VEC) { |
559 | do_load_up_transact_altivec(&new->thread); | 560 | do_load_up_transact_altivec(&new->thread); |
560 | new->thread.regs->msr |= MSR_VEC; | 561 | new->thread.regs->msr |= MSR_VEC; |
561 | } | 562 | } |
563 | #endif | ||
562 | /* We may as well turn on VSX too since all the state is restored now */ | 564 | /* We may as well turn on VSX too since all the state is restored now */ |
563 | if (msr & MSR_VSX) | 565 | if (msr & MSR_VSX) |
564 | new->thread.regs->msr |= MSR_VSX; | 566 | new->thread.regs->msr |= MSR_VSX; |
@@ -829,6 +831,8 @@ void show_regs(struct pt_regs * regs) | |||
829 | { | 831 | { |
830 | int i, trap; | 832 | int i, trap; |
831 | 833 | ||
834 | show_regs_print_info(KERN_DEFAULT); | ||
835 | |||
832 | printk("NIP: "REG" LR: "REG" CTR: "REG"\n", | 836 | printk("NIP: "REG" LR: "REG" CTR: "REG"\n", |
833 | regs->nip, regs->link, regs->ctr); | 837 | regs->nip, regs->link, regs->ctr); |
834 | printk("REGS: %p TRAP: %04lx %s (%s)\n", | 838 | printk("REGS: %p TRAP: %04lx %s (%s)\n", |
@@ -848,12 +852,6 @@ void show_regs(struct pt_regs * regs) | |||
848 | #else | 852 | #else |
849 | printk("DAR: "REG", DSISR: %08lx\n", regs->dar, regs->dsisr); | 853 | printk("DAR: "REG", DSISR: %08lx\n", regs->dar, regs->dsisr); |
850 | #endif | 854 | #endif |
851 | printk("TASK = %p[%d] '%s' THREAD: %p", | ||
852 | current, task_pid_nr(current), current->comm, task_thread_info(current)); | ||
853 | |||
854 | #ifdef CONFIG_SMP | ||
855 | printk(" CPU: %d", raw_smp_processor_id()); | ||
856 | #endif /* CONFIG_SMP */ | ||
857 | 855 | ||
858 | for (i = 0; i < 32; i++) { | 856 | for (i = 0; i < 32; i++) { |
859 | if ((i % REGS_PER_LINE) == 0) | 857 | if ((i % REGS_PER_LINE) == 0) |
@@ -910,10 +908,6 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) | |||
910 | flush_altivec_to_thread(src); | 908 | flush_altivec_to_thread(src); |
911 | flush_vsx_to_thread(src); | 909 | flush_vsx_to_thread(src); |
912 | flush_spe_to_thread(src); | 910 | flush_spe_to_thread(src); |
913 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
914 | flush_ptrace_hw_breakpoint(src); | ||
915 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
916 | |||
917 | *dst = *src; | 911 | *dst = *src; |
918 | return 0; | 912 | return 0; |
919 | } | 913 | } |
@@ -984,6 +978,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
984 | p->thread.ksp_limit = (unsigned long)task_stack_page(p) + | 978 | p->thread.ksp_limit = (unsigned long)task_stack_page(p) + |
985 | _ALIGN_UP(sizeof(struct thread_info), 16); | 979 | _ALIGN_UP(sizeof(struct thread_info), 16); |
986 | 980 | ||
981 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
982 | p->thread.ptrace_bps[0] = NULL; | ||
983 | #endif | ||
984 | |||
987 | #ifdef CONFIG_PPC_STD_MMU_64 | 985 | #ifdef CONFIG_PPC_STD_MMU_64 |
988 | if (mmu_has_feature(MMU_FTR_SLB)) { | 986 | if (mmu_has_feature(MMU_FTR_SLB)) { |
989 | unsigned long sp_vsid; | 987 | unsigned long sp_vsid; |
@@ -1360,12 +1358,6 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) | |||
1360 | } while (count++ < kstack_depth_to_print); | 1358 | } while (count++ < kstack_depth_to_print); |
1361 | } | 1359 | } |
1362 | 1360 | ||
1363 | void dump_stack(void) | ||
1364 | { | ||
1365 | show_stack(current, NULL); | ||
1366 | } | ||
1367 | EXPORT_SYMBOL(dump_stack); | ||
1368 | |||
1369 | #ifdef CONFIG_PPC64 | 1361 | #ifdef CONFIG_PPC64 |
1370 | /* Called with hard IRQs off */ | 1362 | /* Called with hard IRQs off */ |
1371 | void __ppc64_runlatch_on(void) | 1363 | void __ppc64_runlatch_on(void) |
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 13f8d168b3f1..5eccda9fd33f 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -627,16 +627,11 @@ static void __init early_cmdline_parse(void) | |||
627 | 627 | ||
628 | #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) | 628 | #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) |
629 | /* | 629 | /* |
630 | * There are two methods for telling firmware what our capabilities are. | 630 | * The architecture vector has an array of PVR mask/value pairs, |
631 | * Newer machines have an "ibm,client-architecture-support" method on the | 631 | * followed by # option vectors - 1, followed by the option vectors. |
632 | * root node. For older machines, we have to call the "process-elf-header" | 632 | * |
633 | * method in the /packages/elf-loader node, passing it a fake 32-bit | 633 | * See prom.h for the definition of the bits specified in the |
634 | * ELF header containing a couple of PT_NOTE sections that contain | 634 | * architecture vector. |
635 | * structures that contain various information. | ||
636 | */ | ||
637 | |||
638 | /* | ||
639 | * New method - extensible architecture description vector. | ||
640 | * | 635 | * |
641 | * Because the description vector contains a mix of byte and word | 636 | * Because the description vector contains a mix of byte and word |
642 | * values, we declare it as an unsigned char array, and use this | 637 | * values, we declare it as an unsigned char array, and use this |
@@ -645,65 +640,7 @@ static void __init early_cmdline_parse(void) | |||
645 | #define W(x) ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \ | 640 | #define W(x) ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \ |
646 | ((x) >> 8) & 0xff, (x) & 0xff | 641 | ((x) >> 8) & 0xff, (x) & 0xff |
647 | 642 | ||
648 | /* Option vector bits - generic bits in byte 1 */ | 643 | unsigned char ibm_architecture_vec[] = { |
649 | #define OV_IGNORE 0x80 /* ignore this vector */ | ||
650 | #define OV_CESSATION_POLICY 0x40 /* halt if unsupported option present*/ | ||
651 | |||
652 | /* Option vector 1: processor architectures supported */ | ||
653 | #define OV1_PPC_2_00 0x80 /* set if we support PowerPC 2.00 */ | ||
654 | #define OV1_PPC_2_01 0x40 /* set if we support PowerPC 2.01 */ | ||
655 | #define OV1_PPC_2_02 0x20 /* set if we support PowerPC 2.02 */ | ||
656 | #define OV1_PPC_2_03 0x10 /* set if we support PowerPC 2.03 */ | ||
657 | #define OV1_PPC_2_04 0x08 /* set if we support PowerPC 2.04 */ | ||
658 | #define OV1_PPC_2_05 0x04 /* set if we support PowerPC 2.05 */ | ||
659 | #define OV1_PPC_2_06 0x02 /* set if we support PowerPC 2.06 */ | ||
660 | #define OV1_PPC_2_07 0x01 /* set if we support PowerPC 2.07 */ | ||
661 | |||
662 | /* Option vector 2: Open Firmware options supported */ | ||
663 | #define OV2_REAL_MODE 0x20 /* set if we want OF in real mode */ | ||
664 | |||
665 | /* Option vector 3: processor options supported */ | ||
666 | #define OV3_FP 0x80 /* floating point */ | ||
667 | #define OV3_VMX 0x40 /* VMX/Altivec */ | ||
668 | #define OV3_DFP 0x20 /* decimal FP */ | ||
669 | |||
670 | /* Option vector 4: IBM PAPR implementation */ | ||
671 | #define OV4_MIN_ENT_CAP 0x01 /* minimum VP entitled capacity */ | ||
672 | |||
673 | /* Option vector 5: PAPR/OF options supported */ | ||
674 | #define OV5_LPAR 0x80 /* logical partitioning supported */ | ||
675 | #define OV5_SPLPAR 0x40 /* shared-processor LPAR supported */ | ||
676 | /* ibm,dynamic-reconfiguration-memory property supported */ | ||
677 | #define OV5_DRCONF_MEMORY 0x20 | ||
678 | #define OV5_LARGE_PAGES 0x10 /* large pages supported */ | ||
679 | #define OV5_DONATE_DEDICATE_CPU 0x02 /* donate dedicated CPU support */ | ||
680 | /* PCIe/MSI support. Without MSI full PCIe is not supported */ | ||
681 | #ifdef CONFIG_PCI_MSI | ||
682 | #define OV5_MSI 0x01 /* PCIe/MSI support */ | ||
683 | #else | ||
684 | #define OV5_MSI 0x00 | ||
685 | #endif /* CONFIG_PCI_MSI */ | ||
686 | #ifdef CONFIG_PPC_SMLPAR | ||
687 | #define OV5_CMO 0x80 /* Cooperative Memory Overcommitment */ | ||
688 | #define OV5_XCMO 0x40 /* Page Coalescing */ | ||
689 | #else | ||
690 | #define OV5_CMO 0x00 | ||
691 | #define OV5_XCMO 0x00 | ||
692 | #endif | ||
693 | #define OV5_TYPE1_AFFINITY 0x80 /* Type 1 NUMA affinity */ | ||
694 | #define OV5_PFO_HW_RNG 0x80 /* PFO Random Number Generator */ | ||
695 | #define OV5_PFO_HW_842 0x40 /* PFO Compression Accelerator */ | ||
696 | #define OV5_PFO_HW_ENCR 0x20 /* PFO Encryption Accelerator */ | ||
697 | #define OV5_SUB_PROCESSORS 0x01 /* 1,2,or 4 Sub-Processors supported */ | ||
698 | |||
699 | /* Option Vector 6: IBM PAPR hints */ | ||
700 | #define OV6_LINUX 0x02 /* Linux is our OS */ | ||
701 | |||
702 | /* | ||
703 | * The architecture vector has an array of PVR mask/value pairs, | ||
704 | * followed by # option vectors - 1, followed by the option vectors. | ||
705 | */ | ||
706 | static unsigned char ibm_architecture_vec[] = { | ||
707 | W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */ | 644 | W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */ |
708 | W(0xffff0000), W(0x003e0000), /* POWER6 */ | 645 | W(0xffff0000), W(0x003e0000), /* POWER6 */ |
709 | W(0xffff0000), W(0x003f0000), /* POWER7 */ | 646 | W(0xffff0000), W(0x003f0000), /* POWER7 */ |
@@ -747,11 +684,21 @@ static unsigned char ibm_architecture_vec[] = { | |||
747 | /* option vector 5: PAPR/OF options */ | 684 | /* option vector 5: PAPR/OF options */ |
748 | 19 - 2, /* length */ | 685 | 19 - 2, /* length */ |
749 | 0, /* don't ignore, don't halt */ | 686 | 0, /* don't ignore, don't halt */ |
750 | OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY | | 687 | OV5_FEAT(OV5_LPAR) | OV5_FEAT(OV5_SPLPAR) | OV5_FEAT(OV5_LARGE_PAGES) | |
751 | OV5_DONATE_DEDICATE_CPU | OV5_MSI, | 688 | OV5_FEAT(OV5_DRCONF_MEMORY) | OV5_FEAT(OV5_DONATE_DEDICATE_CPU) | |
689 | #ifdef CONFIG_PCI_MSI | ||
690 | /* PCIe/MSI support. Without MSI full PCIe is not supported */ | ||
691 | OV5_FEAT(OV5_MSI), | ||
692 | #else | ||
752 | 0, | 693 | 0, |
753 | OV5_CMO | OV5_XCMO, | 694 | #endif |
754 | OV5_TYPE1_AFFINITY, | 695 | 0, |
696 | #ifdef CONFIG_PPC_SMLPAR | ||
697 | OV5_FEAT(OV5_CMO) | OV5_FEAT(OV5_XCMO), | ||
698 | #else | ||
699 | 0, | ||
700 | #endif | ||
701 | OV5_FEAT(OV5_TYPE1_AFFINITY) | OV5_FEAT(OV5_PRRN), | ||
755 | 0, | 702 | 0, |
756 | 0, | 703 | 0, |
757 | 0, | 704 | 0, |
@@ -765,8 +712,9 @@ static unsigned char ibm_architecture_vec[] = { | |||
765 | 0, | 712 | 0, |
766 | 0, | 713 | 0, |
767 | 0, | 714 | 0, |
768 | OV5_PFO_HW_RNG | OV5_PFO_HW_ENCR | OV5_PFO_HW_842, | 715 | OV5_FEAT(OV5_PFO_HW_RNG) | OV5_FEAT(OV5_PFO_HW_ENCR) | |
769 | OV5_SUB_PROCESSORS, | 716 | OV5_FEAT(OV5_PFO_HW_842), |
717 | OV5_FEAT(OV5_SUB_PROCESSORS), | ||
770 | /* option vector 6: IBM PAPR hints */ | 718 | /* option vector 6: IBM PAPR hints */ |
771 | 4 - 2, /* length */ | 719 | 4 - 2, /* length */ |
772 | 0, | 720 | 0, |
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index f9b30c68ba47..3b14d320e69f 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -180,9 +180,10 @@ static int set_user_msr(struct task_struct *task, unsigned long msr) | |||
180 | } | 180 | } |
181 | 181 | ||
182 | #ifdef CONFIG_PPC64 | 182 | #ifdef CONFIG_PPC64 |
183 | static unsigned long get_user_dscr(struct task_struct *task) | 183 | static int get_user_dscr(struct task_struct *task, unsigned long *data) |
184 | { | 184 | { |
185 | return task->thread.dscr; | 185 | *data = task->thread.dscr; |
186 | return 0; | ||
186 | } | 187 | } |
187 | 188 | ||
188 | static int set_user_dscr(struct task_struct *task, unsigned long dscr) | 189 | static int set_user_dscr(struct task_struct *task, unsigned long dscr) |
@@ -192,7 +193,7 @@ static int set_user_dscr(struct task_struct *task, unsigned long dscr) | |||
192 | return 0; | 193 | return 0; |
193 | } | 194 | } |
194 | #else | 195 | #else |
195 | static unsigned long get_user_dscr(struct task_struct *task) | 196 | static int get_user_dscr(struct task_struct *task, unsigned long *data) |
196 | { | 197 | { |
197 | return -EIO; | 198 | return -EIO; |
198 | } | 199 | } |
@@ -216,19 +217,23 @@ static int set_user_trap(struct task_struct *task, unsigned long trap) | |||
216 | /* | 217 | /* |
217 | * Get contents of register REGNO in task TASK. | 218 | * Get contents of register REGNO in task TASK. |
218 | */ | 219 | */ |
219 | unsigned long ptrace_get_reg(struct task_struct *task, int regno) | 220 | int ptrace_get_reg(struct task_struct *task, int regno, unsigned long *data) |
220 | { | 221 | { |
221 | if (task->thread.regs == NULL) | 222 | if ((task->thread.regs == NULL) || !data) |
222 | return -EIO; | 223 | return -EIO; |
223 | 224 | ||
224 | if (regno == PT_MSR) | 225 | if (regno == PT_MSR) { |
225 | return get_user_msr(task); | 226 | *data = get_user_msr(task); |
227 | return 0; | ||
228 | } | ||
226 | 229 | ||
227 | if (regno == PT_DSCR) | 230 | if (regno == PT_DSCR) |
228 | return get_user_dscr(task); | 231 | return get_user_dscr(task, data); |
229 | 232 | ||
230 | if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) | 233 | if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) { |
231 | return ((unsigned long *)task->thread.regs)[regno]; | 234 | *data = ((unsigned long *)task->thread.regs)[regno]; |
235 | return 0; | ||
236 | } | ||
232 | 237 | ||
233 | return -EIO; | 238 | return -EIO; |
234 | } | 239 | } |
@@ -1560,7 +1565,9 @@ long arch_ptrace(struct task_struct *child, long request, | |||
1560 | 1565 | ||
1561 | CHECK_FULL_REGS(child->thread.regs); | 1566 | CHECK_FULL_REGS(child->thread.regs); |
1562 | if (index < PT_FPR0) { | 1567 | if (index < PT_FPR0) { |
1563 | tmp = ptrace_get_reg(child, (int) index); | 1568 | ret = ptrace_get_reg(child, (int) index, &tmp); |
1569 | if (ret) | ||
1570 | break; | ||
1564 | } else { | 1571 | } else { |
1565 | unsigned int fpidx = index - PT_FPR0; | 1572 | unsigned int fpidx = index - PT_FPR0; |
1566 | 1573 | ||
@@ -1637,6 +1644,8 @@ long arch_ptrace(struct task_struct *child, long request, | |||
1637 | dbginfo.sizeof_condition = 0; | 1644 | dbginfo.sizeof_condition = 0; |
1638 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | 1645 | #ifdef CONFIG_HAVE_HW_BREAKPOINT |
1639 | dbginfo.features = PPC_DEBUG_FEATURE_DATA_BP_RANGE; | 1646 | dbginfo.features = PPC_DEBUG_FEATURE_DATA_BP_RANGE; |
1647 | if (cpu_has_feature(CPU_FTR_DAWR)) | ||
1648 | dbginfo.features |= PPC_DEBUG_FEATURE_DATA_BP_DAWR; | ||
1640 | #else | 1649 | #else |
1641 | dbginfo.features = 0; | 1650 | dbginfo.features = 0; |
1642 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | 1651 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ |
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c index c0244e766834..f51599e941c7 100644 --- a/arch/powerpc/kernel/ptrace32.c +++ b/arch/powerpc/kernel/ptrace32.c | |||
@@ -95,7 +95,9 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, | |||
95 | 95 | ||
96 | CHECK_FULL_REGS(child->thread.regs); | 96 | CHECK_FULL_REGS(child->thread.regs); |
97 | if (index < PT_FPR0) { | 97 | if (index < PT_FPR0) { |
98 | tmp = ptrace_get_reg(child, index); | 98 | ret = ptrace_get_reg(child, index, &tmp); |
99 | if (ret) | ||
100 | break; | ||
99 | } else { | 101 | } else { |
100 | flush_fp_to_thread(child); | 102 | flush_fp_to_thread(child); |
101 | /* | 103 | /* |
@@ -148,7 +150,11 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, | |||
148 | tmp = ((u64 *)child->thread.fpr) | 150 | tmp = ((u64 *)child->thread.fpr) |
149 | [FPRINDEX_3264(numReg)]; | 151 | [FPRINDEX_3264(numReg)]; |
150 | } else { /* register within PT_REGS struct */ | 152 | } else { /* register within PT_REGS struct */ |
151 | tmp = ptrace_get_reg(child, numReg); | 153 | unsigned long tmp2; |
154 | ret = ptrace_get_reg(child, numReg, &tmp2); | ||
155 | if (ret) | ||
156 | break; | ||
157 | tmp = tmp2; | ||
152 | } | 158 | } |
153 | reg32bits = ((u32*)&tmp)[part]; | 159 | reg32bits = ((u32*)&tmp)[part]; |
154 | ret = put_user(reg32bits, (u32 __user *)data); | 160 | ret = put_user(reg32bits, (u32 __user *)data); |
@@ -232,7 +238,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, | |||
232 | break; | 238 | break; |
233 | CHECK_FULL_REGS(child->thread.regs); | 239 | CHECK_FULL_REGS(child->thread.regs); |
234 | if (numReg < PT_FPR0) { | 240 | if (numReg < PT_FPR0) { |
235 | unsigned long freg = ptrace_get_reg(child, numReg); | 241 | unsigned long freg; |
242 | ret = ptrace_get_reg(child, numReg, &freg); | ||
243 | if (ret) | ||
244 | break; | ||
236 | if (index % 2) | 245 | if (index % 2) |
237 | freg = (freg & ~0xfffffffful) | (data & 0xfffffffful); | 246 | freg = (freg & ~0xfffffffful) | (data & 0xfffffffful); |
238 | else | 247 | else |
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index c642f0132988..5b3022470126 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c | |||
@@ -57,13 +57,31 @@ | |||
57 | #define VALIDATE_READY -1001 /* Firmware image ready for validation */ | 57 | #define VALIDATE_READY -1001 /* Firmware image ready for validation */ |
58 | #define VALIDATE_PARAM_ERR -3 /* RTAS Parameter Error */ | 58 | #define VALIDATE_PARAM_ERR -3 /* RTAS Parameter Error */ |
59 | #define VALIDATE_HW_ERR -1 /* RTAS Hardware Error */ | 59 | #define VALIDATE_HW_ERR -1 /* RTAS Hardware Error */ |
60 | #define VALIDATE_TMP_UPDATE 0 /* Validate Return Status */ | 60 | |
61 | #define VALIDATE_FLASH_AUTH 1 /* Validate Return Status */ | 61 | /* ibm,validate-flash-image update result tokens */ |
62 | #define VALIDATE_INVALID_IMG 2 /* Validate Return Status */ | 62 | #define VALIDATE_TMP_UPDATE 0 /* T side will be updated */ |
63 | #define VALIDATE_CUR_UNKNOWN 3 /* Validate Return Status */ | 63 | #define VALIDATE_FLASH_AUTH 1 /* Partition does not have authority */ |
64 | #define VALIDATE_TMP_COMMIT_DL 4 /* Validate Return Status */ | 64 | #define VALIDATE_INVALID_IMG 2 /* Candidate image is not valid */ |
65 | #define VALIDATE_TMP_COMMIT 5 /* Validate Return Status */ | 65 | #define VALIDATE_CUR_UNKNOWN 3 /* Current fixpack level is unknown */ |
66 | #define VALIDATE_TMP_UPDATE_DL 6 /* Validate Return Status */ | 66 | /* |
67 | * Current T side will be committed to P side before being replace with new | ||
68 | * image, and the new image is downlevel from current image | ||
69 | */ | ||
70 | #define VALIDATE_TMP_COMMIT_DL 4 | ||
71 | /* | ||
72 | * Current T side will be committed to P side before being replaced with new | ||
73 | * image | ||
74 | */ | ||
75 | #define VALIDATE_TMP_COMMIT 5 | ||
76 | /* | ||
77 | * T side will be updated with a downlevel image | ||
78 | */ | ||
79 | #define VALIDATE_TMP_UPDATE_DL 6 | ||
80 | /* | ||
81 | * The candidate image's release date is later than the system's firmware | ||
82 | * service entitlement date - service warranty period has expired | ||
83 | */ | ||
84 | #define VALIDATE_OUT_OF_WRNTY 7 | ||
67 | 85 | ||
68 | /* ibm,manage-flash-image operation tokens */ | 86 | /* ibm,manage-flash-image operation tokens */ |
69 | #define RTAS_REJECT_TMP_IMG 0 | 87 | #define RTAS_REJECT_TMP_IMG 0 |
@@ -102,9 +120,10 @@ static struct kmem_cache *flash_block_cache = NULL; | |||
102 | 120 | ||
103 | #define FLASH_BLOCK_LIST_VERSION (1UL) | 121 | #define FLASH_BLOCK_LIST_VERSION (1UL) |
104 | 122 | ||
105 | /* Local copy of the flash block list. | 123 | /* |
106 | * We only allow one open of the flash proc file and create this | 124 | * Local copy of the flash block list. |
107 | * list as we go. The rtas_firmware_flash_list varable will be | 125 | * |
126 | * The rtas_firmware_flash_list varable will be | ||
108 | * set once the data is fully read. | 127 | * set once the data is fully read. |
109 | * | 128 | * |
110 | * For convenience as we build the list we use virtual addrs, | 129 | * For convenience as we build the list we use virtual addrs, |
@@ -125,23 +144,23 @@ struct rtas_update_flash_t | |||
125 | struct rtas_manage_flash_t | 144 | struct rtas_manage_flash_t |
126 | { | 145 | { |
127 | int status; /* Returned status */ | 146 | int status; /* Returned status */ |
128 | unsigned int op; /* Reject or commit image */ | ||
129 | }; | 147 | }; |
130 | 148 | ||
131 | /* Status int must be first member of struct */ | 149 | /* Status int must be first member of struct */ |
132 | struct rtas_validate_flash_t | 150 | struct rtas_validate_flash_t |
133 | { | 151 | { |
134 | int status; /* Returned status */ | 152 | int status; /* Returned status */ |
135 | char buf[VALIDATE_BUF_SIZE]; /* Candidate image buffer */ | 153 | char *buf; /* Candidate image buffer */ |
136 | unsigned int buf_size; /* Size of image buf */ | 154 | unsigned int buf_size; /* Size of image buf */ |
137 | unsigned int update_results; /* Update results token */ | 155 | unsigned int update_results; /* Update results token */ |
138 | }; | 156 | }; |
139 | 157 | ||
140 | static DEFINE_SPINLOCK(flash_file_open_lock); | 158 | static struct rtas_update_flash_t rtas_update_flash_data; |
141 | static struct proc_dir_entry *firmware_flash_pde; | 159 | static struct rtas_manage_flash_t rtas_manage_flash_data; |
142 | static struct proc_dir_entry *firmware_update_pde; | 160 | static struct rtas_validate_flash_t rtas_validate_flash_data; |
143 | static struct proc_dir_entry *validate_pde; | 161 | static DEFINE_MUTEX(rtas_update_flash_mutex); |
144 | static struct proc_dir_entry *manage_pde; | 162 | static DEFINE_MUTEX(rtas_manage_flash_mutex); |
163 | static DEFINE_MUTEX(rtas_validate_flash_mutex); | ||
145 | 164 | ||
146 | /* Do simple sanity checks on the flash image. */ | 165 | /* Do simple sanity checks on the flash image. */ |
147 | static int flash_list_valid(struct flash_block_list *flist) | 166 | static int flash_list_valid(struct flash_block_list *flist) |
@@ -191,10 +210,10 @@ static void free_flash_list(struct flash_block_list *f) | |||
191 | 210 | ||
192 | static int rtas_flash_release(struct inode *inode, struct file *file) | 211 | static int rtas_flash_release(struct inode *inode, struct file *file) |
193 | { | 212 | { |
194 | struct proc_dir_entry *dp = PDE(file_inode(file)); | 213 | struct rtas_update_flash_t *const uf = &rtas_update_flash_data; |
195 | struct rtas_update_flash_t *uf; | 214 | |
196 | 215 | mutex_lock(&rtas_update_flash_mutex); | |
197 | uf = (struct rtas_update_flash_t *) dp->data; | 216 | |
198 | if (uf->flist) { | 217 | if (uf->flist) { |
199 | /* File was opened in write mode for a new flash attempt */ | 218 | /* File was opened in write mode for a new flash attempt */ |
200 | /* Clear saved list */ | 219 | /* Clear saved list */ |
@@ -214,13 +233,14 @@ static int rtas_flash_release(struct inode *inode, struct file *file) | |||
214 | uf->flist = NULL; | 233 | uf->flist = NULL; |
215 | } | 234 | } |
216 | 235 | ||
217 | atomic_dec(&dp->count); | 236 | mutex_unlock(&rtas_update_flash_mutex); |
218 | return 0; | 237 | return 0; |
219 | } | 238 | } |
220 | 239 | ||
221 | static void get_flash_status_msg(int status, char *buf) | 240 | static size_t get_flash_status_msg(int status, char *buf) |
222 | { | 241 | { |
223 | char *msg; | 242 | const char *msg; |
243 | size_t len; | ||
224 | 244 | ||
225 | switch (status) { | 245 | switch (status) { |
226 | case FLASH_AUTH: | 246 | case FLASH_AUTH: |
@@ -242,36 +262,47 @@ static void get_flash_status_msg(int status, char *buf) | |||
242 | msg = "ready: firmware image ready for flash on reboot\n"; | 262 | msg = "ready: firmware image ready for flash on reboot\n"; |
243 | break; | 263 | break; |
244 | default: | 264 | default: |
245 | sprintf(buf, "error: unexpected status value %d\n", status); | 265 | return sprintf(buf, "error: unexpected status value %d\n", |
246 | return; | 266 | status); |
247 | } | 267 | } |
248 | 268 | ||
249 | strcpy(buf, msg); | 269 | len = strlen(msg); |
270 | memcpy(buf, msg, len + 1); | ||
271 | return len; | ||
250 | } | 272 | } |
251 | 273 | ||
252 | /* Reading the proc file will show status (not the firmware contents) */ | 274 | /* Reading the proc file will show status (not the firmware contents) */ |
253 | static ssize_t rtas_flash_read(struct file *file, char __user *buf, | 275 | static ssize_t rtas_flash_read_msg(struct file *file, char __user *buf, |
254 | size_t count, loff_t *ppos) | 276 | size_t count, loff_t *ppos) |
255 | { | 277 | { |
256 | struct proc_dir_entry *dp = PDE(file_inode(file)); | 278 | struct rtas_update_flash_t *const uf = &rtas_update_flash_data; |
257 | struct rtas_update_flash_t *uf; | ||
258 | char msg[RTAS_MSG_MAXLEN]; | 279 | char msg[RTAS_MSG_MAXLEN]; |
280 | size_t len; | ||
281 | int status; | ||
259 | 282 | ||
260 | uf = dp->data; | 283 | mutex_lock(&rtas_update_flash_mutex); |
261 | 284 | status = uf->status; | |
262 | if (!strcmp(dp->name, FIRMWARE_FLASH_NAME)) { | 285 | mutex_unlock(&rtas_update_flash_mutex); |
263 | get_flash_status_msg(uf->status, msg); | ||
264 | } else { /* FIRMWARE_UPDATE_NAME */ | ||
265 | sprintf(msg, "%d\n", uf->status); | ||
266 | } | ||
267 | 286 | ||
268 | return simple_read_from_buffer(buf, count, ppos, msg, strlen(msg)); | 287 | /* Read as text message */ |
288 | len = get_flash_status_msg(status, msg); | ||
289 | return simple_read_from_buffer(buf, count, ppos, msg, len); | ||
269 | } | 290 | } |
270 | 291 | ||
271 | /* constructor for flash_block_cache */ | 292 | static ssize_t rtas_flash_read_num(struct file *file, char __user *buf, |
272 | void rtas_block_ctor(void *ptr) | 293 | size_t count, loff_t *ppos) |
273 | { | 294 | { |
274 | memset(ptr, 0, RTAS_BLK_SIZE); | 295 | struct rtas_update_flash_t *const uf = &rtas_update_flash_data; |
296 | char msg[RTAS_MSG_MAXLEN]; | ||
297 | int status; | ||
298 | |||
299 | mutex_lock(&rtas_update_flash_mutex); | ||
300 | status = uf->status; | ||
301 | mutex_unlock(&rtas_update_flash_mutex); | ||
302 | |||
303 | /* Read as number */ | ||
304 | sprintf(msg, "%d\n", status); | ||
305 | return simple_read_from_buffer(buf, count, ppos, msg, strlen(msg)); | ||
275 | } | 306 | } |
276 | 307 | ||
277 | /* We could be much more efficient here. But to keep this function | 308 | /* We could be much more efficient here. But to keep this function |
@@ -282,25 +313,24 @@ void rtas_block_ctor(void *ptr) | |||
282 | static ssize_t rtas_flash_write(struct file *file, const char __user *buffer, | 313 | static ssize_t rtas_flash_write(struct file *file, const char __user *buffer, |
283 | size_t count, loff_t *off) | 314 | size_t count, loff_t *off) |
284 | { | 315 | { |
285 | struct proc_dir_entry *dp = PDE(file_inode(file)); | 316 | struct rtas_update_flash_t *const uf = &rtas_update_flash_data; |
286 | struct rtas_update_flash_t *uf; | ||
287 | char *p; | 317 | char *p; |
288 | int next_free; | 318 | int next_free, rc; |
289 | struct flash_block_list *fl; | 319 | struct flash_block_list *fl; |
290 | 320 | ||
291 | uf = (struct rtas_update_flash_t *) dp->data; | 321 | mutex_lock(&rtas_update_flash_mutex); |
292 | 322 | ||
293 | if (uf->status == FLASH_AUTH || count == 0) | 323 | if (uf->status == FLASH_AUTH || count == 0) |
294 | return count; /* discard data */ | 324 | goto out; /* discard data */ |
295 | 325 | ||
296 | /* In the case that the image is not ready for flashing, the memory | 326 | /* In the case that the image is not ready for flashing, the memory |
297 | * allocated for the block list will be freed upon the release of the | 327 | * allocated for the block list will be freed upon the release of the |
298 | * proc file | 328 | * proc file |
299 | */ | 329 | */ |
300 | if (uf->flist == NULL) { | 330 | if (uf->flist == NULL) { |
301 | uf->flist = kmem_cache_alloc(flash_block_cache, GFP_KERNEL); | 331 | uf->flist = kmem_cache_zalloc(flash_block_cache, GFP_KERNEL); |
302 | if (!uf->flist) | 332 | if (!uf->flist) |
303 | return -ENOMEM; | 333 | goto nomem; |
304 | } | 334 | } |
305 | 335 | ||
306 | fl = uf->flist; | 336 | fl = uf->flist; |
@@ -309,63 +339,48 @@ static ssize_t rtas_flash_write(struct file *file, const char __user *buffer, | |||
309 | next_free = fl->num_blocks; | 339 | next_free = fl->num_blocks; |
310 | if (next_free == FLASH_BLOCKS_PER_NODE) { | 340 | if (next_free == FLASH_BLOCKS_PER_NODE) { |
311 | /* Need to allocate another block_list */ | 341 | /* Need to allocate another block_list */ |
312 | fl->next = kmem_cache_alloc(flash_block_cache, GFP_KERNEL); | 342 | fl->next = kmem_cache_zalloc(flash_block_cache, GFP_KERNEL); |
313 | if (!fl->next) | 343 | if (!fl->next) |
314 | return -ENOMEM; | 344 | goto nomem; |
315 | fl = fl->next; | 345 | fl = fl->next; |
316 | next_free = 0; | 346 | next_free = 0; |
317 | } | 347 | } |
318 | 348 | ||
319 | if (count > RTAS_BLK_SIZE) | 349 | if (count > RTAS_BLK_SIZE) |
320 | count = RTAS_BLK_SIZE; | 350 | count = RTAS_BLK_SIZE; |
321 | p = kmem_cache_alloc(flash_block_cache, GFP_KERNEL); | 351 | p = kmem_cache_zalloc(flash_block_cache, GFP_KERNEL); |
322 | if (!p) | 352 | if (!p) |
323 | return -ENOMEM; | 353 | goto nomem; |
324 | 354 | ||
325 | if(copy_from_user(p, buffer, count)) { | 355 | if(copy_from_user(p, buffer, count)) { |
326 | kmem_cache_free(flash_block_cache, p); | 356 | kmem_cache_free(flash_block_cache, p); |
327 | return -EFAULT; | 357 | rc = -EFAULT; |
358 | goto error; | ||
328 | } | 359 | } |
329 | fl->blocks[next_free].data = p; | 360 | fl->blocks[next_free].data = p; |
330 | fl->blocks[next_free].length = count; | 361 | fl->blocks[next_free].length = count; |
331 | fl->num_blocks++; | 362 | fl->num_blocks++; |
332 | 363 | out: | |
364 | mutex_unlock(&rtas_update_flash_mutex); | ||
333 | return count; | 365 | return count; |
334 | } | ||
335 | 366 | ||
336 | static int rtas_excl_open(struct inode *inode, struct file *file) | 367 | nomem: |
337 | { | 368 | rc = -ENOMEM; |
338 | struct proc_dir_entry *dp = PDE(inode); | 369 | error: |
339 | 370 | mutex_unlock(&rtas_update_flash_mutex); | |
340 | /* Enforce exclusive open with use count of PDE */ | 371 | return rc; |
341 | spin_lock(&flash_file_open_lock); | ||
342 | if (atomic_read(&dp->count) > 2) { | ||
343 | spin_unlock(&flash_file_open_lock); | ||
344 | return -EBUSY; | ||
345 | } | ||
346 | |||
347 | atomic_inc(&dp->count); | ||
348 | spin_unlock(&flash_file_open_lock); | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static int rtas_excl_release(struct inode *inode, struct file *file) | ||
354 | { | ||
355 | struct proc_dir_entry *dp = PDE(inode); | ||
356 | |||
357 | atomic_dec(&dp->count); | ||
358 | |||
359 | return 0; | ||
360 | } | 372 | } |
361 | 373 | ||
362 | static void manage_flash(struct rtas_manage_flash_t *args_buf) | 374 | /* |
375 | * Flash management routines. | ||
376 | */ | ||
377 | static void manage_flash(struct rtas_manage_flash_t *args_buf, unsigned int op) | ||
363 | { | 378 | { |
364 | s32 rc; | 379 | s32 rc; |
365 | 380 | ||
366 | do { | 381 | do { |
367 | rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1, | 382 | rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1, 1, |
368 | 1, NULL, args_buf->op); | 383 | NULL, op); |
369 | } while (rtas_busy_delay(rc)); | 384 | } while (rtas_busy_delay(rc)); |
370 | 385 | ||
371 | args_buf->status = rc; | 386 | args_buf->status = rc; |
@@ -374,55 +389,62 @@ static void manage_flash(struct rtas_manage_flash_t *args_buf) | |||
374 | static ssize_t manage_flash_read(struct file *file, char __user *buf, | 389 | static ssize_t manage_flash_read(struct file *file, char __user *buf, |
375 | size_t count, loff_t *ppos) | 390 | size_t count, loff_t *ppos) |
376 | { | 391 | { |
377 | struct proc_dir_entry *dp = PDE(file_inode(file)); | 392 | struct rtas_manage_flash_t *const args_buf = &rtas_manage_flash_data; |
378 | struct rtas_manage_flash_t *args_buf; | ||
379 | char msg[RTAS_MSG_MAXLEN]; | 393 | char msg[RTAS_MSG_MAXLEN]; |
380 | int msglen; | 394 | int msglen, status; |
381 | 395 | ||
382 | args_buf = dp->data; | 396 | mutex_lock(&rtas_manage_flash_mutex); |
383 | if (args_buf == NULL) | 397 | status = args_buf->status; |
384 | return 0; | 398 | mutex_unlock(&rtas_manage_flash_mutex); |
385 | |||
386 | msglen = sprintf(msg, "%d\n", args_buf->status); | ||
387 | 399 | ||
400 | msglen = sprintf(msg, "%d\n", status); | ||
388 | return simple_read_from_buffer(buf, count, ppos, msg, msglen); | 401 | return simple_read_from_buffer(buf, count, ppos, msg, msglen); |
389 | } | 402 | } |
390 | 403 | ||
391 | static ssize_t manage_flash_write(struct file *file, const char __user *buf, | 404 | static ssize_t manage_flash_write(struct file *file, const char __user *buf, |
392 | size_t count, loff_t *off) | 405 | size_t count, loff_t *off) |
393 | { | 406 | { |
394 | struct proc_dir_entry *dp = PDE(file_inode(file)); | 407 | struct rtas_manage_flash_t *const args_buf = &rtas_manage_flash_data; |
395 | struct rtas_manage_flash_t *args_buf; | 408 | static const char reject_str[] = "0"; |
396 | const char reject_str[] = "0"; | 409 | static const char commit_str[] = "1"; |
397 | const char commit_str[] = "1"; | ||
398 | char stkbuf[10]; | 410 | char stkbuf[10]; |
399 | int op; | 411 | int op, rc; |
412 | |||
413 | mutex_lock(&rtas_manage_flash_mutex); | ||
400 | 414 | ||
401 | args_buf = (struct rtas_manage_flash_t *) dp->data; | ||
402 | if ((args_buf->status == MANAGE_AUTH) || (count == 0)) | 415 | if ((args_buf->status == MANAGE_AUTH) || (count == 0)) |
403 | return count; | 416 | goto out; |
404 | 417 | ||
405 | op = -1; | 418 | op = -1; |
406 | if (buf) { | 419 | if (buf) { |
407 | if (count > 9) count = 9; | 420 | if (count > 9) count = 9; |
408 | if (copy_from_user (stkbuf, buf, count)) { | 421 | rc = -EFAULT; |
409 | return -EFAULT; | 422 | if (copy_from_user (stkbuf, buf, count)) |
410 | } | 423 | goto error; |
411 | if (strncmp(stkbuf, reject_str, strlen(reject_str)) == 0) | 424 | if (strncmp(stkbuf, reject_str, strlen(reject_str)) == 0) |
412 | op = RTAS_REJECT_TMP_IMG; | 425 | op = RTAS_REJECT_TMP_IMG; |
413 | else if (strncmp(stkbuf, commit_str, strlen(commit_str)) == 0) | 426 | else if (strncmp(stkbuf, commit_str, strlen(commit_str)) == 0) |
414 | op = RTAS_COMMIT_TMP_IMG; | 427 | op = RTAS_COMMIT_TMP_IMG; |
415 | } | 428 | } |
416 | 429 | ||
417 | if (op == -1) /* buf is empty, or contains invalid string */ | 430 | if (op == -1) { /* buf is empty, or contains invalid string */ |
418 | return -EINVAL; | 431 | rc = -EINVAL; |
419 | 432 | goto error; | |
420 | args_buf->op = op; | 433 | } |
421 | manage_flash(args_buf); | ||
422 | 434 | ||
435 | manage_flash(args_buf, op); | ||
436 | out: | ||
437 | mutex_unlock(&rtas_manage_flash_mutex); | ||
423 | return count; | 438 | return count; |
439 | |||
440 | error: | ||
441 | mutex_unlock(&rtas_manage_flash_mutex); | ||
442 | return rc; | ||
424 | } | 443 | } |
425 | 444 | ||
445 | /* | ||
446 | * Validation routines. | ||
447 | */ | ||
426 | static void validate_flash(struct rtas_validate_flash_t *args_buf) | 448 | static void validate_flash(struct rtas_validate_flash_t *args_buf) |
427 | { | 449 | { |
428 | int token = rtas_token("ibm,validate-flash-image"); | 450 | int token = rtas_token("ibm,validate-flash-image"); |
@@ -462,14 +484,14 @@ static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, | |||
462 | static ssize_t validate_flash_read(struct file *file, char __user *buf, | 484 | static ssize_t validate_flash_read(struct file *file, char __user *buf, |
463 | size_t count, loff_t *ppos) | 485 | size_t count, loff_t *ppos) |
464 | { | 486 | { |
465 | struct proc_dir_entry *dp = PDE(file_inode(file)); | 487 | struct rtas_validate_flash_t *const args_buf = |
466 | struct rtas_validate_flash_t *args_buf; | 488 | &rtas_validate_flash_data; |
467 | char msg[RTAS_MSG_MAXLEN]; | 489 | char msg[RTAS_MSG_MAXLEN]; |
468 | int msglen; | 490 | int msglen; |
469 | 491 | ||
470 | args_buf = dp->data; | 492 | mutex_lock(&rtas_validate_flash_mutex); |
471 | |||
472 | msglen = get_validate_flash_msg(args_buf, msg); | 493 | msglen = get_validate_flash_msg(args_buf, msg); |
494 | mutex_unlock(&rtas_validate_flash_mutex); | ||
473 | 495 | ||
474 | return simple_read_from_buffer(buf, count, ppos, msg, msglen); | 496 | return simple_read_from_buffer(buf, count, ppos, msg, msglen); |
475 | } | 497 | } |
@@ -477,24 +499,18 @@ static ssize_t validate_flash_read(struct file *file, char __user *buf, | |||
477 | static ssize_t validate_flash_write(struct file *file, const char __user *buf, | 499 | static ssize_t validate_flash_write(struct file *file, const char __user *buf, |
478 | size_t count, loff_t *off) | 500 | size_t count, loff_t *off) |
479 | { | 501 | { |
480 | struct proc_dir_entry *dp = PDE(file_inode(file)); | 502 | struct rtas_validate_flash_t *const args_buf = |
481 | struct rtas_validate_flash_t *args_buf; | 503 | &rtas_validate_flash_data; |
482 | int rc; | 504 | int rc; |
483 | 505 | ||
484 | args_buf = (struct rtas_validate_flash_t *) dp->data; | 506 | mutex_lock(&rtas_validate_flash_mutex); |
485 | |||
486 | if (dp->data == NULL) { | ||
487 | dp->data = kmalloc(sizeof(struct rtas_validate_flash_t), | ||
488 | GFP_KERNEL); | ||
489 | if (dp->data == NULL) | ||
490 | return -ENOMEM; | ||
491 | } | ||
492 | 507 | ||
493 | /* We are only interested in the first 4K of the | 508 | /* We are only interested in the first 4K of the |
494 | * candidate image */ | 509 | * candidate image */ |
495 | if ((*off >= VALIDATE_BUF_SIZE) || | 510 | if ((*off >= VALIDATE_BUF_SIZE) || |
496 | (args_buf->status == VALIDATE_AUTH)) { | 511 | (args_buf->status == VALIDATE_AUTH)) { |
497 | *off += count; | 512 | *off += count; |
513 | mutex_unlock(&rtas_validate_flash_mutex); | ||
498 | return count; | 514 | return count; |
499 | } | 515 | } |
500 | 516 | ||
@@ -517,31 +533,29 @@ static ssize_t validate_flash_write(struct file *file, const char __user *buf, | |||
517 | *off += count; | 533 | *off += count; |
518 | rc = count; | 534 | rc = count; |
519 | done: | 535 | done: |
520 | if (rc < 0) { | 536 | mutex_unlock(&rtas_validate_flash_mutex); |
521 | kfree(dp->data); | ||
522 | dp->data = NULL; | ||
523 | } | ||
524 | return rc; | 537 | return rc; |
525 | } | 538 | } |
526 | 539 | ||
527 | static int validate_flash_release(struct inode *inode, struct file *file) | 540 | static int validate_flash_release(struct inode *inode, struct file *file) |
528 | { | 541 | { |
529 | struct proc_dir_entry *dp = PDE(file_inode(file)); | 542 | struct rtas_validate_flash_t *const args_buf = |
530 | struct rtas_validate_flash_t *args_buf; | 543 | &rtas_validate_flash_data; |
531 | 544 | ||
532 | args_buf = (struct rtas_validate_flash_t *) dp->data; | 545 | mutex_lock(&rtas_validate_flash_mutex); |
533 | 546 | ||
534 | if (args_buf->status == VALIDATE_READY) { | 547 | if (args_buf->status == VALIDATE_READY) { |
535 | args_buf->buf_size = VALIDATE_BUF_SIZE; | 548 | args_buf->buf_size = VALIDATE_BUF_SIZE; |
536 | validate_flash(args_buf); | 549 | validate_flash(args_buf); |
537 | } | 550 | } |
538 | 551 | ||
539 | /* The matching atomic_inc was in rtas_excl_open() */ | 552 | mutex_unlock(&rtas_validate_flash_mutex); |
540 | atomic_dec(&dp->count); | ||
541 | |||
542 | return 0; | 553 | return 0; |
543 | } | 554 | } |
544 | 555 | ||
556 | /* | ||
557 | * On-reboot flash update applicator. | ||
558 | */ | ||
545 | static void rtas_flash_firmware(int reboot_type) | 559 | static void rtas_flash_firmware(int reboot_type) |
546 | { | 560 | { |
547 | unsigned long image_size; | 561 | unsigned long image_size; |
@@ -634,75 +648,57 @@ static void rtas_flash_firmware(int reboot_type) | |||
634 | spin_unlock(&rtas_data_buf_lock); | 648 | spin_unlock(&rtas_data_buf_lock); |
635 | } | 649 | } |
636 | 650 | ||
637 | static void remove_flash_pde(struct proc_dir_entry *dp) | 651 | /* |
638 | { | 652 | * Manifest of proc files to create |
639 | if (dp) { | 653 | */ |
640 | kfree(dp->data); | 654 | struct rtas_flash_file { |
641 | remove_proc_entry(dp->name, dp->parent); | 655 | const char *filename; |
642 | } | 656 | const char *rtas_call_name; |
643 | } | ||
644 | |||
645 | static int initialize_flash_pde_data(const char *rtas_call_name, | ||
646 | size_t buf_size, | ||
647 | struct proc_dir_entry *dp) | ||
648 | { | ||
649 | int *status; | 657 | int *status; |
650 | int token; | 658 | const struct file_operations fops; |
651 | |||
652 | dp->data = kzalloc(buf_size, GFP_KERNEL); | ||
653 | if (dp->data == NULL) | ||
654 | return -ENOMEM; | ||
655 | |||
656 | /* | ||
657 | * This code assumes that the status int is the first member of the | ||
658 | * struct | ||
659 | */ | ||
660 | status = (int *) dp->data; | ||
661 | token = rtas_token(rtas_call_name); | ||
662 | if (token == RTAS_UNKNOWN_SERVICE) | ||
663 | *status = FLASH_AUTH; | ||
664 | else | ||
665 | *status = FLASH_NO_OP; | ||
666 | |||
667 | return 0; | ||
668 | } | ||
669 | |||
670 | static struct proc_dir_entry *create_flash_pde(const char *filename, | ||
671 | const struct file_operations *fops) | ||
672 | { | ||
673 | return proc_create(filename, S_IRUSR | S_IWUSR, NULL, fops); | ||
674 | } | ||
675 | |||
676 | static const struct file_operations rtas_flash_operations = { | ||
677 | .owner = THIS_MODULE, | ||
678 | .read = rtas_flash_read, | ||
679 | .write = rtas_flash_write, | ||
680 | .open = rtas_excl_open, | ||
681 | .release = rtas_flash_release, | ||
682 | .llseek = default_llseek, | ||
683 | }; | ||
684 | |||
685 | static const struct file_operations manage_flash_operations = { | ||
686 | .owner = THIS_MODULE, | ||
687 | .read = manage_flash_read, | ||
688 | .write = manage_flash_write, | ||
689 | .open = rtas_excl_open, | ||
690 | .release = rtas_excl_release, | ||
691 | .llseek = default_llseek, | ||
692 | }; | 659 | }; |
693 | 660 | ||
694 | static const struct file_operations validate_flash_operations = { | 661 | static const struct rtas_flash_file rtas_flash_files[] = { |
695 | .owner = THIS_MODULE, | 662 | { |
696 | .read = validate_flash_read, | 663 | .filename = "powerpc/rtas/" FIRMWARE_FLASH_NAME, |
697 | .write = validate_flash_write, | 664 | .rtas_call_name = "ibm,update-flash-64-and-reboot", |
698 | .open = rtas_excl_open, | 665 | .status = &rtas_update_flash_data.status, |
699 | .release = validate_flash_release, | 666 | .fops.read = rtas_flash_read_msg, |
700 | .llseek = default_llseek, | 667 | .fops.write = rtas_flash_write, |
668 | .fops.release = rtas_flash_release, | ||
669 | .fops.llseek = default_llseek, | ||
670 | }, | ||
671 | { | ||
672 | .filename = "powerpc/rtas/" FIRMWARE_UPDATE_NAME, | ||
673 | .rtas_call_name = "ibm,update-flash-64-and-reboot", | ||
674 | .status = &rtas_update_flash_data.status, | ||
675 | .fops.read = rtas_flash_read_num, | ||
676 | .fops.write = rtas_flash_write, | ||
677 | .fops.release = rtas_flash_release, | ||
678 | .fops.llseek = default_llseek, | ||
679 | }, | ||
680 | { | ||
681 | .filename = "powerpc/rtas/" VALIDATE_FLASH_NAME, | ||
682 | .rtas_call_name = "ibm,validate-flash-image", | ||
683 | .status = &rtas_validate_flash_data.status, | ||
684 | .fops.read = validate_flash_read, | ||
685 | .fops.write = validate_flash_write, | ||
686 | .fops.release = validate_flash_release, | ||
687 | .fops.llseek = default_llseek, | ||
688 | }, | ||
689 | { | ||
690 | .filename = "powerpc/rtas/" MANAGE_FLASH_NAME, | ||
691 | .rtas_call_name = "ibm,manage-flash-image", | ||
692 | .status = &rtas_manage_flash_data.status, | ||
693 | .fops.read = manage_flash_read, | ||
694 | .fops.write = manage_flash_write, | ||
695 | .fops.llseek = default_llseek, | ||
696 | } | ||
701 | }; | 697 | }; |
702 | 698 | ||
703 | static int __init rtas_flash_init(void) | 699 | static int __init rtas_flash_init(void) |
704 | { | 700 | { |
705 | int rc; | 701 | int i; |
706 | 702 | ||
707 | if (rtas_token("ibm,update-flash-64-and-reboot") == | 703 | if (rtas_token("ibm,update-flash-64-and-reboot") == |
708 | RTAS_UNKNOWN_SERVICE) { | 704 | RTAS_UNKNOWN_SERVICE) { |
@@ -710,93 +706,70 @@ static int __init rtas_flash_init(void) | |||
710 | return 1; | 706 | return 1; |
711 | } | 707 | } |
712 | 708 | ||
713 | firmware_flash_pde = create_flash_pde("powerpc/rtas/" | 709 | rtas_validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL); |
714 | FIRMWARE_FLASH_NAME, | 710 | if (!rtas_validate_flash_data.buf) |
715 | &rtas_flash_operations); | 711 | return -ENOMEM; |
716 | if (firmware_flash_pde == NULL) { | ||
717 | rc = -ENOMEM; | ||
718 | goto cleanup; | ||
719 | } | ||
720 | 712 | ||
721 | rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot", | 713 | flash_block_cache = kmem_cache_create("rtas_flash_cache", |
722 | sizeof(struct rtas_update_flash_t), | 714 | RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0, |
723 | firmware_flash_pde); | 715 | NULL); |
724 | if (rc != 0) | 716 | if (!flash_block_cache) { |
725 | goto cleanup; | 717 | printk(KERN_ERR "%s: failed to create block cache\n", |
726 | 718 | __func__); | |
727 | firmware_update_pde = create_flash_pde("powerpc/rtas/" | 719 | goto enomem_buf; |
728 | FIRMWARE_UPDATE_NAME, | ||
729 | &rtas_flash_operations); | ||
730 | if (firmware_update_pde == NULL) { | ||
731 | rc = -ENOMEM; | ||
732 | goto cleanup; | ||
733 | } | 720 | } |
734 | 721 | ||
735 | rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot", | 722 | for (i = 0; i < ARRAY_SIZE(rtas_flash_files); i++) { |
736 | sizeof(struct rtas_update_flash_t), | 723 | const struct rtas_flash_file *f = &rtas_flash_files[i]; |
737 | firmware_update_pde); | 724 | int token; |
738 | if (rc != 0) | ||
739 | goto cleanup; | ||
740 | |||
741 | validate_pde = create_flash_pde("powerpc/rtas/" VALIDATE_FLASH_NAME, | ||
742 | &validate_flash_operations); | ||
743 | if (validate_pde == NULL) { | ||
744 | rc = -ENOMEM; | ||
745 | goto cleanup; | ||
746 | } | ||
747 | 725 | ||
748 | rc = initialize_flash_pde_data("ibm,validate-flash-image", | 726 | if (!proc_create(f->filename, S_IRUSR | S_IWUSR, NULL, &f->fops)) |
749 | sizeof(struct rtas_validate_flash_t), | 727 | goto enomem; |
750 | validate_pde); | ||
751 | if (rc != 0) | ||
752 | goto cleanup; | ||
753 | |||
754 | manage_pde = create_flash_pde("powerpc/rtas/" MANAGE_FLASH_NAME, | ||
755 | &manage_flash_operations); | ||
756 | if (manage_pde == NULL) { | ||
757 | rc = -ENOMEM; | ||
758 | goto cleanup; | ||
759 | } | ||
760 | 728 | ||
761 | rc = initialize_flash_pde_data("ibm,manage-flash-image", | 729 | /* |
762 | sizeof(struct rtas_manage_flash_t), | 730 | * This code assumes that the status int is the first member of the |
763 | manage_pde); | 731 | * struct |
764 | if (rc != 0) | 732 | */ |
765 | goto cleanup; | 733 | token = rtas_token(f->rtas_call_name); |
734 | if (token == RTAS_UNKNOWN_SERVICE) | ||
735 | *f->status = FLASH_AUTH; | ||
736 | else | ||
737 | *f->status = FLASH_NO_OP; | ||
738 | } | ||
766 | 739 | ||
767 | rtas_flash_term_hook = rtas_flash_firmware; | 740 | rtas_flash_term_hook = rtas_flash_firmware; |
768 | |||
769 | flash_block_cache = kmem_cache_create("rtas_flash_cache", | ||
770 | RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0, | ||
771 | rtas_block_ctor); | ||
772 | if (!flash_block_cache) { | ||
773 | printk(KERN_ERR "%s: failed to create block cache\n", | ||
774 | __func__); | ||
775 | rc = -ENOMEM; | ||
776 | goto cleanup; | ||
777 | } | ||
778 | return 0; | 741 | return 0; |
779 | 742 | ||
780 | cleanup: | 743 | enomem: |
781 | remove_flash_pde(firmware_flash_pde); | 744 | while (--i >= 0) { |
782 | remove_flash_pde(firmware_update_pde); | 745 | const struct rtas_flash_file *f = &rtas_flash_files[i]; |
783 | remove_flash_pde(validate_pde); | 746 | remove_proc_entry(f->filename, NULL); |
784 | remove_flash_pde(manage_pde); | 747 | } |
785 | 748 | ||
786 | return rc; | 749 | kmem_cache_destroy(flash_block_cache); |
750 | enomem_buf: | ||
751 | kfree(rtas_validate_flash_data.buf); | ||
752 | return -ENOMEM; | ||
787 | } | 753 | } |
788 | 754 | ||
789 | static void __exit rtas_flash_cleanup(void) | 755 | static void __exit rtas_flash_cleanup(void) |
790 | { | 756 | { |
757 | int i; | ||
758 | |||
791 | rtas_flash_term_hook = NULL; | 759 | rtas_flash_term_hook = NULL; |
792 | 760 | ||
793 | if (flash_block_cache) | 761 | if (rtas_firmware_flash_list) { |
794 | kmem_cache_destroy(flash_block_cache); | 762 | free_flash_list(rtas_firmware_flash_list); |
763 | rtas_firmware_flash_list = NULL; | ||
764 | } | ||
765 | |||
766 | for (i = 0; i < ARRAY_SIZE(rtas_flash_files); i++) { | ||
767 | const struct rtas_flash_file *f = &rtas_flash_files[i]; | ||
768 | remove_proc_entry(f->filename, NULL); | ||
769 | } | ||
795 | 770 | ||
796 | remove_flash_pde(firmware_flash_pde); | 771 | kmem_cache_destroy(flash_block_cache); |
797 | remove_flash_pde(firmware_update_pde); | 772 | kfree(rtas_validate_flash_data.buf); |
798 | remove_flash_pde(validate_pde); | ||
799 | remove_flash_pde(manage_pde); | ||
800 | } | 773 | } |
801 | 774 | ||
802 | module_init(rtas_flash_init); | 775 | module_init(rtas_flash_init); |
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 71cb20d6ec61..6e7b7cdeec65 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c | |||
@@ -201,7 +201,7 @@ static void python_countermeasures(struct device_node *dev) | |||
201 | iounmap(chip_regs); | 201 | iounmap(chip_regs); |
202 | } | 202 | } |
203 | 203 | ||
204 | void __init init_pci_config_tokens (void) | 204 | void __init init_pci_config_tokens(void) |
205 | { | 205 | { |
206 | read_pci_config = rtas_token("read-pci-config"); | 206 | read_pci_config = rtas_token("read-pci-config"); |
207 | write_pci_config = rtas_token("write-pci-config"); | 207 | write_pci_config = rtas_token("write-pci-config"); |
@@ -209,7 +209,7 @@ void __init init_pci_config_tokens (void) | |||
209 | ibm_write_pci_config = rtas_token("ibm,write-pci-config"); | 209 | ibm_write_pci_config = rtas_token("ibm,write-pci-config"); |
210 | } | 210 | } |
211 | 211 | ||
212 | unsigned long get_phb_buid (struct device_node *phb) | 212 | unsigned long get_phb_buid(struct device_node *phb) |
213 | { | 213 | { |
214 | struct resource r; | 214 | struct resource r; |
215 | 215 | ||
diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index 1045ff49cc6d..1130c53ad652 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <asm/nvram.h> | 29 | #include <asm/nvram.h> |
30 | #include <linux/atomic.h> | 30 | #include <linux/atomic.h> |
31 | #include <asm/machdep.h> | 31 | #include <asm/machdep.h> |
32 | #include <asm/topology.h> | ||
32 | 33 | ||
33 | 34 | ||
34 | static DEFINE_SPINLOCK(rtasd_log_lock); | 35 | static DEFINE_SPINLOCK(rtasd_log_lock); |
@@ -87,6 +88,8 @@ static char *rtas_event_type(int type) | |||
87 | return "Resource Deallocation Event"; | 88 | return "Resource Deallocation Event"; |
88 | case RTAS_TYPE_DUMP: | 89 | case RTAS_TYPE_DUMP: |
89 | return "Dump Notification Event"; | 90 | return "Dump Notification Event"; |
91 | case RTAS_TYPE_PRRN: | ||
92 | return "Platform Resource Reassignment Event"; | ||
90 | } | 93 | } |
91 | 94 | ||
92 | return rtas_type[0]; | 95 | return rtas_type[0]; |
@@ -265,9 +268,51 @@ void pSeries_log_error(char *buf, unsigned int err_type, int fatal) | |||
265 | spin_unlock_irqrestore(&rtasd_log_lock, s); | 268 | spin_unlock_irqrestore(&rtasd_log_lock, s); |
266 | return; | 269 | return; |
267 | } | 270 | } |
271 | } | ||
272 | |||
273 | #ifdef CONFIG_PPC_PSERIES | ||
274 | static s32 prrn_update_scope; | ||
268 | 275 | ||
276 | static void prrn_work_fn(struct work_struct *work) | ||
277 | { | ||
278 | /* | ||
279 | * For PRRN, we must pass the negative of the scope value in | ||
280 | * the RTAS event. | ||
281 | */ | ||
282 | pseries_devicetree_update(-prrn_update_scope); | ||
269 | } | 283 | } |
270 | 284 | ||
285 | static DECLARE_WORK(prrn_work, prrn_work_fn); | ||
286 | |||
287 | void prrn_schedule_update(u32 scope) | ||
288 | { | ||
289 | flush_work(&prrn_work); | ||
290 | prrn_update_scope = scope; | ||
291 | schedule_work(&prrn_work); | ||
292 | } | ||
293 | |||
294 | static void handle_rtas_event(const struct rtas_error_log *log) | ||
295 | { | ||
296 | if (log->type == RTAS_TYPE_PRRN) { | ||
297 | /* For PRRN Events the extended log length is used to denote | ||
298 | * the scope for calling rtas update-nodes. | ||
299 | */ | ||
300 | if (prrn_is_enabled()) | ||
301 | prrn_schedule_update(log->extended_log_length); | ||
302 | } | ||
303 | |||
304 | return; | ||
305 | } | ||
306 | |||
307 | #else | ||
308 | |||
309 | static void handle_rtas_event(const struct rtas_error_log *log) | ||
310 | { | ||
311 | return; | ||
312 | } | ||
313 | |||
314 | #endif | ||
315 | |||
271 | static int rtas_log_open(struct inode * inode, struct file * file) | 316 | static int rtas_log_open(struct inode * inode, struct file * file) |
272 | { | 317 | { |
273 | return 0; | 318 | return 0; |
@@ -388,8 +433,10 @@ static void do_event_scan(void) | |||
388 | break; | 433 | break; |
389 | } | 434 | } |
390 | 435 | ||
391 | if (error == 0) | 436 | if (error == 0) { |
392 | pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0); | 437 | pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0); |
438 | handle_rtas_event((struct rtas_error_log *)logdata); | ||
439 | } | ||
393 | 440 | ||
394 | } while(error == 0); | 441 | } while(error == 0); |
395 | } | 442 | } |
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index bdc499c17872..63d051f5b7a5 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c | |||
@@ -621,12 +621,6 @@ int check_legacy_ioport(unsigned long base_port) | |||
621 | case FDC_BASE: /* FDC1 */ | 621 | case FDC_BASE: /* FDC1 */ |
622 | np = of_find_node_by_type(NULL, "fdc"); | 622 | np = of_find_node_by_type(NULL, "fdc"); |
623 | break; | 623 | break; |
624 | #ifdef CONFIG_PPC_PREP | ||
625 | case _PIDXR: | ||
626 | case _PNPWRP: | ||
627 | case PNPBIOS_BASE: | ||
628 | /* implement me */ | ||
629 | #endif | ||
630 | default: | 624 | default: |
631 | /* ipmi is supposed to fail here */ | 625 | /* ipmi is supposed to fail here */ |
632 | break; | 626 | break; |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 75fbaceb5c87..e379d3fd1694 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -583,7 +583,9 @@ void __init setup_arch(char **cmdline_p) | |||
583 | init_mm.end_code = (unsigned long) _etext; | 583 | init_mm.end_code = (unsigned long) _etext; |
584 | init_mm.end_data = (unsigned long) _edata; | 584 | init_mm.end_data = (unsigned long) _edata; |
585 | init_mm.brk = klimit; | 585 | init_mm.brk = klimit; |
586 | 586 | #ifdef CONFIG_PPC_64K_PAGES | |
587 | init_mm.context.pte_frag = NULL; | ||
588 | #endif | ||
587 | irqstack_early_init(); | 589 | irqstack_early_init(); |
588 | exc_lvl_early_init(); | 590 | exc_lvl_early_init(); |
589 | emergency_stack_init(); | 591 | emergency_stack_init(); |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 3acb28e245b4..95068bf569ad 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -866,10 +866,12 @@ static long restore_tm_user_regs(struct pt_regs *regs, | |||
866 | do_load_up_transact_fpu(¤t->thread); | 866 | do_load_up_transact_fpu(¤t->thread); |
867 | regs->msr |= (MSR_FP | current->thread.fpexc_mode); | 867 | regs->msr |= (MSR_FP | current->thread.fpexc_mode); |
868 | } | 868 | } |
869 | #ifdef CONFIG_ALTIVEC | ||
869 | if (msr & MSR_VEC) { | 870 | if (msr & MSR_VEC) { |
870 | do_load_up_transact_altivec(¤t->thread); | 871 | do_load_up_transact_altivec(¤t->thread); |
871 | regs->msr |= MSR_VEC; | 872 | regs->msr |= MSR_VEC; |
872 | } | 873 | } |
874 | #endif | ||
873 | 875 | ||
874 | return 0; | 876 | return 0; |
875 | } | 877 | } |
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 995f8543cb57..c1794286098c 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
@@ -522,10 +522,12 @@ static long restore_tm_sigcontexts(struct pt_regs *regs, | |||
522 | do_load_up_transact_fpu(¤t->thread); | 522 | do_load_up_transact_fpu(¤t->thread); |
523 | regs->msr |= (MSR_FP | current->thread.fpexc_mode); | 523 | regs->msr |= (MSR_FP | current->thread.fpexc_mode); |
524 | } | 524 | } |
525 | #ifdef CONFIG_ALTIVEC | ||
525 | if (msr & MSR_VEC) { | 526 | if (msr & MSR_VEC) { |
526 | do_load_up_transact_altivec(¤t->thread); | 527 | do_load_up_transact_altivec(¤t->thread); |
527 | regs->msr |= MSR_VEC; | 528 | regs->msr |= MSR_VEC; |
528 | } | 529 | } |
530 | #endif | ||
529 | 531 | ||
530 | return err; | 532 | return err; |
531 | } | 533 | } |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 76bd9da8cb71..ee7ac5e6e28a 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -669,7 +669,7 @@ __cpuinit void start_secondary(void *unused) | |||
669 | 669 | ||
670 | local_irq_enable(); | 670 | local_irq_enable(); |
671 | 671 | ||
672 | cpu_idle(); | 672 | cpu_startup_entry(CPUHP_ONLINE); |
673 | 673 | ||
674 | BUG(); | 674 | BUG(); |
675 | } | 675 | } |
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index d0bafc0cdf06..cd6e19d263b3 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c | |||
@@ -61,91 +61,6 @@ asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp, | |||
61 | return compat_sys_select((int)n, inp, outp, exp, compat_ptr(tvp_x)); | 61 | return compat_sys_select((int)n, inp, outp, exp, compat_ptr(tvp_x)); |
62 | } | 62 | } |
63 | 63 | ||
64 | #ifdef CONFIG_SYSVIPC | ||
65 | long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, | ||
66 | u32 fifth) | ||
67 | { | ||
68 | int version; | ||
69 | |||
70 | version = call >> 16; /* hack for backward compatibility */ | ||
71 | call &= 0xffff; | ||
72 | |||
73 | switch (call) { | ||
74 | |||
75 | case SEMTIMEDOP: | ||
76 | if (fifth) | ||
77 | /* sign extend semid */ | ||
78 | return compat_sys_semtimedop((int)first, | ||
79 | compat_ptr(ptr), second, | ||
80 | compat_ptr(fifth)); | ||
81 | /* else fall through for normal semop() */ | ||
82 | case SEMOP: | ||
83 | /* struct sembuf is the same on 32 and 64bit :)) */ | ||
84 | /* sign extend semid */ | ||
85 | return sys_semtimedop((int)first, compat_ptr(ptr), second, | ||
86 | NULL); | ||
87 | case SEMGET: | ||
88 | /* sign extend key, nsems */ | ||
89 | return sys_semget((int)first, (int)second, third); | ||
90 | case SEMCTL: | ||
91 | /* sign extend semid, semnum */ | ||
92 | return compat_sys_semctl((int)first, (int)second, third, | ||
93 | compat_ptr(ptr)); | ||
94 | |||
95 | case MSGSND: | ||
96 | /* sign extend msqid */ | ||
97 | return compat_sys_msgsnd((int)first, (int)second, third, | ||
98 | compat_ptr(ptr)); | ||
99 | case MSGRCV: | ||
100 | /* sign extend msqid, msgtyp */ | ||
101 | return compat_sys_msgrcv((int)first, second, (int)fifth, | ||
102 | third, version, compat_ptr(ptr)); | ||
103 | case MSGGET: | ||
104 | /* sign extend key */ | ||
105 | return sys_msgget((int)first, second); | ||
106 | case MSGCTL: | ||
107 | /* sign extend msqid */ | ||
108 | return compat_sys_msgctl((int)first, second, compat_ptr(ptr)); | ||
109 | |||
110 | case SHMAT: | ||
111 | /* sign extend shmid */ | ||
112 | return compat_sys_shmat((int)first, second, third, version, | ||
113 | compat_ptr(ptr)); | ||
114 | case SHMDT: | ||
115 | return sys_shmdt(compat_ptr(ptr)); | ||
116 | case SHMGET: | ||
117 | /* sign extend key_t */ | ||
118 | return sys_shmget((int)first, second, third); | ||
119 | case SHMCTL: | ||
120 | /* sign extend shmid */ | ||
121 | return compat_sys_shmctl((int)first, second, compat_ptr(ptr)); | ||
122 | |||
123 | default: | ||
124 | return -ENOSYS; | ||
125 | } | ||
126 | |||
127 | return -ENOSYS; | ||
128 | } | ||
129 | #endif | ||
130 | |||
131 | /* Note: it is necessary to treat out_fd and in_fd as unsigned ints, | ||
132 | * with the corresponding cast to a signed int to insure that the | ||
133 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
134 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
135 | */ | ||
136 | asmlinkage long compat_sys_sendfile_wrapper(u32 out_fd, u32 in_fd, | ||
137 | compat_off_t __user *offset, u32 count) | ||
138 | { | ||
139 | return compat_sys_sendfile((int)out_fd, (int)in_fd, offset, count); | ||
140 | } | ||
141 | |||
142 | asmlinkage long compat_sys_sendfile64_wrapper(u32 out_fd, u32 in_fd, | ||
143 | compat_loff_t __user *offset, u32 count) | ||
144 | { | ||
145 | return sys_sendfile((int)out_fd, (int)in_fd, | ||
146 | (off_t __user *)offset, count); | ||
147 | } | ||
148 | |||
149 | unsigned long compat_sys_mmap2(unsigned long addr, size_t len, | 64 | unsigned long compat_sys_mmap2(unsigned long addr, size_t len, |
150 | unsigned long prot, unsigned long flags, | 65 | unsigned long prot, unsigned long flags, |
151 | unsigned long fd, unsigned long pgoff) | 66 | unsigned long fd, unsigned long pgoff) |
@@ -195,13 +110,6 @@ asmlinkage int compat_sys_ftruncate64(unsigned int fd, u32 reg4, unsigned long h | |||
195 | return sys_ftruncate(fd, (high << 32) | low); | 110 | return sys_ftruncate(fd, (high << 32) | low); |
196 | } | 111 | } |
197 | 112 | ||
198 | long ppc32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char __user *buf, | ||
199 | size_t len) | ||
200 | { | ||
201 | return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low, | ||
202 | buf, len); | ||
203 | } | ||
204 | |||
205 | long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low, | 113 | long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low, |
206 | size_t len, int advice) | 114 | size_t len, int advice) |
207 | { | 115 | { |
@@ -209,23 +117,6 @@ long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low, | |||
209 | advice); | 117 | advice); |
210 | } | 118 | } |
211 | 119 | ||
212 | asmlinkage long compat_sys_add_key(const char __user *_type, | ||
213 | const char __user *_description, | ||
214 | const void __user *_payload, | ||
215 | u32 plen, | ||
216 | u32 ringid) | ||
217 | { | ||
218 | return sys_add_key(_type, _description, _payload, plen, ringid); | ||
219 | } | ||
220 | |||
221 | asmlinkage long compat_sys_request_key(const char __user *_type, | ||
222 | const char __user *_description, | ||
223 | const char __user *_callout_info, | ||
224 | u32 destringid) | ||
225 | { | ||
226 | return sys_request_key(_type, _description, _callout_info, destringid); | ||
227 | } | ||
228 | |||
229 | asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags, | 120 | asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags, |
230 | unsigned offset_hi, unsigned offset_lo, | 121 | unsigned offset_hi, unsigned offset_lo, |
231 | unsigned nbytes_hi, unsigned nbytes_lo) | 122 | unsigned nbytes_hi, unsigned nbytes_lo) |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index f77fa22754bc..5fc29ad7e26f 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -1049,10 +1049,8 @@ static int __init rtc_init(void) | |||
1049 | return -ENODEV; | 1049 | return -ENODEV; |
1050 | 1050 | ||
1051 | pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); | 1051 | pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); |
1052 | if (IS_ERR(pdev)) | ||
1053 | return PTR_ERR(pdev); | ||
1054 | 1052 | ||
1055 | return 0; | 1053 | return PTR_RET(pdev); |
1056 | } | 1054 | } |
1057 | 1055 | ||
1058 | module_init(rtc_init); | 1056 | module_init(rtc_init); |
diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S index 84dbace657ce..2da67e7a16d5 100644 --- a/arch/powerpc/kernel/tm.S +++ b/arch/powerpc/kernel/tm.S | |||
@@ -309,6 +309,7 @@ _GLOBAL(tm_recheckpoint) | |||
309 | or r5, r6, r5 /* Set MSR.FP+.VSX/.VEC */ | 309 | or r5, r6, r5 /* Set MSR.FP+.VSX/.VEC */ |
310 | mtmsr r5 | 310 | mtmsr r5 |
311 | 311 | ||
312 | #ifdef CONFIG_ALTIVEC | ||
312 | /* FP and VEC registers: These are recheckpointed from thread.fpr[] | 313 | /* FP and VEC registers: These are recheckpointed from thread.fpr[] |
313 | * and thread.vr[] respectively. The thread.transact_fpr[] version | 314 | * and thread.vr[] respectively. The thread.transact_fpr[] version |
314 | * is more modern, and will be loaded subsequently by any FPUnavailable | 315 | * is more modern, and will be loaded subsequently by any FPUnavailable |
@@ -323,6 +324,7 @@ _GLOBAL(tm_recheckpoint) | |||
323 | REST_32VRS(0, r5, r3) /* r5 scratch, r3 THREAD ptr */ | 324 | REST_32VRS(0, r5, r3) /* r5 scratch, r3 THREAD ptr */ |
324 | ld r5, THREAD_VRSAVE(r3) | 325 | ld r5, THREAD_VRSAVE(r3) |
325 | mtspr SPRN_VRSAVE, r5 | 326 | mtspr SPRN_VRSAVE, r5 |
327 | #endif | ||
326 | 328 | ||
327 | dont_restore_vec: | 329 | dont_restore_vec: |
328 | andi. r0, r4, MSR_FP | 330 | andi. r0, r4, MSR_FP |
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c index f9748498fe58..13b867093499 100644 --- a/arch/powerpc/kernel/udbg.c +++ b/arch/powerpc/kernel/udbg.c | |||
@@ -156,15 +156,13 @@ static struct console udbg_console = { | |||
156 | .index = 0, | 156 | .index = 0, |
157 | }; | 157 | }; |
158 | 158 | ||
159 | static int early_console_initialized; | ||
160 | |||
161 | /* | 159 | /* |
162 | * Called by setup_system after ppc_md->probe and ppc_md->early_init. | 160 | * Called by setup_system after ppc_md->probe and ppc_md->early_init. |
163 | * Call it again after setting udbg_putc in ppc_md->setup_arch. | 161 | * Call it again after setting udbg_putc in ppc_md->setup_arch. |
164 | */ | 162 | */ |
165 | void __init register_early_udbg_console(void) | 163 | void __init register_early_udbg_console(void) |
166 | { | 164 | { |
167 | if (early_console_initialized) | 165 | if (early_console) |
168 | return; | 166 | return; |
169 | 167 | ||
170 | if (!udbg_putc) | 168 | if (!udbg_putc) |
@@ -174,7 +172,7 @@ void __init register_early_udbg_console(void) | |||
174 | printk(KERN_INFO "early console immortal !\n"); | 172 | printk(KERN_INFO "early console immortal !\n"); |
175 | udbg_console.flags &= ~CON_BOOT; | 173 | udbg_console.flags &= ~CON_BOOT; |
176 | } | 174 | } |
177 | early_console_initialized = 1; | 175 | early_console = &udbg_console; |
178 | register_console(&udbg_console); | 176 | register_console(&udbg_console); |
179 | } | 177 | } |
180 | 178 | ||
diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c index bc77834dbf43..59f419b935f2 100644 --- a/arch/powerpc/kernel/uprobes.c +++ b/arch/powerpc/kernel/uprobes.c | |||
@@ -31,6 +31,16 @@ | |||
31 | #define UPROBE_TRAP_NR UINT_MAX | 31 | #define UPROBE_TRAP_NR UINT_MAX |
32 | 32 | ||
33 | /** | 33 | /** |
34 | * is_trap_insn - check if the instruction is a trap variant | ||
35 | * @insn: instruction to be checked. | ||
36 | * Returns true if @insn is a trap variant. | ||
37 | */ | ||
38 | bool is_trap_insn(uprobe_opcode_t *insn) | ||
39 | { | ||
40 | return (is_trap(*insn)); | ||
41 | } | ||
42 | |||
43 | /** | ||
34 | * arch_uprobe_analyze_insn | 44 | * arch_uprobe_analyze_insn |
35 | * @mm: the probed address space. | 45 | * @mm: the probed address space. |
36 | * @arch_uprobe: the probepoint information. | 46 | * @arch_uprobe: the probepoint information. |
@@ -43,12 +53,6 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, | |||
43 | if (addr & 0x03) | 53 | if (addr & 0x03) |
44 | return -EINVAL; | 54 | return -EINVAL; |
45 | 55 | ||
46 | /* | ||
47 | * We currently don't support a uprobe on an already | ||
48 | * existing breakpoint instruction underneath | ||
49 | */ | ||
50 | if (is_trap(auprobe->ainsn)) | ||
51 | return -ENOTSUPP; | ||
52 | return 0; | 56 | return 0; |
53 | } | 57 | } |
54 | 58 | ||
@@ -188,3 +192,16 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) | |||
188 | 192 | ||
189 | return false; | 193 | return false; |
190 | } | 194 | } |
195 | |||
196 | unsigned long | ||
197 | arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs) | ||
198 | { | ||
199 | unsigned long orig_ret_vaddr; | ||
200 | |||
201 | orig_ret_vaddr = regs->link; | ||
202 | |||
203 | /* Replace the return addr with trampoline addr */ | ||
204 | regs->link = trampoline_vaddr; | ||
205 | |||
206 | return orig_ret_vaddr; | ||
207 | } | ||
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index 1b2076f049ce..d4f463ac65b1 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c | |||
@@ -113,6 +113,10 @@ static struct vdso_patch_def vdso_patches[] = { | |||
113 | CPU_FTR_USE_TB, 0, | 113 | CPU_FTR_USE_TB, 0, |
114 | "__kernel_get_tbfreq", NULL | 114 | "__kernel_get_tbfreq", NULL |
115 | }, | 115 | }, |
116 | { | ||
117 | CPU_FTR_USE_TB, 0, | ||
118 | "__kernel_time", NULL | ||
119 | }, | ||
116 | }; | 120 | }; |
117 | 121 | ||
118 | /* | 122 | /* |
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S index 4ee09ee2e836..27e2f623210b 100644 --- a/arch/powerpc/kernel/vdso32/gettimeofday.S +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S | |||
@@ -181,6 +181,32 @@ V_FUNCTION_END(__kernel_clock_getres) | |||
181 | 181 | ||
182 | 182 | ||
183 | /* | 183 | /* |
184 | * Exact prototype of time() | ||
185 | * | ||
186 | * time_t time(time *t); | ||
187 | * | ||
188 | */ | ||
189 | V_FUNCTION_BEGIN(__kernel_time) | ||
190 | .cfi_startproc | ||
191 | mflr r12 | ||
192 | .cfi_register lr,r12 | ||
193 | |||
194 | mr r11,r3 /* r11 holds t */ | ||
195 | bl __get_datapage@local | ||
196 | mr r9, r3 /* datapage ptr in r9 */ | ||
197 | |||
198 | lwz r3,STAMP_XTIME+TSPEC_TV_SEC(r9) | ||
199 | |||
200 | cmplwi r11,0 /* check if t is NULL */ | ||
201 | beq 2f | ||
202 | stw r3,0(r11) /* store result at *t */ | ||
203 | 2: mtlr r12 | ||
204 | crclr cr0*4+so | ||
205 | blr | ||
206 | .cfi_endproc | ||
207 | V_FUNCTION_END(__kernel_time) | ||
208 | |||
209 | /* | ||
184 | * This is the core of clock_gettime() and gettimeofday(), | 210 | * This is the core of clock_gettime() and gettimeofday(), |
185 | * it returns the current time in r3 (seconds) and r4. | 211 | * it returns the current time in r3 (seconds) and r4. |
186 | * On entry, r7 gives the resolution of r4, either USEC_PER_SEC | 212 | * On entry, r7 gives the resolution of r4, either USEC_PER_SEC |
diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S index 43200ba2e570..f223409629b9 100644 --- a/arch/powerpc/kernel/vdso32/vdso32.lds.S +++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S | |||
@@ -150,6 +150,7 @@ VERSION | |||
150 | #ifdef CONFIG_PPC64 | 150 | #ifdef CONFIG_PPC64 |
151 | __kernel_getcpu; | 151 | __kernel_getcpu; |
152 | #endif | 152 | #endif |
153 | __kernel_time; | ||
153 | 154 | ||
154 | local: *; | 155 | local: *; |
155 | }; | 156 | }; |
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S index e97a9a0dc4ac..a76b4af37ef2 100644 --- a/arch/powerpc/kernel/vdso64/gettimeofday.S +++ b/arch/powerpc/kernel/vdso64/gettimeofday.S | |||
@@ -164,6 +164,32 @@ V_FUNCTION_BEGIN(__kernel_clock_getres) | |||
164 | .cfi_endproc | 164 | .cfi_endproc |
165 | V_FUNCTION_END(__kernel_clock_getres) | 165 | V_FUNCTION_END(__kernel_clock_getres) |
166 | 166 | ||
167 | /* | ||
168 | * Exact prototype of time() | ||
169 | * | ||
170 | * time_t time(time *t); | ||
171 | * | ||
172 | */ | ||
173 | V_FUNCTION_BEGIN(__kernel_time) | ||
174 | .cfi_startproc | ||
175 | mflr r12 | ||
176 | .cfi_register lr,r12 | ||
177 | |||
178 | mr r11,r3 /* r11 holds t */ | ||
179 | bl V_LOCAL_FUNC(__get_datapage) | ||
180 | |||
181 | ld r4,STAMP_XTIME+TSPC64_TV_SEC(r3) | ||
182 | |||
183 | cmpldi r11,0 /* check if t is NULL */ | ||
184 | beq 2f | ||
185 | std r4,0(r11) /* store result at *t */ | ||
186 | 2: mtlr r12 | ||
187 | crclr cr0*4+so | ||
188 | mr r3,r4 | ||
189 | blr | ||
190 | .cfi_endproc | ||
191 | V_FUNCTION_END(__kernel_time) | ||
192 | |||
167 | 193 | ||
168 | /* | 194 | /* |
169 | * This is the core of clock_gettime() and gettimeofday(), | 195 | * This is the core of clock_gettime() and gettimeofday(), |
diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S index e6c1758f3588..e4863819663b 100644 --- a/arch/powerpc/kernel/vdso64/vdso64.lds.S +++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S | |||
@@ -147,6 +147,7 @@ VERSION | |||
147 | __kernel_sync_dicache_p5; | 147 | __kernel_sync_dicache_p5; |
148 | __kernel_sigtramp_rt64; | 148 | __kernel_sigtramp_rt64; |
149 | __kernel_getcpu; | 149 | __kernel_getcpu; |
150 | __kernel_time; | ||
150 | 151 | ||
151 | local: *; | 152 | local: *; |
152 | }; | 153 | }; |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index 5d7d29a313eb..3a9a1aceb14f 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c | |||
@@ -143,7 +143,7 @@ map_again: | |||
143 | } | 143 | } |
144 | 144 | ||
145 | ret = ppc_md.hpte_insert(hpteg, vpn, hpaddr, rflags, vflags, | 145 | ret = ppc_md.hpte_insert(hpteg, vpn, hpaddr, rflags, vflags, |
146 | MMU_PAGE_4K, MMU_SEGSIZE_256M); | 146 | MMU_PAGE_4K, MMU_PAGE_4K, MMU_SEGSIZE_256M); |
147 | 147 | ||
148 | if (ret < 0) { | 148 | if (ret < 0) { |
149 | /* If we couldn't map a primary PTE, try a secondary */ | 149 | /* If we couldn't map a primary PTE, try a secondary */ |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 69efe0d6cedc..5880dfb31074 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c | |||
@@ -1551,7 +1551,7 @@ static int kvm_htab_release(struct inode *inode, struct file *filp) | |||
1551 | return 0; | 1551 | return 0; |
1552 | } | 1552 | } |
1553 | 1553 | ||
1554 | static struct file_operations kvm_htab_fops = { | 1554 | static const struct file_operations kvm_htab_fops = { |
1555 | .read = kvm_htab_read, | 1555 | .read = kvm_htab_read, |
1556 | .write = kvm_htab_write, | 1556 | .write = kvm_htab_write, |
1557 | .llseek = default_llseek, | 1557 | .llseek = default_llseek, |
diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c index 72ffc899c082..b2d3f3b2de72 100644 --- a/arch/powerpc/kvm/book3s_64_vio.c +++ b/arch/powerpc/kvm/book3s_64_vio.c | |||
@@ -92,7 +92,7 @@ static int kvm_spapr_tce_release(struct inode *inode, struct file *filp) | |||
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | static struct file_operations kvm_spapr_tce_fops = { | 95 | static const struct file_operations kvm_spapr_tce_fops = { |
96 | .mmap = kvm_spapr_tce_mmap, | 96 | .mmap = kvm_spapr_tce_mmap, |
97 | .release = kvm_spapr_tce_release, | 97 | .release = kvm_spapr_tce_release, |
98 | }; | 98 | }; |
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 178521e81ce4..9de24f8e03c7 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
@@ -1540,7 +1540,7 @@ static int kvm_rma_release(struct inode *inode, struct file *filp) | |||
1540 | return 0; | 1540 | return 0; |
1541 | } | 1541 | } |
1542 | 1542 | ||
1543 | static struct file_operations kvm_rma_fops = { | 1543 | static const struct file_operations kvm_rma_fops = { |
1544 | .mmap = kvm_rma_mmap, | 1544 | .mmap = kvm_rma_mmap, |
1545 | .release = kvm_rma_release, | 1545 | .release = kvm_rma_release, |
1546 | }; | 1546 | }; |
@@ -1572,7 +1572,13 @@ static void kvmppc_add_seg_page_size(struct kvm_ppc_one_seg_page_size **sps, | |||
1572 | (*sps)->page_shift = def->shift; | 1572 | (*sps)->page_shift = def->shift; |
1573 | (*sps)->slb_enc = def->sllp; | 1573 | (*sps)->slb_enc = def->sllp; |
1574 | (*sps)->enc[0].page_shift = def->shift; | 1574 | (*sps)->enc[0].page_shift = def->shift; |
1575 | (*sps)->enc[0].pte_enc = def->penc; | 1575 | /* |
1576 | * Only return base page encoding. We don't want to return | ||
1577 | * all the supporting pte_enc, because our H_ENTER doesn't | ||
1578 | * support MPSS yet. Once they do, we can start passing all | ||
1579 | * support pte_enc here | ||
1580 | */ | ||
1581 | (*sps)->enc[0].pte_enc = def->penc[linux_psize]; | ||
1576 | (*sps)++; | 1582 | (*sps)++; |
1577 | } | 1583 | } |
1578 | 1584 | ||
diff --git a/arch/powerpc/kvm/book3s_hv_interrupts.S b/arch/powerpc/kvm/book3s_hv_interrupts.S index 84035a528c80..37f1cc417ca0 100644 --- a/arch/powerpc/kvm/book3s_hv_interrupts.S +++ b/arch/powerpc/kvm/book3s_hv_interrupts.S | |||
@@ -122,11 +122,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | |||
122 | add r8,r8,r7 | 122 | add r8,r8,r7 |
123 | std r8,HSTATE_DECEXP(r13) | 123 | std r8,HSTATE_DECEXP(r13) |
124 | 124 | ||
125 | #ifdef CONFIG_SMP | ||
125 | /* | 126 | /* |
126 | * On PPC970, if the guest vcpu has an external interrupt pending, | 127 | * On PPC970, if the guest vcpu has an external interrupt pending, |
127 | * send ourselves an IPI so as to interrupt the guest once it | 128 | * send ourselves an IPI so as to interrupt the guest once it |
128 | * enables interrupts. (It must have interrupts disabled, | 129 | * enables interrupts. (It must have interrupts disabled, |
129 | * otherwise we would already have delivered the interrupt.) | 130 | * otherwise we would already have delivered the interrupt.) |
131 | * | ||
132 | * XXX If this is a UP build, smp_send_reschedule is not available, | ||
133 | * so the interrupt will be delayed until the next time the vcpu | ||
134 | * enters the guest with interrupts enabled. | ||
130 | */ | 135 | */ |
131 | BEGIN_FTR_SECTION | 136 | BEGIN_FTR_SECTION |
132 | ld r0, VCPU_PENDING_EXC(r4) | 137 | ld r0, VCPU_PENDING_EXC(r4) |
@@ -141,6 +146,7 @@ BEGIN_FTR_SECTION | |||
141 | mr r4, r31 | 146 | mr r4, r31 |
142 | 32: | 147 | 32: |
143 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | 148 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) |
149 | #endif /* CONFIG_SMP */ | ||
144 | 150 | ||
145 | /* Jump to partition switch code */ | 151 | /* Jump to partition switch code */ |
146 | bl .kvmppc_hv_entry_trampoline | 152 | bl .kvmppc_hv_entry_trampoline |
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index d09baf143500..bdc40b8e77d9 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c | |||
@@ -1037,7 +1037,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) | |||
1037 | if (!vcpu_book3s) | 1037 | if (!vcpu_book3s) |
1038 | goto out; | 1038 | goto out; |
1039 | 1039 | ||
1040 | vcpu_book3s->shadow_vcpu = (struct kvmppc_book3s_shadow_vcpu *) | 1040 | vcpu_book3s->shadow_vcpu = |
1041 | kzalloc(sizeof(*vcpu_book3s->shadow_vcpu), GFP_KERNEL); | 1041 | kzalloc(sizeof(*vcpu_book3s->shadow_vcpu), GFP_KERNEL); |
1042 | if (!vcpu_book3s->shadow_vcpu) | 1042 | if (!vcpu_book3s->shadow_vcpu) |
1043 | goto free_vcpu; | 1043 | goto free_vcpu; |
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index c3bdc0aeabe2..753cc99eff2b 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c | |||
@@ -108,6 +108,8 @@ void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr) | |||
108 | { | 108 | { |
109 | } | 109 | } |
110 | 110 | ||
111 | static DEFINE_PER_CPU(struct kvm_vcpu *, last_vcpu_on_cpu); | ||
112 | |||
111 | void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | 113 | void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) |
112 | { | 114 | { |
113 | struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); | 115 | struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); |
@@ -136,8 +138,11 @@ void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
136 | mtspr(SPRN_GDEAR, vcpu->arch.shared->dar); | 138 | mtspr(SPRN_GDEAR, vcpu->arch.shared->dar); |
137 | mtspr(SPRN_GESR, vcpu->arch.shared->esr); | 139 | mtspr(SPRN_GESR, vcpu->arch.shared->esr); |
138 | 140 | ||
139 | if (vcpu->arch.oldpir != mfspr(SPRN_PIR)) | 141 | if (vcpu->arch.oldpir != mfspr(SPRN_PIR) || |
142 | __get_cpu_var(last_vcpu_on_cpu) != vcpu) { | ||
140 | kvmppc_e500_tlbil_all(vcpu_e500); | 143 | kvmppc_e500_tlbil_all(vcpu_e500); |
144 | __get_cpu_var(last_vcpu_on_cpu) = vcpu; | ||
145 | } | ||
141 | 146 | ||
142 | kvmppc_load_guest_fp(vcpu); | 147 | kvmppc_load_guest_fp(vcpu); |
143 | } | 148 | } |
diff --git a/arch/powerpc/mm/gup.c b/arch/powerpc/mm/gup.c index d7efdbf640c7..4b921affa495 100644 --- a/arch/powerpc/mm/gup.c +++ b/arch/powerpc/mm/gup.c | |||
@@ -68,7 +68,11 @@ static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, | |||
68 | next = pmd_addr_end(addr, end); | 68 | next = pmd_addr_end(addr, end); |
69 | if (pmd_none(pmd)) | 69 | if (pmd_none(pmd)) |
70 | return 0; | 70 | return 0; |
71 | if (is_hugepd(pmdp)) { | 71 | if (pmd_huge(pmd)) { |
72 | if (!gup_hugepte((pte_t *)pmdp, PMD_SIZE, addr, next, | ||
73 | write, pages, nr)) | ||
74 | return 0; | ||
75 | } else if (is_hugepd(pmdp)) { | ||
72 | if (!gup_hugepd((hugepd_t *)pmdp, PMD_SHIFT, | 76 | if (!gup_hugepd((hugepd_t *)pmdp, PMD_SHIFT, |
73 | addr, next, write, pages, nr)) | 77 | addr, next, write, pages, nr)) |
74 | return 0; | 78 | return 0; |
@@ -92,7 +96,11 @@ static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end, | |||
92 | next = pud_addr_end(addr, end); | 96 | next = pud_addr_end(addr, end); |
93 | if (pud_none(pud)) | 97 | if (pud_none(pud)) |
94 | return 0; | 98 | return 0; |
95 | if (is_hugepd(pudp)) { | 99 | if (pud_huge(pud)) { |
100 | if (!gup_hugepte((pte_t *)pudp, PUD_SIZE, addr, next, | ||
101 | write, pages, nr)) | ||
102 | return 0; | ||
103 | } else if (is_hugepd(pudp)) { | ||
96 | if (!gup_hugepd((hugepd_t *)pudp, PUD_SHIFT, | 104 | if (!gup_hugepd((hugepd_t *)pudp, PUD_SHIFT, |
97 | addr, next, write, pages, nr)) | 105 | addr, next, write, pages, nr)) |
98 | return 0; | 106 | return 0; |
@@ -153,7 +161,11 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, | |||
153 | next = pgd_addr_end(addr, end); | 161 | next = pgd_addr_end(addr, end); |
154 | if (pgd_none(pgd)) | 162 | if (pgd_none(pgd)) |
155 | goto slow; | 163 | goto slow; |
156 | if (is_hugepd(pgdp)) { | 164 | if (pgd_huge(pgd)) { |
165 | if (!gup_hugepte((pte_t *)pgdp, PGDIR_SIZE, addr, next, | ||
166 | write, pages, &nr)) | ||
167 | goto slow; | ||
168 | } else if (is_hugepd(pgdp)) { | ||
157 | if (!gup_hugepd((hugepd_t *)pgdp, PGDIR_SHIFT, | 169 | if (!gup_hugepd((hugepd_t *)pgdp, PGDIR_SHIFT, |
158 | addr, next, write, pages, &nr)) | 170 | addr, next, write, pages, &nr)) |
159 | goto slow; | 171 | goto slow; |
diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S index 7443481a315c..0e980acae67c 100644 --- a/arch/powerpc/mm/hash_low_64.S +++ b/arch/powerpc/mm/hash_low_64.S | |||
@@ -196,7 +196,8 @@ htab_insert_pte: | |||
196 | mr r4,r29 /* Retrieve vpn */ | 196 | mr r4,r29 /* Retrieve vpn */ |
197 | li r7,0 /* !bolted, !secondary */ | 197 | li r7,0 /* !bolted, !secondary */ |
198 | li r8,MMU_PAGE_4K /* page size */ | 198 | li r8,MMU_PAGE_4K /* page size */ |
199 | ld r9,STK_PARAM(R9)(r1) /* segment size */ | 199 | li r9,MMU_PAGE_4K /* actual page size */ |
200 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | ||
200 | _GLOBAL(htab_call_hpte_insert1) | 201 | _GLOBAL(htab_call_hpte_insert1) |
201 | bl . /* Patched by htab_finish_init() */ | 202 | bl . /* Patched by htab_finish_init() */ |
202 | cmpdi 0,r3,0 | 203 | cmpdi 0,r3,0 |
@@ -219,7 +220,8 @@ _GLOBAL(htab_call_hpte_insert1) | |||
219 | mr r4,r29 /* Retrieve vpn */ | 220 | mr r4,r29 /* Retrieve vpn */ |
220 | li r7,HPTE_V_SECONDARY /* !bolted, secondary */ | 221 | li r7,HPTE_V_SECONDARY /* !bolted, secondary */ |
221 | li r8,MMU_PAGE_4K /* page size */ | 222 | li r8,MMU_PAGE_4K /* page size */ |
222 | ld r9,STK_PARAM(R9)(r1) /* segment size */ | 223 | li r9,MMU_PAGE_4K /* actual page size */ |
224 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | ||
223 | _GLOBAL(htab_call_hpte_insert2) | 225 | _GLOBAL(htab_call_hpte_insert2) |
224 | bl . /* Patched by htab_finish_init() */ | 226 | bl . /* Patched by htab_finish_init() */ |
225 | cmpdi 0,r3,0 | 227 | cmpdi 0,r3,0 |
@@ -490,7 +492,7 @@ END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) | |||
490 | beq htab_inval_old_hpte | 492 | beq htab_inval_old_hpte |
491 | 493 | ||
492 | ld r6,STK_PARAM(R6)(r1) | 494 | ld r6,STK_PARAM(R6)(r1) |
493 | ori r26,r6,0x8000 /* Load the hidx mask */ | 495 | ori r26,r6,PTE_PAGE_HIDX_OFFSET /* Load the hidx mask. */ |
494 | ld r26,0(r26) | 496 | ld r26,0(r26) |
495 | addi r5,r25,36 /* Check actual HPTE_SUB bit, this */ | 497 | addi r5,r25,36 /* Check actual HPTE_SUB bit, this */ |
496 | rldcr. r0,r31,r5,0 /* must match pgtable.h definition */ | 498 | rldcr. r0,r31,r5,0 /* must match pgtable.h definition */ |
@@ -515,7 +517,8 @@ htab_special_pfn: | |||
515 | mr r4,r29 /* Retrieve vpn */ | 517 | mr r4,r29 /* Retrieve vpn */ |
516 | li r7,0 /* !bolted, !secondary */ | 518 | li r7,0 /* !bolted, !secondary */ |
517 | li r8,MMU_PAGE_4K /* page size */ | 519 | li r8,MMU_PAGE_4K /* page size */ |
518 | ld r9,STK_PARAM(R9)(r1) /* segment size */ | 520 | li r9,MMU_PAGE_4K /* actual page size */ |
521 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | ||
519 | _GLOBAL(htab_call_hpte_insert1) | 522 | _GLOBAL(htab_call_hpte_insert1) |
520 | bl . /* patched by htab_finish_init() */ | 523 | bl . /* patched by htab_finish_init() */ |
521 | cmpdi 0,r3,0 | 524 | cmpdi 0,r3,0 |
@@ -542,7 +545,8 @@ _GLOBAL(htab_call_hpte_insert1) | |||
542 | mr r4,r29 /* Retrieve vpn */ | 545 | mr r4,r29 /* Retrieve vpn */ |
543 | li r7,HPTE_V_SECONDARY /* !bolted, secondary */ | 546 | li r7,HPTE_V_SECONDARY /* !bolted, secondary */ |
544 | li r8,MMU_PAGE_4K /* page size */ | 547 | li r8,MMU_PAGE_4K /* page size */ |
545 | ld r9,STK_PARAM(R9)(r1) /* segment size */ | 548 | li r9,MMU_PAGE_4K /* actual page size */ |
549 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | ||
546 | _GLOBAL(htab_call_hpte_insert2) | 550 | _GLOBAL(htab_call_hpte_insert2) |
547 | bl . /* patched by htab_finish_init() */ | 551 | bl . /* patched by htab_finish_init() */ |
548 | cmpdi 0,r3,0 | 552 | cmpdi 0,r3,0 |
@@ -607,7 +611,7 @@ htab_pte_insert_ok: | |||
607 | sld r4,r4,r5 | 611 | sld r4,r4,r5 |
608 | andc r26,r26,r4 | 612 | andc r26,r26,r4 |
609 | or r26,r26,r3 | 613 | or r26,r26,r3 |
610 | ori r5,r6,0x8000 | 614 | ori r5,r6,PTE_PAGE_HIDX_OFFSET |
611 | std r26,0(r5) | 615 | std r26,0(r5) |
612 | lwsync | 616 | lwsync |
613 | std r30,0(r6) | 617 | std r30,0(r6) |
@@ -840,7 +844,8 @@ ht64_insert_pte: | |||
840 | mr r4,r29 /* Retrieve vpn */ | 844 | mr r4,r29 /* Retrieve vpn */ |
841 | li r7,0 /* !bolted, !secondary */ | 845 | li r7,0 /* !bolted, !secondary */ |
842 | li r8,MMU_PAGE_64K | 846 | li r8,MMU_PAGE_64K |
843 | ld r9,STK_PARAM(R9)(r1) /* segment size */ | 847 | li r9,MMU_PAGE_64K /* actual page size */ |
848 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | ||
844 | _GLOBAL(ht64_call_hpte_insert1) | 849 | _GLOBAL(ht64_call_hpte_insert1) |
845 | bl . /* patched by htab_finish_init() */ | 850 | bl . /* patched by htab_finish_init() */ |
846 | cmpdi 0,r3,0 | 851 | cmpdi 0,r3,0 |
@@ -863,7 +868,8 @@ _GLOBAL(ht64_call_hpte_insert1) | |||
863 | mr r4,r29 /* Retrieve vpn */ | 868 | mr r4,r29 /* Retrieve vpn */ |
864 | li r7,HPTE_V_SECONDARY /* !bolted, secondary */ | 869 | li r7,HPTE_V_SECONDARY /* !bolted, secondary */ |
865 | li r8,MMU_PAGE_64K | 870 | li r8,MMU_PAGE_64K |
866 | ld r9,STK_PARAM(R9)(r1) /* segment size */ | 871 | li r9,MMU_PAGE_64K /* actual page size */ |
872 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | ||
867 | _GLOBAL(ht64_call_hpte_insert2) | 873 | _GLOBAL(ht64_call_hpte_insert2) |
868 | bl . /* patched by htab_finish_init() */ | 874 | bl . /* patched by htab_finish_init() */ |
869 | cmpdi 0,r3,0 | 875 | cmpdi 0,r3,0 |
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index ffc1e00f7a22..6a2aead5b0e5 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c | |||
@@ -39,7 +39,7 @@ | |||
39 | 39 | ||
40 | DEFINE_RAW_SPINLOCK(native_tlbie_lock); | 40 | DEFINE_RAW_SPINLOCK(native_tlbie_lock); |
41 | 41 | ||
42 | static inline void __tlbie(unsigned long vpn, int psize, int ssize) | 42 | static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize) |
43 | { | 43 | { |
44 | unsigned long va; | 44 | unsigned long va; |
45 | unsigned int penc; | 45 | unsigned int penc; |
@@ -61,17 +61,31 @@ static inline void __tlbie(unsigned long vpn, int psize, int ssize) | |||
61 | 61 | ||
62 | switch (psize) { | 62 | switch (psize) { |
63 | case MMU_PAGE_4K: | 63 | case MMU_PAGE_4K: |
64 | /* clear out bits after (52) [0....52.....63] */ | ||
65 | va &= ~((1ul << (64 - 52)) - 1); | ||
64 | va |= ssize << 8; | 66 | va |= ssize << 8; |
67 | va |= mmu_psize_defs[apsize].sllp << 6; | ||
65 | asm volatile(ASM_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0), %2) | 68 | asm volatile(ASM_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0), %2) |
66 | : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206) | 69 | : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206) |
67 | : "memory"); | 70 | : "memory"); |
68 | break; | 71 | break; |
69 | default: | 72 | default: |
70 | /* We need 14 to 14 + i bits of va */ | 73 | /* We need 14 to 14 + i bits of va */ |
71 | penc = mmu_psize_defs[psize].penc; | 74 | penc = mmu_psize_defs[psize].penc[apsize]; |
72 | va &= ~((1ul << mmu_psize_defs[psize].shift) - 1); | 75 | va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1); |
73 | va |= penc << 12; | 76 | va |= penc << 12; |
74 | va |= ssize << 8; | 77 | va |= ssize << 8; |
78 | /* Add AVAL part */ | ||
79 | if (psize != apsize) { | ||
80 | /* | ||
81 | * MPSS, 64K base page size and 16MB parge page size | ||
82 | * We don't need all the bits, but rest of the bits | ||
83 | * must be ignored by the processor. | ||
84 | * vpn cover upto 65 bits of va. (0...65) and we need | ||
85 | * 58..64 bits of va. | ||
86 | */ | ||
87 | va |= (vpn & 0xfe); | ||
88 | } | ||
75 | va |= 1; /* L */ | 89 | va |= 1; /* L */ |
76 | asm volatile(ASM_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0), %2) | 90 | asm volatile(ASM_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0), %2) |
77 | : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206) | 91 | : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206) |
@@ -80,7 +94,7 @@ static inline void __tlbie(unsigned long vpn, int psize, int ssize) | |||
80 | } | 94 | } |
81 | } | 95 | } |
82 | 96 | ||
83 | static inline void __tlbiel(unsigned long vpn, int psize, int ssize) | 97 | static inline void __tlbiel(unsigned long vpn, int psize, int apsize, int ssize) |
84 | { | 98 | { |
85 | unsigned long va; | 99 | unsigned long va; |
86 | unsigned int penc; | 100 | unsigned int penc; |
@@ -96,16 +110,30 @@ static inline void __tlbiel(unsigned long vpn, int psize, int ssize) | |||
96 | 110 | ||
97 | switch (psize) { | 111 | switch (psize) { |
98 | case MMU_PAGE_4K: | 112 | case MMU_PAGE_4K: |
113 | /* clear out bits after(52) [0....52.....63] */ | ||
114 | va &= ~((1ul << (64 - 52)) - 1); | ||
99 | va |= ssize << 8; | 115 | va |= ssize << 8; |
116 | va |= mmu_psize_defs[apsize].sllp << 6; | ||
100 | asm volatile(".long 0x7c000224 | (%0 << 11) | (0 << 21)" | 117 | asm volatile(".long 0x7c000224 | (%0 << 11) | (0 << 21)" |
101 | : : "r"(va) : "memory"); | 118 | : : "r"(va) : "memory"); |
102 | break; | 119 | break; |
103 | default: | 120 | default: |
104 | /* We need 14 to 14 + i bits of va */ | 121 | /* We need 14 to 14 + i bits of va */ |
105 | penc = mmu_psize_defs[psize].penc; | 122 | penc = mmu_psize_defs[psize].penc[apsize]; |
106 | va &= ~((1ul << mmu_psize_defs[psize].shift) - 1); | 123 | va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1); |
107 | va |= penc << 12; | 124 | va |= penc << 12; |
108 | va |= ssize << 8; | 125 | va |= ssize << 8; |
126 | /* Add AVAL part */ | ||
127 | if (psize != apsize) { | ||
128 | /* | ||
129 | * MPSS, 64K base page size and 16MB parge page size | ||
130 | * We don't need all the bits, but rest of the bits | ||
131 | * must be ignored by the processor. | ||
132 | * vpn cover upto 65 bits of va. (0...65) and we need | ||
133 | * 58..64 bits of va. | ||
134 | */ | ||
135 | va |= (vpn & 0xfe); | ||
136 | } | ||
109 | va |= 1; /* L */ | 137 | va |= 1; /* L */ |
110 | asm volatile(".long 0x7c000224 | (%0 << 11) | (1 << 21)" | 138 | asm volatile(".long 0x7c000224 | (%0 << 11) | (1 << 21)" |
111 | : : "r"(va) : "memory"); | 139 | : : "r"(va) : "memory"); |
@@ -114,7 +142,8 @@ static inline void __tlbiel(unsigned long vpn, int psize, int ssize) | |||
114 | 142 | ||
115 | } | 143 | } |
116 | 144 | ||
117 | static inline void tlbie(unsigned long vpn, int psize, int ssize, int local) | 145 | static inline void tlbie(unsigned long vpn, int psize, int apsize, |
146 | int ssize, int local) | ||
118 | { | 147 | { |
119 | unsigned int use_local = local && mmu_has_feature(MMU_FTR_TLBIEL); | 148 | unsigned int use_local = local && mmu_has_feature(MMU_FTR_TLBIEL); |
120 | int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE); | 149 | int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE); |
@@ -125,10 +154,10 @@ static inline void tlbie(unsigned long vpn, int psize, int ssize, int local) | |||
125 | raw_spin_lock(&native_tlbie_lock); | 154 | raw_spin_lock(&native_tlbie_lock); |
126 | asm volatile("ptesync": : :"memory"); | 155 | asm volatile("ptesync": : :"memory"); |
127 | if (use_local) { | 156 | if (use_local) { |
128 | __tlbiel(vpn, psize, ssize); | 157 | __tlbiel(vpn, psize, apsize, ssize); |
129 | asm volatile("ptesync": : :"memory"); | 158 | asm volatile("ptesync": : :"memory"); |
130 | } else { | 159 | } else { |
131 | __tlbie(vpn, psize, ssize); | 160 | __tlbie(vpn, psize, apsize, ssize); |
132 | asm volatile("eieio; tlbsync; ptesync": : :"memory"); | 161 | asm volatile("eieio; tlbsync; ptesync": : :"memory"); |
133 | } | 162 | } |
134 | if (lock_tlbie && !use_local) | 163 | if (lock_tlbie && !use_local) |
@@ -156,7 +185,7 @@ static inline void native_unlock_hpte(struct hash_pte *hptep) | |||
156 | 185 | ||
157 | static long native_hpte_insert(unsigned long hpte_group, unsigned long vpn, | 186 | static long native_hpte_insert(unsigned long hpte_group, unsigned long vpn, |
158 | unsigned long pa, unsigned long rflags, | 187 | unsigned long pa, unsigned long rflags, |
159 | unsigned long vflags, int psize, int ssize) | 188 | unsigned long vflags, int psize, int apsize, int ssize) |
160 | { | 189 | { |
161 | struct hash_pte *hptep = htab_address + hpte_group; | 190 | struct hash_pte *hptep = htab_address + hpte_group; |
162 | unsigned long hpte_v, hpte_r; | 191 | unsigned long hpte_v, hpte_r; |
@@ -183,8 +212,8 @@ static long native_hpte_insert(unsigned long hpte_group, unsigned long vpn, | |||
183 | if (i == HPTES_PER_GROUP) | 212 | if (i == HPTES_PER_GROUP) |
184 | return -1; | 213 | return -1; |
185 | 214 | ||
186 | hpte_v = hpte_encode_v(vpn, psize, ssize) | vflags | HPTE_V_VALID; | 215 | hpte_v = hpte_encode_v(vpn, psize, apsize, ssize) | vflags | HPTE_V_VALID; |
187 | hpte_r = hpte_encode_r(pa, psize) | rflags; | 216 | hpte_r = hpte_encode_r(pa, psize, apsize) | rflags; |
188 | 217 | ||
189 | if (!(vflags & HPTE_V_BOLTED)) { | 218 | if (!(vflags & HPTE_V_BOLTED)) { |
190 | DBG_LOW(" i=%x hpte_v=%016lx, hpte_r=%016lx\n", | 219 | DBG_LOW(" i=%x hpte_v=%016lx, hpte_r=%016lx\n", |
@@ -244,6 +273,51 @@ static long native_hpte_remove(unsigned long hpte_group) | |||
244 | return i; | 273 | return i; |
245 | } | 274 | } |
246 | 275 | ||
276 | static inline int __hpte_actual_psize(unsigned int lp, int psize) | ||
277 | { | ||
278 | int i, shift; | ||
279 | unsigned int mask; | ||
280 | |||
281 | /* start from 1 ignoring MMU_PAGE_4K */ | ||
282 | for (i = 1; i < MMU_PAGE_COUNT; i++) { | ||
283 | |||
284 | /* invalid penc */ | ||
285 | if (mmu_psize_defs[psize].penc[i] == -1) | ||
286 | continue; | ||
287 | /* | ||
288 | * encoding bits per actual page size | ||
289 | * PTE LP actual page size | ||
290 | * rrrr rrrz >=8KB | ||
291 | * rrrr rrzz >=16KB | ||
292 | * rrrr rzzz >=32KB | ||
293 | * rrrr zzzz >=64KB | ||
294 | * ....... | ||
295 | */ | ||
296 | shift = mmu_psize_defs[i].shift - LP_SHIFT; | ||
297 | if (shift > LP_BITS) | ||
298 | shift = LP_BITS; | ||
299 | mask = (1 << shift) - 1; | ||
300 | if ((lp & mask) == mmu_psize_defs[psize].penc[i]) | ||
301 | return i; | ||
302 | } | ||
303 | return -1; | ||
304 | } | ||
305 | |||
306 | static inline int hpte_actual_psize(struct hash_pte *hptep, int psize) | ||
307 | { | ||
308 | /* Look at the 8 bit LP value */ | ||
309 | unsigned int lp = (hptep->r >> LP_SHIFT) & ((1 << LP_BITS) - 1); | ||
310 | |||
311 | if (!(hptep->v & HPTE_V_VALID)) | ||
312 | return -1; | ||
313 | |||
314 | /* First check if it is large page */ | ||
315 | if (!(hptep->v & HPTE_V_LARGE)) | ||
316 | return MMU_PAGE_4K; | ||
317 | |||
318 | return __hpte_actual_psize(lp, psize); | ||
319 | } | ||
320 | |||
247 | static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, | 321 | static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, |
248 | unsigned long vpn, int psize, int ssize, | 322 | unsigned long vpn, int psize, int ssize, |
249 | int local) | 323 | int local) |
@@ -251,8 +325,9 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, | |||
251 | struct hash_pte *hptep = htab_address + slot; | 325 | struct hash_pte *hptep = htab_address + slot; |
252 | unsigned long hpte_v, want_v; | 326 | unsigned long hpte_v, want_v; |
253 | int ret = 0; | 327 | int ret = 0; |
328 | int actual_psize; | ||
254 | 329 | ||
255 | want_v = hpte_encode_v(vpn, psize, ssize); | 330 | want_v = hpte_encode_avpn(vpn, psize, ssize); |
256 | 331 | ||
257 | DBG_LOW(" update(vpn=%016lx, avpnv=%016lx, group=%lx, newpp=%lx)", | 332 | DBG_LOW(" update(vpn=%016lx, avpnv=%016lx, group=%lx, newpp=%lx)", |
258 | vpn, want_v & HPTE_V_AVPN, slot, newpp); | 333 | vpn, want_v & HPTE_V_AVPN, slot, newpp); |
@@ -260,9 +335,13 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, | |||
260 | native_lock_hpte(hptep); | 335 | native_lock_hpte(hptep); |
261 | 336 | ||
262 | hpte_v = hptep->v; | 337 | hpte_v = hptep->v; |
263 | 338 | actual_psize = hpte_actual_psize(hptep, psize); | |
339 | if (actual_psize < 0) { | ||
340 | native_unlock_hpte(hptep); | ||
341 | return -1; | ||
342 | } | ||
264 | /* Even if we miss, we need to invalidate the TLB */ | 343 | /* Even if we miss, we need to invalidate the TLB */ |
265 | if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) { | 344 | if (!HPTE_V_COMPARE(hpte_v, want_v)) { |
266 | DBG_LOW(" -> miss\n"); | 345 | DBG_LOW(" -> miss\n"); |
267 | ret = -1; | 346 | ret = -1; |
268 | } else { | 347 | } else { |
@@ -274,7 +353,7 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, | |||
274 | native_unlock_hpte(hptep); | 353 | native_unlock_hpte(hptep); |
275 | 354 | ||
276 | /* Ensure it is out of the tlb too. */ | 355 | /* Ensure it is out of the tlb too. */ |
277 | tlbie(vpn, psize, ssize, local); | 356 | tlbie(vpn, psize, actual_psize, ssize, local); |
278 | 357 | ||
279 | return ret; | 358 | return ret; |
280 | } | 359 | } |
@@ -288,7 +367,7 @@ static long native_hpte_find(unsigned long vpn, int psize, int ssize) | |||
288 | unsigned long want_v, hpte_v; | 367 | unsigned long want_v, hpte_v; |
289 | 368 | ||
290 | hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, ssize); | 369 | hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, ssize); |
291 | want_v = hpte_encode_v(vpn, psize, ssize); | 370 | want_v = hpte_encode_avpn(vpn, psize, ssize); |
292 | 371 | ||
293 | /* Bolted mappings are only ever in the primary group */ | 372 | /* Bolted mappings are only ever in the primary group */ |
294 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; | 373 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; |
@@ -315,6 +394,7 @@ static long native_hpte_find(unsigned long vpn, int psize, int ssize) | |||
315 | static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea, | 394 | static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea, |
316 | int psize, int ssize) | 395 | int psize, int ssize) |
317 | { | 396 | { |
397 | int actual_psize; | ||
318 | unsigned long vpn; | 398 | unsigned long vpn; |
319 | unsigned long vsid; | 399 | unsigned long vsid; |
320 | long slot; | 400 | long slot; |
@@ -327,13 +407,16 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea, | |||
327 | if (slot == -1) | 407 | if (slot == -1) |
328 | panic("could not find page to bolt\n"); | 408 | panic("could not find page to bolt\n"); |
329 | hptep = htab_address + slot; | 409 | hptep = htab_address + slot; |
410 | actual_psize = hpte_actual_psize(hptep, psize); | ||
411 | if (actual_psize < 0) | ||
412 | return; | ||
330 | 413 | ||
331 | /* Update the HPTE */ | 414 | /* Update the HPTE */ |
332 | hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) | | 415 | hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) | |
333 | (newpp & (HPTE_R_PP | HPTE_R_N)); | 416 | (newpp & (HPTE_R_PP | HPTE_R_N)); |
334 | 417 | ||
335 | /* Ensure it is out of the tlb too. */ | 418 | /* Ensure it is out of the tlb too. */ |
336 | tlbie(vpn, psize, ssize, 0); | 419 | tlbie(vpn, psize, actual_psize, ssize, 0); |
337 | } | 420 | } |
338 | 421 | ||
339 | static void native_hpte_invalidate(unsigned long slot, unsigned long vpn, | 422 | static void native_hpte_invalidate(unsigned long slot, unsigned long vpn, |
@@ -343,64 +426,60 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn, | |||
343 | unsigned long hpte_v; | 426 | unsigned long hpte_v; |
344 | unsigned long want_v; | 427 | unsigned long want_v; |
345 | unsigned long flags; | 428 | unsigned long flags; |
429 | int actual_psize; | ||
346 | 430 | ||
347 | local_irq_save(flags); | 431 | local_irq_save(flags); |
348 | 432 | ||
349 | DBG_LOW(" invalidate(vpn=%016lx, hash: %lx)\n", vpn, slot); | 433 | DBG_LOW(" invalidate(vpn=%016lx, hash: %lx)\n", vpn, slot); |
350 | 434 | ||
351 | want_v = hpte_encode_v(vpn, psize, ssize); | 435 | want_v = hpte_encode_avpn(vpn, psize, ssize); |
352 | native_lock_hpte(hptep); | 436 | native_lock_hpte(hptep); |
353 | hpte_v = hptep->v; | 437 | hpte_v = hptep->v; |
354 | 438 | ||
439 | actual_psize = hpte_actual_psize(hptep, psize); | ||
440 | if (actual_psize < 0) { | ||
441 | native_unlock_hpte(hptep); | ||
442 | local_irq_restore(flags); | ||
443 | return; | ||
444 | } | ||
355 | /* Even if we miss, we need to invalidate the TLB */ | 445 | /* Even if we miss, we need to invalidate the TLB */ |
356 | if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) | 446 | if (!HPTE_V_COMPARE(hpte_v, want_v)) |
357 | native_unlock_hpte(hptep); | 447 | native_unlock_hpte(hptep); |
358 | else | 448 | else |
359 | /* Invalidate the hpte. NOTE: this also unlocks it */ | 449 | /* Invalidate the hpte. NOTE: this also unlocks it */ |
360 | hptep->v = 0; | 450 | hptep->v = 0; |
361 | 451 | ||
362 | /* Invalidate the TLB */ | 452 | /* Invalidate the TLB */ |
363 | tlbie(vpn, psize, ssize, local); | 453 | tlbie(vpn, psize, actual_psize, ssize, local); |
364 | 454 | ||
365 | local_irq_restore(flags); | 455 | local_irq_restore(flags); |
366 | } | 456 | } |
367 | 457 | ||
368 | #define LP_SHIFT 12 | ||
369 | #define LP_BITS 8 | ||
370 | #define LP_MASK(i) ((0xFF >> (i)) << LP_SHIFT) | ||
371 | |||
372 | static void hpte_decode(struct hash_pte *hpte, unsigned long slot, | 458 | static void hpte_decode(struct hash_pte *hpte, unsigned long slot, |
373 | int *psize, int *ssize, unsigned long *vpn) | 459 | int *psize, int *apsize, int *ssize, unsigned long *vpn) |
374 | { | 460 | { |
375 | unsigned long avpn, pteg, vpi; | 461 | unsigned long avpn, pteg, vpi; |
376 | unsigned long hpte_r = hpte->r; | ||
377 | unsigned long hpte_v = hpte->v; | 462 | unsigned long hpte_v = hpte->v; |
378 | unsigned long vsid, seg_off; | 463 | unsigned long vsid, seg_off; |
379 | int i, size, shift, penc; | 464 | int size, a_size, shift; |
465 | /* Look at the 8 bit LP value */ | ||
466 | unsigned int lp = (hpte->r >> LP_SHIFT) & ((1 << LP_BITS) - 1); | ||
380 | 467 | ||
381 | if (!(hpte_v & HPTE_V_LARGE)) | 468 | if (!(hpte_v & HPTE_V_LARGE)) { |
382 | size = MMU_PAGE_4K; | 469 | size = MMU_PAGE_4K; |
383 | else { | 470 | a_size = MMU_PAGE_4K; |
384 | for (i = 0; i < LP_BITS; i++) { | 471 | } else { |
385 | if ((hpte_r & LP_MASK(i+1)) == LP_MASK(i+1)) | ||
386 | break; | ||
387 | } | ||
388 | penc = LP_MASK(i+1) >> LP_SHIFT; | ||
389 | for (size = 0; size < MMU_PAGE_COUNT; size++) { | 472 | for (size = 0; size < MMU_PAGE_COUNT; size++) { |
390 | 473 | ||
391 | /* 4K pages are not represented by LP */ | ||
392 | if (size == MMU_PAGE_4K) | ||
393 | continue; | ||
394 | |||
395 | /* valid entries have a shift value */ | 474 | /* valid entries have a shift value */ |
396 | if (!mmu_psize_defs[size].shift) | 475 | if (!mmu_psize_defs[size].shift) |
397 | continue; | 476 | continue; |
398 | 477 | ||
399 | if (penc == mmu_psize_defs[size].penc) | 478 | a_size = __hpte_actual_psize(lp, size); |
479 | if (a_size != -1) | ||
400 | break; | 480 | break; |
401 | } | 481 | } |
402 | } | 482 | } |
403 | |||
404 | /* This works for all page sizes, and for 256M and 1T segments */ | 483 | /* This works for all page sizes, and for 256M and 1T segments */ |
405 | *ssize = hpte_v >> HPTE_V_SSIZE_SHIFT; | 484 | *ssize = hpte_v >> HPTE_V_SSIZE_SHIFT; |
406 | shift = mmu_psize_defs[size].shift; | 485 | shift = mmu_psize_defs[size].shift; |
@@ -433,7 +512,8 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot, | |||
433 | default: | 512 | default: |
434 | *vpn = size = 0; | 513 | *vpn = size = 0; |
435 | } | 514 | } |
436 | *psize = size; | 515 | *psize = size; |
516 | *apsize = a_size; | ||
437 | } | 517 | } |
438 | 518 | ||
439 | /* | 519 | /* |
@@ -451,7 +531,7 @@ static void native_hpte_clear(void) | |||
451 | struct hash_pte *hptep = htab_address; | 531 | struct hash_pte *hptep = htab_address; |
452 | unsigned long hpte_v; | 532 | unsigned long hpte_v; |
453 | unsigned long pteg_count; | 533 | unsigned long pteg_count; |
454 | int psize, ssize; | 534 | int psize, apsize, ssize; |
455 | 535 | ||
456 | pteg_count = htab_hash_mask + 1; | 536 | pteg_count = htab_hash_mask + 1; |
457 | 537 | ||
@@ -477,9 +557,9 @@ static void native_hpte_clear(void) | |||
477 | * already hold the native_tlbie_lock. | 557 | * already hold the native_tlbie_lock. |
478 | */ | 558 | */ |
479 | if (hpte_v & HPTE_V_VALID) { | 559 | if (hpte_v & HPTE_V_VALID) { |
480 | hpte_decode(hptep, slot, &psize, &ssize, &vpn); | 560 | hpte_decode(hptep, slot, &psize, &apsize, &ssize, &vpn); |
481 | hptep->v = 0; | 561 | hptep->v = 0; |
482 | __tlbie(vpn, psize, ssize); | 562 | __tlbie(vpn, psize, apsize, ssize); |
483 | } | 563 | } |
484 | } | 564 | } |
485 | 565 | ||
@@ -520,7 +600,7 @@ static void native_flush_hash_range(unsigned long number, int local) | |||
520 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; | 600 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; |
521 | slot += hidx & _PTEIDX_GROUP_IX; | 601 | slot += hidx & _PTEIDX_GROUP_IX; |
522 | hptep = htab_address + slot; | 602 | hptep = htab_address + slot; |
523 | want_v = hpte_encode_v(vpn, psize, ssize); | 603 | want_v = hpte_encode_avpn(vpn, psize, ssize); |
524 | native_lock_hpte(hptep); | 604 | native_lock_hpte(hptep); |
525 | hpte_v = hptep->v; | 605 | hpte_v = hptep->v; |
526 | if (!HPTE_V_COMPARE(hpte_v, want_v) || | 606 | if (!HPTE_V_COMPARE(hpte_v, want_v) || |
@@ -540,7 +620,7 @@ static void native_flush_hash_range(unsigned long number, int local) | |||
540 | 620 | ||
541 | pte_iterate_hashed_subpages(pte, psize, | 621 | pte_iterate_hashed_subpages(pte, psize, |
542 | vpn, index, shift) { | 622 | vpn, index, shift) { |
543 | __tlbiel(vpn, psize, ssize); | 623 | __tlbiel(vpn, psize, psize, ssize); |
544 | } pte_iterate_hashed_end(); | 624 | } pte_iterate_hashed_end(); |
545 | } | 625 | } |
546 | asm volatile("ptesync":::"memory"); | 626 | asm volatile("ptesync":::"memory"); |
@@ -557,7 +637,7 @@ static void native_flush_hash_range(unsigned long number, int local) | |||
557 | 637 | ||
558 | pte_iterate_hashed_subpages(pte, psize, | 638 | pte_iterate_hashed_subpages(pte, psize, |
559 | vpn, index, shift) { | 639 | vpn, index, shift) { |
560 | __tlbie(vpn, psize, ssize); | 640 | __tlbie(vpn, psize, psize, ssize); |
561 | } pte_iterate_hashed_end(); | 641 | } pte_iterate_hashed_end(); |
562 | } | 642 | } |
563 | asm volatile("eieio; tlbsync; ptesync":::"memory"); | 643 | asm volatile("eieio; tlbsync; ptesync":::"memory"); |
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index f410c3e12c1e..3e4c4ed19335 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -126,7 +126,7 @@ static struct mmu_psize_def mmu_psize_defaults_old[] = { | |||
126 | [MMU_PAGE_4K] = { | 126 | [MMU_PAGE_4K] = { |
127 | .shift = 12, | 127 | .shift = 12, |
128 | .sllp = 0, | 128 | .sllp = 0, |
129 | .penc = 0, | 129 | .penc = {[MMU_PAGE_4K] = 0, [1 ... MMU_PAGE_COUNT - 1] = -1}, |
130 | .avpnm = 0, | 130 | .avpnm = 0, |
131 | .tlbiel = 0, | 131 | .tlbiel = 0, |
132 | }, | 132 | }, |
@@ -140,14 +140,15 @@ static struct mmu_psize_def mmu_psize_defaults_gp[] = { | |||
140 | [MMU_PAGE_4K] = { | 140 | [MMU_PAGE_4K] = { |
141 | .shift = 12, | 141 | .shift = 12, |
142 | .sllp = 0, | 142 | .sllp = 0, |
143 | .penc = 0, | 143 | .penc = {[MMU_PAGE_4K] = 0, [1 ... MMU_PAGE_COUNT - 1] = -1}, |
144 | .avpnm = 0, | 144 | .avpnm = 0, |
145 | .tlbiel = 1, | 145 | .tlbiel = 1, |
146 | }, | 146 | }, |
147 | [MMU_PAGE_16M] = { | 147 | [MMU_PAGE_16M] = { |
148 | .shift = 24, | 148 | .shift = 24, |
149 | .sllp = SLB_VSID_L, | 149 | .sllp = SLB_VSID_L, |
150 | .penc = 0, | 150 | .penc = {[0 ... MMU_PAGE_16M - 1] = -1, [MMU_PAGE_16M] = 0, |
151 | [MMU_PAGE_16M + 1 ... MMU_PAGE_COUNT - 1] = -1 }, | ||
151 | .avpnm = 0x1UL, | 152 | .avpnm = 0x1UL, |
152 | .tlbiel = 0, | 153 | .tlbiel = 0, |
153 | }, | 154 | }, |
@@ -209,7 +210,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | |||
209 | 210 | ||
210 | BUG_ON(!ppc_md.hpte_insert); | 211 | BUG_ON(!ppc_md.hpte_insert); |
211 | ret = ppc_md.hpte_insert(hpteg, vpn, paddr, tprot, | 212 | ret = ppc_md.hpte_insert(hpteg, vpn, paddr, tprot, |
212 | HPTE_V_BOLTED, psize, ssize); | 213 | HPTE_V_BOLTED, psize, psize, ssize); |
213 | 214 | ||
214 | if (ret < 0) | 215 | if (ret < 0) |
215 | break; | 216 | break; |
@@ -276,6 +277,30 @@ static void __init htab_init_seg_sizes(void) | |||
276 | of_scan_flat_dt(htab_dt_scan_seg_sizes, NULL); | 277 | of_scan_flat_dt(htab_dt_scan_seg_sizes, NULL); |
277 | } | 278 | } |
278 | 279 | ||
280 | static int __init get_idx_from_shift(unsigned int shift) | ||
281 | { | ||
282 | int idx = -1; | ||
283 | |||
284 | switch (shift) { | ||
285 | case 0xc: | ||
286 | idx = MMU_PAGE_4K; | ||
287 | break; | ||
288 | case 0x10: | ||
289 | idx = MMU_PAGE_64K; | ||
290 | break; | ||
291 | case 0x14: | ||
292 | idx = MMU_PAGE_1M; | ||
293 | break; | ||
294 | case 0x18: | ||
295 | idx = MMU_PAGE_16M; | ||
296 | break; | ||
297 | case 0x22: | ||
298 | idx = MMU_PAGE_16G; | ||
299 | break; | ||
300 | } | ||
301 | return idx; | ||
302 | } | ||
303 | |||
279 | static int __init htab_dt_scan_page_sizes(unsigned long node, | 304 | static int __init htab_dt_scan_page_sizes(unsigned long node, |
280 | const char *uname, int depth, | 305 | const char *uname, int depth, |
281 | void *data) | 306 | void *data) |
@@ -291,64 +316,65 @@ static int __init htab_dt_scan_page_sizes(unsigned long node, | |||
291 | prop = (u32 *)of_get_flat_dt_prop(node, | 316 | prop = (u32 *)of_get_flat_dt_prop(node, |
292 | "ibm,segment-page-sizes", &size); | 317 | "ibm,segment-page-sizes", &size); |
293 | if (prop != NULL) { | 318 | if (prop != NULL) { |
294 | DBG("Page sizes from device-tree:\n"); | 319 | pr_info("Page sizes from device-tree:\n"); |
295 | size /= 4; | 320 | size /= 4; |
296 | cur_cpu_spec->mmu_features &= ~(MMU_FTR_16M_PAGE); | 321 | cur_cpu_spec->mmu_features &= ~(MMU_FTR_16M_PAGE); |
297 | while(size > 0) { | 322 | while(size > 0) { |
298 | unsigned int shift = prop[0]; | 323 | unsigned int base_shift = prop[0]; |
299 | unsigned int slbenc = prop[1]; | 324 | unsigned int slbenc = prop[1]; |
300 | unsigned int lpnum = prop[2]; | 325 | unsigned int lpnum = prop[2]; |
301 | unsigned int lpenc = 0; | ||
302 | struct mmu_psize_def *def; | 326 | struct mmu_psize_def *def; |
303 | int idx = -1; | 327 | int idx, base_idx; |
304 | 328 | ||
305 | size -= 3; prop += 3; | 329 | size -= 3; prop += 3; |
306 | while(size > 0 && lpnum) { | 330 | base_idx = get_idx_from_shift(base_shift); |
307 | if (prop[0] == shift) | 331 | if (base_idx < 0) { |
308 | lpenc = prop[1]; | 332 | /* |
309 | prop += 2; size -= 2; | 333 | * skip the pte encoding also |
310 | lpnum--; | 334 | */ |
335 | prop += lpnum * 2; size -= lpnum * 2; | ||
336 | continue; | ||
311 | } | 337 | } |
312 | switch(shift) { | 338 | def = &mmu_psize_defs[base_idx]; |
313 | case 0xc: | 339 | if (base_idx == MMU_PAGE_16M) |
314 | idx = MMU_PAGE_4K; | ||
315 | break; | ||
316 | case 0x10: | ||
317 | idx = MMU_PAGE_64K; | ||
318 | break; | ||
319 | case 0x14: | ||
320 | idx = MMU_PAGE_1M; | ||
321 | break; | ||
322 | case 0x18: | ||
323 | idx = MMU_PAGE_16M; | ||
324 | cur_cpu_spec->mmu_features |= MMU_FTR_16M_PAGE; | 340 | cur_cpu_spec->mmu_features |= MMU_FTR_16M_PAGE; |
325 | break; | 341 | |
326 | case 0x22: | 342 | def->shift = base_shift; |
327 | idx = MMU_PAGE_16G; | 343 | if (base_shift <= 23) |
328 | break; | ||
329 | } | ||
330 | if (idx < 0) | ||
331 | continue; | ||
332 | def = &mmu_psize_defs[idx]; | ||
333 | def->shift = shift; | ||
334 | if (shift <= 23) | ||
335 | def->avpnm = 0; | 344 | def->avpnm = 0; |
336 | else | 345 | else |
337 | def->avpnm = (1 << (shift - 23)) - 1; | 346 | def->avpnm = (1 << (base_shift - 23)) - 1; |
338 | def->sllp = slbenc; | 347 | def->sllp = slbenc; |
339 | def->penc = lpenc; | 348 | /* |
340 | /* We don't know for sure what's up with tlbiel, so | 349 | * We don't know for sure what's up with tlbiel, so |
341 | * for now we only set it for 4K and 64K pages | 350 | * for now we only set it for 4K and 64K pages |
342 | */ | 351 | */ |
343 | if (idx == MMU_PAGE_4K || idx == MMU_PAGE_64K) | 352 | if (base_idx == MMU_PAGE_4K || base_idx == MMU_PAGE_64K) |
344 | def->tlbiel = 1; | 353 | def->tlbiel = 1; |
345 | else | 354 | else |
346 | def->tlbiel = 0; | 355 | def->tlbiel = 0; |
347 | 356 | ||
348 | DBG(" %d: shift=%02x, sllp=%04lx, avpnm=%08lx, " | 357 | while (size > 0 && lpnum) { |
349 | "tlbiel=%d, penc=%d\n", | 358 | unsigned int shift = prop[0]; |
350 | idx, shift, def->sllp, def->avpnm, def->tlbiel, | 359 | int penc = prop[1]; |
351 | def->penc); | 360 | |
361 | prop += 2; size -= 2; | ||
362 | lpnum--; | ||
363 | |||
364 | idx = get_idx_from_shift(shift); | ||
365 | if (idx < 0) | ||
366 | continue; | ||
367 | |||
368 | if (penc == -1) | ||
369 | pr_err("Invalid penc for base_shift=%d " | ||
370 | "shift=%d\n", base_shift, shift); | ||
371 | |||
372 | def->penc[idx] = penc; | ||
373 | pr_info("base_shift=%d: shift=%d, sllp=0x%04lx," | ||
374 | " avpnm=0x%08lx, tlbiel=%d, penc=%d\n", | ||
375 | base_shift, shift, def->sllp, | ||
376 | def->avpnm, def->tlbiel, def->penc[idx]); | ||
377 | } | ||
352 | } | 378 | } |
353 | return 1; | 379 | return 1; |
354 | } | 380 | } |
@@ -397,10 +423,21 @@ static int __init htab_dt_scan_hugepage_blocks(unsigned long node, | |||
397 | } | 423 | } |
398 | #endif /* CONFIG_HUGETLB_PAGE */ | 424 | #endif /* CONFIG_HUGETLB_PAGE */ |
399 | 425 | ||
426 | static void mmu_psize_set_default_penc(void) | ||
427 | { | ||
428 | int bpsize, apsize; | ||
429 | for (bpsize = 0; bpsize < MMU_PAGE_COUNT; bpsize++) | ||
430 | for (apsize = 0; apsize < MMU_PAGE_COUNT; apsize++) | ||
431 | mmu_psize_defs[bpsize].penc[apsize] = -1; | ||
432 | } | ||
433 | |||
400 | static void __init htab_init_page_sizes(void) | 434 | static void __init htab_init_page_sizes(void) |
401 | { | 435 | { |
402 | int rc; | 436 | int rc; |
403 | 437 | ||
438 | /* se the invalid penc to -1 */ | ||
439 | mmu_psize_set_default_penc(); | ||
440 | |||
404 | /* Default to 4K pages only */ | 441 | /* Default to 4K pages only */ |
405 | memcpy(mmu_psize_defs, mmu_psize_defaults_old, | 442 | memcpy(mmu_psize_defs, mmu_psize_defaults_old, |
406 | sizeof(mmu_psize_defaults_old)); | 443 | sizeof(mmu_psize_defaults_old)); |
@@ -899,14 +936,14 @@ static inline int subpage_protection(struct mm_struct *mm, unsigned long ea) | |||
899 | 936 | ||
900 | void hash_failure_debug(unsigned long ea, unsigned long access, | 937 | void hash_failure_debug(unsigned long ea, unsigned long access, |
901 | unsigned long vsid, unsigned long trap, | 938 | unsigned long vsid, unsigned long trap, |
902 | int ssize, int psize, unsigned long pte) | 939 | int ssize, int psize, int lpsize, unsigned long pte) |
903 | { | 940 | { |
904 | if (!printk_ratelimit()) | 941 | if (!printk_ratelimit()) |
905 | return; | 942 | return; |
906 | pr_info("mm: Hashing failure ! EA=0x%lx access=0x%lx current=%s\n", | 943 | pr_info("mm: Hashing failure ! EA=0x%lx access=0x%lx current=%s\n", |
907 | ea, access, current->comm); | 944 | ea, access, current->comm); |
908 | pr_info(" trap=0x%lx vsid=0x%lx ssize=%d psize=%d pte=0x%lx\n", | 945 | pr_info(" trap=0x%lx vsid=0x%lx ssize=%d base psize=%d psize %d pte=0x%lx\n", |
909 | trap, vsid, ssize, psize, pte); | 946 | trap, vsid, ssize, psize, lpsize, pte); |
910 | } | 947 | } |
911 | 948 | ||
912 | /* Result code is: | 949 | /* Result code is: |
@@ -1079,7 +1116,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
1079 | */ | 1116 | */ |
1080 | if (rc == -1) | 1117 | if (rc == -1) |
1081 | hash_failure_debug(ea, access, vsid, trap, ssize, psize, | 1118 | hash_failure_debug(ea, access, vsid, trap, ssize, psize, |
1082 | pte_val(*ptep)); | 1119 | psize, pte_val(*ptep)); |
1083 | #ifndef CONFIG_PPC_64K_PAGES | 1120 | #ifndef CONFIG_PPC_64K_PAGES |
1084 | DBG_LOW(" o-pte: %016lx\n", pte_val(*ptep)); | 1121 | DBG_LOW(" o-pte: %016lx\n", pte_val(*ptep)); |
1085 | #else | 1122 | #else |
@@ -1157,7 +1194,9 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, | |||
1157 | */ | 1194 | */ |
1158 | if (rc == -1) | 1195 | if (rc == -1) |
1159 | hash_failure_debug(ea, access, vsid, trap, ssize, | 1196 | hash_failure_debug(ea, access, vsid, trap, ssize, |
1160 | mm->context.user_psize, pte_val(*ptep)); | 1197 | mm->context.user_psize, |
1198 | mm->context.user_psize, | ||
1199 | pte_val(*ptep)); | ||
1161 | 1200 | ||
1162 | local_irq_restore(flags); | 1201 | local_irq_restore(flags); |
1163 | } | 1202 | } |
@@ -1230,24 +1269,60 @@ void low_hash_fault(struct pt_regs *regs, unsigned long address, int rc) | |||
1230 | bad_page_fault(regs, address, SIGBUS); | 1269 | bad_page_fault(regs, address, SIGBUS); |
1231 | } | 1270 | } |
1232 | 1271 | ||
1272 | long hpte_insert_repeating(unsigned long hash, unsigned long vpn, | ||
1273 | unsigned long pa, unsigned long rflags, | ||
1274 | unsigned long vflags, int psize, int ssize) | ||
1275 | { | ||
1276 | unsigned long hpte_group; | ||
1277 | long slot; | ||
1278 | |||
1279 | repeat: | ||
1280 | hpte_group = ((hash & htab_hash_mask) * | ||
1281 | HPTES_PER_GROUP) & ~0x7UL; | ||
1282 | |||
1283 | /* Insert into the hash table, primary slot */ | ||
1284 | slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, vflags, | ||
1285 | psize, psize, ssize); | ||
1286 | |||
1287 | /* Primary is full, try the secondary */ | ||
1288 | if (unlikely(slot == -1)) { | ||
1289 | hpte_group = ((~hash & htab_hash_mask) * | ||
1290 | HPTES_PER_GROUP) & ~0x7UL; | ||
1291 | slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, | ||
1292 | vflags | HPTE_V_SECONDARY, | ||
1293 | psize, psize, ssize); | ||
1294 | if (slot == -1) { | ||
1295 | if (mftb() & 0x1) | ||
1296 | hpte_group = ((hash & htab_hash_mask) * | ||
1297 | HPTES_PER_GROUP)&~0x7UL; | ||
1298 | |||
1299 | ppc_md.hpte_remove(hpte_group); | ||
1300 | goto repeat; | ||
1301 | } | ||
1302 | } | ||
1303 | |||
1304 | return slot; | ||
1305 | } | ||
1306 | |||
1233 | #ifdef CONFIG_DEBUG_PAGEALLOC | 1307 | #ifdef CONFIG_DEBUG_PAGEALLOC |
1234 | static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) | 1308 | static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) |
1235 | { | 1309 | { |
1236 | unsigned long hash, hpteg; | 1310 | unsigned long hash; |
1237 | unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize); | 1311 | unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize); |
1238 | unsigned long vpn = hpt_vpn(vaddr, vsid, mmu_kernel_ssize); | 1312 | unsigned long vpn = hpt_vpn(vaddr, vsid, mmu_kernel_ssize); |
1239 | unsigned long mode = htab_convert_pte_flags(PAGE_KERNEL); | 1313 | unsigned long mode = htab_convert_pte_flags(PAGE_KERNEL); |
1240 | int ret; | 1314 | long ret; |
1241 | 1315 | ||
1242 | hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize); | 1316 | hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize); |
1243 | hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); | ||
1244 | 1317 | ||
1245 | /* Don't create HPTE entries for bad address */ | 1318 | /* Don't create HPTE entries for bad address */ |
1246 | if (!vsid) | 1319 | if (!vsid) |
1247 | return; | 1320 | return; |
1248 | ret = ppc_md.hpte_insert(hpteg, vpn, __pa(vaddr), | 1321 | |
1249 | mode, HPTE_V_BOLTED, | 1322 | ret = hpte_insert_repeating(hash, vpn, __pa(vaddr), mode, |
1250 | mmu_linear_psize, mmu_kernel_ssize); | 1323 | HPTE_V_BOLTED, |
1324 | mmu_linear_psize, mmu_kernel_ssize); | ||
1325 | |||
1251 | BUG_ON (ret < 0); | 1326 | BUG_ON (ret < 0); |
1252 | spin_lock(&linear_map_hash_lock); | 1327 | spin_lock(&linear_map_hash_lock); |
1253 | BUG_ON(linear_map_hash_slots[lmi] & 0x80); | 1328 | BUG_ON(linear_map_hash_slots[lmi] & 0x80); |
diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c index cecad348f604..0f1d94a1fb82 100644 --- a/arch/powerpc/mm/hugetlbpage-hash64.c +++ b/arch/powerpc/mm/hugetlbpage-hash64.c | |||
@@ -14,6 +14,10 @@ | |||
14 | #include <asm/cacheflush.h> | 14 | #include <asm/cacheflush.h> |
15 | #include <asm/machdep.h> | 15 | #include <asm/machdep.h> |
16 | 16 | ||
17 | extern long hpte_insert_repeating(unsigned long hash, unsigned long vpn, | ||
18 | unsigned long pa, unsigned long rlags, | ||
19 | unsigned long vflags, int psize, int ssize); | ||
20 | |||
17 | int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, | 21 | int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, |
18 | pte_t *ptep, unsigned long trap, int local, int ssize, | 22 | pte_t *ptep, unsigned long trap, int local, int ssize, |
19 | unsigned int shift, unsigned int mmu_psize) | 23 | unsigned int shift, unsigned int mmu_psize) |
@@ -83,14 +87,9 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, | |||
83 | 87 | ||
84 | if (likely(!(old_pte & _PAGE_HASHPTE))) { | 88 | if (likely(!(old_pte & _PAGE_HASHPTE))) { |
85 | unsigned long hash = hpt_hash(vpn, shift, ssize); | 89 | unsigned long hash = hpt_hash(vpn, shift, ssize); |
86 | unsigned long hpte_group; | ||
87 | 90 | ||
88 | pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT; | 91 | pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT; |
89 | 92 | ||
90 | repeat: | ||
91 | hpte_group = ((hash & htab_hash_mask) * | ||
92 | HPTES_PER_GROUP) & ~0x7UL; | ||
93 | |||
94 | /* clear HPTE slot informations in new PTE */ | 93 | /* clear HPTE slot informations in new PTE */ |
95 | #ifdef CONFIG_PPC_64K_PAGES | 94 | #ifdef CONFIG_PPC_64K_PAGES |
96 | new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HPTE_SUB0; | 95 | new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HPTE_SUB0; |
@@ -101,26 +100,8 @@ repeat: | |||
101 | rflags |= (new_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE | | 100 | rflags |= (new_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE | |
102 | _PAGE_COHERENT | _PAGE_GUARDED)); | 101 | _PAGE_COHERENT | _PAGE_GUARDED)); |
103 | 102 | ||
104 | /* Insert into the hash table, primary slot */ | 103 | slot = hpte_insert_repeating(hash, vpn, pa, rflags, 0, |
105 | slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, 0, | 104 | mmu_psize, ssize); |
106 | mmu_psize, ssize); | ||
107 | |||
108 | /* Primary is full, try the secondary */ | ||
109 | if (unlikely(slot == -1)) { | ||
110 | hpte_group = ((~hash & htab_hash_mask) * | ||
111 | HPTES_PER_GROUP) & ~0x7UL; | ||
112 | slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, | ||
113 | HPTE_V_SECONDARY, | ||
114 | mmu_psize, ssize); | ||
115 | if (slot == -1) { | ||
116 | if (mftb() & 0x1) | ||
117 | hpte_group = ((hash & htab_hash_mask) * | ||
118 | HPTES_PER_GROUP)&~0x7UL; | ||
119 | |||
120 | ppc_md.hpte_remove(hpte_group); | ||
121 | goto repeat; | ||
122 | } | ||
123 | } | ||
124 | 105 | ||
125 | /* | 106 | /* |
126 | * Hypervisor failure. Restore old pte and return -1 | 107 | * Hypervisor failure. Restore old pte and return -1 |
@@ -129,7 +110,7 @@ repeat: | |||
129 | if (unlikely(slot == -2)) { | 110 | if (unlikely(slot == -2)) { |
130 | *ptep = __pte(old_pte); | 111 | *ptep = __pte(old_pte); |
131 | hash_failure_debug(ea, access, vsid, trap, ssize, | 112 | hash_failure_debug(ea, access, vsid, trap, ssize, |
132 | mmu_psize, old_pte); | 113 | mmu_psize, mmu_psize, old_pte); |
133 | return -1; | 114 | return -1; |
134 | } | 115 | } |
135 | 116 | ||
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 1a6de0a7d8eb..237c8e5f2640 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c | |||
@@ -48,30 +48,71 @@ static u64 gpage_freearray[MAX_NUMBER_GPAGES]; | |||
48 | static unsigned nr_gpages; | 48 | static unsigned nr_gpages; |
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | static inline int shift_to_mmu_psize(unsigned int shift) | 51 | #define hugepd_none(hpd) ((hpd).pd == 0) |
52 | |||
53 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
54 | /* | ||
55 | * At this point we do the placement change only for BOOK3S 64. This would | ||
56 | * possibly work on other subarchs. | ||
57 | */ | ||
58 | |||
59 | /* | ||
60 | * We have PGD_INDEX_SIZ = 12 and PTE_INDEX_SIZE = 8, so that we can have | ||
61 | * 16GB hugepage pte in PGD and 16MB hugepage pte at PMD; | ||
62 | */ | ||
63 | int pmd_huge(pmd_t pmd) | ||
52 | { | 64 | { |
53 | int psize; | 65 | /* |
66 | * leaf pte for huge page, bottom two bits != 00 | ||
67 | */ | ||
68 | return ((pmd_val(pmd) & 0x3) != 0x0); | ||
69 | } | ||
54 | 70 | ||
55 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) | 71 | int pud_huge(pud_t pud) |
56 | if (mmu_psize_defs[psize].shift == shift) | 72 | { |
57 | return psize; | 73 | /* |
58 | return -1; | 74 | * leaf pte for huge page, bottom two bits != 00 |
75 | */ | ||
76 | return ((pud_val(pud) & 0x3) != 0x0); | ||
59 | } | 77 | } |
60 | 78 | ||
61 | static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize) | 79 | int pgd_huge(pgd_t pgd) |
62 | { | 80 | { |
63 | if (mmu_psize_defs[mmu_psize].shift) | 81 | /* |
64 | return mmu_psize_defs[mmu_psize].shift; | 82 | * leaf pte for huge page, bottom two bits != 00 |
65 | BUG(); | 83 | */ |
84 | return ((pgd_val(pgd) & 0x3) != 0x0); | ||
85 | } | ||
86 | #else | ||
87 | int pmd_huge(pmd_t pmd) | ||
88 | { | ||
89 | return 0; | ||
66 | } | 90 | } |
67 | 91 | ||
68 | #define hugepd_none(hpd) ((hpd).pd == 0) | 92 | int pud_huge(pud_t pud) |
93 | { | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | int pgd_huge(pgd_t pgd) | ||
98 | { | ||
99 | return 0; | ||
100 | } | ||
101 | #endif | ||
69 | 102 | ||
103 | /* | ||
104 | * We have 4 cases for pgds and pmds: | ||
105 | * (1) invalid (all zeroes) | ||
106 | * (2) pointer to next table, as normal; bottom 6 bits == 0 | ||
107 | * (3) leaf pte for huge page, bottom two bits != 00 | ||
108 | * (4) hugepd pointer, bottom two bits == 00, next 4 bits indicate size of table | ||
109 | */ | ||
70 | pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift) | 110 | pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift) |
71 | { | 111 | { |
72 | pgd_t *pg; | 112 | pgd_t *pg; |
73 | pud_t *pu; | 113 | pud_t *pu; |
74 | pmd_t *pm; | 114 | pmd_t *pm; |
115 | pte_t *ret_pte; | ||
75 | hugepd_t *hpdp = NULL; | 116 | hugepd_t *hpdp = NULL; |
76 | unsigned pdshift = PGDIR_SHIFT; | 117 | unsigned pdshift = PGDIR_SHIFT; |
77 | 118 | ||
@@ -79,30 +120,43 @@ pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift | |||
79 | *shift = 0; | 120 | *shift = 0; |
80 | 121 | ||
81 | pg = pgdir + pgd_index(ea); | 122 | pg = pgdir + pgd_index(ea); |
82 | if (is_hugepd(pg)) { | 123 | |
124 | if (pgd_huge(*pg)) { | ||
125 | ret_pte = (pte_t *) pg; | ||
126 | goto out; | ||
127 | } else if (is_hugepd(pg)) | ||
83 | hpdp = (hugepd_t *)pg; | 128 | hpdp = (hugepd_t *)pg; |
84 | } else if (!pgd_none(*pg)) { | 129 | else if (!pgd_none(*pg)) { |
85 | pdshift = PUD_SHIFT; | 130 | pdshift = PUD_SHIFT; |
86 | pu = pud_offset(pg, ea); | 131 | pu = pud_offset(pg, ea); |
87 | if (is_hugepd(pu)) | 132 | |
133 | if (pud_huge(*pu)) { | ||
134 | ret_pte = (pte_t *) pu; | ||
135 | goto out; | ||
136 | } else if (is_hugepd(pu)) | ||
88 | hpdp = (hugepd_t *)pu; | 137 | hpdp = (hugepd_t *)pu; |
89 | else if (!pud_none(*pu)) { | 138 | else if (!pud_none(*pu)) { |
90 | pdshift = PMD_SHIFT; | 139 | pdshift = PMD_SHIFT; |
91 | pm = pmd_offset(pu, ea); | 140 | pm = pmd_offset(pu, ea); |
92 | if (is_hugepd(pm)) | 141 | |
142 | if (pmd_huge(*pm)) { | ||
143 | ret_pte = (pte_t *) pm; | ||
144 | goto out; | ||
145 | } else if (is_hugepd(pm)) | ||
93 | hpdp = (hugepd_t *)pm; | 146 | hpdp = (hugepd_t *)pm; |
94 | else if (!pmd_none(*pm)) { | 147 | else if (!pmd_none(*pm)) |
95 | return pte_offset_kernel(pm, ea); | 148 | return pte_offset_kernel(pm, ea); |
96 | } | ||
97 | } | 149 | } |
98 | } | 150 | } |
99 | |||
100 | if (!hpdp) | 151 | if (!hpdp) |
101 | return NULL; | 152 | return NULL; |
102 | 153 | ||
154 | ret_pte = hugepte_offset(hpdp, ea, pdshift); | ||
155 | pdshift = hugepd_shift(*hpdp); | ||
156 | out: | ||
103 | if (shift) | 157 | if (shift) |
104 | *shift = hugepd_shift(*hpdp); | 158 | *shift = pdshift; |
105 | return hugepte_offset(hpdp, ea, pdshift); | 159 | return ret_pte; |
106 | } | 160 | } |
107 | EXPORT_SYMBOL_GPL(find_linux_pte_or_hugepte); | 161 | EXPORT_SYMBOL_GPL(find_linux_pte_or_hugepte); |
108 | 162 | ||
@@ -145,6 +199,7 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, | |||
145 | if (unlikely(!hugepd_none(*hpdp))) | 199 | if (unlikely(!hugepd_none(*hpdp))) |
146 | break; | 200 | break; |
147 | else | 201 | else |
202 | /* We use the old format for PPC_FSL_BOOK3E */ | ||
148 | hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift; | 203 | hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift; |
149 | } | 204 | } |
150 | /* If we bailed from the for loop early, an error occurred, clean up */ | 205 | /* If we bailed from the for loop early, an error occurred, clean up */ |
@@ -156,9 +211,15 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, | |||
156 | #else | 211 | #else |
157 | if (!hugepd_none(*hpdp)) | 212 | if (!hugepd_none(*hpdp)) |
158 | kmem_cache_free(cachep, new); | 213 | kmem_cache_free(cachep, new); |
159 | else | 214 | else { |
215 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
216 | hpdp->pd = (unsigned long)new | | ||
217 | (shift_to_mmu_psize(pshift) << 2); | ||
218 | #else | ||
160 | hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift; | 219 | hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift; |
161 | #endif | 220 | #endif |
221 | } | ||
222 | #endif | ||
162 | spin_unlock(&mm->page_table_lock); | 223 | spin_unlock(&mm->page_table_lock); |
163 | return 0; | 224 | return 0; |
164 | } | 225 | } |
@@ -175,6 +236,61 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, | |||
175 | #define HUGEPD_PUD_SHIFT PMD_SHIFT | 236 | #define HUGEPD_PUD_SHIFT PMD_SHIFT |
176 | #endif | 237 | #endif |
177 | 238 | ||
239 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
240 | /* | ||
241 | * At this point we do the placement change only for BOOK3S 64. This would | ||
242 | * possibly work on other subarchs. | ||
243 | */ | ||
244 | pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz) | ||
245 | { | ||
246 | pgd_t *pg; | ||
247 | pud_t *pu; | ||
248 | pmd_t *pm; | ||
249 | hugepd_t *hpdp = NULL; | ||
250 | unsigned pshift = __ffs(sz); | ||
251 | unsigned pdshift = PGDIR_SHIFT; | ||
252 | |||
253 | addr &= ~(sz-1); | ||
254 | pg = pgd_offset(mm, addr); | ||
255 | |||
256 | if (pshift == PGDIR_SHIFT) | ||
257 | /* 16GB huge page */ | ||
258 | return (pte_t *) pg; | ||
259 | else if (pshift > PUD_SHIFT) | ||
260 | /* | ||
261 | * We need to use hugepd table | ||
262 | */ | ||
263 | hpdp = (hugepd_t *)pg; | ||
264 | else { | ||
265 | pdshift = PUD_SHIFT; | ||
266 | pu = pud_alloc(mm, pg, addr); | ||
267 | if (pshift == PUD_SHIFT) | ||
268 | return (pte_t *)pu; | ||
269 | else if (pshift > PMD_SHIFT) | ||
270 | hpdp = (hugepd_t *)pu; | ||
271 | else { | ||
272 | pdshift = PMD_SHIFT; | ||
273 | pm = pmd_alloc(mm, pu, addr); | ||
274 | if (pshift == PMD_SHIFT) | ||
275 | /* 16MB hugepage */ | ||
276 | return (pte_t *)pm; | ||
277 | else | ||
278 | hpdp = (hugepd_t *)pm; | ||
279 | } | ||
280 | } | ||
281 | if (!hpdp) | ||
282 | return NULL; | ||
283 | |||
284 | BUG_ON(!hugepd_none(*hpdp) && !hugepd_ok(*hpdp)); | ||
285 | |||
286 | if (hugepd_none(*hpdp) && __hugepte_alloc(mm, hpdp, addr, pdshift, pshift)) | ||
287 | return NULL; | ||
288 | |||
289 | return hugepte_offset(hpdp, addr, pdshift); | ||
290 | } | ||
291 | |||
292 | #else | ||
293 | |||
178 | pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz) | 294 | pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz) |
179 | { | 295 | { |
180 | pgd_t *pg; | 296 | pgd_t *pg; |
@@ -212,6 +328,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz | |||
212 | 328 | ||
213 | return hugepte_offset(hpdp, addr, pdshift); | 329 | return hugepte_offset(hpdp, addr, pdshift); |
214 | } | 330 | } |
331 | #endif | ||
215 | 332 | ||
216 | #ifdef CONFIG_PPC_FSL_BOOK3E | 333 | #ifdef CONFIG_PPC_FSL_BOOK3E |
217 | /* Build list of addresses of gigantic pages. This function is used in early | 334 | /* Build list of addresses of gigantic pages. This function is used in early |
@@ -475,7 +592,7 @@ static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud, | |||
475 | do { | 592 | do { |
476 | pmd = pmd_offset(pud, addr); | 593 | pmd = pmd_offset(pud, addr); |
477 | next = pmd_addr_end(addr, end); | 594 | next = pmd_addr_end(addr, end); |
478 | if (pmd_none(*pmd)) | 595 | if (pmd_none_or_clear_bad(pmd)) |
479 | continue; | 596 | continue; |
480 | #ifdef CONFIG_PPC_FSL_BOOK3E | 597 | #ifdef CONFIG_PPC_FSL_BOOK3E |
481 | /* | 598 | /* |
@@ -628,16 +745,6 @@ follow_huge_addr(struct mm_struct *mm, unsigned long address, int write) | |||
628 | return page; | 745 | return page; |
629 | } | 746 | } |
630 | 747 | ||
631 | int pmd_huge(pmd_t pmd) | ||
632 | { | ||
633 | return 0; | ||
634 | } | ||
635 | |||
636 | int pud_huge(pud_t pud) | ||
637 | { | ||
638 | return 0; | ||
639 | } | ||
640 | |||
641 | struct page * | 748 | struct page * |
642 | follow_huge_pmd(struct mm_struct *mm, unsigned long address, | 749 | follow_huge_pmd(struct mm_struct *mm, unsigned long address, |
643 | pmd_t *pmd, int write) | 750 | pmd_t *pmd, int write) |
@@ -646,8 +753,8 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address, | |||
646 | return NULL; | 753 | return NULL; |
647 | } | 754 | } |
648 | 755 | ||
649 | static noinline int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, | 756 | int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, |
650 | unsigned long end, int write, struct page **pages, int *nr) | 757 | unsigned long end, int write, struct page **pages, int *nr) |
651 | { | 758 | { |
652 | unsigned long mask; | 759 | unsigned long mask; |
653 | unsigned long pte_end; | 760 | unsigned long pte_end; |
@@ -742,7 +849,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, | |||
742 | struct hstate *hstate = hstate_file(file); | 849 | struct hstate *hstate = hstate_file(file); |
743 | int mmu_psize = shift_to_mmu_psize(huge_page_shift(hstate)); | 850 | int mmu_psize = shift_to_mmu_psize(huge_page_shift(hstate)); |
744 | 851 | ||
745 | return slice_get_unmapped_area(addr, len, flags, mmu_psize, 1, 0); | 852 | return slice_get_unmapped_area(addr, len, flags, mmu_psize, 1); |
746 | } | 853 | } |
747 | #endif | 854 | #endif |
748 | 855 | ||
@@ -883,11 +990,16 @@ static int __init hugetlbpage_init(void) | |||
883 | pdshift = PUD_SHIFT; | 990 | pdshift = PUD_SHIFT; |
884 | else | 991 | else |
885 | pdshift = PGDIR_SHIFT; | 992 | pdshift = PGDIR_SHIFT; |
886 | 993 | /* | |
887 | pgtable_cache_add(pdshift - shift, NULL); | 994 | * if we have pdshift and shift value same, we don't |
888 | if (!PGT_CACHE(pdshift - shift)) | 995 | * use pgt cache for hugepd. |
889 | panic("hugetlbpage_init(): could not create " | 996 | */ |
890 | "pgtable cache for %d bit pagesize\n", shift); | 997 | if (pdshift != shift) { |
998 | pgtable_cache_add(pdshift - shift, NULL); | ||
999 | if (!PGT_CACHE(pdshift - shift)) | ||
1000 | panic("hugetlbpage_init(): could not create " | ||
1001 | "pgtable cache for %d bit pagesize\n", shift); | ||
1002 | } | ||
891 | } | 1003 | } |
892 | 1004 | ||
893 | /* Set default large page size. Currently, we pick 16M or 1M | 1005 | /* Set default large page size. Currently, we pick 16M or 1M |
diff --git a/arch/powerpc/mm/icswx.c b/arch/powerpc/mm/icswx.c index 8cdbd8634a58..915412e4d5ba 100644 --- a/arch/powerpc/mm/icswx.c +++ b/arch/powerpc/mm/icswx.c | |||
@@ -67,7 +67,7 @@ | |||
67 | 67 | ||
68 | void switch_cop(struct mm_struct *next) | 68 | void switch_cop(struct mm_struct *next) |
69 | { | 69 | { |
70 | #ifdef CONFIG_ICSWX_PID | 70 | #ifdef CONFIG_PPC_ICSWX_PID |
71 | mtspr(SPRN_PID, next->context.cop_pid); | 71 | mtspr(SPRN_PID, next->context.cop_pid); |
72 | #endif | 72 | #endif |
73 | mtspr(SPRN_ACOP, next->context.acop); | 73 | mtspr(SPRN_ACOP, next->context.acop); |
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 7e2246fb2f31..c2787bf779ca 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c | |||
@@ -129,8 +129,7 @@ void pgtable_cache_add(unsigned shift, void (*ctor)(void *)) | |||
129 | align = max_t(unsigned long, align, minalign); | 129 | align = max_t(unsigned long, align, minalign); |
130 | name = kasprintf(GFP_KERNEL, "pgtable-2^%d", shift); | 130 | name = kasprintf(GFP_KERNEL, "pgtable-2^%d", shift); |
131 | new = kmem_cache_create(name, table_size, align, 0, ctor); | 131 | new = kmem_cache_create(name, table_size, align, 0, ctor); |
132 | PGT_CACHE(shift) = new; | 132 | pgtable_cache[shift - 1] = new; |
133 | |||
134 | pr_debug("Allocated pgtable cache for order %d\n", shift); | 133 | pr_debug("Allocated pgtable cache for order %d\n", shift); |
135 | } | 134 | } |
136 | 135 | ||
@@ -263,19 +262,14 @@ static __meminit void vmemmap_list_populate(unsigned long phys, | |||
263 | vmemmap_list = vmem_back; | 262 | vmemmap_list = vmem_back; |
264 | } | 263 | } |
265 | 264 | ||
266 | int __meminit vmemmap_populate(struct page *start_page, | 265 | int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) |
267 | unsigned long nr_pages, int node) | ||
268 | { | 266 | { |
269 | unsigned long start = (unsigned long)start_page; | ||
270 | unsigned long end = (unsigned long)(start_page + nr_pages); | ||
271 | unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift; | 267 | unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift; |
272 | 268 | ||
273 | /* Align to the page size of the linear mapping. */ | 269 | /* Align to the page size of the linear mapping. */ |
274 | start = _ALIGN_DOWN(start, page_size); | 270 | start = _ALIGN_DOWN(start, page_size); |
275 | 271 | ||
276 | pr_debug("vmemmap_populate page %p, %ld pages, node %d\n", | 272 | pr_debug("vmemmap_populate %lx..%lx, node %d\n", start, end, node); |
277 | start_page, nr_pages, node); | ||
278 | pr_debug(" -> map %lx..%lx\n", start, end); | ||
279 | 273 | ||
280 | for (; start < end; start += page_size) { | 274 | for (; start < end; start += page_size) { |
281 | void *p; | 275 | void *p; |
@@ -298,7 +292,7 @@ int __meminit vmemmap_populate(struct page *start_page, | |||
298 | return 0; | 292 | return 0; |
299 | } | 293 | } |
300 | 294 | ||
301 | void vmemmap_free(struct page *memmap, unsigned long nr_pages) | 295 | void vmemmap_free(unsigned long start, unsigned long end) |
302 | { | 296 | { |
303 | } | 297 | } |
304 | 298 | ||
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index f1f7409a4183..0988a26e0413 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c | |||
@@ -66,10 +66,9 @@ unsigned long long memory_limit; | |||
66 | 66 | ||
67 | #ifdef CONFIG_HIGHMEM | 67 | #ifdef CONFIG_HIGHMEM |
68 | pte_t *kmap_pte; | 68 | pte_t *kmap_pte; |
69 | EXPORT_SYMBOL(kmap_pte); | ||
69 | pgprot_t kmap_prot; | 70 | pgprot_t kmap_prot; |
70 | |||
71 | EXPORT_SYMBOL(kmap_prot); | 71 | EXPORT_SYMBOL(kmap_prot); |
72 | EXPORT_SYMBOL(kmap_pte); | ||
73 | 72 | ||
74 | static inline pte_t *virt_to_kpte(unsigned long vaddr) | 73 | static inline pte_t *virt_to_kpte(unsigned long vaddr) |
75 | { | 74 | { |
@@ -352,13 +351,9 @@ void __init mem_init(void) | |||
352 | struct page *page = pfn_to_page(pfn); | 351 | struct page *page = pfn_to_page(pfn); |
353 | if (memblock_is_reserved(paddr)) | 352 | if (memblock_is_reserved(paddr)) |
354 | continue; | 353 | continue; |
355 | ClearPageReserved(page); | 354 | free_highmem_page(page); |
356 | init_page_count(page); | ||
357 | __free_page(page); | ||
358 | totalhigh_pages++; | ||
359 | reservedpages--; | 355 | reservedpages--; |
360 | } | 356 | } |
361 | totalram_pages += totalhigh_pages; | ||
362 | printk(KERN_DEBUG "High memory: %luk\n", | 357 | printk(KERN_DEBUG "High memory: %luk\n", |
363 | totalhigh_pages << (PAGE_SHIFT-10)); | 358 | totalhigh_pages << (PAGE_SHIFT-10)); |
364 | } | 359 | } |
@@ -405,39 +400,14 @@ void __init mem_init(void) | |||
405 | 400 | ||
406 | void free_initmem(void) | 401 | void free_initmem(void) |
407 | { | 402 | { |
408 | unsigned long addr; | ||
409 | |||
410 | ppc_md.progress = ppc_printk_progress; | 403 | ppc_md.progress = ppc_printk_progress; |
411 | 404 | free_initmem_default(POISON_FREE_INITMEM); | |
412 | addr = (unsigned long)__init_begin; | ||
413 | for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) { | ||
414 | memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); | ||
415 | ClearPageReserved(virt_to_page(addr)); | ||
416 | init_page_count(virt_to_page(addr)); | ||
417 | free_page(addr); | ||
418 | totalram_pages++; | ||
419 | } | ||
420 | pr_info("Freeing unused kernel memory: %luk freed\n", | ||
421 | ((unsigned long)__init_end - | ||
422 | (unsigned long)__init_begin) >> 10); | ||
423 | } | 405 | } |
424 | 406 | ||
425 | #ifdef CONFIG_BLK_DEV_INITRD | 407 | #ifdef CONFIG_BLK_DEV_INITRD |
426 | void __init free_initrd_mem(unsigned long start, unsigned long end) | 408 | void __init free_initrd_mem(unsigned long start, unsigned long end) |
427 | { | 409 | { |
428 | if (start >= end) | 410 | free_reserved_area(start, end, 0, "initrd"); |
429 | return; | ||
430 | |||
431 | start = _ALIGN_DOWN(start, PAGE_SIZE); | ||
432 | end = _ALIGN_UP(end, PAGE_SIZE); | ||
433 | pr_info("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); | ||
434 | |||
435 | for (; start < end; start += PAGE_SIZE) { | ||
436 | ClearPageReserved(virt_to_page(start)); | ||
437 | init_page_count(virt_to_page(start)); | ||
438 | free_page(start); | ||
439 | totalram_pages++; | ||
440 | } | ||
441 | } | 411 | } |
442 | #endif | 412 | #endif |
443 | 413 | ||
diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c index d1d1b92c5b99..178876aef40f 100644 --- a/arch/powerpc/mm/mmu_context_hash64.c +++ b/arch/powerpc/mm/mmu_context_hash64.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | 24 | ||
25 | #include <asm/mmu_context.h> | 25 | #include <asm/mmu_context.h> |
26 | #include <asm/pgalloc.h> | ||
26 | 27 | ||
27 | #include "icswx.h" | 28 | #include "icswx.h" |
28 | 29 | ||
@@ -85,6 +86,9 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) | |||
85 | spin_lock_init(mm->context.cop_lockp); | 86 | spin_lock_init(mm->context.cop_lockp); |
86 | #endif /* CONFIG_PPC_ICSWX */ | 87 | #endif /* CONFIG_PPC_ICSWX */ |
87 | 88 | ||
89 | #ifdef CONFIG_PPC_64K_PAGES | ||
90 | mm->context.pte_frag = NULL; | ||
91 | #endif | ||
88 | return 0; | 92 | return 0; |
89 | } | 93 | } |
90 | 94 | ||
@@ -96,13 +100,46 @@ void __destroy_context(int context_id) | |||
96 | } | 100 | } |
97 | EXPORT_SYMBOL_GPL(__destroy_context); | 101 | EXPORT_SYMBOL_GPL(__destroy_context); |
98 | 102 | ||
103 | #ifdef CONFIG_PPC_64K_PAGES | ||
104 | static void destroy_pagetable_page(struct mm_struct *mm) | ||
105 | { | ||
106 | int count; | ||
107 | void *pte_frag; | ||
108 | struct page *page; | ||
109 | |||
110 | pte_frag = mm->context.pte_frag; | ||
111 | if (!pte_frag) | ||
112 | return; | ||
113 | |||
114 | page = virt_to_page(pte_frag); | ||
115 | /* drop all the pending references */ | ||
116 | count = ((unsigned long)pte_frag & ~PAGE_MASK) >> PTE_FRAG_SIZE_SHIFT; | ||
117 | /* We allow PTE_FRAG_NR fragments from a PTE page */ | ||
118 | count = atomic_sub_return(PTE_FRAG_NR - count, &page->_count); | ||
119 | if (!count) { | ||
120 | pgtable_page_dtor(page); | ||
121 | free_hot_cold_page(page, 0); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | #else | ||
126 | static inline void destroy_pagetable_page(struct mm_struct *mm) | ||
127 | { | ||
128 | return; | ||
129 | } | ||
130 | #endif | ||
131 | |||
132 | |||
99 | void destroy_context(struct mm_struct *mm) | 133 | void destroy_context(struct mm_struct *mm) |
100 | { | 134 | { |
135 | |||
101 | #ifdef CONFIG_PPC_ICSWX | 136 | #ifdef CONFIG_PPC_ICSWX |
102 | drop_cop(mm->context.acop, mm); | 137 | drop_cop(mm->context.acop, mm); |
103 | kfree(mm->context.cop_lockp); | 138 | kfree(mm->context.cop_lockp); |
104 | mm->context.cop_lockp = NULL; | 139 | mm->context.cop_lockp = NULL; |
105 | #endif /* CONFIG_PPC_ICSWX */ | 140 | #endif /* CONFIG_PPC_ICSWX */ |
141 | |||
142 | destroy_pagetable_page(mm); | ||
106 | __destroy_context(mm->context.id); | 143 | __destroy_context(mm->context.id); |
107 | subpage_prot_free(mm); | 144 | subpage_prot_free(mm); |
108 | mm->context.id = MMU_NO_CONTEXT; | 145 | mm->context.id = MMU_NO_CONTEXT; |
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index bba87ca2b4d7..88c0425dc0a8 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
@@ -22,6 +22,11 @@ | |||
22 | #include <linux/pfn.h> | 22 | #include <linux/pfn.h> |
23 | #include <linux/cpuset.h> | 23 | #include <linux/cpuset.h> |
24 | #include <linux/node.h> | 24 | #include <linux/node.h> |
25 | #include <linux/stop_machine.h> | ||
26 | #include <linux/proc_fs.h> | ||
27 | #include <linux/seq_file.h> | ||
28 | #include <linux/uaccess.h> | ||
29 | #include <linux/slab.h> | ||
25 | #include <asm/sparsemem.h> | 30 | #include <asm/sparsemem.h> |
26 | #include <asm/prom.h> | 31 | #include <asm/prom.h> |
27 | #include <asm/smp.h> | 32 | #include <asm/smp.h> |
@@ -29,6 +34,7 @@ | |||
29 | #include <asm/paca.h> | 34 | #include <asm/paca.h> |
30 | #include <asm/hvcall.h> | 35 | #include <asm/hvcall.h> |
31 | #include <asm/setup.h> | 36 | #include <asm/setup.h> |
37 | #include <asm/vdso.h> | ||
32 | 38 | ||
33 | static int numa_enabled = 1; | 39 | static int numa_enabled = 1; |
34 | 40 | ||
@@ -62,14 +68,11 @@ static int distance_lookup_table[MAX_NUMNODES][MAX_DISTANCE_REF_POINTS]; | |||
62 | */ | 68 | */ |
63 | static void __init setup_node_to_cpumask_map(void) | 69 | static void __init setup_node_to_cpumask_map(void) |
64 | { | 70 | { |
65 | unsigned int node, num = 0; | 71 | unsigned int node; |
66 | 72 | ||
67 | /* setup nr_node_ids if not done yet */ | 73 | /* setup nr_node_ids if not done yet */ |
68 | if (nr_node_ids == MAX_NUMNODES) { | 74 | if (nr_node_ids == MAX_NUMNODES) |
69 | for_each_node_mask(node, node_possible_map) | 75 | setup_nr_node_ids(); |
70 | num = node; | ||
71 | nr_node_ids = num + 1; | ||
72 | } | ||
73 | 76 | ||
74 | /* allocate the map */ | 77 | /* allocate the map */ |
75 | for (node = 0; node < nr_node_ids; node++) | 78 | for (node = 0; node < nr_node_ids; node++) |
@@ -79,7 +82,7 @@ static void __init setup_node_to_cpumask_map(void) | |||
79 | dbg("Node to cpumask map for %d nodes\n", nr_node_ids); | 82 | dbg("Node to cpumask map for %d nodes\n", nr_node_ids); |
80 | } | 83 | } |
81 | 84 | ||
82 | static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn, | 85 | static int __init fake_numa_create_new_node(unsigned long end_pfn, |
83 | unsigned int *nid) | 86 | unsigned int *nid) |
84 | { | 87 | { |
85 | unsigned long long mem; | 88 | unsigned long long mem; |
@@ -201,7 +204,7 @@ int __node_distance(int a, int b) | |||
201 | int distance = LOCAL_DISTANCE; | 204 | int distance = LOCAL_DISTANCE; |
202 | 205 | ||
203 | if (!form1_affinity) | 206 | if (!form1_affinity) |
204 | return distance; | 207 | return ((a == b) ? LOCAL_DISTANCE : REMOTE_DISTANCE); |
205 | 208 | ||
206 | for (i = 0; i < distance_ref_points_depth; i++) { | 209 | for (i = 0; i < distance_ref_points_depth; i++) { |
207 | if (distance_lookup_table[a][i] == distance_lookup_table[b][i]) | 210 | if (distance_lookup_table[a][i] == distance_lookup_table[b][i]) |
@@ -291,9 +294,7 @@ EXPORT_SYMBOL_GPL(of_node_to_nid); | |||
291 | static int __init find_min_common_depth(void) | 294 | static int __init find_min_common_depth(void) |
292 | { | 295 | { |
293 | int depth; | 296 | int depth; |
294 | struct device_node *chosen; | ||
295 | struct device_node *root; | 297 | struct device_node *root; |
296 | const char *vec5; | ||
297 | 298 | ||
298 | if (firmware_has_feature(FW_FEATURE_OPAL)) | 299 | if (firmware_has_feature(FW_FEATURE_OPAL)) |
299 | root = of_find_node_by_path("/ibm,opal"); | 300 | root = of_find_node_by_path("/ibm,opal"); |
@@ -325,24 +326,10 @@ static int __init find_min_common_depth(void) | |||
325 | 326 | ||
326 | distance_ref_points_depth /= sizeof(int); | 327 | distance_ref_points_depth /= sizeof(int); |
327 | 328 | ||
328 | #define VEC5_AFFINITY_BYTE 5 | 329 | if (firmware_has_feature(FW_FEATURE_OPAL) || |
329 | #define VEC5_AFFINITY 0x80 | 330 | firmware_has_feature(FW_FEATURE_TYPE1_AFFINITY)) { |
330 | 331 | dbg("Using form 1 affinity\n"); | |
331 | if (firmware_has_feature(FW_FEATURE_OPAL)) | ||
332 | form1_affinity = 1; | 332 | form1_affinity = 1; |
333 | else { | ||
334 | chosen = of_find_node_by_path("/chosen"); | ||
335 | if (chosen) { | ||
336 | vec5 = of_get_property(chosen, | ||
337 | "ibm,architecture-vec-5", NULL); | ||
338 | if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & | ||
339 | VEC5_AFFINITY)) { | ||
340 | dbg("Using form 1 affinity\n"); | ||
341 | form1_affinity = 1; | ||
342 | } | ||
343 | |||
344 | of_node_put(chosen); | ||
345 | } | ||
346 | } | 333 | } |
347 | 334 | ||
348 | if (form1_affinity) { | 335 | if (form1_affinity) { |
@@ -1270,10 +1257,18 @@ u64 memory_hotplug_max(void) | |||
1270 | 1257 | ||
1271 | /* Virtual Processor Home Node (VPHN) support */ | 1258 | /* Virtual Processor Home Node (VPHN) support */ |
1272 | #ifdef CONFIG_PPC_SPLPAR | 1259 | #ifdef CONFIG_PPC_SPLPAR |
1260 | struct topology_update_data { | ||
1261 | struct topology_update_data *next; | ||
1262 | unsigned int cpu; | ||
1263 | int old_nid; | ||
1264 | int new_nid; | ||
1265 | }; | ||
1266 | |||
1273 | static u8 vphn_cpu_change_counts[NR_CPUS][MAX_DISTANCE_REF_POINTS]; | 1267 | static u8 vphn_cpu_change_counts[NR_CPUS][MAX_DISTANCE_REF_POINTS]; |
1274 | static cpumask_t cpu_associativity_changes_mask; | 1268 | static cpumask_t cpu_associativity_changes_mask; |
1275 | static int vphn_enabled; | 1269 | static int vphn_enabled; |
1276 | static void set_topology_timer(void); | 1270 | static int prrn_enabled; |
1271 | static void reset_topology_timer(void); | ||
1277 | 1272 | ||
1278 | /* | 1273 | /* |
1279 | * Store the current values of the associativity change counters in the | 1274 | * Store the current values of the associativity change counters in the |
@@ -1309,11 +1304,9 @@ static void setup_cpu_associativity_change_counters(void) | |||
1309 | */ | 1304 | */ |
1310 | static int update_cpu_associativity_changes_mask(void) | 1305 | static int update_cpu_associativity_changes_mask(void) |
1311 | { | 1306 | { |
1312 | int cpu, nr_cpus = 0; | 1307 | int cpu; |
1313 | cpumask_t *changes = &cpu_associativity_changes_mask; | 1308 | cpumask_t *changes = &cpu_associativity_changes_mask; |
1314 | 1309 | ||
1315 | cpumask_clear(changes); | ||
1316 | |||
1317 | for_each_possible_cpu(cpu) { | 1310 | for_each_possible_cpu(cpu) { |
1318 | int i, changed = 0; | 1311 | int i, changed = 0; |
1319 | u8 *counts = vphn_cpu_change_counts[cpu]; | 1312 | u8 *counts = vphn_cpu_change_counts[cpu]; |
@@ -1327,11 +1320,10 @@ static int update_cpu_associativity_changes_mask(void) | |||
1327 | } | 1320 | } |
1328 | if (changed) { | 1321 | if (changed) { |
1329 | cpumask_set_cpu(cpu, changes); | 1322 | cpumask_set_cpu(cpu, changes); |
1330 | nr_cpus++; | ||
1331 | } | 1323 | } |
1332 | } | 1324 | } |
1333 | 1325 | ||
1334 | return nr_cpus; | 1326 | return cpumask_weight(changes); |
1335 | } | 1327 | } |
1336 | 1328 | ||
1337 | /* | 1329 | /* |
@@ -1423,40 +1415,84 @@ static long vphn_get_associativity(unsigned long cpu, | |||
1423 | } | 1415 | } |
1424 | 1416 | ||
1425 | /* | 1417 | /* |
1418 | * Update the CPU maps and sysfs entries for a single CPU when its NUMA | ||
1419 | * characteristics change. This function doesn't perform any locking and is | ||
1420 | * only safe to call from stop_machine(). | ||
1421 | */ | ||
1422 | static int update_cpu_topology(void *data) | ||
1423 | { | ||
1424 | struct topology_update_data *update; | ||
1425 | unsigned long cpu; | ||
1426 | |||
1427 | if (!data) | ||
1428 | return -EINVAL; | ||
1429 | |||
1430 | cpu = get_cpu(); | ||
1431 | |||
1432 | for (update = data; update; update = update->next) { | ||
1433 | if (cpu != update->cpu) | ||
1434 | continue; | ||
1435 | |||
1436 | unregister_cpu_under_node(update->cpu, update->old_nid); | ||
1437 | unmap_cpu_from_node(update->cpu); | ||
1438 | map_cpu_to_node(update->cpu, update->new_nid); | ||
1439 | vdso_getcpu_init(); | ||
1440 | register_cpu_under_node(update->cpu, update->new_nid); | ||
1441 | } | ||
1442 | |||
1443 | return 0; | ||
1444 | } | ||
1445 | |||
1446 | /* | ||
1426 | * Update the node maps and sysfs entries for each cpu whose home node | 1447 | * Update the node maps and sysfs entries for each cpu whose home node |
1427 | * has changed. Returns 1 when the topology has changed, and 0 otherwise. | 1448 | * has changed. Returns 1 when the topology has changed, and 0 otherwise. |
1428 | */ | 1449 | */ |
1429 | int arch_update_cpu_topology(void) | 1450 | int arch_update_cpu_topology(void) |
1430 | { | 1451 | { |
1431 | int cpu, nid, old_nid, changed = 0; | 1452 | unsigned int cpu, changed = 0; |
1453 | struct topology_update_data *updates, *ud; | ||
1432 | unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0}; | 1454 | unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0}; |
1455 | cpumask_t updated_cpus; | ||
1433 | struct device *dev; | 1456 | struct device *dev; |
1457 | int weight, i = 0; | ||
1458 | |||
1459 | weight = cpumask_weight(&cpu_associativity_changes_mask); | ||
1460 | if (!weight) | ||
1461 | return 0; | ||
1462 | |||
1463 | updates = kzalloc(weight * (sizeof(*updates)), GFP_KERNEL); | ||
1464 | if (!updates) | ||
1465 | return 0; | ||
1434 | 1466 | ||
1435 | for_each_cpu(cpu,&cpu_associativity_changes_mask) { | 1467 | cpumask_clear(&updated_cpus); |
1468 | |||
1469 | for_each_cpu(cpu, &cpu_associativity_changes_mask) { | ||
1470 | ud = &updates[i++]; | ||
1471 | ud->cpu = cpu; | ||
1436 | vphn_get_associativity(cpu, associativity); | 1472 | vphn_get_associativity(cpu, associativity); |
1437 | nid = associativity_to_nid(associativity); | 1473 | ud->new_nid = associativity_to_nid(associativity); |
1438 | 1474 | ||
1439 | if (nid < 0 || !node_online(nid)) | 1475 | if (ud->new_nid < 0 || !node_online(ud->new_nid)) |
1440 | nid = first_online_node; | 1476 | ud->new_nid = first_online_node; |
1441 | 1477 | ||
1442 | old_nid = numa_cpu_lookup_table[cpu]; | 1478 | ud->old_nid = numa_cpu_lookup_table[cpu]; |
1479 | cpumask_set_cpu(cpu, &updated_cpus); | ||
1443 | 1480 | ||
1444 | /* Disable hotplug while we update the cpu | 1481 | if (i < weight) |
1445 | * masks and sysfs. | 1482 | ud->next = &updates[i]; |
1446 | */ | 1483 | } |
1447 | get_online_cpus(); | 1484 | |
1448 | unregister_cpu_under_node(cpu, old_nid); | 1485 | stop_machine(update_cpu_topology, &updates[0], &updated_cpus); |
1449 | unmap_cpu_from_node(cpu); | 1486 | |
1450 | map_cpu_to_node(cpu, nid); | 1487 | for (ud = &updates[0]; ud; ud = ud->next) { |
1451 | register_cpu_under_node(cpu, nid); | 1488 | dev = get_cpu_device(ud->cpu); |
1452 | put_online_cpus(); | ||
1453 | |||
1454 | dev = get_cpu_device(cpu); | ||
1455 | if (dev) | 1489 | if (dev) |
1456 | kobject_uevent(&dev->kobj, KOBJ_CHANGE); | 1490 | kobject_uevent(&dev->kobj, KOBJ_CHANGE); |
1491 | cpumask_clear_cpu(ud->cpu, &cpu_associativity_changes_mask); | ||
1457 | changed = 1; | 1492 | changed = 1; |
1458 | } | 1493 | } |
1459 | 1494 | ||
1495 | kfree(updates); | ||
1460 | return changed; | 1496 | return changed; |
1461 | } | 1497 | } |
1462 | 1498 | ||
@@ -1473,49 +1509,165 @@ void topology_schedule_update(void) | |||
1473 | 1509 | ||
1474 | static void topology_timer_fn(unsigned long ignored) | 1510 | static void topology_timer_fn(unsigned long ignored) |
1475 | { | 1511 | { |
1476 | if (!vphn_enabled) | 1512 | if (prrn_enabled && cpumask_weight(&cpu_associativity_changes_mask)) |
1477 | return; | ||
1478 | if (update_cpu_associativity_changes_mask() > 0) | ||
1479 | topology_schedule_update(); | 1513 | topology_schedule_update(); |
1480 | set_topology_timer(); | 1514 | else if (vphn_enabled) { |
1515 | if (update_cpu_associativity_changes_mask() > 0) | ||
1516 | topology_schedule_update(); | ||
1517 | reset_topology_timer(); | ||
1518 | } | ||
1481 | } | 1519 | } |
1482 | static struct timer_list topology_timer = | 1520 | static struct timer_list topology_timer = |
1483 | TIMER_INITIALIZER(topology_timer_fn, 0, 0); | 1521 | TIMER_INITIALIZER(topology_timer_fn, 0, 0); |
1484 | 1522 | ||
1485 | static void set_topology_timer(void) | 1523 | static void reset_topology_timer(void) |
1486 | { | 1524 | { |
1487 | topology_timer.data = 0; | 1525 | topology_timer.data = 0; |
1488 | topology_timer.expires = jiffies + 60 * HZ; | 1526 | topology_timer.expires = jiffies + 60 * HZ; |
1489 | add_timer(&topology_timer); | 1527 | mod_timer(&topology_timer, topology_timer.expires); |
1528 | } | ||
1529 | |||
1530 | #ifdef CONFIG_SMP | ||
1531 | |||
1532 | static void stage_topology_update(int core_id) | ||
1533 | { | ||
1534 | cpumask_or(&cpu_associativity_changes_mask, | ||
1535 | &cpu_associativity_changes_mask, cpu_sibling_mask(core_id)); | ||
1536 | reset_topology_timer(); | ||
1490 | } | 1537 | } |
1491 | 1538 | ||
1539 | static int dt_update_callback(struct notifier_block *nb, | ||
1540 | unsigned long action, void *data) | ||
1541 | { | ||
1542 | struct of_prop_reconfig *update; | ||
1543 | int rc = NOTIFY_DONE; | ||
1544 | |||
1545 | switch (action) { | ||
1546 | case OF_RECONFIG_UPDATE_PROPERTY: | ||
1547 | update = (struct of_prop_reconfig *)data; | ||
1548 | if (!of_prop_cmp(update->dn->type, "cpu") && | ||
1549 | !of_prop_cmp(update->prop->name, "ibm,associativity")) { | ||
1550 | u32 core_id; | ||
1551 | of_property_read_u32(update->dn, "reg", &core_id); | ||
1552 | stage_topology_update(core_id); | ||
1553 | rc = NOTIFY_OK; | ||
1554 | } | ||
1555 | break; | ||
1556 | } | ||
1557 | |||
1558 | return rc; | ||
1559 | } | ||
1560 | |||
1561 | static struct notifier_block dt_update_nb = { | ||
1562 | .notifier_call = dt_update_callback, | ||
1563 | }; | ||
1564 | |||
1565 | #endif | ||
1566 | |||
1492 | /* | 1567 | /* |
1493 | * Start polling for VPHN associativity changes. | 1568 | * Start polling for associativity changes. |
1494 | */ | 1569 | */ |
1495 | int start_topology_update(void) | 1570 | int start_topology_update(void) |
1496 | { | 1571 | { |
1497 | int rc = 0; | 1572 | int rc = 0; |
1498 | 1573 | ||
1499 | /* Disabled until races with load balancing are fixed */ | 1574 | if (firmware_has_feature(FW_FEATURE_PRRN)) { |
1500 | if (0 && firmware_has_feature(FW_FEATURE_VPHN) && | 1575 | if (!prrn_enabled) { |
1501 | get_lppaca()->shared_proc) { | 1576 | prrn_enabled = 1; |
1502 | vphn_enabled = 1; | 1577 | vphn_enabled = 0; |
1503 | setup_cpu_associativity_change_counters(); | 1578 | #ifdef CONFIG_SMP |
1504 | init_timer_deferrable(&topology_timer); | 1579 | rc = of_reconfig_notifier_register(&dt_update_nb); |
1505 | set_topology_timer(); | 1580 | #endif |
1506 | rc = 1; | 1581 | } |
1582 | } else if (firmware_has_feature(FW_FEATURE_VPHN) && | ||
1583 | get_lppaca()->shared_proc) { | ||
1584 | if (!vphn_enabled) { | ||
1585 | prrn_enabled = 0; | ||
1586 | vphn_enabled = 1; | ||
1587 | setup_cpu_associativity_change_counters(); | ||
1588 | init_timer_deferrable(&topology_timer); | ||
1589 | reset_topology_timer(); | ||
1590 | } | ||
1507 | } | 1591 | } |
1508 | 1592 | ||
1509 | return rc; | 1593 | return rc; |
1510 | } | 1594 | } |
1511 | __initcall(start_topology_update); | ||
1512 | 1595 | ||
1513 | /* | 1596 | /* |
1514 | * Disable polling for VPHN associativity changes. | 1597 | * Disable polling for VPHN associativity changes. |
1515 | */ | 1598 | */ |
1516 | int stop_topology_update(void) | 1599 | int stop_topology_update(void) |
1517 | { | 1600 | { |
1518 | vphn_enabled = 0; | 1601 | int rc = 0; |
1519 | return del_timer_sync(&topology_timer); | 1602 | |
1603 | if (prrn_enabled) { | ||
1604 | prrn_enabled = 0; | ||
1605 | #ifdef CONFIG_SMP | ||
1606 | rc = of_reconfig_notifier_unregister(&dt_update_nb); | ||
1607 | #endif | ||
1608 | } else if (vphn_enabled) { | ||
1609 | vphn_enabled = 0; | ||
1610 | rc = del_timer_sync(&topology_timer); | ||
1611 | } | ||
1612 | |||
1613 | return rc; | ||
1614 | } | ||
1615 | |||
1616 | int prrn_is_enabled(void) | ||
1617 | { | ||
1618 | return prrn_enabled; | ||
1619 | } | ||
1620 | |||
1621 | static int topology_read(struct seq_file *file, void *v) | ||
1622 | { | ||
1623 | if (vphn_enabled || prrn_enabled) | ||
1624 | seq_puts(file, "on\n"); | ||
1625 | else | ||
1626 | seq_puts(file, "off\n"); | ||
1627 | |||
1628 | return 0; | ||
1629 | } | ||
1630 | |||
1631 | static int topology_open(struct inode *inode, struct file *file) | ||
1632 | { | ||
1633 | return single_open(file, topology_read, NULL); | ||
1634 | } | ||
1635 | |||
1636 | static ssize_t topology_write(struct file *file, const char __user *buf, | ||
1637 | size_t count, loff_t *off) | ||
1638 | { | ||
1639 | char kbuf[4]; /* "on" or "off" plus null. */ | ||
1640 | int read_len; | ||
1641 | |||
1642 | read_len = count < 3 ? count : 3; | ||
1643 | if (copy_from_user(kbuf, buf, read_len)) | ||
1644 | return -EINVAL; | ||
1645 | |||
1646 | kbuf[read_len] = '\0'; | ||
1647 | |||
1648 | if (!strncmp(kbuf, "on", 2)) | ||
1649 | start_topology_update(); | ||
1650 | else if (!strncmp(kbuf, "off", 3)) | ||
1651 | stop_topology_update(); | ||
1652 | else | ||
1653 | return -EINVAL; | ||
1654 | |||
1655 | return count; | ||
1656 | } | ||
1657 | |||
1658 | static const struct file_operations topology_ops = { | ||
1659 | .read = seq_read, | ||
1660 | .write = topology_write, | ||
1661 | .open = topology_open, | ||
1662 | .release = single_release | ||
1663 | }; | ||
1664 | |||
1665 | static int topology_update_init(void) | ||
1666 | { | ||
1667 | start_topology_update(); | ||
1668 | proc_create("powerpc/topology_updates", 644, NULL, &topology_ops); | ||
1669 | |||
1670 | return 0; | ||
1520 | } | 1671 | } |
1672 | device_initcall(topology_update_init); | ||
1521 | #endif /* CONFIG_PPC_SPLPAR */ | 1673 | #endif /* CONFIG_PPC_SPLPAR */ |
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 654258f165ae..a854096e1023 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c | |||
@@ -337,3 +337,121 @@ EXPORT_SYMBOL(__ioremap_at); | |||
337 | EXPORT_SYMBOL(iounmap); | 337 | EXPORT_SYMBOL(iounmap); |
338 | EXPORT_SYMBOL(__iounmap); | 338 | EXPORT_SYMBOL(__iounmap); |
339 | EXPORT_SYMBOL(__iounmap_at); | 339 | EXPORT_SYMBOL(__iounmap_at); |
340 | |||
341 | #ifdef CONFIG_PPC_64K_PAGES | ||
342 | static pte_t *get_from_cache(struct mm_struct *mm) | ||
343 | { | ||
344 | void *pte_frag, *ret; | ||
345 | |||
346 | spin_lock(&mm->page_table_lock); | ||
347 | ret = mm->context.pte_frag; | ||
348 | if (ret) { | ||
349 | pte_frag = ret + PTE_FRAG_SIZE; | ||
350 | /* | ||
351 | * If we have taken up all the fragments mark PTE page NULL | ||
352 | */ | ||
353 | if (((unsigned long)pte_frag & ~PAGE_MASK) == 0) | ||
354 | pte_frag = NULL; | ||
355 | mm->context.pte_frag = pte_frag; | ||
356 | } | ||
357 | spin_unlock(&mm->page_table_lock); | ||
358 | return (pte_t *)ret; | ||
359 | } | ||
360 | |||
361 | static pte_t *__alloc_for_cache(struct mm_struct *mm, int kernel) | ||
362 | { | ||
363 | void *ret = NULL; | ||
364 | struct page *page = alloc_page(GFP_KERNEL | __GFP_NOTRACK | | ||
365 | __GFP_REPEAT | __GFP_ZERO); | ||
366 | if (!page) | ||
367 | return NULL; | ||
368 | |||
369 | ret = page_address(page); | ||
370 | spin_lock(&mm->page_table_lock); | ||
371 | /* | ||
372 | * If we find pgtable_page set, we return | ||
373 | * the allocated page with single fragement | ||
374 | * count. | ||
375 | */ | ||
376 | if (likely(!mm->context.pte_frag)) { | ||
377 | atomic_set(&page->_count, PTE_FRAG_NR); | ||
378 | mm->context.pte_frag = ret + PTE_FRAG_SIZE; | ||
379 | } | ||
380 | spin_unlock(&mm->page_table_lock); | ||
381 | |||
382 | if (!kernel) | ||
383 | pgtable_page_ctor(page); | ||
384 | |||
385 | return (pte_t *)ret; | ||
386 | } | ||
387 | |||
388 | pte_t *page_table_alloc(struct mm_struct *mm, unsigned long vmaddr, int kernel) | ||
389 | { | ||
390 | pte_t *pte; | ||
391 | |||
392 | pte = get_from_cache(mm); | ||
393 | if (pte) | ||
394 | return pte; | ||
395 | |||
396 | return __alloc_for_cache(mm, kernel); | ||
397 | } | ||
398 | |||
399 | void page_table_free(struct mm_struct *mm, unsigned long *table, int kernel) | ||
400 | { | ||
401 | struct page *page = virt_to_page(table); | ||
402 | if (put_page_testzero(page)) { | ||
403 | if (!kernel) | ||
404 | pgtable_page_dtor(page); | ||
405 | free_hot_cold_page(page, 0); | ||
406 | } | ||
407 | } | ||
408 | |||
409 | #ifdef CONFIG_SMP | ||
410 | static void page_table_free_rcu(void *table) | ||
411 | { | ||
412 | struct page *page = virt_to_page(table); | ||
413 | if (put_page_testzero(page)) { | ||
414 | pgtable_page_dtor(page); | ||
415 | free_hot_cold_page(page, 0); | ||
416 | } | ||
417 | } | ||
418 | |||
419 | void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift) | ||
420 | { | ||
421 | unsigned long pgf = (unsigned long)table; | ||
422 | |||
423 | BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE); | ||
424 | pgf |= shift; | ||
425 | tlb_remove_table(tlb, (void *)pgf); | ||
426 | } | ||
427 | |||
428 | void __tlb_remove_table(void *_table) | ||
429 | { | ||
430 | void *table = (void *)((unsigned long)_table & ~MAX_PGTABLE_INDEX_SIZE); | ||
431 | unsigned shift = (unsigned long)_table & MAX_PGTABLE_INDEX_SIZE; | ||
432 | |||
433 | if (!shift) | ||
434 | /* PTE page needs special handling */ | ||
435 | page_table_free_rcu(table); | ||
436 | else { | ||
437 | BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE); | ||
438 | kmem_cache_free(PGT_CACHE(shift), table); | ||
439 | } | ||
440 | } | ||
441 | #else | ||
442 | void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift) | ||
443 | { | ||
444 | if (!shift) { | ||
445 | /* PTE page needs special handling */ | ||
446 | struct page *page = virt_to_page(table); | ||
447 | if (put_page_testzero(page)) { | ||
448 | pgtable_page_dtor(page); | ||
449 | free_hot_cold_page(page, 0); | ||
450 | } | ||
451 | } else { | ||
452 | BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE); | ||
453 | kmem_cache_free(PGT_CACHE(shift), table); | ||
454 | } | ||
455 | } | ||
456 | #endif | ||
457 | #endif /* CONFIG_PPC_64K_PAGES */ | ||
diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c index cf9dada734b6..3e99c149271a 100644 --- a/arch/powerpc/mm/slice.c +++ b/arch/powerpc/mm/slice.c | |||
@@ -237,134 +237,112 @@ static void slice_convert(struct mm_struct *mm, struct slice_mask mask, int psiz | |||
237 | #endif | 237 | #endif |
238 | } | 238 | } |
239 | 239 | ||
240 | /* | ||
241 | * Compute which slice addr is part of; | ||
242 | * set *boundary_addr to the start or end boundary of that slice | ||
243 | * (depending on 'end' parameter); | ||
244 | * return boolean indicating if the slice is marked as available in the | ||
245 | * 'available' slice_mark. | ||
246 | */ | ||
247 | static bool slice_scan_available(unsigned long addr, | ||
248 | struct slice_mask available, | ||
249 | int end, | ||
250 | unsigned long *boundary_addr) | ||
251 | { | ||
252 | unsigned long slice; | ||
253 | if (addr < SLICE_LOW_TOP) { | ||
254 | slice = GET_LOW_SLICE_INDEX(addr); | ||
255 | *boundary_addr = (slice + end) << SLICE_LOW_SHIFT; | ||
256 | return !!(available.low_slices & (1u << slice)); | ||
257 | } else { | ||
258 | slice = GET_HIGH_SLICE_INDEX(addr); | ||
259 | *boundary_addr = (slice + end) ? | ||
260 | ((slice + end) << SLICE_HIGH_SHIFT) : SLICE_LOW_TOP; | ||
261 | return !!(available.high_slices & (1u << slice)); | ||
262 | } | ||
263 | } | ||
264 | |||
240 | static unsigned long slice_find_area_bottomup(struct mm_struct *mm, | 265 | static unsigned long slice_find_area_bottomup(struct mm_struct *mm, |
241 | unsigned long len, | 266 | unsigned long len, |
242 | struct slice_mask available, | 267 | struct slice_mask available, |
243 | int psize, int use_cache) | 268 | int psize) |
244 | { | 269 | { |
245 | struct vm_area_struct *vma; | ||
246 | unsigned long start_addr, addr; | ||
247 | struct slice_mask mask; | ||
248 | int pshift = max_t(int, mmu_psize_defs[psize].shift, PAGE_SHIFT); | 270 | int pshift = max_t(int, mmu_psize_defs[psize].shift, PAGE_SHIFT); |
249 | 271 | unsigned long addr, found, next_end; | |
250 | if (use_cache) { | 272 | struct vm_unmapped_area_info info; |
251 | if (len <= mm->cached_hole_size) { | 273 | |
252 | start_addr = addr = TASK_UNMAPPED_BASE; | 274 | info.flags = 0; |
253 | mm->cached_hole_size = 0; | 275 | info.length = len; |
254 | } else | 276 | info.align_mask = PAGE_MASK & ((1ul << pshift) - 1); |
255 | start_addr = addr = mm->free_area_cache; | 277 | info.align_offset = 0; |
256 | } else | 278 | |
257 | start_addr = addr = TASK_UNMAPPED_BASE; | 279 | addr = TASK_UNMAPPED_BASE; |
258 | 280 | while (addr < TASK_SIZE) { | |
259 | full_search: | 281 | info.low_limit = addr; |
260 | for (;;) { | 282 | if (!slice_scan_available(addr, available, 1, &addr)) |
261 | addr = _ALIGN_UP(addr, 1ul << pshift); | ||
262 | if ((TASK_SIZE - len) < addr) | ||
263 | break; | ||
264 | vma = find_vma(mm, addr); | ||
265 | BUG_ON(vma && (addr >= vma->vm_end)); | ||
266 | |||
267 | mask = slice_range_to_mask(addr, len); | ||
268 | if (!slice_check_fit(mask, available)) { | ||
269 | if (addr < SLICE_LOW_TOP) | ||
270 | addr = _ALIGN_UP(addr + 1, 1ul << SLICE_LOW_SHIFT); | ||
271 | else | ||
272 | addr = _ALIGN_UP(addr + 1, 1ul << SLICE_HIGH_SHIFT); | ||
273 | continue; | 283 | continue; |
284 | |||
285 | next_slice: | ||
286 | /* | ||
287 | * At this point [info.low_limit; addr) covers | ||
288 | * available slices only and ends at a slice boundary. | ||
289 | * Check if we need to reduce the range, or if we can | ||
290 | * extend it to cover the next available slice. | ||
291 | */ | ||
292 | if (addr >= TASK_SIZE) | ||
293 | addr = TASK_SIZE; | ||
294 | else if (slice_scan_available(addr, available, 1, &next_end)) { | ||
295 | addr = next_end; | ||
296 | goto next_slice; | ||
274 | } | 297 | } |
275 | if (!vma || addr + len <= vma->vm_start) { | 298 | info.high_limit = addr; |
276 | /* | ||
277 | * Remember the place where we stopped the search: | ||
278 | */ | ||
279 | if (use_cache) | ||
280 | mm->free_area_cache = addr + len; | ||
281 | return addr; | ||
282 | } | ||
283 | if (use_cache && (addr + mm->cached_hole_size) < vma->vm_start) | ||
284 | mm->cached_hole_size = vma->vm_start - addr; | ||
285 | addr = vma->vm_end; | ||
286 | } | ||
287 | 299 | ||
288 | /* Make sure we didn't miss any holes */ | 300 | found = vm_unmapped_area(&info); |
289 | if (use_cache && start_addr != TASK_UNMAPPED_BASE) { | 301 | if (!(found & ~PAGE_MASK)) |
290 | start_addr = addr = TASK_UNMAPPED_BASE; | 302 | return found; |
291 | mm->cached_hole_size = 0; | ||
292 | goto full_search; | ||
293 | } | 303 | } |
304 | |||
294 | return -ENOMEM; | 305 | return -ENOMEM; |
295 | } | 306 | } |
296 | 307 | ||
297 | static unsigned long slice_find_area_topdown(struct mm_struct *mm, | 308 | static unsigned long slice_find_area_topdown(struct mm_struct *mm, |
298 | unsigned long len, | 309 | unsigned long len, |
299 | struct slice_mask available, | 310 | struct slice_mask available, |
300 | int psize, int use_cache) | 311 | int psize) |
301 | { | 312 | { |
302 | struct vm_area_struct *vma; | ||
303 | unsigned long addr; | ||
304 | struct slice_mask mask; | ||
305 | int pshift = max_t(int, mmu_psize_defs[psize].shift, PAGE_SHIFT); | 313 | int pshift = max_t(int, mmu_psize_defs[psize].shift, PAGE_SHIFT); |
314 | unsigned long addr, found, prev; | ||
315 | struct vm_unmapped_area_info info; | ||
306 | 316 | ||
307 | /* check if free_area_cache is useful for us */ | 317 | info.flags = VM_UNMAPPED_AREA_TOPDOWN; |
308 | if (use_cache) { | 318 | info.length = len; |
309 | if (len <= mm->cached_hole_size) { | 319 | info.align_mask = PAGE_MASK & ((1ul << pshift) - 1); |
310 | mm->cached_hole_size = 0; | 320 | info.align_offset = 0; |
311 | mm->free_area_cache = mm->mmap_base; | ||
312 | } | ||
313 | |||
314 | /* either no address requested or can't fit in requested | ||
315 | * address hole | ||
316 | */ | ||
317 | addr = mm->free_area_cache; | ||
318 | |||
319 | /* make sure it can fit in the remaining address space */ | ||
320 | if (addr > len) { | ||
321 | addr = _ALIGN_DOWN(addr - len, 1ul << pshift); | ||
322 | mask = slice_range_to_mask(addr, len); | ||
323 | if (slice_check_fit(mask, available) && | ||
324 | slice_area_is_free(mm, addr, len)) | ||
325 | /* remember the address as a hint for | ||
326 | * next time | ||
327 | */ | ||
328 | return (mm->free_area_cache = addr); | ||
329 | } | ||
330 | } | ||
331 | 321 | ||
332 | addr = mm->mmap_base; | 322 | addr = mm->mmap_base; |
333 | while (addr > len) { | 323 | while (addr > PAGE_SIZE) { |
334 | /* Go down by chunk size */ | 324 | info.high_limit = addr; |
335 | addr = _ALIGN_DOWN(addr - len, 1ul << pshift); | 325 | if (!slice_scan_available(addr - 1, available, 0, &addr)) |
336 | |||
337 | /* Check for hit with different page size */ | ||
338 | mask = slice_range_to_mask(addr, len); | ||
339 | if (!slice_check_fit(mask, available)) { | ||
340 | if (addr < SLICE_LOW_TOP) | ||
341 | addr = _ALIGN_DOWN(addr, 1ul << SLICE_LOW_SHIFT); | ||
342 | else if (addr < (1ul << SLICE_HIGH_SHIFT)) | ||
343 | addr = SLICE_LOW_TOP; | ||
344 | else | ||
345 | addr = _ALIGN_DOWN(addr, 1ul << SLICE_HIGH_SHIFT); | ||
346 | continue; | 326 | continue; |
347 | } | ||
348 | 327 | ||
328 | prev_slice: | ||
349 | /* | 329 | /* |
350 | * Lookup failure means no vma is above this address, | 330 | * At this point [addr; info.high_limit) covers |
351 | * else if new region fits below vma->vm_start, | 331 | * available slices only and starts at a slice boundary. |
352 | * return with success: | 332 | * Check if we need to reduce the range, or if we can |
333 | * extend it to cover the previous available slice. | ||
353 | */ | 334 | */ |
354 | vma = find_vma(mm, addr); | 335 | if (addr < PAGE_SIZE) |
355 | if (!vma || (addr + len) <= vma->vm_start) { | 336 | addr = PAGE_SIZE; |
356 | /* remember the address as a hint for next time */ | 337 | else if (slice_scan_available(addr - 1, available, 0, &prev)) { |
357 | if (use_cache) | 338 | addr = prev; |
358 | mm->free_area_cache = addr; | 339 | goto prev_slice; |
359 | return addr; | ||
360 | } | 340 | } |
341 | info.low_limit = addr; | ||
361 | 342 | ||
362 | /* remember the largest hole we saw so far */ | 343 | found = vm_unmapped_area(&info); |
363 | if (use_cache && (addr + mm->cached_hole_size) < vma->vm_start) | 344 | if (!(found & ~PAGE_MASK)) |
364 | mm->cached_hole_size = vma->vm_start - addr; | 345 | return found; |
365 | |||
366 | /* try just below the current vma->vm_start */ | ||
367 | addr = vma->vm_start; | ||
368 | } | 346 | } |
369 | 347 | ||
370 | /* | 348 | /* |
@@ -373,28 +351,18 @@ static unsigned long slice_find_area_topdown(struct mm_struct *mm, | |||
373 | * can happen with large stack limits and large mmap() | 351 | * can happen with large stack limits and large mmap() |
374 | * allocations. | 352 | * allocations. |
375 | */ | 353 | */ |
376 | addr = slice_find_area_bottomup(mm, len, available, psize, 0); | 354 | return slice_find_area_bottomup(mm, len, available, psize); |
377 | |||
378 | /* | ||
379 | * Restore the topdown base: | ||
380 | */ | ||
381 | if (use_cache) { | ||
382 | mm->free_area_cache = mm->mmap_base; | ||
383 | mm->cached_hole_size = ~0UL; | ||
384 | } | ||
385 | |||
386 | return addr; | ||
387 | } | 355 | } |
388 | 356 | ||
389 | 357 | ||
390 | static unsigned long slice_find_area(struct mm_struct *mm, unsigned long len, | 358 | static unsigned long slice_find_area(struct mm_struct *mm, unsigned long len, |
391 | struct slice_mask mask, int psize, | 359 | struct slice_mask mask, int psize, |
392 | int topdown, int use_cache) | 360 | int topdown) |
393 | { | 361 | { |
394 | if (topdown) | 362 | if (topdown) |
395 | return slice_find_area_topdown(mm, len, mask, psize, use_cache); | 363 | return slice_find_area_topdown(mm, len, mask, psize); |
396 | else | 364 | else |
397 | return slice_find_area_bottomup(mm, len, mask, psize, use_cache); | 365 | return slice_find_area_bottomup(mm, len, mask, psize); |
398 | } | 366 | } |
399 | 367 | ||
400 | #define or_mask(dst, src) do { \ | 368 | #define or_mask(dst, src) do { \ |
@@ -415,7 +383,7 @@ static unsigned long slice_find_area(struct mm_struct *mm, unsigned long len, | |||
415 | 383 | ||
416 | unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len, | 384 | unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len, |
417 | unsigned long flags, unsigned int psize, | 385 | unsigned long flags, unsigned int psize, |
418 | int topdown, int use_cache) | 386 | int topdown) |
419 | { | 387 | { |
420 | struct slice_mask mask = {0, 0}; | 388 | struct slice_mask mask = {0, 0}; |
421 | struct slice_mask good_mask; | 389 | struct slice_mask good_mask; |
@@ -430,8 +398,8 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len, | |||
430 | BUG_ON(mm->task_size == 0); | 398 | BUG_ON(mm->task_size == 0); |
431 | 399 | ||
432 | slice_dbg("slice_get_unmapped_area(mm=%p, psize=%d...\n", mm, psize); | 400 | slice_dbg("slice_get_unmapped_area(mm=%p, psize=%d...\n", mm, psize); |
433 | slice_dbg(" addr=%lx, len=%lx, flags=%lx, topdown=%d, use_cache=%d\n", | 401 | slice_dbg(" addr=%lx, len=%lx, flags=%lx, topdown=%d\n", |
434 | addr, len, flags, topdown, use_cache); | 402 | addr, len, flags, topdown); |
435 | 403 | ||
436 | if (len > mm->task_size) | 404 | if (len > mm->task_size) |
437 | return -ENOMEM; | 405 | return -ENOMEM; |
@@ -503,8 +471,7 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len, | |||
503 | /* Now let's see if we can find something in the existing | 471 | /* Now let's see if we can find something in the existing |
504 | * slices for that size | 472 | * slices for that size |
505 | */ | 473 | */ |
506 | newaddr = slice_find_area(mm, len, good_mask, psize, topdown, | 474 | newaddr = slice_find_area(mm, len, good_mask, psize, topdown); |
507 | use_cache); | ||
508 | if (newaddr != -ENOMEM) { | 475 | if (newaddr != -ENOMEM) { |
509 | /* Found within the good mask, we don't have to setup, | 476 | /* Found within the good mask, we don't have to setup, |
510 | * we thus return directly | 477 | * we thus return directly |
@@ -536,8 +503,7 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len, | |||
536 | * anywhere in the good area. | 503 | * anywhere in the good area. |
537 | */ | 504 | */ |
538 | if (addr) { | 505 | if (addr) { |
539 | addr = slice_find_area(mm, len, good_mask, psize, topdown, | 506 | addr = slice_find_area(mm, len, good_mask, psize, topdown); |
540 | use_cache); | ||
541 | if (addr != -ENOMEM) { | 507 | if (addr != -ENOMEM) { |
542 | slice_dbg(" found area at 0x%lx\n", addr); | 508 | slice_dbg(" found area at 0x%lx\n", addr); |
543 | return addr; | 509 | return addr; |
@@ -547,15 +513,14 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len, | |||
547 | /* Now let's see if we can find something in the existing slices | 513 | /* Now let's see if we can find something in the existing slices |
548 | * for that size plus free slices | 514 | * for that size plus free slices |
549 | */ | 515 | */ |
550 | addr = slice_find_area(mm, len, potential_mask, psize, topdown, | 516 | addr = slice_find_area(mm, len, potential_mask, psize, topdown); |
551 | use_cache); | ||
552 | 517 | ||
553 | #ifdef CONFIG_PPC_64K_PAGES | 518 | #ifdef CONFIG_PPC_64K_PAGES |
554 | if (addr == -ENOMEM && psize == MMU_PAGE_64K) { | 519 | if (addr == -ENOMEM && psize == MMU_PAGE_64K) { |
555 | /* retry the search with 4k-page slices included */ | 520 | /* retry the search with 4k-page slices included */ |
556 | or_mask(potential_mask, compat_mask); | 521 | or_mask(potential_mask, compat_mask); |
557 | addr = slice_find_area(mm, len, potential_mask, psize, | 522 | addr = slice_find_area(mm, len, potential_mask, psize, |
558 | topdown, use_cache); | 523 | topdown); |
559 | } | 524 | } |
560 | #endif | 525 | #endif |
561 | 526 | ||
@@ -586,8 +551,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, | |||
586 | unsigned long flags) | 551 | unsigned long flags) |
587 | { | 552 | { |
588 | return slice_get_unmapped_area(addr, len, flags, | 553 | return slice_get_unmapped_area(addr, len, flags, |
589 | current->mm->context.user_psize, | 554 | current->mm->context.user_psize, 0); |
590 | 0, 1); | ||
591 | } | 555 | } |
592 | 556 | ||
593 | unsigned long arch_get_unmapped_area_topdown(struct file *filp, | 557 | unsigned long arch_get_unmapped_area_topdown(struct file *filp, |
@@ -597,8 +561,7 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, | |||
597 | const unsigned long flags) | 561 | const unsigned long flags) |
598 | { | 562 | { |
599 | return slice_get_unmapped_area(addr0, len, flags, | 563 | return slice_get_unmapped_area(addr0, len, flags, |
600 | current->mm->context.user_psize, | 564 | current->mm->context.user_psize, 1); |
601 | 1, 1); | ||
602 | } | 565 | } |
603 | 566 | ||
604 | unsigned int get_slice_psize(struct mm_struct *mm, unsigned long addr) | 567 | unsigned int get_slice_psize(struct mm_struct *mm, unsigned long addr) |
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index df32a838dcfa..6888cad5103d 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c | |||
@@ -414,9 +414,9 @@ static void setup_page_sizes(void) | |||
414 | 414 | ||
415 | #ifdef CONFIG_PPC_FSL_BOOK3E | 415 | #ifdef CONFIG_PPC_FSL_BOOK3E |
416 | unsigned int mmucfg = mfspr(SPRN_MMUCFG); | 416 | unsigned int mmucfg = mfspr(SPRN_MMUCFG); |
417 | int fsl_mmu = mmu_has_feature(MMU_FTR_TYPE_FSL_E); | ||
417 | 418 | ||
418 | if (((mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) && | 419 | if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) { |
419 | (mmu_has_feature(MMU_FTR_TYPE_FSL_E))) { | ||
420 | unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG); | 420 | unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG); |
421 | unsigned int min_pg, max_pg; | 421 | unsigned int min_pg, max_pg; |
422 | 422 | ||
@@ -442,6 +442,20 @@ static void setup_page_sizes(void) | |||
442 | 442 | ||
443 | goto no_indirect; | 443 | goto no_indirect; |
444 | } | 444 | } |
445 | |||
446 | if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2) { | ||
447 | u32 tlb1ps = mfspr(SPRN_TLB1PS); | ||
448 | |||
449 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { | ||
450 | struct mmu_psize_def *def = &mmu_psize_defs[psize]; | ||
451 | |||
452 | if (tlb1ps & (1U << (def->shift - 10))) { | ||
453 | def->flags |= MMU_PAGE_SIZE_DIRECT; | ||
454 | } | ||
455 | } | ||
456 | |||
457 | goto no_indirect; | ||
458 | } | ||
445 | #endif | 459 | #endif |
446 | 460 | ||
447 | tlb0cfg = mfspr(SPRN_TLB0CFG); | 461 | tlb0cfg = mfspr(SPRN_TLB0CFG); |
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index e834f1ec23c8..c427ae36374a 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c | |||
@@ -671,16 +671,12 @@ void bpf_jit_compile(struct sk_filter *fp) | |||
671 | } | 671 | } |
672 | 672 | ||
673 | if (bpf_jit_enable > 1) | 673 | if (bpf_jit_enable > 1) |
674 | pr_info("flen=%d proglen=%u pass=%d image=%p\n", | 674 | /* Note that we output the base address of the code_base |
675 | flen, proglen, pass, image); | 675 | * rather than image, since opcodes are in code_base. |
676 | */ | ||
677 | bpf_jit_dump(flen, proglen, pass, code_base); | ||
676 | 678 | ||
677 | if (image) { | 679 | if (image) { |
678 | if (bpf_jit_enable > 1) | ||
679 | print_hex_dump(KERN_ERR, "JIT code: ", | ||
680 | DUMP_PREFIX_ADDRESS, | ||
681 | 16, 1, code_base, | ||
682 | proglen, false); | ||
683 | |||
684 | bpf_flush_icache(code_base, code_base + (proglen/4)); | 680 | bpf_flush_icache(code_base, code_base + (proglen/4)); |
685 | /* Function descriptor nastiness: Address + TOC */ | 681 | /* Function descriptor nastiness: Address + TOC */ |
686 | ((u64 *)image)[0] = (u64)code_base; | 682 | ((u64 *)image)[0] = (u64)code_base; |
diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile index af3fac23768c..510fae10513d 100644 --- a/arch/powerpc/perf/Makefile +++ b/arch/powerpc/perf/Makefile | |||
@@ -2,9 +2,10 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror | |||
2 | 2 | ||
3 | obj-$(CONFIG_PERF_EVENTS) += callchain.o | 3 | obj-$(CONFIG_PERF_EVENTS) += callchain.o |
4 | 4 | ||
5 | obj-$(CONFIG_PPC_PERF_CTRS) += core-book3s.o | 5 | obj-$(CONFIG_PPC_PERF_CTRS) += core-book3s.o bhrb.o |
6 | obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \ | 6 | obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \ |
7 | power5+-pmu.o power6-pmu.o power7-pmu.o | 7 | power5+-pmu.o power6-pmu.o power7-pmu.o \ |
8 | power8-pmu.o | ||
8 | obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o | 9 | obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o |
9 | 10 | ||
10 | obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o | 11 | obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o |
diff --git a/arch/powerpc/perf/bhrb.S b/arch/powerpc/perf/bhrb.S new file mode 100644 index 000000000000..d85f9a58ddbc --- /dev/null +++ b/arch/powerpc/perf/bhrb.S | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * Basic assembly code to read BHRB entries | ||
3 | * | ||
4 | * Copyright 2013 Anshuman Khandual, IBM Corporation. | ||
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 | #include <asm/ppc_asm.h> | ||
12 | #include <asm/ppc-opcode.h> | ||
13 | |||
14 | .text | ||
15 | |||
16 | .balign 8 | ||
17 | |||
18 | /* r3 = n (where n = [0-31]) | ||
19 | * The maximum number of BHRB entries supported with PPC_MFBHRBE instruction | ||
20 | * is 1024. We have limited number of table entries here as POWER8 implements | ||
21 | * 32 BHRB entries. | ||
22 | */ | ||
23 | |||
24 | /* .global read_bhrb */ | ||
25 | _GLOBAL(read_bhrb) | ||
26 | cmpldi r3,31 | ||
27 | bgt 1f | ||
28 | ld r4,bhrb_table@got(r2) | ||
29 | sldi r3,r3,3 | ||
30 | add r3,r4,r3 | ||
31 | mtctr r3 | ||
32 | bctr | ||
33 | 1: li r3,0 | ||
34 | blr | ||
35 | |||
36 | #define MFBHRB_TABLE1(n) PPC_MFBHRBE(R3,n); blr | ||
37 | #define MFBHRB_TABLE2(n) MFBHRB_TABLE1(n); MFBHRB_TABLE1(n+1) | ||
38 | #define MFBHRB_TABLE4(n) MFBHRB_TABLE2(n); MFBHRB_TABLE2(n+2) | ||
39 | #define MFBHRB_TABLE8(n) MFBHRB_TABLE4(n); MFBHRB_TABLE4(n+4) | ||
40 | #define MFBHRB_TABLE16(n) MFBHRB_TABLE8(n); MFBHRB_TABLE8(n+8) | ||
41 | #define MFBHRB_TABLE32(n) MFBHRB_TABLE16(n); MFBHRB_TABLE16(n+16) | ||
42 | |||
43 | bhrb_table: | ||
44 | MFBHRB_TABLE32(0) | ||
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 65362e98eb26..c627843c5b2e 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c | |||
@@ -19,6 +19,11 @@ | |||
19 | #include <asm/firmware.h> | 19 | #include <asm/firmware.h> |
20 | #include <asm/ptrace.h> | 20 | #include <asm/ptrace.h> |
21 | 21 | ||
22 | #define BHRB_MAX_ENTRIES 32 | ||
23 | #define BHRB_TARGET 0x0000000000000002 | ||
24 | #define BHRB_PREDICTION 0x0000000000000001 | ||
25 | #define BHRB_EA 0xFFFFFFFFFFFFFFFC | ||
26 | |||
22 | struct cpu_hw_events { | 27 | struct cpu_hw_events { |
23 | int n_events; | 28 | int n_events; |
24 | int n_percpu; | 29 | int n_percpu; |
@@ -38,7 +43,15 @@ struct cpu_hw_events { | |||
38 | 43 | ||
39 | unsigned int group_flag; | 44 | unsigned int group_flag; |
40 | int n_txn_start; | 45 | int n_txn_start; |
46 | |||
47 | /* BHRB bits */ | ||
48 | u64 bhrb_filter; /* BHRB HW branch filter */ | ||
49 | int bhrb_users; | ||
50 | void *bhrb_context; | ||
51 | struct perf_branch_stack bhrb_stack; | ||
52 | struct perf_branch_entry bhrb_entries[BHRB_MAX_ENTRIES]; | ||
41 | }; | 53 | }; |
54 | |||
42 | DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); | 55 | DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); |
43 | 56 | ||
44 | struct power_pmu *ppmu; | 57 | struct power_pmu *ppmu; |
@@ -89,6 +102,11 @@ static inline int siar_valid(struct pt_regs *regs) | |||
89 | 102 | ||
90 | #endif /* CONFIG_PPC32 */ | 103 | #endif /* CONFIG_PPC32 */ |
91 | 104 | ||
105 | static bool regs_use_siar(struct pt_regs *regs) | ||
106 | { | ||
107 | return !!(regs->result & 1); | ||
108 | } | ||
109 | |||
92 | /* | 110 | /* |
93 | * Things that are specific to 64-bit implementations. | 111 | * Things that are specific to 64-bit implementations. |
94 | */ | 112 | */ |
@@ -98,11 +116,12 @@ static inline unsigned long perf_ip_adjust(struct pt_regs *regs) | |||
98 | { | 116 | { |
99 | unsigned long mmcra = regs->dsisr; | 117 | unsigned long mmcra = regs->dsisr; |
100 | 118 | ||
101 | if ((mmcra & MMCRA_SAMPLE_ENABLE) && !(ppmu->flags & PPMU_ALT_SIPR)) { | 119 | if ((ppmu->flags & PPMU_HAS_SSLOT) && (mmcra & MMCRA_SAMPLE_ENABLE)) { |
102 | unsigned long slot = (mmcra & MMCRA_SLOT) >> MMCRA_SLOT_SHIFT; | 120 | unsigned long slot = (mmcra & MMCRA_SLOT) >> MMCRA_SLOT_SHIFT; |
103 | if (slot > 1) | 121 | if (slot > 1) |
104 | return 4 * (slot - 1); | 122 | return 4 * (slot - 1); |
105 | } | 123 | } |
124 | |||
106 | return 0; | 125 | return 0; |
107 | } | 126 | } |
108 | 127 | ||
@@ -130,24 +149,35 @@ static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp) | |||
130 | *addrp = mfspr(SPRN_SDAR); | 149 | *addrp = mfspr(SPRN_SDAR); |
131 | } | 150 | } |
132 | 151 | ||
133 | static bool mmcra_sihv(unsigned long mmcra) | 152 | static bool regs_sihv(struct pt_regs *regs) |
134 | { | 153 | { |
135 | unsigned long sihv = MMCRA_SIHV; | 154 | unsigned long sihv = MMCRA_SIHV; |
136 | 155 | ||
156 | if (ppmu->flags & PPMU_HAS_SIER) | ||
157 | return !!(regs->dar & SIER_SIHV); | ||
158 | |||
137 | if (ppmu->flags & PPMU_ALT_SIPR) | 159 | if (ppmu->flags & PPMU_ALT_SIPR) |
138 | sihv = POWER6_MMCRA_SIHV; | 160 | sihv = POWER6_MMCRA_SIHV; |
139 | 161 | ||
140 | return !!(mmcra & sihv); | 162 | return !!(regs->dsisr & sihv); |
141 | } | 163 | } |
142 | 164 | ||
143 | static bool mmcra_sipr(unsigned long mmcra) | 165 | static bool regs_sipr(struct pt_regs *regs) |
144 | { | 166 | { |
145 | unsigned long sipr = MMCRA_SIPR; | 167 | unsigned long sipr = MMCRA_SIPR; |
146 | 168 | ||
169 | if (ppmu->flags & PPMU_HAS_SIER) | ||
170 | return !!(regs->dar & SIER_SIPR); | ||
171 | |||
147 | if (ppmu->flags & PPMU_ALT_SIPR) | 172 | if (ppmu->flags & PPMU_ALT_SIPR) |
148 | sipr = POWER6_MMCRA_SIPR; | 173 | sipr = POWER6_MMCRA_SIPR; |
149 | 174 | ||
150 | return !!(mmcra & sipr); | 175 | return !!(regs->dsisr & sipr); |
176 | } | ||
177 | |||
178 | static bool regs_no_sipr(struct pt_regs *regs) | ||
179 | { | ||
180 | return !!(regs->result & 2); | ||
151 | } | 181 | } |
152 | 182 | ||
153 | static inline u32 perf_flags_from_msr(struct pt_regs *regs) | 183 | static inline u32 perf_flags_from_msr(struct pt_regs *regs) |
@@ -161,8 +191,7 @@ static inline u32 perf_flags_from_msr(struct pt_regs *regs) | |||
161 | 191 | ||
162 | static inline u32 perf_get_misc_flags(struct pt_regs *regs) | 192 | static inline u32 perf_get_misc_flags(struct pt_regs *regs) |
163 | { | 193 | { |
164 | unsigned long mmcra = regs->dsisr; | 194 | bool use_siar = regs_use_siar(regs); |
165 | unsigned long use_siar = regs->result; | ||
166 | 195 | ||
167 | if (!use_siar) | 196 | if (!use_siar) |
168 | return perf_flags_from_msr(regs); | 197 | return perf_flags_from_msr(regs); |
@@ -173,7 +202,7 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs) | |||
173 | * SIAR which should give slightly more reliable | 202 | * SIAR which should give slightly more reliable |
174 | * results | 203 | * results |
175 | */ | 204 | */ |
176 | if (ppmu->flags & PPMU_NO_SIPR) { | 205 | if (regs_no_sipr(regs)) { |
177 | unsigned long siar = mfspr(SPRN_SIAR); | 206 | unsigned long siar = mfspr(SPRN_SIAR); |
178 | if (siar >= PAGE_OFFSET) | 207 | if (siar >= PAGE_OFFSET) |
179 | return PERF_RECORD_MISC_KERNEL; | 208 | return PERF_RECORD_MISC_KERNEL; |
@@ -181,16 +210,19 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs) | |||
181 | } | 210 | } |
182 | 211 | ||
183 | /* PR has priority over HV, so order below is important */ | 212 | /* PR has priority over HV, so order below is important */ |
184 | if (mmcra_sipr(mmcra)) | 213 | if (regs_sipr(regs)) |
185 | return PERF_RECORD_MISC_USER; | 214 | return PERF_RECORD_MISC_USER; |
186 | if (mmcra_sihv(mmcra) && (freeze_events_kernel != MMCR0_FCHV)) | 215 | |
216 | if (regs_sihv(regs) && (freeze_events_kernel != MMCR0_FCHV)) | ||
187 | return PERF_RECORD_MISC_HYPERVISOR; | 217 | return PERF_RECORD_MISC_HYPERVISOR; |
218 | |||
188 | return PERF_RECORD_MISC_KERNEL; | 219 | return PERF_RECORD_MISC_KERNEL; |
189 | } | 220 | } |
190 | 221 | ||
191 | /* | 222 | /* |
192 | * Overload regs->dsisr to store MMCRA so we only need to read it once | 223 | * Overload regs->dsisr to store MMCRA so we only need to read it once |
193 | * on each interrupt. | 224 | * on each interrupt. |
225 | * Overload regs->dar to store SIER if we have it. | ||
194 | * Overload regs->result to specify whether we should use the MSR (result | 226 | * Overload regs->result to specify whether we should use the MSR (result |
195 | * is zero) or the SIAR (result is non zero). | 227 | * is zero) or the SIAR (result is non zero). |
196 | */ | 228 | */ |
@@ -200,6 +232,24 @@ static inline void perf_read_regs(struct pt_regs *regs) | |||
200 | int marked = mmcra & MMCRA_SAMPLE_ENABLE; | 232 | int marked = mmcra & MMCRA_SAMPLE_ENABLE; |
201 | int use_siar; | 233 | int use_siar; |
202 | 234 | ||
235 | regs->dsisr = mmcra; | ||
236 | regs->result = 0; | ||
237 | |||
238 | if (ppmu->flags & PPMU_NO_SIPR) | ||
239 | regs->result |= 2; | ||
240 | |||
241 | /* | ||
242 | * On power8 if we're in random sampling mode, the SIER is updated. | ||
243 | * If we're in continuous sampling mode, we don't have SIPR. | ||
244 | */ | ||
245 | if (ppmu->flags & PPMU_HAS_SIER) { | ||
246 | if (marked) | ||
247 | regs->dar = mfspr(SPRN_SIER); | ||
248 | else | ||
249 | regs->result |= 2; | ||
250 | } | ||
251 | |||
252 | |||
203 | /* | 253 | /* |
204 | * If this isn't a PMU exception (eg a software event) the SIAR is | 254 | * If this isn't a PMU exception (eg a software event) the SIAR is |
205 | * not valid. Use pt_regs. | 255 | * not valid. Use pt_regs. |
@@ -223,13 +273,12 @@ static inline void perf_read_regs(struct pt_regs *regs) | |||
223 | use_siar = 1; | 273 | use_siar = 1; |
224 | else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING)) | 274 | else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING)) |
225 | use_siar = 0; | 275 | use_siar = 0; |
226 | else if (!(ppmu->flags & PPMU_NO_SIPR) && mmcra_sipr(mmcra)) | 276 | else if (!regs_no_sipr(regs) && regs_sipr(regs)) |
227 | use_siar = 0; | 277 | use_siar = 0; |
228 | else | 278 | else |
229 | use_siar = 1; | 279 | use_siar = 1; |
230 | 280 | ||
231 | regs->dsisr = mmcra; | 281 | regs->result |= use_siar; |
232 | regs->result = use_siar; | ||
233 | } | 282 | } |
234 | 283 | ||
235 | /* | 284 | /* |
@@ -822,6 +871,9 @@ static void power_pmu_enable(struct pmu *pmu) | |||
822 | } | 871 | } |
823 | 872 | ||
824 | out: | 873 | out: |
874 | if (cpuhw->bhrb_users) | ||
875 | ppmu->config_bhrb(cpuhw->bhrb_filter); | ||
876 | |||
825 | local_irq_restore(flags); | 877 | local_irq_restore(flags); |
826 | } | 878 | } |
827 | 879 | ||
@@ -852,6 +904,47 @@ static int collect_events(struct perf_event *group, int max_count, | |||
852 | return n; | 904 | return n; |
853 | } | 905 | } |
854 | 906 | ||
907 | /* Reset all possible BHRB entries */ | ||
908 | static void power_pmu_bhrb_reset(void) | ||
909 | { | ||
910 | asm volatile(PPC_CLRBHRB); | ||
911 | } | ||
912 | |||
913 | void power_pmu_bhrb_enable(struct perf_event *event) | ||
914 | { | ||
915 | struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); | ||
916 | |||
917 | if (!ppmu->bhrb_nr) | ||
918 | return; | ||
919 | |||
920 | /* Clear BHRB if we changed task context to avoid data leaks */ | ||
921 | if (event->ctx->task && cpuhw->bhrb_context != event->ctx) { | ||
922 | power_pmu_bhrb_reset(); | ||
923 | cpuhw->bhrb_context = event->ctx; | ||
924 | } | ||
925 | cpuhw->bhrb_users++; | ||
926 | } | ||
927 | |||
928 | void power_pmu_bhrb_disable(struct perf_event *event) | ||
929 | { | ||
930 | struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); | ||
931 | |||
932 | if (!ppmu->bhrb_nr) | ||
933 | return; | ||
934 | |||
935 | cpuhw->bhrb_users--; | ||
936 | WARN_ON_ONCE(cpuhw->bhrb_users < 0); | ||
937 | |||
938 | if (!cpuhw->disabled && !cpuhw->bhrb_users) { | ||
939 | /* BHRB cannot be turned off when other | ||
940 | * events are active on the PMU. | ||
941 | */ | ||
942 | |||
943 | /* avoid stale pointer */ | ||
944 | cpuhw->bhrb_context = NULL; | ||
945 | } | ||
946 | } | ||
947 | |||
855 | /* | 948 | /* |
856 | * Add a event to the PMU. | 949 | * Add a event to the PMU. |
857 | * If all events are not already frozen, then we disable and | 950 | * If all events are not already frozen, then we disable and |
@@ -911,6 +1004,9 @@ nocheck: | |||
911 | 1004 | ||
912 | ret = 0; | 1005 | ret = 0; |
913 | out: | 1006 | out: |
1007 | if (has_branch_stack(event)) | ||
1008 | power_pmu_bhrb_enable(event); | ||
1009 | |||
914 | perf_pmu_enable(event->pmu); | 1010 | perf_pmu_enable(event->pmu); |
915 | local_irq_restore(flags); | 1011 | local_irq_restore(flags); |
916 | return ret; | 1012 | return ret; |
@@ -963,6 +1059,9 @@ static void power_pmu_del(struct perf_event *event, int ef_flags) | |||
963 | cpuhw->mmcr[0] &= ~(MMCR0_PMXE | MMCR0_FCECE); | 1059 | cpuhw->mmcr[0] &= ~(MMCR0_PMXE | MMCR0_FCECE); |
964 | } | 1060 | } |
965 | 1061 | ||
1062 | if (has_branch_stack(event)) | ||
1063 | power_pmu_bhrb_disable(event); | ||
1064 | |||
966 | perf_pmu_enable(event->pmu); | 1065 | perf_pmu_enable(event->pmu); |
967 | local_irq_restore(flags); | 1066 | local_irq_restore(flags); |
968 | } | 1067 | } |
@@ -1081,6 +1180,15 @@ int power_pmu_commit_txn(struct pmu *pmu) | |||
1081 | return 0; | 1180 | return 0; |
1082 | } | 1181 | } |
1083 | 1182 | ||
1183 | /* Called from ctxsw to prevent one process's branch entries to | ||
1184 | * mingle with the other process's entries during context switch. | ||
1185 | */ | ||
1186 | void power_pmu_flush_branch_stack(void) | ||
1187 | { | ||
1188 | if (ppmu->bhrb_nr) | ||
1189 | power_pmu_bhrb_reset(); | ||
1190 | } | ||
1191 | |||
1084 | /* | 1192 | /* |
1085 | * Return 1 if we might be able to put event on a limited PMC, | 1193 | * Return 1 if we might be able to put event on a limited PMC, |
1086 | * or 0 if not. | 1194 | * or 0 if not. |
@@ -1195,9 +1303,11 @@ static int power_pmu_event_init(struct perf_event *event) | |||
1195 | if (!ppmu) | 1303 | if (!ppmu) |
1196 | return -ENOENT; | 1304 | return -ENOENT; |
1197 | 1305 | ||
1198 | /* does not support taken branch sampling */ | 1306 | if (has_branch_stack(event)) { |
1199 | if (has_branch_stack(event)) | 1307 | /* PMU has BHRB enabled */ |
1200 | return -EOPNOTSUPP; | 1308 | if (!(ppmu->flags & PPMU_BHRB)) |
1309 | return -EOPNOTSUPP; | ||
1310 | } | ||
1201 | 1311 | ||
1202 | switch (event->attr.type) { | 1312 | switch (event->attr.type) { |
1203 | case PERF_TYPE_HARDWARE: | 1313 | case PERF_TYPE_HARDWARE: |
@@ -1278,6 +1388,15 @@ static int power_pmu_event_init(struct perf_event *event) | |||
1278 | 1388 | ||
1279 | cpuhw = &get_cpu_var(cpu_hw_events); | 1389 | cpuhw = &get_cpu_var(cpu_hw_events); |
1280 | err = power_check_constraints(cpuhw, events, cflags, n + 1); | 1390 | err = power_check_constraints(cpuhw, events, cflags, n + 1); |
1391 | |||
1392 | if (has_branch_stack(event)) { | ||
1393 | cpuhw->bhrb_filter = ppmu->bhrb_filter_map( | ||
1394 | event->attr.branch_sample_type); | ||
1395 | |||
1396 | if(cpuhw->bhrb_filter == -1) | ||
1397 | return -EOPNOTSUPP; | ||
1398 | } | ||
1399 | |||
1281 | put_cpu_var(cpu_hw_events); | 1400 | put_cpu_var(cpu_hw_events); |
1282 | if (err) | 1401 | if (err) |
1283 | return -EINVAL; | 1402 | return -EINVAL; |
@@ -1336,8 +1455,79 @@ struct pmu power_pmu = { | |||
1336 | .cancel_txn = power_pmu_cancel_txn, | 1455 | .cancel_txn = power_pmu_cancel_txn, |
1337 | .commit_txn = power_pmu_commit_txn, | 1456 | .commit_txn = power_pmu_commit_txn, |
1338 | .event_idx = power_pmu_event_idx, | 1457 | .event_idx = power_pmu_event_idx, |
1458 | .flush_branch_stack = power_pmu_flush_branch_stack, | ||
1339 | }; | 1459 | }; |
1340 | 1460 | ||
1461 | /* Processing BHRB entries */ | ||
1462 | void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) | ||
1463 | { | ||
1464 | u64 val; | ||
1465 | u64 addr; | ||
1466 | int r_index, u_index, target, pred; | ||
1467 | |||
1468 | r_index = 0; | ||
1469 | u_index = 0; | ||
1470 | while (r_index < ppmu->bhrb_nr) { | ||
1471 | /* Assembly read function */ | ||
1472 | val = read_bhrb(r_index); | ||
1473 | |||
1474 | /* Terminal marker: End of valid BHRB entries */ | ||
1475 | if (val == 0) { | ||
1476 | break; | ||
1477 | } else { | ||
1478 | /* BHRB field break up */ | ||
1479 | addr = val & BHRB_EA; | ||
1480 | pred = val & BHRB_PREDICTION; | ||
1481 | target = val & BHRB_TARGET; | ||
1482 | |||
1483 | /* Probable Missed entry: Not applicable for POWER8 */ | ||
1484 | if ((addr == 0) && (target == 0) && (pred == 1)) { | ||
1485 | r_index++; | ||
1486 | continue; | ||
1487 | } | ||
1488 | |||
1489 | /* Real Missed entry: Power8 based missed entry */ | ||
1490 | if ((addr == 0) && (target == 1) && (pred == 1)) { | ||
1491 | r_index++; | ||
1492 | continue; | ||
1493 | } | ||
1494 | |||
1495 | /* Reserved condition: Not a valid entry */ | ||
1496 | if ((addr == 0) && (target == 1) && (pred == 0)) { | ||
1497 | r_index++; | ||
1498 | continue; | ||
1499 | } | ||
1500 | |||
1501 | /* Is a target address */ | ||
1502 | if (val & BHRB_TARGET) { | ||
1503 | /* First address cannot be a target address */ | ||
1504 | if (r_index == 0) { | ||
1505 | r_index++; | ||
1506 | continue; | ||
1507 | } | ||
1508 | |||
1509 | /* Update target address for the previous entry */ | ||
1510 | cpuhw->bhrb_entries[u_index - 1].to = addr; | ||
1511 | cpuhw->bhrb_entries[u_index - 1].mispred = pred; | ||
1512 | cpuhw->bhrb_entries[u_index - 1].predicted = ~pred; | ||
1513 | |||
1514 | /* Dont increment u_index */ | ||
1515 | r_index++; | ||
1516 | } else { | ||
1517 | /* Update address, flags for current entry */ | ||
1518 | cpuhw->bhrb_entries[u_index].from = addr; | ||
1519 | cpuhw->bhrb_entries[u_index].mispred = pred; | ||
1520 | cpuhw->bhrb_entries[u_index].predicted = ~pred; | ||
1521 | |||
1522 | /* Successfully popullated one entry */ | ||
1523 | u_index++; | ||
1524 | r_index++; | ||
1525 | } | ||
1526 | } | ||
1527 | } | ||
1528 | cpuhw->bhrb_stack.nr = u_index; | ||
1529 | return; | ||
1530 | } | ||
1341 | 1531 | ||
1342 | /* | 1532 | /* |
1343 | * A counter has overflowed; update its count and record | 1533 | * A counter has overflowed; update its count and record |
@@ -1397,6 +1587,13 @@ static void record_and_restart(struct perf_event *event, unsigned long val, | |||
1397 | if (event->attr.sample_type & PERF_SAMPLE_ADDR) | 1587 | if (event->attr.sample_type & PERF_SAMPLE_ADDR) |
1398 | perf_get_data_addr(regs, &data.addr); | 1588 | perf_get_data_addr(regs, &data.addr); |
1399 | 1589 | ||
1590 | if (event->attr.sample_type & PERF_SAMPLE_BRANCH_STACK) { | ||
1591 | struct cpu_hw_events *cpuhw; | ||
1592 | cpuhw = &__get_cpu_var(cpu_hw_events); | ||
1593 | power_pmu_bhrb_read(cpuhw); | ||
1594 | data.br_stack = &cpuhw->bhrb_stack; | ||
1595 | } | ||
1596 | |||
1400 | if (perf_event_overflow(event, &data, regs)) | 1597 | if (perf_event_overflow(event, &data, regs)) |
1401 | power_pmu_stop(event, 0); | 1598 | power_pmu_stop(event, 0); |
1402 | } | 1599 | } |
@@ -1422,7 +1619,7 @@ unsigned long perf_misc_flags(struct pt_regs *regs) | |||
1422 | */ | 1619 | */ |
1423 | unsigned long perf_instruction_pointer(struct pt_regs *regs) | 1620 | unsigned long perf_instruction_pointer(struct pt_regs *regs) |
1424 | { | 1621 | { |
1425 | unsigned long use_siar = regs->result; | 1622 | bool use_siar = regs_use_siar(regs); |
1426 | 1623 | ||
1427 | if (use_siar && siar_valid(regs)) | 1624 | if (use_siar && siar_valid(regs)) |
1428 | return mfspr(SPRN_SIAR) + perf_ip_adjust(regs); | 1625 | return mfspr(SPRN_SIAR) + perf_ip_adjust(regs); |
diff --git a/arch/powerpc/perf/power5+-pmu.c b/arch/powerpc/perf/power5+-pmu.c index a8757baa28f3..b03b6dc0172d 100644 --- a/arch/powerpc/perf/power5+-pmu.c +++ b/arch/powerpc/perf/power5+-pmu.c | |||
@@ -671,7 +671,7 @@ static struct power_pmu power5p_pmu = { | |||
671 | .get_alternatives = power5p_get_alternatives, | 671 | .get_alternatives = power5p_get_alternatives, |
672 | .disable_pmc = power5p_disable_pmc, | 672 | .disable_pmc = power5p_disable_pmc, |
673 | .limited_pmc_event = power5p_limited_pmc_event, | 673 | .limited_pmc_event = power5p_limited_pmc_event, |
674 | .flags = PPMU_LIMITED_PMC5_6, | 674 | .flags = PPMU_LIMITED_PMC5_6 | PPMU_HAS_SSLOT, |
675 | .n_generic = ARRAY_SIZE(power5p_generic_events), | 675 | .n_generic = ARRAY_SIZE(power5p_generic_events), |
676 | .generic_events = power5p_generic_events, | 676 | .generic_events = power5p_generic_events, |
677 | .cache_events = &power5p_cache_events, | 677 | .cache_events = &power5p_cache_events, |
diff --git a/arch/powerpc/perf/power5-pmu.c b/arch/powerpc/perf/power5-pmu.c index e7f06eb7a861..1e8ce423c3af 100644 --- a/arch/powerpc/perf/power5-pmu.c +++ b/arch/powerpc/perf/power5-pmu.c | |||
@@ -615,6 +615,7 @@ static struct power_pmu power5_pmu = { | |||
615 | .n_generic = ARRAY_SIZE(power5_generic_events), | 615 | .n_generic = ARRAY_SIZE(power5_generic_events), |
616 | .generic_events = power5_generic_events, | 616 | .generic_events = power5_generic_events, |
617 | .cache_events = &power5_cache_events, | 617 | .cache_events = &power5_cache_events, |
618 | .flags = PPMU_HAS_SSLOT, | ||
618 | }; | 619 | }; |
619 | 620 | ||
620 | static int __init init_power5_pmu(void) | 621 | static int __init init_power5_pmu(void) |
diff --git a/arch/powerpc/perf/power7-pmu.c b/arch/powerpc/perf/power7-pmu.c index b554879bd31e..3c475d6267c7 100644 --- a/arch/powerpc/perf/power7-pmu.c +++ b/arch/powerpc/perf/power7-pmu.c | |||
@@ -420,7 +420,20 @@ static struct attribute_group power7_pmu_events_group = { | |||
420 | .attrs = power7_events_attr, | 420 | .attrs = power7_events_attr, |
421 | }; | 421 | }; |
422 | 422 | ||
423 | PMU_FORMAT_ATTR(event, "config:0-19"); | ||
424 | |||
425 | static struct attribute *power7_pmu_format_attr[] = { | ||
426 | &format_attr_event.attr, | ||
427 | NULL, | ||
428 | }; | ||
429 | |||
430 | struct attribute_group power7_pmu_format_group = { | ||
431 | .name = "format", | ||
432 | .attrs = power7_pmu_format_attr, | ||
433 | }; | ||
434 | |||
423 | static const struct attribute_group *power7_pmu_attr_groups[] = { | 435 | static const struct attribute_group *power7_pmu_attr_groups[] = { |
436 | &power7_pmu_format_group, | ||
424 | &power7_pmu_events_group, | 437 | &power7_pmu_events_group, |
425 | NULL, | 438 | NULL, |
426 | }; | 439 | }; |
diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c new file mode 100644 index 000000000000..f7d1c4fff303 --- /dev/null +++ b/arch/powerpc/perf/power8-pmu.c | |||
@@ -0,0 +1,592 @@ | |||
1 | /* | ||
2 | * Performance counter support for POWER8 processors. | ||
3 | * | ||
4 | * Copyright 2009 Paul Mackerras, IBM Corporation. | ||
5 | * Copyright 2013 Michael Ellerman, IBM Corporation. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version | ||
10 | * 2 of the License, or (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/perf_event.h> | ||
15 | #include <asm/firmware.h> | ||
16 | |||
17 | |||
18 | /* | ||
19 | * Some power8 event codes. | ||
20 | */ | ||
21 | #define PM_CYC 0x0001e | ||
22 | #define PM_GCT_NOSLOT_CYC 0x100f8 | ||
23 | #define PM_CMPLU_STALL 0x4000a | ||
24 | #define PM_INST_CMPL 0x00002 | ||
25 | #define PM_BRU_FIN 0x10068 | ||
26 | #define PM_BR_MPRED_CMPL 0x400f6 | ||
27 | |||
28 | |||
29 | /* | ||
30 | * Raw event encoding for POWER8: | ||
31 | * | ||
32 | * 60 56 52 48 44 40 36 32 | ||
33 | * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | | ||
34 | * [ thresh_cmp ] [ thresh_ctl ] | ||
35 | * | | ||
36 | * thresh start/stop OR FAB match -* | ||
37 | * | ||
38 | * 28 24 20 16 12 8 4 0 | ||
39 | * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | | ||
40 | * [ ] [ sample ] [cache] [ pmc ] [unit ] c m [ pmcxsel ] | ||
41 | * | | | | | | ||
42 | * | | | | *- mark | ||
43 | * | | *- L1/L2/L3 cache_sel | | ||
44 | * | | | | ||
45 | * | *- sampling mode for marked events *- combine | ||
46 | * | | ||
47 | * *- thresh_sel | ||
48 | * | ||
49 | * Below uses IBM bit numbering. | ||
50 | * | ||
51 | * MMCR1[x:y] = unit (PMCxUNIT) | ||
52 | * MMCR1[x] = combine (PMCxCOMB) | ||
53 | * | ||
54 | * if pmc == 3 and unit == 0 and pmcxsel[0:6] == 0b0101011 | ||
55 | * # PM_MRK_FAB_RSP_MATCH | ||
56 | * MMCR1[20:27] = thresh_ctl (FAB_CRESP_MATCH / FAB_TYPE_MATCH) | ||
57 | * else if pmc == 4 and unit == 0xf and pmcxsel[0:6] == 0b0101001 | ||
58 | * # PM_MRK_FAB_RSP_MATCH_CYC | ||
59 | * MMCR1[20:27] = thresh_ctl (FAB_CRESP_MATCH / FAB_TYPE_MATCH) | ||
60 | * else | ||
61 | * MMCRA[48:55] = thresh_ctl (THRESH START/END) | ||
62 | * | ||
63 | * if thresh_sel: | ||
64 | * MMCRA[45:47] = thresh_sel | ||
65 | * | ||
66 | * if thresh_cmp: | ||
67 | * MMCRA[22:24] = thresh_cmp[0:2] | ||
68 | * MMCRA[25:31] = thresh_cmp[3:9] | ||
69 | * | ||
70 | * if unit == 6 or unit == 7 | ||
71 | * MMCRC[53:55] = cache_sel[1:3] (L2EVENT_SEL) | ||
72 | * else if unit == 8 or unit == 9: | ||
73 | * if cache_sel[0] == 0: # L3 bank | ||
74 | * MMCRC[47:49] = cache_sel[1:3] (L3EVENT_SEL0) | ||
75 | * else if cache_sel[0] == 1: | ||
76 | * MMCRC[50:51] = cache_sel[2:3] (L3EVENT_SEL1) | ||
77 | * else if cache_sel[1]: # L1 event | ||
78 | * MMCR1[16] = cache_sel[2] | ||
79 | Â * MMCR1[17] = cache_sel[3] | ||
80 | * | ||
81 | * if mark: | ||
82 | * MMCRA[63] = 1 (SAMPLE_ENABLE) | ||
83 | * MMCRA[57:59] = sample[0:2] (RAND_SAMP_ELIG) | ||
84 | Â * MMCRA[61:62] = sample[3:4] (RAND_SAMP_MODE) | ||
85 | * | ||
86 | */ | ||
87 | |||
88 | #define EVENT_THR_CMP_SHIFT 40 /* Threshold CMP value */ | ||
89 | #define EVENT_THR_CMP_MASK 0x3ff | ||
90 | #define EVENT_THR_CTL_SHIFT 32 /* Threshold control value (start/stop) */ | ||
91 | #define EVENT_THR_CTL_MASK 0xffull | ||
92 | #define EVENT_THR_SEL_SHIFT 29 /* Threshold select value */ | ||
93 | #define EVENT_THR_SEL_MASK 0x7 | ||
94 | #define EVENT_THRESH_SHIFT 29 /* All threshold bits */ | ||
95 | #define EVENT_THRESH_MASK 0x1fffffull | ||
96 | #define EVENT_SAMPLE_SHIFT 24 /* Sampling mode & eligibility */ | ||
97 | #define EVENT_SAMPLE_MASK 0x1f | ||
98 | #define EVENT_CACHE_SEL_SHIFT 20 /* L2/L3 cache select */ | ||
99 | #define EVENT_CACHE_SEL_MASK 0xf | ||
100 | #define EVENT_IS_L1 (4 << EVENT_CACHE_SEL_SHIFT) | ||
101 | #define EVENT_PMC_SHIFT 16 /* PMC number (1-based) */ | ||
102 | #define EVENT_PMC_MASK 0xf | ||
103 | #define EVENT_UNIT_SHIFT 12 /* Unit */ | ||
104 | #define EVENT_UNIT_MASK 0xf | ||
105 | #define EVENT_COMBINE_SHIFT 11 /* Combine bit */ | ||
106 | #define EVENT_COMBINE_MASK 0x1 | ||
107 | #define EVENT_MARKED_SHIFT 8 /* Marked bit */ | ||
108 | #define EVENT_MARKED_MASK 0x1 | ||
109 | #define EVENT_IS_MARKED (EVENT_MARKED_MASK << EVENT_MARKED_SHIFT) | ||
110 | #define EVENT_PSEL_MASK 0xff /* PMCxSEL value */ | ||
111 | |||
112 | /* MMCRA IFM bits - POWER8 */ | ||
113 | #define POWER8_MMCRA_IFM1 0x0000000040000000UL | ||
114 | #define POWER8_MMCRA_IFM2 0x0000000080000000UL | ||
115 | #define POWER8_MMCRA_IFM3 0x00000000C0000000UL | ||
116 | |||
117 | #define ONLY_PLM \ | ||
118 | (PERF_SAMPLE_BRANCH_USER |\ | ||
119 | PERF_SAMPLE_BRANCH_KERNEL |\ | ||
120 | PERF_SAMPLE_BRANCH_HV) | ||
121 | |||
122 | /* | ||
123 | * Layout of constraint bits: | ||
124 | * | ||
125 | * 60 56 52 48 44 40 36 32 | ||
126 | * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | | ||
127 | * [ fab_match ] [ thresh_cmp ] [ thresh_ctl ] [ ] | ||
128 | * | | ||
129 | * thresh_sel -* | ||
130 | * | ||
131 | * 28 24 20 16 12 8 4 0 | ||
132 | * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | | ||
133 | * [ ] [ sample ] [ ] [6] [5] [4] [3] [2] [1] | ||
134 | * | | | ||
135 | * L1 I/D qualifier -* | Count of events for each PMC. | ||
136 | * | p1, p2, p3, p4, p5, p6. | ||
137 | * nc - number of counters -* | ||
138 | * | ||
139 | * The PMC fields P1..P6, and NC, are adder fields. As we accumulate constraints | ||
140 | * we want the low bit of each field to be added to any existing value. | ||
141 | * | ||
142 | * Everything else is a value field. | ||
143 | */ | ||
144 | |||
145 | #define CNST_FAB_MATCH_VAL(v) (((v) & EVENT_THR_CTL_MASK) << 56) | ||
146 | #define CNST_FAB_MATCH_MASK CNST_FAB_MATCH_VAL(EVENT_THR_CTL_MASK) | ||
147 | |||
148 | /* We just throw all the threshold bits into the constraint */ | ||
149 | #define CNST_THRESH_VAL(v) (((v) & EVENT_THRESH_MASK) << 32) | ||
150 | #define CNST_THRESH_MASK CNST_THRESH_VAL(EVENT_THRESH_MASK) | ||
151 | |||
152 | #define CNST_L1_QUAL_VAL(v) (((v) & 3) << 22) | ||
153 | #define CNST_L1_QUAL_MASK CNST_L1_QUAL_VAL(3) | ||
154 | |||
155 | #define CNST_SAMPLE_VAL(v) (((v) & EVENT_SAMPLE_MASK) << 16) | ||
156 | #define CNST_SAMPLE_MASK CNST_SAMPLE_VAL(EVENT_SAMPLE_MASK) | ||
157 | |||
158 | /* | ||
159 | * For NC we are counting up to 4 events. This requires three bits, and we need | ||
160 | * the fifth event to overflow and set the 4th bit. To achieve that we bias the | ||
161 | * fields by 3 in test_adder. | ||
162 | */ | ||
163 | #define CNST_NC_SHIFT 12 | ||
164 | #define CNST_NC_VAL (1 << CNST_NC_SHIFT) | ||
165 | #define CNST_NC_MASK (8 << CNST_NC_SHIFT) | ||
166 | #define POWER8_TEST_ADDER (3 << CNST_NC_SHIFT) | ||
167 | |||
168 | /* | ||
169 | * For the per-PMC fields we have two bits. The low bit is added, so if two | ||
170 | * events ask for the same PMC the sum will overflow, setting the high bit, | ||
171 | * indicating an error. So our mask sets the high bit. | ||
172 | */ | ||
173 | #define CNST_PMC_SHIFT(pmc) ((pmc - 1) * 2) | ||
174 | #define CNST_PMC_VAL(pmc) (1 << CNST_PMC_SHIFT(pmc)) | ||
175 | #define CNST_PMC_MASK(pmc) (2 << CNST_PMC_SHIFT(pmc)) | ||
176 | |||
177 | /* Our add_fields is defined as: */ | ||
178 | #define POWER8_ADD_FIELDS \ | ||
179 | CNST_PMC_VAL(1) | CNST_PMC_VAL(2) | CNST_PMC_VAL(3) | \ | ||
180 | CNST_PMC_VAL(4) | CNST_PMC_VAL(5) | CNST_PMC_VAL(6) | CNST_NC_VAL | ||
181 | |||
182 | |||
183 | /* Bits in MMCR1 for POWER8 */ | ||
184 | #define MMCR1_UNIT_SHIFT(pmc) (60 - (4 * ((pmc) - 1))) | ||
185 | #define MMCR1_COMBINE_SHIFT(pmc) (35 - ((pmc) - 1)) | ||
186 | #define MMCR1_PMCSEL_SHIFT(pmc) (24 - (((pmc) - 1)) * 8) | ||
187 | #define MMCR1_DC_QUAL_SHIFT 47 | ||
188 | #define MMCR1_IC_QUAL_SHIFT 46 | ||
189 | |||
190 | /* Bits in MMCRA for POWER8 */ | ||
191 | #define MMCRA_SAMP_MODE_SHIFT 1 | ||
192 | #define MMCRA_SAMP_ELIG_SHIFT 4 | ||
193 | #define MMCRA_THR_CTL_SHIFT 8 | ||
194 | #define MMCRA_THR_SEL_SHIFT 16 | ||
195 | #define MMCRA_THR_CMP_SHIFT 32 | ||
196 | #define MMCRA_SDAR_MODE_TLB (1ull << 42) | ||
197 | |||
198 | |||
199 | static inline bool event_is_fab_match(u64 event) | ||
200 | { | ||
201 | /* Only check pmc, unit and pmcxsel, ignore the edge bit (0) */ | ||
202 | event &= 0xff0fe; | ||
203 | |||
204 | /* PM_MRK_FAB_RSP_MATCH & PM_MRK_FAB_RSP_MATCH_CYC */ | ||
205 | return (event == 0x30056 || event == 0x4f052); | ||
206 | } | ||
207 | |||
208 | static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp) | ||
209 | { | ||
210 | unsigned int unit, pmc, cache; | ||
211 | unsigned long mask, value; | ||
212 | |||
213 | mask = value = 0; | ||
214 | |||
215 | pmc = (event >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK; | ||
216 | unit = (event >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK; | ||
217 | cache = (event >> EVENT_CACHE_SEL_SHIFT) & EVENT_CACHE_SEL_MASK; | ||
218 | |||
219 | if (pmc) { | ||
220 | if (pmc > 6) | ||
221 | return -1; | ||
222 | |||
223 | mask |= CNST_PMC_MASK(pmc); | ||
224 | value |= CNST_PMC_VAL(pmc); | ||
225 | |||
226 | if (pmc >= 5 && event != 0x500fa && event != 0x600f4) | ||
227 | return -1; | ||
228 | } | ||
229 | |||
230 | if (pmc <= 4) { | ||
231 | /* | ||
232 | * Add to number of counters in use. Note this includes events with | ||
233 | * a PMC of 0 - they still need a PMC, it's just assigned later. | ||
234 | * Don't count events on PMC 5 & 6, there is only one valid event | ||
235 | * on each of those counters, and they are handled above. | ||
236 | */ | ||
237 | mask |= CNST_NC_MASK; | ||
238 | value |= CNST_NC_VAL; | ||
239 | } | ||
240 | |||
241 | if (unit >= 6 && unit <= 9) { | ||
242 | /* | ||
243 | * L2/L3 events contain a cache selector field, which is | ||
244 | * supposed to be programmed into MMCRC. However MMCRC is only | ||
245 | * HV writable, and there is no API for guest kernels to modify | ||
246 | * it. The solution is for the hypervisor to initialise the | ||
247 | * field to zeroes, and for us to only ever allow events that | ||
248 | * have a cache selector of zero. | ||
249 | */ | ||
250 | if (cache) | ||
251 | return -1; | ||
252 | |||
253 | } else if (event & EVENT_IS_L1) { | ||
254 | mask |= CNST_L1_QUAL_MASK; | ||
255 | value |= CNST_L1_QUAL_VAL(cache); | ||
256 | } | ||
257 | |||
258 | if (event & EVENT_IS_MARKED) { | ||
259 | mask |= CNST_SAMPLE_MASK; | ||
260 | value |= CNST_SAMPLE_VAL(event >> EVENT_SAMPLE_SHIFT); | ||
261 | } | ||
262 | |||
263 | /* | ||
264 | * Special case for PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC, | ||
265 | * the threshold control bits are used for the match value. | ||
266 | */ | ||
267 | if (event_is_fab_match(event)) { | ||
268 | mask |= CNST_FAB_MATCH_MASK; | ||
269 | value |= CNST_FAB_MATCH_VAL(event >> EVENT_THR_CTL_SHIFT); | ||
270 | } else { | ||
271 | /* | ||
272 | * Check the mantissa upper two bits are not zero, unless the | ||
273 | * exponent is also zero. See the THRESH_CMP_MANTISSA doc. | ||
274 | */ | ||
275 | unsigned int cmp, exp; | ||
276 | |||
277 | cmp = (event >> EVENT_THR_CMP_SHIFT) & EVENT_THR_CMP_MASK; | ||
278 | exp = cmp >> 7; | ||
279 | |||
280 | if (exp && (cmp & 0x60) == 0) | ||
281 | return -1; | ||
282 | |||
283 | mask |= CNST_THRESH_MASK; | ||
284 | value |= CNST_THRESH_VAL(event >> EVENT_THRESH_SHIFT); | ||
285 | } | ||
286 | |||
287 | *maskp = mask; | ||
288 | *valp = value; | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static int power8_compute_mmcr(u64 event[], int n_ev, | ||
294 | unsigned int hwc[], unsigned long mmcr[]) | ||
295 | { | ||
296 | unsigned long mmcra, mmcr1, unit, combine, psel, cache, val; | ||
297 | unsigned int pmc, pmc_inuse; | ||
298 | int i; | ||
299 | |||
300 | pmc_inuse = 0; | ||
301 | |||
302 | /* First pass to count resource use */ | ||
303 | for (i = 0; i < n_ev; ++i) { | ||
304 | pmc = (event[i] >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK; | ||
305 | if (pmc) | ||
306 | pmc_inuse |= 1 << pmc; | ||
307 | } | ||
308 | |||
309 | /* In continous sampling mode, update SDAR on TLB miss */ | ||
310 | mmcra = MMCRA_SDAR_MODE_TLB; | ||
311 | mmcr1 = 0; | ||
312 | |||
313 | /* Second pass: assign PMCs, set all MMCR1 fields */ | ||
314 | for (i = 0; i < n_ev; ++i) { | ||
315 | pmc = (event[i] >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK; | ||
316 | unit = (event[i] >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK; | ||
317 | combine = (event[i] >> EVENT_COMBINE_SHIFT) & EVENT_COMBINE_MASK; | ||
318 | psel = event[i] & EVENT_PSEL_MASK; | ||
319 | |||
320 | if (!pmc) { | ||
321 | for (pmc = 1; pmc <= 4; ++pmc) { | ||
322 | if (!(pmc_inuse & (1 << pmc))) | ||
323 | break; | ||
324 | } | ||
325 | |||
326 | pmc_inuse |= 1 << pmc; | ||
327 | } | ||
328 | |||
329 | if (pmc <= 4) { | ||
330 | mmcr1 |= unit << MMCR1_UNIT_SHIFT(pmc); | ||
331 | mmcr1 |= combine << MMCR1_COMBINE_SHIFT(pmc); | ||
332 | mmcr1 |= psel << MMCR1_PMCSEL_SHIFT(pmc); | ||
333 | } | ||
334 | |||
335 | if (event[i] & EVENT_IS_L1) { | ||
336 | cache = event[i] >> EVENT_CACHE_SEL_SHIFT; | ||
337 | mmcr1 |= (cache & 1) << MMCR1_IC_QUAL_SHIFT; | ||
338 | cache >>= 1; | ||
339 | mmcr1 |= (cache & 1) << MMCR1_DC_QUAL_SHIFT; | ||
340 | } | ||
341 | |||
342 | if (event[i] & EVENT_IS_MARKED) { | ||
343 | mmcra |= MMCRA_SAMPLE_ENABLE; | ||
344 | |||
345 | val = (event[i] >> EVENT_SAMPLE_SHIFT) & EVENT_SAMPLE_MASK; | ||
346 | if (val) { | ||
347 | mmcra |= (val & 3) << MMCRA_SAMP_MODE_SHIFT; | ||
348 | mmcra |= (val >> 2) << MMCRA_SAMP_ELIG_SHIFT; | ||
349 | } | ||
350 | } | ||
351 | |||
352 | /* | ||
353 | * PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC, | ||
354 | * the threshold bits are used for the match value. | ||
355 | */ | ||
356 | if (event_is_fab_match(event[i])) { | ||
357 | mmcr1 |= (event[i] >> EVENT_THR_CTL_SHIFT) & | ||
358 | EVENT_THR_CTL_MASK; | ||
359 | } else { | ||
360 | val = (event[i] >> EVENT_THR_CTL_SHIFT) & EVENT_THR_CTL_MASK; | ||
361 | mmcra |= val << MMCRA_THR_CTL_SHIFT; | ||
362 | val = (event[i] >> EVENT_THR_SEL_SHIFT) & EVENT_THR_SEL_MASK; | ||
363 | mmcra |= val << MMCRA_THR_SEL_SHIFT; | ||
364 | val = (event[i] >> EVENT_THR_CMP_SHIFT) & EVENT_THR_CMP_MASK; | ||
365 | mmcra |= val << MMCRA_THR_CMP_SHIFT; | ||
366 | } | ||
367 | |||
368 | hwc[i] = pmc - 1; | ||
369 | } | ||
370 | |||
371 | /* Return MMCRx values */ | ||
372 | mmcr[0] = 0; | ||
373 | |||
374 | /* pmc_inuse is 1-based */ | ||
375 | if (pmc_inuse & 2) | ||
376 | mmcr[0] = MMCR0_PMC1CE; | ||
377 | |||
378 | if (pmc_inuse & 0x7c) | ||
379 | mmcr[0] |= MMCR0_PMCjCE; | ||
380 | |||
381 | mmcr[1] = mmcr1; | ||
382 | mmcr[2] = mmcra; | ||
383 | |||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | #define MAX_ALT 2 | ||
388 | |||
389 | /* Table of alternatives, sorted by column 0 */ | ||
390 | static const unsigned int event_alternatives[][MAX_ALT] = { | ||
391 | { 0x10134, 0x301e2 }, /* PM_MRK_ST_CMPL */ | ||
392 | { 0x10138, 0x40138 }, /* PM_BR_MRK_2PATH */ | ||
393 | { 0x18082, 0x3e05e }, /* PM_L3_CO_MEPF */ | ||
394 | { 0x1d14e, 0x401e8 }, /* PM_MRK_DATA_FROM_L2MISS */ | ||
395 | { 0x1e054, 0x4000a }, /* PM_CMPLU_STALL */ | ||
396 | { 0x20036, 0x40036 }, /* PM_BR_2PATH */ | ||
397 | { 0x200f2, 0x300f2 }, /* PM_INST_DISP */ | ||
398 | { 0x200f4, 0x600f4 }, /* PM_RUN_CYC */ | ||
399 | { 0x2013c, 0x3012e }, /* PM_MRK_FILT_MATCH */ | ||
400 | { 0x3e054, 0x400f0 }, /* PM_LD_MISS_L1 */ | ||
401 | { 0x400fa, 0x500fa }, /* PM_RUN_INST_CMPL */ | ||
402 | }; | ||
403 | |||
404 | /* | ||
405 | * Scan the alternatives table for a match and return the | ||
406 | * index into the alternatives table if found, else -1. | ||
407 | */ | ||
408 | static int find_alternative(u64 event) | ||
409 | { | ||
410 | int i, j; | ||
411 | |||
412 | for (i = 0; i < ARRAY_SIZE(event_alternatives); ++i) { | ||
413 | if (event < event_alternatives[i][0]) | ||
414 | break; | ||
415 | |||
416 | for (j = 0; j < MAX_ALT && event_alternatives[i][j]; ++j) | ||
417 | if (event == event_alternatives[i][j]) | ||
418 | return i; | ||
419 | } | ||
420 | |||
421 | return -1; | ||
422 | } | ||
423 | |||
424 | static int power8_get_alternatives(u64 event, unsigned int flags, u64 alt[]) | ||
425 | { | ||
426 | int i, j, num_alt = 0; | ||
427 | u64 alt_event; | ||
428 | |||
429 | alt[num_alt++] = event; | ||
430 | |||
431 | i = find_alternative(event); | ||
432 | if (i >= 0) { | ||
433 | /* Filter out the original event, it's already in alt[0] */ | ||
434 | for (j = 0; j < MAX_ALT; ++j) { | ||
435 | alt_event = event_alternatives[i][j]; | ||
436 | if (alt_event && alt_event != event) | ||
437 | alt[num_alt++] = alt_event; | ||
438 | } | ||
439 | } | ||
440 | |||
441 | if (flags & PPMU_ONLY_COUNT_RUN) { | ||
442 | /* | ||
443 | * We're only counting in RUN state, so PM_CYC is equivalent to | ||
444 | * PM_RUN_CYC and PM_INST_CMPL === PM_RUN_INST_CMPL. | ||
445 | */ | ||
446 | j = num_alt; | ||
447 | for (i = 0; i < num_alt; ++i) { | ||
448 | switch (alt[i]) { | ||
449 | case 0x1e: /* PM_CYC */ | ||
450 | alt[j++] = 0x600f4; /* PM_RUN_CYC */ | ||
451 | break; | ||
452 | case 0x600f4: /* PM_RUN_CYC */ | ||
453 | alt[j++] = 0x1e; | ||
454 | break; | ||
455 | case 0x2: /* PM_PPC_CMPL */ | ||
456 | alt[j++] = 0x500fa; /* PM_RUN_INST_CMPL */ | ||
457 | break; | ||
458 | case 0x500fa: /* PM_RUN_INST_CMPL */ | ||
459 | alt[j++] = 0x2; /* PM_PPC_CMPL */ | ||
460 | break; | ||
461 | } | ||
462 | } | ||
463 | num_alt = j; | ||
464 | } | ||
465 | |||
466 | return num_alt; | ||
467 | } | ||
468 | |||
469 | static void power8_disable_pmc(unsigned int pmc, unsigned long mmcr[]) | ||
470 | { | ||
471 | if (pmc <= 3) | ||
472 | mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SHIFT(pmc + 1)); | ||
473 | } | ||
474 | |||
475 | PMU_FORMAT_ATTR(event, "config:0-49"); | ||
476 | PMU_FORMAT_ATTR(pmcxsel, "config:0-7"); | ||
477 | PMU_FORMAT_ATTR(mark, "config:8"); | ||
478 | PMU_FORMAT_ATTR(combine, "config:11"); | ||
479 | PMU_FORMAT_ATTR(unit, "config:12-15"); | ||
480 | PMU_FORMAT_ATTR(pmc, "config:16-19"); | ||
481 | PMU_FORMAT_ATTR(cache_sel, "config:20-23"); | ||
482 | PMU_FORMAT_ATTR(sample_mode, "config:24-28"); | ||
483 | PMU_FORMAT_ATTR(thresh_sel, "config:29-31"); | ||
484 | PMU_FORMAT_ATTR(thresh_stop, "config:32-35"); | ||
485 | PMU_FORMAT_ATTR(thresh_start, "config:36-39"); | ||
486 | PMU_FORMAT_ATTR(thresh_cmp, "config:40-49"); | ||
487 | |||
488 | static struct attribute *power8_pmu_format_attr[] = { | ||
489 | &format_attr_event.attr, | ||
490 | &format_attr_pmcxsel.attr, | ||
491 | &format_attr_mark.attr, | ||
492 | &format_attr_combine.attr, | ||
493 | &format_attr_unit.attr, | ||
494 | &format_attr_pmc.attr, | ||
495 | &format_attr_cache_sel.attr, | ||
496 | &format_attr_sample_mode.attr, | ||
497 | &format_attr_thresh_sel.attr, | ||
498 | &format_attr_thresh_stop.attr, | ||
499 | &format_attr_thresh_start.attr, | ||
500 | &format_attr_thresh_cmp.attr, | ||
501 | NULL, | ||
502 | }; | ||
503 | |||
504 | struct attribute_group power8_pmu_format_group = { | ||
505 | .name = "format", | ||
506 | .attrs = power8_pmu_format_attr, | ||
507 | }; | ||
508 | |||
509 | static const struct attribute_group *power8_pmu_attr_groups[] = { | ||
510 | &power8_pmu_format_group, | ||
511 | NULL, | ||
512 | }; | ||
513 | |||
514 | static int power8_generic_events[] = { | ||
515 | [PERF_COUNT_HW_CPU_CYCLES] = PM_CYC, | ||
516 | [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = PM_GCT_NOSLOT_CYC, | ||
517 | [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = PM_CMPLU_STALL, | ||
518 | [PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL, | ||
519 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BRU_FIN, | ||
520 | [PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED_CMPL, | ||
521 | }; | ||
522 | |||
523 | static u64 power8_bhrb_filter_map(u64 branch_sample_type) | ||
524 | { | ||
525 | u64 pmu_bhrb_filter = 0; | ||
526 | u64 br_privilege = branch_sample_type & ONLY_PLM; | ||
527 | |||
528 | /* BHRB and regular PMU events share the same prvillege state | ||
529 | * filter configuration. BHRB is always recorded along with a | ||
530 | * regular PMU event. So privilege state filter criteria for BHRB | ||
531 | * and the companion PMU events has to be the same. As a default | ||
532 | * "perf record" tool sets all privillege bits ON when no filter | ||
533 | * criteria is provided in the command line. So as along as all | ||
534 | * privillege bits are ON or they are OFF, we are good to go. | ||
535 | */ | ||
536 | if ((br_privilege != 7) && (br_privilege != 0)) | ||
537 | return -1; | ||
538 | |||
539 | /* No branch filter requested */ | ||
540 | if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY) | ||
541 | return pmu_bhrb_filter; | ||
542 | |||
543 | /* Invalid branch filter options - HW does not support */ | ||
544 | if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_RETURN) | ||
545 | return -1; | ||
546 | |||
547 | if (branch_sample_type & PERF_SAMPLE_BRANCH_IND_CALL) | ||
548 | return -1; | ||
549 | |||
550 | if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_CALL) { | ||
551 | pmu_bhrb_filter |= POWER8_MMCRA_IFM1; | ||
552 | return pmu_bhrb_filter; | ||
553 | } | ||
554 | |||
555 | /* Every thing else is unsupported */ | ||
556 | return -1; | ||
557 | } | ||
558 | |||
559 | static void power8_config_bhrb(u64 pmu_bhrb_filter) | ||
560 | { | ||
561 | /* Enable BHRB filter in PMU */ | ||
562 | mtspr(SPRN_MMCRA, (mfspr(SPRN_MMCRA) | pmu_bhrb_filter)); | ||
563 | } | ||
564 | |||
565 | static struct power_pmu power8_pmu = { | ||
566 | .name = "POWER8", | ||
567 | .n_counter = 6, | ||
568 | .max_alternatives = MAX_ALT + 1, | ||
569 | .add_fields = POWER8_ADD_FIELDS, | ||
570 | .test_adder = POWER8_TEST_ADDER, | ||
571 | .compute_mmcr = power8_compute_mmcr, | ||
572 | .config_bhrb = power8_config_bhrb, | ||
573 | .bhrb_filter_map = power8_bhrb_filter_map, | ||
574 | .get_constraint = power8_get_constraint, | ||
575 | .get_alternatives = power8_get_alternatives, | ||
576 | .disable_pmc = power8_disable_pmc, | ||
577 | .flags = PPMU_HAS_SSLOT | PPMU_HAS_SIER | PPMU_BHRB, | ||
578 | .n_generic = ARRAY_SIZE(power8_generic_events), | ||
579 | .generic_events = power8_generic_events, | ||
580 | .attr_groups = power8_pmu_attr_groups, | ||
581 | .bhrb_nr = 32, | ||
582 | }; | ||
583 | |||
584 | static int __init init_power8_pmu(void) | ||
585 | { | ||
586 | if (!cur_cpu_spec->oprofile_cpu_type || | ||
587 | strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power8")) | ||
588 | return -ENODEV; | ||
589 | |||
590 | return register_power_pmu(&power8_pmu); | ||
591 | } | ||
592 | early_initcall(init_power8_pmu); | ||
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig index a392d12dd21f..bd40bbb15e14 100644 --- a/arch/powerpc/platforms/40x/Kconfig +++ b/arch/powerpc/platforms/40x/Kconfig | |||
@@ -20,7 +20,6 @@ config HOTFOOT | |||
20 | bool "Hotfoot" | 20 | bool "Hotfoot" |
21 | depends on 40x | 21 | depends on 40x |
22 | default n | 22 | default n |
23 | select 405EP | ||
24 | select PPC40x_SIMPLE | 23 | select PPC40x_SIMPLE |
25 | select PCI | 24 | select PCI |
26 | help | 25 | help |
@@ -105,9 +104,6 @@ config 405GP | |||
105 | select IBM405_ERR51 | 104 | select IBM405_ERR51 |
106 | select IBM_EMAC_ZMII | 105 | select IBM_EMAC_ZMII |
107 | 106 | ||
108 | config 405EP | ||
109 | bool | ||
110 | |||
111 | config 405EX | 107 | config 405EX |
112 | bool | 108 | bool |
113 | select IBM_EMAC_EMAC4 | 109 | select IBM_EMAC_EMAC4 |
@@ -119,9 +115,6 @@ config 405EZ | |||
119 | select IBM_EMAC_MAL_CLR_ICINTSTAT | 115 | select IBM_EMAC_MAL_CLR_ICINTSTAT |
120 | select IBM_EMAC_MAL_COMMON_ERR | 116 | select IBM_EMAC_MAL_COMMON_ERR |
121 | 117 | ||
122 | config 405GPR | ||
123 | bool | ||
124 | |||
125 | config XILINX_VIRTEX | 118 | config XILINX_VIRTEX |
126 | bool | 119 | bool |
127 | select DEFAULT_UIMAGE | 120 | select DEFAULT_UIMAGE |
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index 0effe9f5a1ea..7be93367d92f 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig | |||
@@ -274,6 +274,8 @@ config 440EPX | |||
274 | select IBM_EMAC_EMAC4 | 274 | select IBM_EMAC_EMAC4 |
275 | select IBM_EMAC_RGMII | 275 | select IBM_EMAC_RGMII |
276 | select IBM_EMAC_ZMII | 276 | select IBM_EMAC_ZMII |
277 | select USB_EHCI_BIG_ENDIAN_MMIO | ||
278 | select USB_EHCI_BIG_ENDIAN_DESC | ||
277 | 279 | ||
278 | config 440GRX | 280 | config 440GRX |
279 | bool | 281 | bool |
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig index c16999802ecf..fc9c1cbfcb1d 100644 --- a/arch/powerpc/platforms/512x/Kconfig +++ b/arch/powerpc/platforms/512x/Kconfig | |||
@@ -7,6 +7,8 @@ config PPC_MPC512x | |||
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 | select ARCH_WANT_OPTIONAL_GPIOLIB |
10 | select USB_EHCI_BIG_ENDIAN_MMIO | ||
11 | select USB_EHCI_BIG_ENDIAN_DESC | ||
10 | 12 | ||
11 | config MPC5121_ADS | 13 | config MPC5121_ADS |
12 | bool "Freescale MPC5121E ADS" | 14 | bool "Freescale MPC5121E ADS" |
@@ -15,16 +17,16 @@ config MPC5121_ADS | |||
15 | help | 17 | help |
16 | This option enables support for the MPC5121E ADS board. | 18 | This option enables support for the MPC5121E ADS board. |
17 | 19 | ||
18 | config MPC5121_GENERIC | 20 | config MPC512x_GENERIC |
19 | bool "Generic support for simple MPC5121 based boards" | 21 | bool "Generic support for simple MPC512x based boards" |
20 | depends on PPC_MPC512x | 22 | depends on PPC_MPC512x |
21 | select DEFAULT_UIMAGE | 23 | select DEFAULT_UIMAGE |
22 | help | 24 | help |
23 | This option enables support for simple MPC5121 based boards | 25 | This option enables support for simple MPC512x based boards |
24 | which do not need custom platform specific setup. | 26 | which do not need custom platform specific setup. |
25 | 27 | ||
26 | Compatible boards include: Protonic LVT base boards (ZANMCU | 28 | Compatible boards include: Protonic LVT base boards (ZANMCU |
27 | and VICVT2). | 29 | and VICVT2), Freescale MPC5125 Tower system. |
28 | 30 | ||
29 | config PDM360NG | 31 | config PDM360NG |
30 | bool "ifm PDM360NG board" | 32 | bool "ifm PDM360NG board" |
diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile index 4efc1c4b6fb5..72fb9340e09f 100644 --- a/arch/powerpc/platforms/512x/Makefile +++ b/arch/powerpc/platforms/512x/Makefile | |||
@@ -3,5 +3,5 @@ | |||
3 | # | 3 | # |
4 | obj-y += clock.o mpc512x_shared.o | 4 | obj-y += clock.o mpc512x_shared.o |
5 | obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o | 5 | obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o |
6 | obj-$(CONFIG_MPC5121_GENERIC) += mpc5121_generic.o | 6 | obj-$(CONFIG_MPC512x_GENERIC) += mpc512x_generic.o |
7 | obj-$(CONFIG_PDM360NG) += pdm360ng.o | 7 | obj-$(CONFIG_PDM360NG) += pdm360ng.o |
diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c index 52d57d281724..e504166e089a 100644 --- a/arch/powerpc/platforms/512x/clock.c +++ b/arch/powerpc/platforms/512x/clock.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include <asm/mpc5121.h> | 29 | #include <asm/mpc5121.h> |
30 | #include <asm/clk_interface.h> | 30 | #include <asm/clk_interface.h> |
31 | 31 | ||
32 | #include "mpc512x.h" | ||
33 | |||
32 | #undef CLK_DEBUG | 34 | #undef CLK_DEBUG |
33 | 35 | ||
34 | static int clocks_initialized; | 36 | static int clocks_initialized; |
@@ -683,8 +685,13 @@ static void psc_clks_init(void) | |||
683 | struct device_node *np; | 685 | struct device_node *np; |
684 | struct platform_device *ofdev; | 686 | struct platform_device *ofdev; |
685 | u32 reg; | 687 | u32 reg; |
688 | const char *psc_compat; | ||
689 | |||
690 | psc_compat = mpc512x_select_psc_compat(); | ||
691 | if (!psc_compat) | ||
692 | return; | ||
686 | 693 | ||
687 | for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { | 694 | for_each_compatible_node(np, NULL, psc_compat) { |
688 | if (!of_property_read_u32(np, "reg", ®)) { | 695 | if (!of_property_read_u32(np, "reg", ®)) { |
689 | int pscnum = (reg & 0xf00) >> 8; | 696 | int pscnum = (reg & 0xf00) >> 8; |
690 | struct clk *clk = psc_dev_clk(pscnum); | 697 | struct clk *clk = psc_dev_clk(pscnum); |
diff --git a/arch/powerpc/platforms/512x/mpc512x.h b/arch/powerpc/platforms/512x/mpc512x.h index c32b399eb952..0a8e60023944 100644 --- a/arch/powerpc/platforms/512x/mpc512x.h +++ b/arch/powerpc/platforms/512x/mpc512x.h | |||
@@ -15,6 +15,7 @@ extern void __init mpc512x_init_IRQ(void); | |||
15 | extern void __init mpc512x_init(void); | 15 | extern void __init mpc512x_init(void); |
16 | extern int __init mpc5121_clk_init(void); | 16 | extern int __init mpc5121_clk_init(void); |
17 | void __init mpc512x_declare_of_platform_devices(void); | 17 | void __init mpc512x_declare_of_platform_devices(void); |
18 | extern const char *mpc512x_select_psc_compat(void); | ||
18 | extern void mpc512x_restart(char *cmd); | 19 | extern void mpc512x_restart(char *cmd); |
19 | 20 | ||
20 | #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) | 21 | #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) |
diff --git a/arch/powerpc/platforms/512x/mpc5121_generic.c b/arch/powerpc/platforms/512x/mpc512x_generic.c index ca1ca6669990..5fb919b30924 100644 --- a/arch/powerpc/platforms/512x/mpc5121_generic.c +++ b/arch/powerpc/platforms/512x/mpc512x_generic.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Author: John Rigby, <jrigby@freescale.com> | 4 | * Author: John Rigby, <jrigby@freescale.com> |
5 | * | 5 | * |
6 | * Description: | 6 | * Description: |
7 | * MPC5121 SoC setup | 7 | * MPC512x SoC setup |
8 | * | 8 | * |
9 | * This is free software; you can redistribute it and/or modify it | 9 | * This is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License as published by | 10 | * under the terms of the GNU General Public License as published by |
@@ -28,20 +28,22 @@ | |||
28 | */ | 28 | */ |
29 | static const char * const board[] __initconst = { | 29 | static const char * const board[] __initconst = { |
30 | "prt,prtlvt", | 30 | "prt,prtlvt", |
31 | "fsl,mpc5125ads", | ||
32 | "ifm,ac14xx", | ||
31 | NULL | 33 | NULL |
32 | }; | 34 | }; |
33 | 35 | ||
34 | /* | 36 | /* |
35 | * Called very early, MMU is off, device-tree isn't unflattened | 37 | * Called very early, MMU is off, device-tree isn't unflattened |
36 | */ | 38 | */ |
37 | static int __init mpc5121_generic_probe(void) | 39 | static int __init mpc512x_generic_probe(void) |
38 | { | 40 | { |
39 | return of_flat_dt_match(of_get_flat_dt_root(), board); | 41 | return of_flat_dt_match(of_get_flat_dt_root(), board); |
40 | } | 42 | } |
41 | 43 | ||
42 | define_machine(mpc5121_generic) { | 44 | define_machine(mpc512x_generic) { |
43 | .name = "MPC5121 generic", | 45 | .name = "MPC512x generic", |
44 | .probe = mpc5121_generic_probe, | 46 | .probe = mpc512x_generic_probe, |
45 | .init = mpc512x_init, | 47 | .init = mpc512x_init, |
46 | .init_early = mpc512x_init_diu, | 48 | .init_early = mpc512x_init_diu, |
47 | .setup_arch = mpc512x_setup_diu, | 49 | .setup_arch = mpc512x_setup_diu, |
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c index d30235b7e3f7..6eb94ab99d39 100644 --- a/arch/powerpc/platforms/512x/mpc512x_shared.c +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c | |||
@@ -172,12 +172,9 @@ static struct fsl_diu_shared_fb __attribute__ ((__aligned__(8))) diu_shared_fb; | |||
172 | 172 | ||
173 | static inline void mpc512x_free_bootmem(struct page *page) | 173 | static inline void mpc512x_free_bootmem(struct page *page) |
174 | { | 174 | { |
175 | __ClearPageReserved(page); | ||
176 | BUG_ON(PageTail(page)); | 175 | BUG_ON(PageTail(page)); |
177 | BUG_ON(atomic_read(&page->_count) > 1); | 176 | BUG_ON(atomic_read(&page->_count) > 1); |
178 | atomic_set(&page->_count, 1); | 177 | free_reserved_page(page); |
179 | __free_page(page); | ||
180 | totalram_pages++; | ||
181 | } | 178 | } |
182 | 179 | ||
183 | void mpc512x_release_bootmem(void) | 180 | void mpc512x_release_bootmem(void) |
@@ -330,26 +327,34 @@ void __init mpc512x_init_IRQ(void) | |||
330 | static struct of_device_id __initdata of_bus_ids[] = { | 327 | static struct of_device_id __initdata of_bus_ids[] = { |
331 | { .compatible = "fsl,mpc5121-immr", }, | 328 | { .compatible = "fsl,mpc5121-immr", }, |
332 | { .compatible = "fsl,mpc5121-localbus", }, | 329 | { .compatible = "fsl,mpc5121-localbus", }, |
330 | { .compatible = "fsl,mpc5121-mbx", }, | ||
331 | { .compatible = "fsl,mpc5121-nfc", }, | ||
332 | { .compatible = "fsl,mpc5121-sram", }, | ||
333 | { .compatible = "fsl,mpc5121-pci", }, | ||
334 | { .compatible = "gpio-leds", }, | ||
333 | {}, | 335 | {}, |
334 | }; | 336 | }; |
335 | 337 | ||
336 | void __init mpc512x_declare_of_platform_devices(void) | 338 | void __init mpc512x_declare_of_platform_devices(void) |
337 | { | 339 | { |
338 | struct device_node *np; | ||
339 | |||
340 | if (of_platform_bus_probe(NULL, of_bus_ids, NULL)) | 340 | if (of_platform_bus_probe(NULL, of_bus_ids, NULL)) |
341 | printk(KERN_ERR __FILE__ ": " | 341 | printk(KERN_ERR __FILE__ ": " |
342 | "Error while probing of_platform bus\n"); | 342 | "Error while probing of_platform bus\n"); |
343 | |||
344 | np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-nfc"); | ||
345 | if (np) { | ||
346 | of_platform_device_create(np, NULL, NULL); | ||
347 | of_node_put(np); | ||
348 | } | ||
349 | } | 343 | } |
350 | 344 | ||
351 | #define DEFAULT_FIFO_SIZE 16 | 345 | #define DEFAULT_FIFO_SIZE 16 |
352 | 346 | ||
347 | const char *mpc512x_select_psc_compat(void) | ||
348 | { | ||
349 | if (of_machine_is_compatible("fsl,mpc5121")) | ||
350 | return "fsl,mpc5121-psc"; | ||
351 | |||
352 | if (of_machine_is_compatible("fsl,mpc5125")) | ||
353 | return "fsl,mpc5125-psc"; | ||
354 | |||
355 | return NULL; | ||
356 | } | ||
357 | |||
353 | static unsigned int __init get_fifo_size(struct device_node *np, | 358 | static unsigned int __init get_fifo_size(struct device_node *np, |
354 | char *prop_name) | 359 | char *prop_name) |
355 | { | 360 | { |
@@ -375,9 +380,16 @@ void __init mpc512x_psc_fifo_init(void) | |||
375 | void __iomem *psc; | 380 | void __iomem *psc; |
376 | unsigned int tx_fifo_size; | 381 | unsigned int tx_fifo_size; |
377 | unsigned int rx_fifo_size; | 382 | unsigned int rx_fifo_size; |
383 | const char *psc_compat; | ||
378 | int fifobase = 0; /* current fifo address in 32 bit words */ | 384 | int fifobase = 0; /* current fifo address in 32 bit words */ |
379 | 385 | ||
380 | for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { | 386 | psc_compat = mpc512x_select_psc_compat(); |
387 | if (!psc_compat) { | ||
388 | pr_err("%s: no compatible devices found\n", __func__); | ||
389 | return; | ||
390 | } | ||
391 | |||
392 | for_each_compatible_node(np, NULL, psc_compat) { | ||
381 | tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size"); | 393 | tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size"); |
382 | rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size"); | 394 | rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size"); |
383 | 395 | ||
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index a0dcd577fb0d..8f02b05f4c96 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig | |||
@@ -305,6 +305,40 @@ config PPC_QEMU_E500 | |||
305 | unset based on the emulated CPU (or actual host CPU in the case | 305 | unset based on the emulated CPU (or actual host CPU in the case |
306 | of KVM). | 306 | of KVM). |
307 | 307 | ||
308 | if PPC64 | ||
309 | |||
310 | config T4240_QDS | ||
311 | bool "Freescale T4240 QDS" | ||
312 | select DEFAULT_UIMAGE | ||
313 | select E500 | ||
314 | select PPC_E500MC | ||
315 | select PHYS_64BIT | ||
316 | select SWIOTLB | ||
317 | select ARCH_REQUIRE_GPIOLIB | ||
318 | select GPIO_MPC8XXX | ||
319 | select HAS_RAPIDIO | ||
320 | select PPC_EPAPR_HV_PIC | ||
321 | help | ||
322 | This option enables support for the T4240 QDS board | ||
323 | |||
324 | config B4_QDS | ||
325 | bool "Freescale B4 QDS" | ||
326 | select DEFAULT_UIMAGE | ||
327 | select E500 | ||
328 | select PPC_E500MC | ||
329 | select PHYS_64BIT | ||
330 | select SWIOTLB | ||
331 | select GENERIC_GPIO | ||
332 | select ARCH_REQUIRE_GPIOLIB | ||
333 | select HAS_RAPIDIO | ||
334 | select PPC_EPAPR_HV_PIC | ||
335 | help | ||
336 | This option enables support for the B4 QDS board | ||
337 | The B4 application development system B4 QDS is a complete | ||
338 | debugging environment intended for engineers developing | ||
339 | applications for the B4. | ||
340 | |||
341 | endif | ||
308 | endif # FSL_SOC_BOOKE | 342 | endif # FSL_SOC_BOOKE |
309 | 343 | ||
310 | config TQM85xx | 344 | config TQM85xx |
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 07d0dbb141c0..2eab37ea4a9d 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile | |||
@@ -22,6 +22,8 @@ obj-$(CONFIG_P3041_DS) += p3041_ds.o corenet_ds.o | |||
22 | obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o | 22 | obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o |
23 | obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o | 23 | obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o |
24 | obj-$(CONFIG_P5040_DS) += p5040_ds.o corenet_ds.o | 24 | obj-$(CONFIG_P5040_DS) += p5040_ds.o corenet_ds.o |
25 | obj-$(CONFIG_T4240_QDS) += t4240_qds.o corenet_ds.o | ||
26 | obj-$(CONFIG_B4_QDS) += b4_qds.o corenet_ds.o | ||
25 | obj-$(CONFIG_STX_GP3) += stx_gp3.o | 27 | obj-$(CONFIG_STX_GP3) += stx_gp3.o |
26 | obj-$(CONFIG_TQM85xx) += tqm85xx.o | 28 | obj-$(CONFIG_TQM85xx) += tqm85xx.o |
27 | obj-$(CONFIG_SBC8548) += sbc8548.o | 29 | obj-$(CONFIG_SBC8548) += sbc8548.o |
diff --git a/arch/powerpc/platforms/85xx/b4_qds.c b/arch/powerpc/platforms/85xx/b4_qds.c new file mode 100644 index 000000000000..0c6702f8b88e --- /dev/null +++ b/arch/powerpc/platforms/85xx/b4_qds.c | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | * B4 QDS Setup | ||
3 | * Should apply for QDS platform of B4860 and it's personalities. | ||
4 | * viz B4860/B4420/B4220QDS | ||
5 | * | ||
6 | * Copyright 2012 Freescale Semiconductor Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <linux/kdev_t.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/phy.h> | ||
20 | |||
21 | #include <asm/time.h> | ||
22 | #include <asm/machdep.h> | ||
23 | #include <asm/pci-bridge.h> | ||
24 | #include <mm/mmu_decl.h> | ||
25 | #include <asm/prom.h> | ||
26 | #include <asm/udbg.h> | ||
27 | #include <asm/mpic.h> | ||
28 | |||
29 | #include <linux/of_platform.h> | ||
30 | #include <sysdev/fsl_soc.h> | ||
31 | #include <sysdev/fsl_pci.h> | ||
32 | #include <asm/ehv_pic.h> | ||
33 | |||
34 | #include "corenet_ds.h" | ||
35 | |||
36 | /* | ||
37 | * Called very early, device-tree isn't unflattened | ||
38 | */ | ||
39 | static int __init b4_qds_probe(void) | ||
40 | { | ||
41 | unsigned long root = of_get_flat_dt_root(); | ||
42 | #ifdef CONFIG_SMP | ||
43 | extern struct smp_ops_t smp_85xx_ops; | ||
44 | #endif | ||
45 | |||
46 | if ((of_flat_dt_is_compatible(root, "fsl,B4860QDS")) || | ||
47 | (of_flat_dt_is_compatible(root, "fsl,B4420QDS")) || | ||
48 | (of_flat_dt_is_compatible(root, "fsl,B4220QDS"))) | ||
49 | return 1; | ||
50 | |||
51 | /* Check if we're running under the Freescale hypervisor */ | ||
52 | if ((of_flat_dt_is_compatible(root, "fsl,B4860QDS-hv")) || | ||
53 | (of_flat_dt_is_compatible(root, "fsl,B4420QDS-hv")) || | ||
54 | (of_flat_dt_is_compatible(root, "fsl,B4220QDS-hv"))) { | ||
55 | ppc_md.init_IRQ = ehv_pic_init; | ||
56 | ppc_md.get_irq = ehv_pic_get_irq; | ||
57 | ppc_md.restart = fsl_hv_restart; | ||
58 | ppc_md.power_off = fsl_hv_halt; | ||
59 | ppc_md.halt = fsl_hv_halt; | ||
60 | #ifdef CONFIG_SMP | ||
61 | /* | ||
62 | * Disable the timebase sync operations because we can't write | ||
63 | * to the timebase registers under the hypervisor. | ||
64 | */ | ||
65 | smp_85xx_ops.give_timebase = NULL; | ||
66 | smp_85xx_ops.take_timebase = NULL; | ||
67 | #endif | ||
68 | return 1; | ||
69 | } | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | define_machine(b4_qds) { | ||
75 | .name = "B4 QDS", | ||
76 | .probe = b4_qds_probe, | ||
77 | .setup_arch = corenet_ds_setup_arch, | ||
78 | .init_IRQ = corenet_ds_pic_init, | ||
79 | #ifdef CONFIG_PCI | ||
80 | .pcibios_fixup_bus = fsl_pcibios_fixup_bus, | ||
81 | #endif | ||
82 | /* coreint doesn't play nice with lazy EE, use legacy mpic for now */ | ||
83 | #ifdef CONFIG_PPC64 | ||
84 | .get_irq = mpic_get_irq, | ||
85 | #else | ||
86 | .get_irq = mpic_get_coreint_irq, | ||
87 | #endif | ||
88 | .restart = fsl_rstcr_restart, | ||
89 | .calibrate_decr = generic_calibrate_decr, | ||
90 | .progress = udbg_progress, | ||
91 | #ifdef CONFIG_PPC64 | ||
92 | .power_save = book3e_idle, | ||
93 | #else | ||
94 | .power_save = e500_idle, | ||
95 | #endif | ||
96 | }; | ||
97 | |||
98 | machine_arch_initcall(b4_qds, corenet_ds_publish_devices); | ||
99 | |||
100 | #ifdef CONFIG_SWIOTLB | ||
101 | machine_arch_initcall(b4_qds, swiotlb_setup_bus_notifier); | ||
102 | #endif | ||
diff --git a/arch/powerpc/platforms/85xx/corenet_ds.c b/arch/powerpc/platforms/85xx/corenet_ds.c index 6f355d8c92f6..c59c617eee93 100644 --- a/arch/powerpc/platforms/85xx/corenet_ds.c +++ b/arch/powerpc/platforms/85xx/corenet_ds.c | |||
@@ -40,7 +40,7 @@ void __init corenet_ds_pic_init(void) | |||
40 | if (ppc_md.get_irq == mpic_get_coreint_irq) | 40 | if (ppc_md.get_irq == mpic_get_coreint_irq) |
41 | flags |= MPIC_ENABLE_COREINT; | 41 | flags |= MPIC_ENABLE_COREINT; |
42 | 42 | ||
43 | mpic = mpic_alloc(NULL, 0, flags, 0, 256, " OpenPIC "); | 43 | mpic = mpic_alloc(NULL, 0, flags, 0, 512, " OpenPIC "); |
44 | BUG_ON(mpic == NULL); | 44 | BUG_ON(mpic == NULL); |
45 | 45 | ||
46 | mpic_init(mpic); | 46 | mpic_init(mpic); |
@@ -83,6 +83,9 @@ static const struct of_device_id of_device_ids[] = { | |||
83 | { | 83 | { |
84 | .compatible = "fsl,qoriq-pcie-v2.4", | 84 | .compatible = "fsl,qoriq-pcie-v2.4", |
85 | }, | 85 | }, |
86 | { | ||
87 | .compatible = "fsl,qoriq-pcie-v3.0", | ||
88 | }, | ||
86 | /* The following two are for the Freescale hypervisor */ | 89 | /* The following two are for the Freescale hypervisor */ |
87 | { | 90 | { |
88 | .name = "hypervisor", | 91 | .name = "hypervisor", |
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 148c2f2d9780..6a1759939c6b 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c | |||
@@ -201,7 +201,7 @@ static int __cpuinit smp_85xx_kick_cpu(int nr) | |||
201 | * We don't set the BPTR register here since it already points | 201 | * We don't set the BPTR register here since it already points |
202 | * to the boot page properly. | 202 | * to the boot page properly. |
203 | */ | 203 | */ |
204 | mpic_reset_core(hw_cpu); | 204 | mpic_reset_core(nr); |
205 | 205 | ||
206 | /* | 206 | /* |
207 | * wait until core is ready... | 207 | * wait until core is ready... |
diff --git a/arch/powerpc/platforms/85xx/t4240_qds.c b/arch/powerpc/platforms/85xx/t4240_qds.c new file mode 100644 index 000000000000..5998e9f33304 --- /dev/null +++ b/arch/powerpc/platforms/85xx/t4240_qds.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * T4240 QDS Setup | ||
3 | * | ||
4 | * Maintained by Kumar Gala (see MAINTAINERS for contact information) | ||
5 | * | ||
6 | * Copyright 2012 Freescale Semiconductor Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <linux/kdev_t.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/phy.h> | ||
20 | |||
21 | #include <asm/time.h> | ||
22 | #include <asm/machdep.h> | ||
23 | #include <asm/pci-bridge.h> | ||
24 | #include <mm/mmu_decl.h> | ||
25 | #include <asm/prom.h> | ||
26 | #include <asm/udbg.h> | ||
27 | #include <asm/mpic.h> | ||
28 | |||
29 | #include <linux/of_platform.h> | ||
30 | #include <sysdev/fsl_soc.h> | ||
31 | #include <sysdev/fsl_pci.h> | ||
32 | #include <asm/ehv_pic.h> | ||
33 | |||
34 | #include "corenet_ds.h" | ||
35 | |||
36 | /* | ||
37 | * Called very early, device-tree isn't unflattened | ||
38 | */ | ||
39 | static int __init t4240_qds_probe(void) | ||
40 | { | ||
41 | unsigned long root = of_get_flat_dt_root(); | ||
42 | #ifdef CONFIG_SMP | ||
43 | extern struct smp_ops_t smp_85xx_ops; | ||
44 | #endif | ||
45 | |||
46 | if (of_flat_dt_is_compatible(root, "fsl,T4240QDS")) | ||
47 | return 1; | ||
48 | |||
49 | /* Check if we're running under the Freescale hypervisor */ | ||
50 | if (of_flat_dt_is_compatible(root, "fsl,T4240QDS-hv")) { | ||
51 | ppc_md.init_IRQ = ehv_pic_init; | ||
52 | ppc_md.get_irq = ehv_pic_get_irq; | ||
53 | ppc_md.restart = fsl_hv_restart; | ||
54 | ppc_md.power_off = fsl_hv_halt; | ||
55 | ppc_md.halt = fsl_hv_halt; | ||
56 | #ifdef CONFIG_SMP | ||
57 | /* | ||
58 | * Disable the timebase sync operations because we can't write | ||
59 | * to the timebase registers under the hypervisor. | ||
60 | */ | ||
61 | smp_85xx_ops.give_timebase = NULL; | ||
62 | smp_85xx_ops.take_timebase = NULL; | ||
63 | #endif | ||
64 | return 1; | ||
65 | } | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | define_machine(t4240_qds) { | ||
71 | .name = "T4240 QDS", | ||
72 | .probe = t4240_qds_probe, | ||
73 | .setup_arch = corenet_ds_setup_arch, | ||
74 | .init_IRQ = corenet_ds_pic_init, | ||
75 | #ifdef CONFIG_PCI | ||
76 | .pcibios_fixup_bus = fsl_pcibios_fixup_bus, | ||
77 | #endif | ||
78 | /* coreint doesn't play nice with lazy EE, use legacy mpic for now */ | ||
79 | #ifdef CONFIG_PPC64 | ||
80 | .get_irq = mpic_get_irq, | ||
81 | #else | ||
82 | .get_irq = mpic_get_coreint_irq, | ||
83 | #endif | ||
84 | .restart = fsl_rstcr_restart, | ||
85 | .calibrate_decr = generic_calibrate_decr, | ||
86 | .progress = udbg_progress, | ||
87 | #ifdef CONFIG_PPC64 | ||
88 | .power_save = book3e_idle, | ||
89 | #else | ||
90 | .power_save = e500_idle, | ||
91 | #endif | ||
92 | }; | ||
93 | |||
94 | machine_arch_initcall(t4240_qds, corenet_ds_publish_devices); | ||
95 | |||
96 | #ifdef CONFIG_SWIOTLB | ||
97 | machine_arch_initcall(t4240_qds, swiotlb_setup_bus_notifier); | ||
98 | #endif | ||
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index 52de8bccfb30..34d224be93ba 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig | |||
@@ -6,7 +6,6 @@ source "arch/powerpc/platforms/chrp/Kconfig" | |||
6 | source "arch/powerpc/platforms/512x/Kconfig" | 6 | source "arch/powerpc/platforms/512x/Kconfig" |
7 | source "arch/powerpc/platforms/52xx/Kconfig" | 7 | source "arch/powerpc/platforms/52xx/Kconfig" |
8 | source "arch/powerpc/platforms/powermac/Kconfig" | 8 | source "arch/powerpc/platforms/powermac/Kconfig" |
9 | source "arch/powerpc/platforms/prep/Kconfig" | ||
10 | source "arch/powerpc/platforms/maple/Kconfig" | 9 | source "arch/powerpc/platforms/maple/Kconfig" |
11 | source "arch/powerpc/platforms/pasemi/Kconfig" | 10 | source "arch/powerpc/platforms/pasemi/Kconfig" |
12 | source "arch/powerpc/platforms/ps3/Kconfig" | 11 | source "arch/powerpc/platforms/ps3/Kconfig" |
@@ -233,7 +232,7 @@ endmenu | |||
233 | 232 | ||
234 | config PPC601_SYNC_FIX | 233 | config PPC601_SYNC_FIX |
235 | bool "Workarounds for PPC601 bugs" | 234 | bool "Workarounds for PPC601 bugs" |
236 | depends on 6xx && (PPC_PREP || PPC_PMAC) | 235 | depends on 6xx && PPC_PMAC |
237 | help | 236 | help |
238 | Some versions of the PPC601 (the first PowerPC chip) have bugs which | 237 | Some versions of the PPC601 (the first PowerPC chip) have bugs which |
239 | mean that extra synchronization instructions are required near | 238 | mean that extra synchronization instructions are required near |
@@ -344,7 +343,6 @@ config FSL_ULI1575 | |||
344 | 343 | ||
345 | config CPM | 344 | config CPM |
346 | bool | 345 | bool |
347 | select PPC_CLOCK | ||
348 | 346 | ||
349 | config OF_RTC | 347 | config OF_RTC |
350 | bool | 348 | bool |
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 18e3b76c78d7..54f3936001aa 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype | |||
@@ -230,7 +230,7 @@ config PHYS_64BIT | |||
230 | 230 | ||
231 | config ALTIVEC | 231 | config ALTIVEC |
232 | bool "AltiVec Support" | 232 | bool "AltiVec Support" |
233 | depends on 6xx || POWER4 | 233 | depends on 6xx || POWER4 || (PPC_E500MC && PPC64) |
234 | ---help--- | 234 | ---help--- |
235 | This option enables kernel support for the Altivec extensions to the | 235 | This option enables kernel support for the Altivec extensions to the |
236 | PowerPC processor. The kernel currently supports saving and restoring | 236 | PowerPC processor. The kernel currently supports saving and restoring |
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig index 53aaefeb3386..9978f594cac0 100644 --- a/arch/powerpc/platforms/cell/Kconfig +++ b/arch/powerpc/platforms/cell/Kconfig | |||
@@ -113,34 +113,10 @@ config CBE_THERM | |||
113 | default m | 113 | default m |
114 | depends on CBE_RAS && SPU_BASE | 114 | depends on CBE_RAS && SPU_BASE |
115 | 115 | ||
116 | config CBE_CPUFREQ | ||
117 | tristate "CBE frequency scaling" | ||
118 | depends on CBE_RAS && CPU_FREQ | ||
119 | default m | ||
120 | help | ||
121 | This adds the cpufreq driver for Cell BE processors. | ||
122 | For details, take a look at <file:Documentation/cpu-freq/>. | ||
123 | If you don't have such processor, say N | ||
124 | |||
125 | config CBE_CPUFREQ_PMI_ENABLE | ||
126 | bool "CBE frequency scaling using PMI interface" | ||
127 | depends on CBE_CPUFREQ | ||
128 | default n | ||
129 | help | ||
130 | Select this, if you want to use the PMI interface | ||
131 | to switch frequencies. Using PMI, the | ||
132 | processor will not only be able to run at lower speed, | ||
133 | but also at lower core voltage. | ||
134 | |||
135 | config CBE_CPUFREQ_PMI | ||
136 | tristate | ||
137 | depends on CBE_CPUFREQ_PMI_ENABLE | ||
138 | default CBE_CPUFREQ | ||
139 | |||
140 | config PPC_PMI | 116 | config PPC_PMI |
141 | tristate | 117 | tristate |
142 | default y | 118 | default y |
143 | depends on CBE_CPUFREQ_PMI || PPC_IBM_CELL_POWERBUTTON | 119 | depends on CPU_FREQ_CBE_PMI || PPC_IBM_CELL_POWERBUTTON |
144 | help | 120 | help |
145 | PMI (Platform Management Interrupt) is a way to | 121 | PMI (Platform Management Interrupt) is a way to |
146 | communicate with the BMC (Baseboard Management Controller). | 122 | communicate with the BMC (Baseboard Management Controller). |
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile index a4a89350bcfc..fe053e7c73ee 100644 --- a/arch/powerpc/platforms/cell/Makefile +++ b/arch/powerpc/platforms/cell/Makefile | |||
@@ -5,9 +5,6 @@ obj-$(CONFIG_PPC_CELL_NATIVE) += iommu.o setup.o spider-pic.o \ | |||
5 | obj-$(CONFIG_CBE_RAS) += ras.o | 5 | obj-$(CONFIG_CBE_RAS) += ras.o |
6 | 6 | ||
7 | obj-$(CONFIG_CBE_THERM) += cbe_thermal.o | 7 | obj-$(CONFIG_CBE_THERM) += cbe_thermal.o |
8 | obj-$(CONFIG_CBE_CPUFREQ_PMI) += cbe_cpufreq_pmi.o | ||
9 | obj-$(CONFIG_CBE_CPUFREQ) += cbe-cpufreq.o | ||
10 | cbe-cpufreq-y += cbe_cpufreq_pervasive.o cbe_cpufreq.o | ||
11 | obj-$(CONFIG_CBE_CPUFREQ_SPU_GOVERNOR) += cpufreq_spudemand.o | 8 | obj-$(CONFIG_CBE_CPUFREQ_SPU_GOVERNOR) += cpufreq_spudemand.o |
12 | 9 | ||
13 | obj-$(CONFIG_PPC_IBM_CELL_POWERBUTTON) += cbe_powerbutton.o | 10 | obj-$(CONFIG_PPC_IBM_CELL_POWERBUTTON) += cbe_powerbutton.o |
diff --git a/arch/powerpc/platforms/cell/beat_htab.c b/arch/powerpc/platforms/cell/beat_htab.c index 0f6f83988b3d..246e1d8b3af3 100644 --- a/arch/powerpc/platforms/cell/beat_htab.c +++ b/arch/powerpc/platforms/cell/beat_htab.c | |||
@@ -90,7 +90,7 @@ static inline unsigned int beat_read_mask(unsigned hpte_group) | |||
90 | static long beat_lpar_hpte_insert(unsigned long hpte_group, | 90 | static long beat_lpar_hpte_insert(unsigned long hpte_group, |
91 | unsigned long vpn, unsigned long pa, | 91 | unsigned long vpn, unsigned long pa, |
92 | unsigned long rflags, unsigned long vflags, | 92 | unsigned long rflags, unsigned long vflags, |
93 | int psize, int ssize) | 93 | int psize, int apsize, int ssize) |
94 | { | 94 | { |
95 | unsigned long lpar_rc; | 95 | unsigned long lpar_rc; |
96 | u64 hpte_v, hpte_r, slot; | 96 | u64 hpte_v, hpte_r, slot; |
@@ -103,9 +103,9 @@ static long beat_lpar_hpte_insert(unsigned long hpte_group, | |||
103 | "rflags=%lx, vflags=%lx, psize=%d)\n", | 103 | "rflags=%lx, vflags=%lx, psize=%d)\n", |
104 | hpte_group, va, pa, rflags, vflags, psize); | 104 | hpte_group, va, pa, rflags, vflags, psize); |
105 | 105 | ||
106 | hpte_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M) | | 106 | hpte_v = hpte_encode_v(vpn, psize, apsize, MMU_SEGSIZE_256M) | |
107 | vflags | HPTE_V_VALID; | 107 | vflags | HPTE_V_VALID; |
108 | hpte_r = hpte_encode_r(pa, psize) | rflags; | 108 | hpte_r = hpte_encode_r(pa, psize, apsize) | rflags; |
109 | 109 | ||
110 | if (!(vflags & HPTE_V_BOLTED)) | 110 | if (!(vflags & HPTE_V_BOLTED)) |
111 | DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); | 111 | DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); |
@@ -191,7 +191,7 @@ static long beat_lpar_hpte_updatepp(unsigned long slot, | |||
191 | u64 dummy0, dummy1; | 191 | u64 dummy0, dummy1; |
192 | unsigned long want_v; | 192 | unsigned long want_v; |
193 | 193 | ||
194 | want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M); | 194 | want_v = hpte_encode_avpn(vpn, psize, MMU_SEGSIZE_256M); |
195 | 195 | ||
196 | DBG_LOW(" update: " | 196 | DBG_LOW(" update: " |
197 | "avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ", | 197 | "avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ", |
@@ -228,7 +228,7 @@ static long beat_lpar_hpte_find(unsigned long vpn, int psize) | |||
228 | unsigned long want_v, hpte_v; | 228 | unsigned long want_v, hpte_v; |
229 | 229 | ||
230 | hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, MMU_SEGSIZE_256M); | 230 | hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, MMU_SEGSIZE_256M); |
231 | want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M); | 231 | want_v = hpte_encode_avpn(vpn, psize, MMU_SEGSIZE_256M); |
232 | 232 | ||
233 | for (j = 0; j < 2; j++) { | 233 | for (j = 0; j < 2; j++) { |
234 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; | 234 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; |
@@ -283,7 +283,7 @@ static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long vpn, | |||
283 | 283 | ||
284 | DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n", | 284 | DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n", |
285 | slot, va, psize, local); | 285 | slot, va, psize, local); |
286 | want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M); | 286 | want_v = hpte_encode_avpn(vpn, psize, MMU_SEGSIZE_256M); |
287 | 287 | ||
288 | raw_spin_lock_irqsave(&beat_htab_lock, flags); | 288 | raw_spin_lock_irqsave(&beat_htab_lock, flags); |
289 | dummy1 = beat_lpar_hpte_getword0(slot); | 289 | dummy1 = beat_lpar_hpte_getword0(slot); |
@@ -314,7 +314,7 @@ void __init hpte_init_beat(void) | |||
314 | static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, | 314 | static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, |
315 | unsigned long vpn, unsigned long pa, | 315 | unsigned long vpn, unsigned long pa, |
316 | unsigned long rflags, unsigned long vflags, | 316 | unsigned long rflags, unsigned long vflags, |
317 | int psize, int ssize) | 317 | int psize, int apsize, int ssize) |
318 | { | 318 | { |
319 | unsigned long lpar_rc; | 319 | unsigned long lpar_rc; |
320 | u64 hpte_v, hpte_r, slot; | 320 | u64 hpte_v, hpte_r, slot; |
@@ -327,9 +327,9 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, | |||
327 | "rflags=%lx, vflags=%lx, psize=%d)\n", | 327 | "rflags=%lx, vflags=%lx, psize=%d)\n", |
328 | hpte_group, vpn, pa, rflags, vflags, psize); | 328 | hpte_group, vpn, pa, rflags, vflags, psize); |
329 | 329 | ||
330 | hpte_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M) | | 330 | hpte_v = hpte_encode_v(vpn, psize, apsize, MMU_SEGSIZE_256M) | |
331 | vflags | HPTE_V_VALID; | 331 | vflags | HPTE_V_VALID; |
332 | hpte_r = hpte_encode_r(pa, psize) | rflags; | 332 | hpte_r = hpte_encode_r(pa, psize, apsize) | rflags; |
333 | 333 | ||
334 | if (!(vflags & HPTE_V_BOLTED)) | 334 | if (!(vflags & HPTE_V_BOLTED)) |
335 | DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); | 335 | DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); |
@@ -372,8 +372,8 @@ static long beat_lpar_hpte_updatepp_v3(unsigned long slot, | |||
372 | unsigned long want_v; | 372 | unsigned long want_v; |
373 | unsigned long pss; | 373 | unsigned long pss; |
374 | 374 | ||
375 | want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M); | 375 | want_v = hpte_encode_avpn(vpn, psize, MMU_SEGSIZE_256M); |
376 | pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc; | 376 | pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc[psize]; |
377 | 377 | ||
378 | DBG_LOW(" update: " | 378 | DBG_LOW(" update: " |
379 | "avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ", | 379 | "avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ", |
@@ -402,8 +402,8 @@ static void beat_lpar_hpte_invalidate_v3(unsigned long slot, unsigned long vpn, | |||
402 | 402 | ||
403 | DBG_LOW(" inval : slot=%lx, vpn=%016lx, psize: %d, local: %d\n", | 403 | DBG_LOW(" inval : slot=%lx, vpn=%016lx, psize: %d, local: %d\n", |
404 | slot, vpn, psize, local); | 404 | slot, vpn, psize, local); |
405 | want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M); | 405 | want_v = hpte_encode_avpn(vpn, psize, MMU_SEGSIZE_256M); |
406 | pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc; | 406 | pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc[psize]; |
407 | 407 | ||
408 | lpar_rc = beat_invalidate_htab_entry3(0, slot, want_v, pss); | 408 | lpar_rc = beat_invalidate_htab_entry3(0, slot, want_v, pss); |
409 | 409 | ||
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c deleted file mode 100644 index d4c39e32f147..000000000000 --- a/arch/powerpc/platforms/cell/cbe_cpufreq.c +++ /dev/null | |||
@@ -1,209 +0,0 @@ | |||
1 | /* | ||
2 | * cpufreq driver for the cell processor | ||
3 | * | ||
4 | * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007 | ||
5 | * | ||
6 | * Author: Christian Krafft <krafft@de.ibm.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2, or (at your option) | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/cpufreq.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/of_platform.h> | ||
26 | |||
27 | #include <asm/machdep.h> | ||
28 | #include <asm/prom.h> | ||
29 | #include <asm/cell-regs.h> | ||
30 | #include "cbe_cpufreq.h" | ||
31 | |||
32 | static DEFINE_MUTEX(cbe_switch_mutex); | ||
33 | |||
34 | |||
35 | /* the CBE supports an 8 step frequency scaling */ | ||
36 | static struct cpufreq_frequency_table cbe_freqs[] = { | ||
37 | {1, 0}, | ||
38 | {2, 0}, | ||
39 | {3, 0}, | ||
40 | {4, 0}, | ||
41 | {5, 0}, | ||
42 | {6, 0}, | ||
43 | {8, 0}, | ||
44 | {10, 0}, | ||
45 | {0, CPUFREQ_TABLE_END}, | ||
46 | }; | ||
47 | |||
48 | /* | ||
49 | * hardware specific functions | ||
50 | */ | ||
51 | |||
52 | static int set_pmode(unsigned int cpu, unsigned int slow_mode) | ||
53 | { | ||
54 | int rc; | ||
55 | |||
56 | if (cbe_cpufreq_has_pmi) | ||
57 | rc = cbe_cpufreq_set_pmode_pmi(cpu, slow_mode); | ||
58 | else | ||
59 | rc = cbe_cpufreq_set_pmode(cpu, slow_mode); | ||
60 | |||
61 | pr_debug("register contains slow mode %d\n", cbe_cpufreq_get_pmode(cpu)); | ||
62 | |||
63 | return rc; | ||
64 | } | ||
65 | |||
66 | /* | ||
67 | * cpufreq functions | ||
68 | */ | ||
69 | |||
70 | static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) | ||
71 | { | ||
72 | const u32 *max_freqp; | ||
73 | u32 max_freq; | ||
74 | int i, cur_pmode; | ||
75 | struct device_node *cpu; | ||
76 | |||
77 | cpu = of_get_cpu_node(policy->cpu, NULL); | ||
78 | |||
79 | if (!cpu) | ||
80 | return -ENODEV; | ||
81 | |||
82 | pr_debug("init cpufreq on CPU %d\n", policy->cpu); | ||
83 | |||
84 | /* | ||
85 | * Let's check we can actually get to the CELL regs | ||
86 | */ | ||
87 | if (!cbe_get_cpu_pmd_regs(policy->cpu) || | ||
88 | !cbe_get_cpu_mic_tm_regs(policy->cpu)) { | ||
89 | pr_info("invalid CBE regs pointers for cpufreq\n"); | ||
90 | return -EINVAL; | ||
91 | } | ||
92 | |||
93 | max_freqp = of_get_property(cpu, "clock-frequency", NULL); | ||
94 | |||
95 | of_node_put(cpu); | ||
96 | |||
97 | if (!max_freqp) | ||
98 | return -EINVAL; | ||
99 | |||
100 | /* we need the freq in kHz */ | ||
101 | max_freq = *max_freqp / 1000; | ||
102 | |||
103 | pr_debug("max clock-frequency is at %u kHz\n", max_freq); | ||
104 | pr_debug("initializing frequency table\n"); | ||
105 | |||
106 | /* initialize frequency table */ | ||
107 | for (i=0; cbe_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) { | ||
108 | cbe_freqs[i].frequency = max_freq / cbe_freqs[i].index; | ||
109 | pr_debug("%d: %d\n", i, cbe_freqs[i].frequency); | ||
110 | } | ||
111 | |||
112 | /* if DEBUG is enabled set_pmode() measures the latency | ||
113 | * of a transition */ | ||
114 | policy->cpuinfo.transition_latency = 25000; | ||
115 | |||
116 | cur_pmode = cbe_cpufreq_get_pmode(policy->cpu); | ||
117 | pr_debug("current pmode is at %d\n",cur_pmode); | ||
118 | |||
119 | policy->cur = cbe_freqs[cur_pmode].frequency; | ||
120 | |||
121 | #ifdef CONFIG_SMP | ||
122 | cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu)); | ||
123 | #endif | ||
124 | |||
125 | cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu); | ||
126 | |||
127 | /* this ensures that policy->cpuinfo_min | ||
128 | * and policy->cpuinfo_max are set correctly */ | ||
129 | return cpufreq_frequency_table_cpuinfo(policy, cbe_freqs); | ||
130 | } | ||
131 | |||
132 | static int cbe_cpufreq_cpu_exit(struct cpufreq_policy *policy) | ||
133 | { | ||
134 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static int cbe_cpufreq_verify(struct cpufreq_policy *policy) | ||
139 | { | ||
140 | return cpufreq_frequency_table_verify(policy, cbe_freqs); | ||
141 | } | ||
142 | |||
143 | static int cbe_cpufreq_target(struct cpufreq_policy *policy, | ||
144 | unsigned int target_freq, | ||
145 | unsigned int relation) | ||
146 | { | ||
147 | int rc; | ||
148 | struct cpufreq_freqs freqs; | ||
149 | unsigned int cbe_pmode_new; | ||
150 | |||
151 | cpufreq_frequency_table_target(policy, | ||
152 | cbe_freqs, | ||
153 | target_freq, | ||
154 | relation, | ||
155 | &cbe_pmode_new); | ||
156 | |||
157 | freqs.old = policy->cur; | ||
158 | freqs.new = cbe_freqs[cbe_pmode_new].frequency; | ||
159 | freqs.cpu = policy->cpu; | ||
160 | |||
161 | mutex_lock(&cbe_switch_mutex); | ||
162 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
163 | |||
164 | pr_debug("setting frequency for cpu %d to %d kHz, " \ | ||
165 | "1/%d of max frequency\n", | ||
166 | policy->cpu, | ||
167 | cbe_freqs[cbe_pmode_new].frequency, | ||
168 | cbe_freqs[cbe_pmode_new].index); | ||
169 | |||
170 | rc = set_pmode(policy->cpu, cbe_pmode_new); | ||
171 | |||
172 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
173 | mutex_unlock(&cbe_switch_mutex); | ||
174 | |||
175 | return rc; | ||
176 | } | ||
177 | |||
178 | static struct cpufreq_driver cbe_cpufreq_driver = { | ||
179 | .verify = cbe_cpufreq_verify, | ||
180 | .target = cbe_cpufreq_target, | ||
181 | .init = cbe_cpufreq_cpu_init, | ||
182 | .exit = cbe_cpufreq_cpu_exit, | ||
183 | .name = "cbe-cpufreq", | ||
184 | .owner = THIS_MODULE, | ||
185 | .flags = CPUFREQ_CONST_LOOPS, | ||
186 | }; | ||
187 | |||
188 | /* | ||
189 | * module init and destoy | ||
190 | */ | ||
191 | |||
192 | static int __init cbe_cpufreq_init(void) | ||
193 | { | ||
194 | if (!machine_is(cell)) | ||
195 | return -ENODEV; | ||
196 | |||
197 | return cpufreq_register_driver(&cbe_cpufreq_driver); | ||
198 | } | ||
199 | |||
200 | static void __exit cbe_cpufreq_exit(void) | ||
201 | { | ||
202 | cpufreq_unregister_driver(&cbe_cpufreq_driver); | ||
203 | } | ||
204 | |||
205 | module_init(cbe_cpufreq_init); | ||
206 | module_exit(cbe_cpufreq_exit); | ||
207 | |||
208 | MODULE_LICENSE("GPL"); | ||
209 | MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>"); | ||
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.h b/arch/powerpc/platforms/cell/cbe_cpufreq.h deleted file mode 100644 index c1d86bfa92ff..000000000000 --- a/arch/powerpc/platforms/cell/cbe_cpufreq.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /* | ||
2 | * cbe_cpufreq.h | ||
3 | * | ||
4 | * This file contains the definitions used by the cbe_cpufreq driver. | ||
5 | * | ||
6 | * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007 | ||
7 | * | ||
8 | * Author: Christian Krafft <krafft@de.ibm.com> | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/cpufreq.h> | ||
13 | #include <linux/types.h> | ||
14 | |||
15 | int cbe_cpufreq_set_pmode(int cpu, unsigned int pmode); | ||
16 | int cbe_cpufreq_get_pmode(int cpu); | ||
17 | |||
18 | int cbe_cpufreq_set_pmode_pmi(int cpu, unsigned int pmode); | ||
19 | |||
20 | #if defined(CONFIG_CBE_CPUFREQ_PMI) || defined(CONFIG_CBE_CPUFREQ_PMI_MODULE) | ||
21 | extern bool cbe_cpufreq_has_pmi; | ||
22 | #else | ||
23 | #define cbe_cpufreq_has_pmi (0) | ||
24 | #endif | ||
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq_pervasive.c b/arch/powerpc/platforms/cell/cbe_cpufreq_pervasive.c deleted file mode 100644 index 20472e487b6f..000000000000 --- a/arch/powerpc/platforms/cell/cbe_cpufreq_pervasive.c +++ /dev/null | |||
@@ -1,115 +0,0 @@ | |||
1 | /* | ||
2 | * pervasive backend for the cbe_cpufreq driver | ||
3 | * | ||
4 | * This driver makes use of the pervasive unit to | ||
5 | * engage the desired frequency. | ||
6 | * | ||
7 | * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007 | ||
8 | * | ||
9 | * Author: Christian Krafft <krafft@de.ibm.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2, or (at your option) | ||
14 | * any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | */ | ||
25 | |||
26 | #include <linux/io.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/time.h> | ||
29 | #include <asm/machdep.h> | ||
30 | #include <asm/hw_irq.h> | ||
31 | #include <asm/cell-regs.h> | ||
32 | |||
33 | #include "cbe_cpufreq.h" | ||
34 | |||
35 | /* to write to MIC register */ | ||
36 | static u64 MIC_Slow_Fast_Timer_table[] = { | ||
37 | [0 ... 7] = 0x007fc00000000000ull, | ||
38 | }; | ||
39 | |||
40 | /* more values for the MIC */ | ||
41 | static u64 MIC_Slow_Next_Timer_table[] = { | ||
42 | 0x0000240000000000ull, | ||
43 | 0x0000268000000000ull, | ||
44 | 0x000029C000000000ull, | ||
45 | 0x00002D0000000000ull, | ||
46 | 0x0000300000000000ull, | ||
47 | 0x0000334000000000ull, | ||
48 | 0x000039C000000000ull, | ||
49 | 0x00003FC000000000ull, | ||
50 | }; | ||
51 | |||
52 | |||
53 | int cbe_cpufreq_set_pmode(int cpu, unsigned int pmode) | ||
54 | { | ||
55 | struct cbe_pmd_regs __iomem *pmd_regs; | ||
56 | struct cbe_mic_tm_regs __iomem *mic_tm_regs; | ||
57 | unsigned long flags; | ||
58 | u64 value; | ||
59 | #ifdef DEBUG | ||
60 | long time; | ||
61 | #endif | ||
62 | |||
63 | local_irq_save(flags); | ||
64 | |||
65 | mic_tm_regs = cbe_get_cpu_mic_tm_regs(cpu); | ||
66 | pmd_regs = cbe_get_cpu_pmd_regs(cpu); | ||
67 | |||
68 | #ifdef DEBUG | ||
69 | time = jiffies; | ||
70 | #endif | ||
71 | |||
72 | out_be64(&mic_tm_regs->slow_fast_timer_0, MIC_Slow_Fast_Timer_table[pmode]); | ||
73 | out_be64(&mic_tm_regs->slow_fast_timer_1, MIC_Slow_Fast_Timer_table[pmode]); | ||
74 | |||
75 | out_be64(&mic_tm_regs->slow_next_timer_0, MIC_Slow_Next_Timer_table[pmode]); | ||
76 | out_be64(&mic_tm_regs->slow_next_timer_1, MIC_Slow_Next_Timer_table[pmode]); | ||
77 | |||
78 | value = in_be64(&pmd_regs->pmcr); | ||
79 | /* set bits to zero */ | ||
80 | value &= 0xFFFFFFFFFFFFFFF8ull; | ||
81 | /* set bits to next pmode */ | ||
82 | value |= pmode; | ||
83 | |||
84 | out_be64(&pmd_regs->pmcr, value); | ||
85 | |||
86 | #ifdef DEBUG | ||
87 | /* wait until new pmode appears in status register */ | ||
88 | value = in_be64(&pmd_regs->pmsr) & 0x07; | ||
89 | while (value != pmode) { | ||
90 | cpu_relax(); | ||
91 | value = in_be64(&pmd_regs->pmsr) & 0x07; | ||
92 | } | ||
93 | |||
94 | time = jiffies - time; | ||
95 | time = jiffies_to_msecs(time); | ||
96 | pr_debug("had to wait %lu ms for a transition using " \ | ||
97 | "pervasive unit\n", time); | ||
98 | #endif | ||
99 | local_irq_restore(flags); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | |||
105 | int cbe_cpufreq_get_pmode(int cpu) | ||
106 | { | ||
107 | int ret; | ||
108 | struct cbe_pmd_regs __iomem *pmd_regs; | ||
109 | |||
110 | pmd_regs = cbe_get_cpu_pmd_regs(cpu); | ||
111 | ret = in_be64(&pmd_regs->pmsr) & 0x07; | ||
112 | |||
113 | return ret; | ||
114 | } | ||
115 | |||
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c b/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c deleted file mode 100644 index 60a07a4f9326..000000000000 --- a/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c +++ /dev/null | |||
@@ -1,156 +0,0 @@ | |||
1 | /* | ||
2 | * pmi backend for the cbe_cpufreq driver | ||
3 | * | ||
4 | * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007 | ||
5 | * | ||
6 | * Author: Christian Krafft <krafft@de.ibm.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2, or (at your option) | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/types.h> | ||
25 | #include <linux/timer.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/of_platform.h> | ||
28 | |||
29 | #include <asm/processor.h> | ||
30 | #include <asm/prom.h> | ||
31 | #include <asm/pmi.h> | ||
32 | #include <asm/cell-regs.h> | ||
33 | |||
34 | #ifdef DEBUG | ||
35 | #include <asm/time.h> | ||
36 | #endif | ||
37 | |||
38 | #include "cbe_cpufreq.h" | ||
39 | |||
40 | static u8 pmi_slow_mode_limit[MAX_CBE]; | ||
41 | |||
42 | bool cbe_cpufreq_has_pmi = false; | ||
43 | EXPORT_SYMBOL_GPL(cbe_cpufreq_has_pmi); | ||
44 | |||
45 | /* | ||
46 | * hardware specific functions | ||
47 | */ | ||
48 | |||
49 | int cbe_cpufreq_set_pmode_pmi(int cpu, unsigned int pmode) | ||
50 | { | ||
51 | int ret; | ||
52 | pmi_message_t pmi_msg; | ||
53 | #ifdef DEBUG | ||
54 | long time; | ||
55 | #endif | ||
56 | pmi_msg.type = PMI_TYPE_FREQ_CHANGE; | ||
57 | pmi_msg.data1 = cbe_cpu_to_node(cpu); | ||
58 | pmi_msg.data2 = pmode; | ||
59 | |||
60 | #ifdef DEBUG | ||
61 | time = jiffies; | ||
62 | #endif | ||
63 | pmi_send_message(pmi_msg); | ||
64 | |||
65 | #ifdef DEBUG | ||
66 | time = jiffies - time; | ||
67 | time = jiffies_to_msecs(time); | ||
68 | pr_debug("had to wait %lu ms for a transition using " \ | ||
69 | "PMI\n", time); | ||
70 | #endif | ||
71 | ret = pmi_msg.data2; | ||
72 | pr_debug("PMI returned slow mode %d\n", ret); | ||
73 | |||
74 | return ret; | ||
75 | } | ||
76 | EXPORT_SYMBOL_GPL(cbe_cpufreq_set_pmode_pmi); | ||
77 | |||
78 | |||
79 | static void cbe_cpufreq_handle_pmi(pmi_message_t pmi_msg) | ||
80 | { | ||
81 | u8 node, slow_mode; | ||
82 | |||
83 | BUG_ON(pmi_msg.type != PMI_TYPE_FREQ_CHANGE); | ||
84 | |||
85 | node = pmi_msg.data1; | ||
86 | slow_mode = pmi_msg.data2; | ||
87 | |||
88 | pmi_slow_mode_limit[node] = slow_mode; | ||
89 | |||
90 | pr_debug("cbe_handle_pmi: node: %d max_freq: %d\n", node, slow_mode); | ||
91 | } | ||
92 | |||
93 | static int pmi_notifier(struct notifier_block *nb, | ||
94 | unsigned long event, void *data) | ||
95 | { | ||
96 | struct cpufreq_policy *policy = data; | ||
97 | struct cpufreq_frequency_table *cbe_freqs; | ||
98 | u8 node; | ||
99 | |||
100 | /* Should this really be called for CPUFREQ_ADJUST, CPUFREQ_INCOMPATIBLE | ||
101 | * and CPUFREQ_NOTIFY policy events?) | ||
102 | */ | ||
103 | if (event == CPUFREQ_START) | ||
104 | return 0; | ||
105 | |||
106 | cbe_freqs = cpufreq_frequency_get_table(policy->cpu); | ||
107 | node = cbe_cpu_to_node(policy->cpu); | ||
108 | |||
109 | pr_debug("got notified, event=%lu, node=%u\n", event, node); | ||
110 | |||
111 | if (pmi_slow_mode_limit[node] != 0) { | ||
112 | pr_debug("limiting node %d to slow mode %d\n", | ||
113 | node, pmi_slow_mode_limit[node]); | ||
114 | |||
115 | cpufreq_verify_within_limits(policy, 0, | ||
116 | |||
117 | cbe_freqs[pmi_slow_mode_limit[node]].frequency); | ||
118 | } | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static struct notifier_block pmi_notifier_block = { | ||
124 | .notifier_call = pmi_notifier, | ||
125 | }; | ||
126 | |||
127 | static struct pmi_handler cbe_pmi_handler = { | ||
128 | .type = PMI_TYPE_FREQ_CHANGE, | ||
129 | .handle_pmi_message = cbe_cpufreq_handle_pmi, | ||
130 | }; | ||
131 | |||
132 | |||
133 | |||
134 | static int __init cbe_cpufreq_pmi_init(void) | ||
135 | { | ||
136 | cbe_cpufreq_has_pmi = pmi_register_handler(&cbe_pmi_handler) == 0; | ||
137 | |||
138 | if (!cbe_cpufreq_has_pmi) | ||
139 | return -ENODEV; | ||
140 | |||
141 | cpufreq_register_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static void __exit cbe_cpufreq_pmi_exit(void) | ||
147 | { | ||
148 | cpufreq_unregister_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER); | ||
149 | pmi_unregister_handler(&cbe_pmi_handler); | ||
150 | } | ||
151 | |||
152 | module_init(cbe_cpufreq_pmi_init); | ||
153 | module_exit(cbe_cpufreq_pmi_exit); | ||
154 | |||
155 | MODULE_LICENSE("GPL"); | ||
156 | MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>"); | ||
diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c index 59c1a1694104..348a27b12512 100644 --- a/arch/powerpc/platforms/cell/pmu.c +++ b/arch/powerpc/platforms/cell/pmu.c | |||
@@ -382,7 +382,7 @@ static int __init cbe_init_pm_irq(void) | |||
382 | unsigned int irq; | 382 | unsigned int irq; |
383 | int rc, node; | 383 | int rc, node; |
384 | 384 | ||
385 | for_each_node(node) { | 385 | for_each_online_node(node) { |
386 | irq = irq_create_mapping(NULL, IIC_IRQ_IOEX_PMI | | 386 | irq = irq_create_mapping(NULL, IIC_IRQ_IOEX_PMI | |
387 | (node << IIC_IRQ_NODE_SHIFT)); | 387 | (node << IIC_IRQ_NODE_SHIFT)); |
388 | if (irq == NO_IRQ) { | 388 | if (irq == NO_IRQ) { |
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 68c57d38745a..90986923a53a 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c | |||
@@ -149,7 +149,6 @@ static int __fops ## _open(struct inode *inode, struct file *file) \ | |||
149 | return spufs_attr_open(inode, file, __get, __set, __fmt); \ | 149 | return spufs_attr_open(inode, file, __get, __set, __fmt); \ |
150 | } \ | 150 | } \ |
151 | static const struct file_operations __fops = { \ | 151 | static const struct file_operations __fops = { \ |
152 | .owner = THIS_MODULE, \ | ||
153 | .open = __fops ## _open, \ | 152 | .open = __fops ## _open, \ |
154 | .release = spufs_attr_release, \ | 153 | .release = spufs_attr_release, \ |
155 | .read = spufs_attr_read, \ | 154 | .read = spufs_attr_read, \ |
@@ -352,7 +351,7 @@ static unsigned long spufs_get_unmapped_area(struct file *file, | |||
352 | 351 | ||
353 | /* Else, try to obtain a 64K pages slice */ | 352 | /* Else, try to obtain a 64K pages slice */ |
354 | return slice_get_unmapped_area(addr, len, flags, | 353 | return slice_get_unmapped_area(addr, len, flags, |
355 | MMU_PAGE_64K, 1, 0); | 354 | MMU_PAGE_64K, 1); |
356 | } | 355 | } |
357 | #endif /* CONFIG_SPU_FS_64K_LS */ | 356 | #endif /* CONFIG_SPU_FS_64K_LS */ |
358 | 357 | ||
@@ -2591,7 +2590,6 @@ static unsigned int spufs_switch_log_poll(struct file *file, poll_table *wait) | |||
2591 | } | 2590 | } |
2592 | 2591 | ||
2593 | static const struct file_operations spufs_switch_log_fops = { | 2592 | static const struct file_operations spufs_switch_log_fops = { |
2594 | .owner = THIS_MODULE, | ||
2595 | .open = spufs_switch_log_open, | 2593 | .open = spufs_switch_log_open, |
2596 | .read = spufs_switch_log_read, | 2594 | .read = spufs_switch_log_read, |
2597 | .poll = spufs_switch_log_poll, | 2595 | .poll = spufs_switch_log_poll, |
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 3f3bb4cdbbec..35f77a42bedf 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c | |||
@@ -99,6 +99,7 @@ spufs_new_inode(struct super_block *sb, umode_t mode) | |||
99 | if (!inode) | 99 | if (!inode) |
100 | goto out; | 100 | goto out; |
101 | 101 | ||
102 | inode->i_ino = get_next_ino(); | ||
102 | inode->i_mode = mode; | 103 | inode->i_mode = mode; |
103 | inode->i_uid = current_fsuid(); | 104 | inode->i_uid = current_fsuid(); |
104 | inode->i_gid = current_fsgid(); | 105 | inode->i_gid = current_fsgid(); |
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c index 039fc8e82199..2b4dc6abde6c 100644 --- a/arch/powerpc/platforms/chrp/pegasos_eth.c +++ b/arch/powerpc/platforms/chrp/pegasos_eth.c | |||
@@ -47,6 +47,25 @@ static struct platform_device mv643xx_eth_shared_device = { | |||
47 | .resource = mv643xx_eth_shared_resources, | 47 | .resource = mv643xx_eth_shared_resources, |
48 | }; | 48 | }; |
49 | 49 | ||
50 | /* | ||
51 | * The orion mdio driver only covers shared + 0x4 up to shared + 0x84 - 1 | ||
52 | */ | ||
53 | static struct resource mv643xx_eth_mvmdio_resources[] = { | ||
54 | [0] = { | ||
55 | .name = "ethernet mdio base", | ||
56 | .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 0x4, | ||
57 | .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 0x83, | ||
58 | .flags = IORESOURCE_MEM, | ||
59 | }, | ||
60 | }; | ||
61 | |||
62 | static struct platform_device mv643xx_eth_mvmdio_device = { | ||
63 | .name = "orion-mdio", | ||
64 | .id = -1, | ||
65 | .num_resources = ARRAY_SIZE(mv643xx_eth_mvmdio_resources), | ||
66 | .resource = mv643xx_eth_shared_resources, | ||
67 | }; | ||
68 | |||
50 | static struct resource mv643xx_eth_port1_resources[] = { | 69 | static struct resource mv643xx_eth_port1_resources[] = { |
51 | [0] = { | 70 | [0] = { |
52 | .name = "eth port1 irq", | 71 | .name = "eth port1 irq", |
@@ -82,6 +101,7 @@ static struct platform_device eth_port1_device = { | |||
82 | 101 | ||
83 | static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { | 102 | static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { |
84 | &mv643xx_eth_shared_device, | 103 | &mv643xx_eth_shared_device, |
104 | &mv643xx_eth_mvmdio_device, | ||
85 | ð_port1_device, | 105 | ð_port1_device, |
86 | }; | 106 | }; |
87 | 107 | ||
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 5a8f50a9afa7..302ba43d73a1 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig | |||
@@ -9,7 +9,6 @@ config LINKSTATION | |||
9 | select FSL_SOC | 9 | select FSL_SOC |
10 | select PPC_UDBG_16550 if SERIAL_8250 | 10 | select PPC_UDBG_16550 if SERIAL_8250 |
11 | select DEFAULT_UIMAGE | 11 | select DEFAULT_UIMAGE |
12 | select MPC10X_OPENPIC | ||
13 | select MPC10X_BRIDGE | 12 | select MPC10X_BRIDGE |
14 | help | 13 | help |
15 | Select LINKSTATION if configuring for one of PPC- (MPC8241) | 14 | Select LINKSTATION if configuring for one of PPC- (MPC8241) |
@@ -24,7 +23,6 @@ config STORCENTER | |||
24 | select MPIC | 23 | select MPIC |
25 | select FSL_SOC | 24 | select FSL_SOC |
26 | select PPC_UDBG_16550 if SERIAL_8250 | 25 | select PPC_UDBG_16550 if SERIAL_8250 |
27 | select MPC10X_OPENPIC | ||
28 | select MPC10X_BRIDGE | 26 | select MPC10X_BRIDGE |
29 | help | 27 | help |
30 | Select STORCENTER if configuring for the iomega StorCenter | 28 | Select STORCENTER if configuring for the iomega StorCenter |
@@ -84,9 +82,6 @@ config MV64X60 | |||
84 | select PPC_INDIRECT_PCI | 82 | select PPC_INDIRECT_PCI |
85 | select CHECK_CACHE_COHERENCY | 83 | select CHECK_CACHE_COHERENCY |
86 | 84 | ||
87 | config MPC10X_OPENPIC | ||
88 | bool | ||
89 | |||
90 | config GAMECUBE_COMMON | 85 | config GAMECUBE_COMMON |
91 | bool | 86 | bool |
92 | 87 | ||
diff --git a/arch/powerpc/platforms/pasemi/cpufreq.c b/arch/powerpc/platforms/pasemi/cpufreq.c index 890f30e70f98..be1e7958909e 100644 --- a/arch/powerpc/platforms/pasemi/cpufreq.c +++ b/arch/powerpc/platforms/pasemi/cpufreq.c | |||
@@ -273,10 +273,9 @@ static int pas_cpufreq_target(struct cpufreq_policy *policy, | |||
273 | 273 | ||
274 | freqs.old = policy->cur; | 274 | freqs.old = policy->cur; |
275 | freqs.new = pas_freqs[pas_astate_new].frequency; | 275 | freqs.new = pas_freqs[pas_astate_new].frequency; |
276 | freqs.cpu = policy->cpu; | ||
277 | 276 | ||
278 | mutex_lock(&pas_switch_mutex); | 277 | mutex_lock(&pas_switch_mutex); |
279 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 278 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); |
280 | 279 | ||
281 | pr_debug("setting frequency for cpu %d to %d kHz, 1/%d of max frequency\n", | 280 | pr_debug("setting frequency for cpu %d to %d kHz, 1/%d of max frequency\n", |
282 | policy->cpu, | 281 | policy->cpu, |
@@ -288,7 +287,7 @@ static int pas_cpufreq_target(struct cpufreq_policy *policy, | |||
288 | for_each_online_cpu(i) | 287 | for_each_online_cpu(i) |
289 | set_astate(i, pas_astate_new); | 288 | set_astate(i, pas_astate_new); |
290 | 289 | ||
291 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 290 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); |
292 | mutex_unlock(&pas_switch_mutex); | 291 | mutex_unlock(&pas_switch_mutex); |
293 | 292 | ||
294 | ppc_proc_freq = freqs.new * 1000ul; | 293 | ppc_proc_freq = freqs.new * 1000ul; |
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c index 311b804353b1..3104fad82480 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_32.c +++ b/arch/powerpc/platforms/powermac/cpufreq_32.c | |||
@@ -335,7 +335,8 @@ static int pmu_set_cpu_speed(int low_speed) | |||
335 | return 0; | 335 | return 0; |
336 | } | 336 | } |
337 | 337 | ||
338 | static int do_set_cpu_speed(int speed_mode, int notify) | 338 | static int do_set_cpu_speed(struct cpufreq_policy *policy, int speed_mode, |
339 | int notify) | ||
339 | { | 340 | { |
340 | struct cpufreq_freqs freqs; | 341 | struct cpufreq_freqs freqs; |
341 | unsigned long l3cr; | 342 | unsigned long l3cr; |
@@ -343,13 +344,12 @@ static int do_set_cpu_speed(int speed_mode, int notify) | |||
343 | 344 | ||
344 | freqs.old = cur_freq; | 345 | freqs.old = cur_freq; |
345 | freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; | 346 | freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; |
346 | freqs.cpu = smp_processor_id(); | ||
347 | 347 | ||
348 | if (freqs.old == freqs.new) | 348 | if (freqs.old == freqs.new) |
349 | return 0; | 349 | return 0; |
350 | 350 | ||
351 | if (notify) | 351 | if (notify) |
352 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 352 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); |
353 | if (speed_mode == CPUFREQ_LOW && | 353 | if (speed_mode == CPUFREQ_LOW && |
354 | cpu_has_feature(CPU_FTR_L3CR)) { | 354 | cpu_has_feature(CPU_FTR_L3CR)) { |
355 | l3cr = _get_L3CR(); | 355 | l3cr = _get_L3CR(); |
@@ -366,7 +366,7 @@ static int do_set_cpu_speed(int speed_mode, int notify) | |||
366 | _set_L3CR(prev_l3cr); | 366 | _set_L3CR(prev_l3cr); |
367 | } | 367 | } |
368 | if (notify) | 368 | if (notify) |
369 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 369 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); |
370 | cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; | 370 | cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; |
371 | 371 | ||
372 | return 0; | 372 | return 0; |
@@ -393,7 +393,7 @@ static int pmac_cpufreq_target( struct cpufreq_policy *policy, | |||
393 | target_freq, relation, &newstate)) | 393 | target_freq, relation, &newstate)) |
394 | return -EINVAL; | 394 | return -EINVAL; |
395 | 395 | ||
396 | rc = do_set_cpu_speed(newstate, 1); | 396 | rc = do_set_cpu_speed(policy, newstate, 1); |
397 | 397 | ||
398 | ppc_proc_freq = cur_freq * 1000ul; | 398 | ppc_proc_freq = cur_freq * 1000ul; |
399 | return rc; | 399 | return rc; |
@@ -442,7 +442,7 @@ static int pmac_cpufreq_suspend(struct cpufreq_policy *policy) | |||
442 | no_schedule = 1; | 442 | no_schedule = 1; |
443 | sleep_freq = cur_freq; | 443 | sleep_freq = cur_freq; |
444 | if (cur_freq == low_freq && !is_pmu_based) | 444 | if (cur_freq == low_freq && !is_pmu_based) |
445 | do_set_cpu_speed(CPUFREQ_HIGH, 0); | 445 | do_set_cpu_speed(policy, CPUFREQ_HIGH, 0); |
446 | return 0; | 446 | return 0; |
447 | } | 447 | } |
448 | 448 | ||
@@ -458,7 +458,7 @@ static int pmac_cpufreq_resume(struct cpufreq_policy *policy) | |||
458 | * is that we force a switch to whatever it was, which is | 458 | * is that we force a switch to whatever it was, which is |
459 | * probably high speed due to our suspend() routine | 459 | * probably high speed due to our suspend() routine |
460 | */ | 460 | */ |
461 | do_set_cpu_speed(sleep_freq == low_freq ? | 461 | do_set_cpu_speed(policy, sleep_freq == low_freq ? |
462 | CPUFREQ_LOW : CPUFREQ_HIGH, 0); | 462 | CPUFREQ_LOW : CPUFREQ_HIGH, 0); |
463 | 463 | ||
464 | ppc_proc_freq = cur_freq * 1000ul; | 464 | ppc_proc_freq = cur_freq * 1000ul; |
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c index 9650c6029c82..7ba423431cfe 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_64.c +++ b/arch/powerpc/platforms/powermac/cpufreq_64.c | |||
@@ -339,11 +339,10 @@ static int g5_cpufreq_target(struct cpufreq_policy *policy, | |||
339 | 339 | ||
340 | freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency; | 340 | freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency; |
341 | freqs.new = g5_cpu_freqs[newstate].frequency; | 341 | freqs.new = g5_cpu_freqs[newstate].frequency; |
342 | freqs.cpu = 0; | ||
343 | 342 | ||
344 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 343 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); |
345 | rc = g5_switch_freq(newstate); | 344 | rc = g5_switch_freq(newstate); |
346 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 345 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); |
347 | 346 | ||
348 | mutex_unlock(&g5_switch_mutex); | 347 | mutex_unlock(&g5_switch_mutex); |
349 | 348 | ||
diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig index 74fea5c21839..d3e840d643af 100644 --- a/arch/powerpc/platforms/powernv/Kconfig +++ b/arch/powerpc/platforms/powernv/Kconfig | |||
@@ -8,6 +8,11 @@ config PPC_POWERNV | |||
8 | select PPC_PCI_CHOICE if EMBEDDED | 8 | select PPC_PCI_CHOICE if EMBEDDED |
9 | default y | 9 | default y |
10 | 10 | ||
11 | config POWERNV_MSI | ||
12 | bool "Support PCI MSI on PowerNV platform" | ||
13 | depends on PCI_MSI | ||
14 | default y | ||
15 | |||
11 | config PPC_POWERNV_RTAS | 16 | config PPC_POWERNV_RTAS |
12 | depends on PPC_POWERNV | 17 | depends on PPC_POWERNV |
13 | bool "Support for RTAS based PowerNV platforms such as BML" | 18 | bool "Support for RTAS based PowerNV platforms such as BML" |
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index 3bb07e5e43cd..6fabe92eafb6 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S | |||
@@ -107,3 +107,4 @@ OPAL_CALL(opal_pci_mask_pe_error, OPAL_PCI_MASK_PE_ERROR); | |||
107 | OPAL_CALL(opal_set_slot_led_status, OPAL_SET_SLOT_LED_STATUS); | 107 | OPAL_CALL(opal_set_slot_led_status, OPAL_SET_SLOT_LED_STATUS); |
108 | OPAL_CALL(opal_get_epow_status, OPAL_GET_EPOW_STATUS); | 108 | OPAL_CALL(opal_get_epow_status, OPAL_GET_EPOW_STATUS); |
109 | OPAL_CALL(opal_set_system_attention_led, OPAL_SET_SYSTEM_ATTENTION_LED); | 109 | OPAL_CALL(opal_set_system_attention_led, OPAL_SET_SYSTEM_ATTENTION_LED); |
110 | OPAL_CALL(opal_pci_msi_eoi, OPAL_PCI_MSI_EOI); | ||
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 8e90e8906df3..8c6c9cf91c13 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
@@ -26,10 +26,12 @@ | |||
26 | #include <asm/prom.h> | 26 | #include <asm/prom.h> |
27 | #include <asm/pci-bridge.h> | 27 | #include <asm/pci-bridge.h> |
28 | #include <asm/machdep.h> | 28 | #include <asm/machdep.h> |
29 | #include <asm/msi_bitmap.h> | ||
29 | #include <asm/ppc-pci.h> | 30 | #include <asm/ppc-pci.h> |
30 | #include <asm/opal.h> | 31 | #include <asm/opal.h> |
31 | #include <asm/iommu.h> | 32 | #include <asm/iommu.h> |
32 | #include <asm/tce.h> | 33 | #include <asm/tce.h> |
34 | #include <asm/xics.h> | ||
33 | 35 | ||
34 | #include "powernv.h" | 36 | #include "powernv.h" |
35 | #include "pci.h" | 37 | #include "pci.h" |
@@ -87,6 +89,7 @@ static int pnv_ioda_alloc_pe(struct pnv_phb *phb) | |||
87 | return IODA_INVALID_PE; | 89 | return IODA_INVALID_PE; |
88 | } while(test_and_set_bit(pe, phb->ioda.pe_alloc)); | 90 | } while(test_and_set_bit(pe, phb->ioda.pe_alloc)); |
89 | 91 | ||
92 | phb->ioda.pe_array[pe].phb = phb; | ||
90 | phb->ioda.pe_array[pe].pe_number = pe; | 93 | phb->ioda.pe_array[pe].pe_number = pe; |
91 | return pe; | 94 | return pe; |
92 | } | 95 | } |
@@ -431,22 +434,102 @@ static void pnv_pci_ioda_setup_PEs(void) | |||
431 | } | 434 | } |
432 | } | 435 | } |
433 | 436 | ||
434 | static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *dev) | 437 | static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev) |
435 | { | 438 | { |
436 | /* We delay DMA setup after we have assigned all PE# */ | 439 | struct pci_dn *pdn = pnv_ioda_get_pdn(pdev); |
440 | struct pnv_ioda_pe *pe; | ||
441 | |||
442 | /* | ||
443 | * The function can be called while the PE# | ||
444 | * hasn't been assigned. Do nothing for the | ||
445 | * case. | ||
446 | */ | ||
447 | if (!pdn || pdn->pe_number == IODA_INVALID_PE) | ||
448 | return; | ||
449 | |||
450 | pe = &phb->ioda.pe_array[pdn->pe_number]; | ||
451 | set_iommu_table_base(&pdev->dev, &pe->tce32_table); | ||
437 | } | 452 | } |
438 | 453 | ||
439 | static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus) | 454 | static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl, |
455 | u64 *startp, u64 *endp) | ||
440 | { | 456 | { |
441 | struct pci_dev *dev; | 457 | u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index; |
458 | unsigned long start, end, inc; | ||
459 | |||
460 | start = __pa(startp); | ||
461 | end = __pa(endp); | ||
462 | |||
463 | /* BML uses this case for p6/p7/galaxy2: Shift addr and put in node */ | ||
464 | if (tbl->it_busno) { | ||
465 | start <<= 12; | ||
466 | end <<= 12; | ||
467 | inc = 128 << 12; | ||
468 | start |= tbl->it_busno; | ||
469 | end |= tbl->it_busno; | ||
470 | } else if (tbl->it_type & TCE_PCI_SWINV_PAIR) { | ||
471 | /* p7ioc-style invalidation, 2 TCEs per write */ | ||
472 | start |= (1ull << 63); | ||
473 | end |= (1ull << 63); | ||
474 | inc = 16; | ||
475 | } else { | ||
476 | /* Default (older HW) */ | ||
477 | inc = 128; | ||
478 | } | ||
442 | 479 | ||
443 | list_for_each_entry(dev, &bus->devices, bus_list) { | 480 | end |= inc - 1; /* round up end to be different than start */ |
444 | set_iommu_table_base(&dev->dev, &pe->tce32_table); | 481 | |
445 | if (dev->subordinate) | 482 | mb(); /* Ensure above stores are visible */ |
446 | pnv_ioda_setup_bus_dma(pe, dev->subordinate); | 483 | while (start <= end) { |
484 | __raw_writeq(start, invalidate); | ||
485 | start += inc; | ||
486 | } | ||
487 | |||
488 | /* | ||
489 | * The iommu layer will do another mb() for us on build() | ||
490 | * and we don't care on free() | ||
491 | */ | ||
492 | } | ||
493 | |||
494 | static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe, | ||
495 | struct iommu_table *tbl, | ||
496 | u64 *startp, u64 *endp) | ||
497 | { | ||
498 | unsigned long start, end, inc; | ||
499 | u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index; | ||
500 | |||
501 | /* We'll invalidate DMA address in PE scope */ | ||
502 | start = 0x2ul << 60; | ||
503 | start |= (pe->pe_number & 0xFF); | ||
504 | end = start; | ||
505 | |||
506 | /* Figure out the start, end and step */ | ||
507 | inc = tbl->it_offset + (((u64)startp - tbl->it_base) / sizeof(u64)); | ||
508 | start |= (inc << 12); | ||
509 | inc = tbl->it_offset + (((u64)endp - tbl->it_base) / sizeof(u64)); | ||
510 | end |= (inc << 12); | ||
511 | inc = (0x1ul << 12); | ||
512 | mb(); | ||
513 | |||
514 | while (start <= end) { | ||
515 | __raw_writeq(start, invalidate); | ||
516 | start += inc; | ||
447 | } | 517 | } |
448 | } | 518 | } |
449 | 519 | ||
520 | void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, | ||
521 | u64 *startp, u64 *endp) | ||
522 | { | ||
523 | struct pnv_ioda_pe *pe = container_of(tbl, struct pnv_ioda_pe, | ||
524 | tce32_table); | ||
525 | struct pnv_phb *phb = pe->phb; | ||
526 | |||
527 | if (phb->type == PNV_PHB_IODA1) | ||
528 | pnv_pci_ioda1_tce_invalidate(tbl, startp, endp); | ||
529 | else | ||
530 | pnv_pci_ioda2_tce_invalidate(pe, tbl, startp, endp); | ||
531 | } | ||
532 | |||
450 | static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb, | 533 | static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb, |
451 | struct pnv_ioda_pe *pe, unsigned int base, | 534 | struct pnv_ioda_pe *pe, unsigned int base, |
452 | unsigned int segs) | 535 | unsigned int segs) |
@@ -518,16 +601,11 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb, | |||
518 | */ | 601 | */ |
519 | tbl->it_busno = 0; | 602 | tbl->it_busno = 0; |
520 | tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8); | 603 | tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8); |
521 | tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE | 604 | tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE | |
522 | | TCE_PCI_SWINV_PAIR; | 605 | TCE_PCI_SWINV_PAIR; |
523 | } | 606 | } |
524 | iommu_init_table(tbl, phb->hose->node); | 607 | iommu_init_table(tbl, phb->hose->node); |
525 | 608 | ||
526 | if (pe->pdev) | ||
527 | set_iommu_table_base(&pe->pdev->dev, tbl); | ||
528 | else | ||
529 | pnv_ioda_setup_bus_dma(pe, pe->pbus); | ||
530 | |||
531 | return; | 609 | return; |
532 | fail: | 610 | fail: |
533 | /* XXX Failure: Try to fallback to 64-bit only ? */ | 611 | /* XXX Failure: Try to fallback to 64-bit only ? */ |
@@ -537,6 +615,76 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb, | |||
537 | __free_pages(tce_mem, get_order(TCE32_TABLE_SIZE * segs)); | 615 | __free_pages(tce_mem, get_order(TCE32_TABLE_SIZE * segs)); |
538 | } | 616 | } |
539 | 617 | ||
618 | static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb, | ||
619 | struct pnv_ioda_pe *pe) | ||
620 | { | ||
621 | struct page *tce_mem = NULL; | ||
622 | void *addr; | ||
623 | const __be64 *swinvp; | ||
624 | struct iommu_table *tbl; | ||
625 | unsigned int tce_table_size, end; | ||
626 | int64_t rc; | ||
627 | |||
628 | /* We shouldn't already have a 32-bit DMA associated */ | ||
629 | if (WARN_ON(pe->tce32_seg >= 0)) | ||
630 | return; | ||
631 | |||
632 | /* The PE will reserve all possible 32-bits space */ | ||
633 | pe->tce32_seg = 0; | ||
634 | end = (1 << ilog2(phb->ioda.m32_pci_base)); | ||
635 | tce_table_size = (end / 0x1000) * 8; | ||
636 | pe_info(pe, "Setting up 32-bit TCE table at 0..%08x\n", | ||
637 | end); | ||
638 | |||
639 | /* Allocate TCE table */ | ||
640 | tce_mem = alloc_pages_node(phb->hose->node, GFP_KERNEL, | ||
641 | get_order(tce_table_size)); | ||
642 | if (!tce_mem) { | ||
643 | pe_err(pe, "Failed to allocate a 32-bit TCE memory\n"); | ||
644 | goto fail; | ||
645 | } | ||
646 | addr = page_address(tce_mem); | ||
647 | memset(addr, 0, tce_table_size); | ||
648 | |||
649 | /* | ||
650 | * Map TCE table through TVT. The TVE index is the PE number | ||
651 | * shifted by 1 bit for 32-bits DMA space. | ||
652 | */ | ||
653 | rc = opal_pci_map_pe_dma_window(phb->opal_id, pe->pe_number, | ||
654 | pe->pe_number << 1, 1, __pa(addr), | ||
655 | tce_table_size, 0x1000); | ||
656 | if (rc) { | ||
657 | pe_err(pe, "Failed to configure 32-bit TCE table," | ||
658 | " err %ld\n", rc); | ||
659 | goto fail; | ||
660 | } | ||
661 | |||
662 | /* Setup linux iommu table */ | ||
663 | tbl = &pe->tce32_table; | ||
664 | pnv_pci_setup_iommu_table(tbl, addr, tce_table_size, 0); | ||
665 | |||
666 | /* OPAL variant of PHB3 invalidated TCEs */ | ||
667 | swinvp = of_get_property(phb->hose->dn, "ibm,opal-tce-kill", NULL); | ||
668 | if (swinvp) { | ||
669 | /* We need a couple more fields -- an address and a data | ||
670 | * to or. Since the bus is only printed out on table free | ||
671 | * errors, and on the first pass the data will be a relative | ||
672 | * bus number, print that out instead. | ||
673 | */ | ||
674 | tbl->it_busno = 0; | ||
675 | tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8); | ||
676 | tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE; | ||
677 | } | ||
678 | iommu_init_table(tbl, phb->hose->node); | ||
679 | |||
680 | return; | ||
681 | fail: | ||
682 | if (pe->tce32_seg >= 0) | ||
683 | pe->tce32_seg = -1; | ||
684 | if (tce_mem) | ||
685 | __free_pages(tce_mem, get_order(tce_table_size)); | ||
686 | } | ||
687 | |||
540 | static void pnv_ioda_setup_dma(struct pnv_phb *phb) | 688 | static void pnv_ioda_setup_dma(struct pnv_phb *phb) |
541 | { | 689 | { |
542 | struct pci_controller *hose = phb->hose; | 690 | struct pci_controller *hose = phb->hose; |
@@ -579,20 +727,49 @@ static void pnv_ioda_setup_dma(struct pnv_phb *phb) | |||
579 | if (segs > remaining) | 727 | if (segs > remaining) |
580 | segs = remaining; | 728 | segs = remaining; |
581 | } | 729 | } |
582 | pe_info(pe, "DMA weight %d, assigned %d DMA32 segments\n", | 730 | |
583 | pe->dma_weight, segs); | 731 | /* |
584 | pnv_pci_ioda_setup_dma_pe(phb, pe, base, segs); | 732 | * For IODA2 compliant PHB3, we needn't care about the weight. |
733 | * The all available 32-bits DMA space will be assigned to | ||
734 | * the specific PE. | ||
735 | */ | ||
736 | if (phb->type == PNV_PHB_IODA1) { | ||
737 | pe_info(pe, "DMA weight %d, assigned %d DMA32 segments\n", | ||
738 | pe->dma_weight, segs); | ||
739 | pnv_pci_ioda_setup_dma_pe(phb, pe, base, segs); | ||
740 | } else { | ||
741 | pe_info(pe, "Assign DMA32 space\n"); | ||
742 | segs = 0; | ||
743 | pnv_pci_ioda2_setup_dma_pe(phb, pe); | ||
744 | } | ||
745 | |||
585 | remaining -= segs; | 746 | remaining -= segs; |
586 | base += segs; | 747 | base += segs; |
587 | } | 748 | } |
588 | } | 749 | } |
589 | 750 | ||
590 | #ifdef CONFIG_PCI_MSI | 751 | #ifdef CONFIG_PCI_MSI |
752 | static void pnv_ioda2_msi_eoi(struct irq_data *d) | ||
753 | { | ||
754 | unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); | ||
755 | struct irq_chip *chip = irq_data_get_irq_chip(d); | ||
756 | struct pnv_phb *phb = container_of(chip, struct pnv_phb, | ||
757 | ioda.irq_chip); | ||
758 | int64_t rc; | ||
759 | |||
760 | rc = opal_pci_msi_eoi(phb->opal_id, hw_irq); | ||
761 | WARN_ON_ONCE(rc); | ||
762 | |||
763 | icp_native_eoi(d); | ||
764 | } | ||
765 | |||
591 | static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | 766 | static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, |
592 | unsigned int hwirq, unsigned int is_64, | 767 | unsigned int hwirq, unsigned int virq, |
593 | struct msi_msg *msg) | 768 | unsigned int is_64, struct msi_msg *msg) |
594 | { | 769 | { |
595 | struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); | 770 | struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); |
771 | struct irq_data *idata; | ||
772 | struct irq_chip *ichip; | ||
596 | unsigned int xive_num = hwirq - phb->msi_base; | 773 | unsigned int xive_num = hwirq - phb->msi_base; |
597 | uint64_t addr64; | 774 | uint64_t addr64; |
598 | uint32_t addr32, data; | 775 | uint32_t addr32, data; |
@@ -637,6 +814,23 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | |||
637 | } | 814 | } |
638 | msg->data = data; | 815 | msg->data = data; |
639 | 816 | ||
817 | /* | ||
818 | * Change the IRQ chip for the MSI interrupts on PHB3. | ||
819 | * The corresponding IRQ chip should be populated for | ||
820 | * the first time. | ||
821 | */ | ||
822 | if (phb->type == PNV_PHB_IODA2) { | ||
823 | if (!phb->ioda.irq_chip_init) { | ||
824 | idata = irq_get_irq_data(virq); | ||
825 | ichip = irq_data_get_irq_chip(idata); | ||
826 | phb->ioda.irq_chip_init = 1; | ||
827 | phb->ioda.irq_chip = *ichip; | ||
828 | phb->ioda.irq_chip.irq_eoi = pnv_ioda2_msi_eoi; | ||
829 | } | ||
830 | |||
831 | irq_set_chip(virq, &phb->ioda.irq_chip); | ||
832 | } | ||
833 | |||
640 | pr_devel("%s: %s-bit MSI on hwirq %x (xive #%d)," | 834 | pr_devel("%s: %s-bit MSI on hwirq %x (xive #%d)," |
641 | " address=%x_%08x data=%x PE# %d\n", | 835 | " address=%x_%08x data=%x PE# %d\n", |
642 | pci_name(dev), is_64 ? "64" : "32", hwirq, xive_num, | 836 | pci_name(dev), is_64 ? "64" : "32", hwirq, xive_num, |
@@ -647,7 +841,7 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | |||
647 | 841 | ||
648 | static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) | 842 | static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) |
649 | { | 843 | { |
650 | unsigned int bmap_size; | 844 | unsigned int count; |
651 | const __be32 *prop = of_get_property(phb->hose->dn, | 845 | const __be32 *prop = of_get_property(phb->hose->dn, |
652 | "ibm,opal-msi-ranges", NULL); | 846 | "ibm,opal-msi-ranges", NULL); |
653 | if (!prop) { | 847 | if (!prop) { |
@@ -658,18 +852,17 @@ static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) | |||
658 | return; | 852 | return; |
659 | 853 | ||
660 | phb->msi_base = be32_to_cpup(prop); | 854 | phb->msi_base = be32_to_cpup(prop); |
661 | phb->msi_count = be32_to_cpup(prop + 1); | 855 | count = be32_to_cpup(prop + 1); |
662 | bmap_size = BITS_TO_LONGS(phb->msi_count) * sizeof(unsigned long); | 856 | if (msi_bitmap_alloc(&phb->msi_bmp, count, phb->hose->dn)) { |
663 | phb->msi_map = zalloc_maybe_bootmem(bmap_size, GFP_KERNEL); | ||
664 | if (!phb->msi_map) { | ||
665 | pr_err("PCI %d: Failed to allocate MSI bitmap !\n", | 857 | pr_err("PCI %d: Failed to allocate MSI bitmap !\n", |
666 | phb->hose->global_number); | 858 | phb->hose->global_number); |
667 | return; | 859 | return; |
668 | } | 860 | } |
861 | |||
669 | phb->msi_setup = pnv_pci_ioda_msi_setup; | 862 | phb->msi_setup = pnv_pci_ioda_msi_setup; |
670 | phb->msi32_support = 1; | 863 | phb->msi32_support = 1; |
671 | pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n", | 864 | pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n", |
672 | phb->msi_count, phb->msi_base); | 865 | count, phb->msi_base); |
673 | } | 866 | } |
674 | #else | 867 | #else |
675 | static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { } | 868 | static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { } |
@@ -852,18 +1045,19 @@ static u32 pnv_ioda_bdfn_to_pe(struct pnv_phb *phb, struct pci_bus *bus, | |||
852 | return phb->ioda.pe_rmap[(bus->number << 8) | devfn]; | 1045 | return phb->ioda.pe_rmap[(bus->number << 8) | devfn]; |
853 | } | 1046 | } |
854 | 1047 | ||
855 | void __init pnv_pci_init_ioda1_phb(struct device_node *np) | 1048 | void __init pnv_pci_init_ioda_phb(struct device_node *np, int ioda_type) |
856 | { | 1049 | { |
857 | struct pci_controller *hose; | 1050 | struct pci_controller *hose; |
858 | static int primary = 1; | 1051 | static int primary = 1; |
859 | struct pnv_phb *phb; | 1052 | struct pnv_phb *phb; |
860 | unsigned long size, m32map_off, iomap_off, pemap_off; | 1053 | unsigned long size, m32map_off, iomap_off, pemap_off; |
861 | const u64 *prop64; | 1054 | const u64 *prop64; |
1055 | const u32 *prop32; | ||
862 | u64 phb_id; | 1056 | u64 phb_id; |
863 | void *aux; | 1057 | void *aux; |
864 | long rc; | 1058 | long rc; |
865 | 1059 | ||
866 | pr_info(" Initializing IODA OPAL PHB %s\n", np->full_name); | 1060 | pr_info(" Initializing IODA%d OPAL PHB %s\n", ioda_type, np->full_name); |
867 | 1061 | ||
868 | prop64 = of_get_property(np, "ibm,opal-phbid", NULL); | 1062 | prop64 = of_get_property(np, "ibm,opal-phbid", NULL); |
869 | if (!prop64) { | 1063 | if (!prop64) { |
@@ -890,37 +1084,34 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np) | |||
890 | hose->last_busno = 0xff; | 1084 | hose->last_busno = 0xff; |
891 | hose->private_data = phb; | 1085 | hose->private_data = phb; |
892 | phb->opal_id = phb_id; | 1086 | phb->opal_id = phb_id; |
893 | phb->type = PNV_PHB_IODA1; | 1087 | phb->type = ioda_type; |
894 | 1088 | ||
895 | /* Detect specific models for error handling */ | 1089 | /* Detect specific models for error handling */ |
896 | if (of_device_is_compatible(np, "ibm,p7ioc-pciex")) | 1090 | if (of_device_is_compatible(np, "ibm,p7ioc-pciex")) |
897 | phb->model = PNV_PHB_MODEL_P7IOC; | 1091 | phb->model = PNV_PHB_MODEL_P7IOC; |
1092 | else if (of_device_is_compatible(np, "ibm,p8-pciex")) | ||
1093 | phb->model = PNV_PHB_MODEL_PHB3; | ||
898 | else | 1094 | else |
899 | phb->model = PNV_PHB_MODEL_UNKNOWN; | 1095 | phb->model = PNV_PHB_MODEL_UNKNOWN; |
900 | 1096 | ||
901 | /* We parse "ranges" now since we need to deduce the register base | 1097 | /* Parse 32-bit and IO ranges (if any) */ |
902 | * from the IO base | ||
903 | */ | ||
904 | pci_process_bridge_OF_ranges(phb->hose, np, primary); | 1098 | pci_process_bridge_OF_ranges(phb->hose, np, primary); |
905 | primary = 0; | 1099 | primary = 0; |
906 | 1100 | ||
907 | /* Magic formula from Milton */ | 1101 | /* Get registers */ |
908 | phb->regs = of_iomap(np, 0); | 1102 | phb->regs = of_iomap(np, 0); |
909 | if (phb->regs == NULL) | 1103 | if (phb->regs == NULL) |
910 | pr_err(" Failed to map registers !\n"); | 1104 | pr_err(" Failed to map registers !\n"); |
911 | 1105 | ||
912 | |||
913 | /* XXX This is hack-a-thon. This needs to be changed so that: | ||
914 | * - we obtain stuff like PE# etc... from device-tree | ||
915 | * - we properly re-allocate M32 ourselves | ||
916 | * (the OFW one isn't very good) | ||
917 | */ | ||
918 | |||
919 | /* Initialize more IODA stuff */ | 1106 | /* Initialize more IODA stuff */ |
920 | phb->ioda.total_pe = 128; | 1107 | prop32 = of_get_property(np, "ibm,opal-num-pes", NULL); |
1108 | if (!prop32) | ||
1109 | phb->ioda.total_pe = 1; | ||
1110 | else | ||
1111 | phb->ioda.total_pe = *prop32; | ||
921 | 1112 | ||
922 | phb->ioda.m32_size = resource_size(&hose->mem_resources[0]); | 1113 | phb->ioda.m32_size = resource_size(&hose->mem_resources[0]); |
923 | /* OFW Has already off top 64k of M32 space (MSI space) */ | 1114 | /* FW Has already off top 64k of M32 space (MSI space) */ |
924 | phb->ioda.m32_size += 0x10000; | 1115 | phb->ioda.m32_size += 0x10000; |
925 | 1116 | ||
926 | phb->ioda.m32_segsize = phb->ioda.m32_size / phb->ioda.total_pe; | 1117 | phb->ioda.m32_segsize = phb->ioda.m32_size / phb->ioda.total_pe; |
@@ -930,7 +1121,10 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np) | |||
930 | phb->ioda.io_segsize = phb->ioda.io_size / phb->ioda.total_pe; | 1121 | phb->ioda.io_segsize = phb->ioda.io_size / phb->ioda.total_pe; |
931 | phb->ioda.io_pci_base = 0; /* XXX calculate this ? */ | 1122 | phb->ioda.io_pci_base = 0; /* XXX calculate this ? */ |
932 | 1123 | ||
933 | /* Allocate aux data & arrays */ | 1124 | /* Allocate aux data & arrays |
1125 | * | ||
1126 | * XXX TODO: Don't allocate io segmap on PHB3 | ||
1127 | */ | ||
934 | size = _ALIGN_UP(phb->ioda.total_pe / 8, sizeof(unsigned long)); | 1128 | size = _ALIGN_UP(phb->ioda.total_pe / 8, sizeof(unsigned long)); |
935 | m32map_off = size; | 1129 | m32map_off = size; |
936 | size += phb->ioda.total_pe * sizeof(phb->ioda.m32_segmap[0]); | 1130 | size += phb->ioda.total_pe * sizeof(phb->ioda.m32_segmap[0]); |
@@ -960,7 +1154,7 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np) | |||
960 | hose->mem_resources[2].start = 0; | 1154 | hose->mem_resources[2].start = 0; |
961 | hose->mem_resources[2].end = 0; | 1155 | hose->mem_resources[2].end = 0; |
962 | 1156 | ||
963 | #if 0 | 1157 | #if 0 /* We should really do that ... */ |
964 | rc = opal_pci_set_phb_mem_window(opal->phb_id, | 1158 | rc = opal_pci_set_phb_mem_window(opal->phb_id, |
965 | window_type, | 1159 | window_type, |
966 | window_num, | 1160 | window_num, |
@@ -974,16 +1168,6 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np) | |||
974 | phb->ioda.m32_size, phb->ioda.m32_segsize, | 1168 | phb->ioda.m32_size, phb->ioda.m32_segsize, |
975 | phb->ioda.io_size, phb->ioda.io_segsize); | 1169 | phb->ioda.io_size, phb->ioda.io_segsize); |
976 | 1170 | ||
977 | if (phb->regs) { | ||
978 | pr_devel(" BUID = 0x%016llx\n", in_be64(phb->regs + 0x100)); | ||
979 | pr_devel(" PHB2_CR = 0x%016llx\n", in_be64(phb->regs + 0x160)); | ||
980 | pr_devel(" IO_BAR = 0x%016llx\n", in_be64(phb->regs + 0x170)); | ||
981 | pr_devel(" IO_BAMR = 0x%016llx\n", in_be64(phb->regs + 0x178)); | ||
982 | pr_devel(" IO_SAR = 0x%016llx\n", in_be64(phb->regs + 0x180)); | ||
983 | pr_devel(" M32_BAR = 0x%016llx\n", in_be64(phb->regs + 0x190)); | ||
984 | pr_devel(" M32_BAMR = 0x%016llx\n", in_be64(phb->regs + 0x198)); | ||
985 | pr_devel(" M32_SAR = 0x%016llx\n", in_be64(phb->regs + 0x1a0)); | ||
986 | } | ||
987 | phb->hose->ops = &pnv_pci_ops; | 1171 | phb->hose->ops = &pnv_pci_ops; |
988 | 1172 | ||
989 | /* Setup RID -> PE mapping function */ | 1173 | /* Setup RID -> PE mapping function */ |
@@ -1011,7 +1195,18 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np) | |||
1011 | rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); | 1195 | rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); |
1012 | if (rc) | 1196 | if (rc) |
1013 | pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc); | 1197 | pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc); |
1014 | opal_pci_set_pe(phb_id, 0, 0, 7, 1, 1 , OPAL_MAP_PE); | 1198 | |
1199 | /* | ||
1200 | * On IODA1 map everything to PE#0, on IODA2 we assume the IODA reset | ||
1201 | * has cleared the RTT which has the same effect | ||
1202 | */ | ||
1203 | if (ioda_type == PNV_PHB_IODA1) | ||
1204 | opal_pci_set_pe(phb_id, 0, 0, 7, 1, 1 , OPAL_MAP_PE); | ||
1205 | } | ||
1206 | |||
1207 | void pnv_pci_init_ioda2_phb(struct device_node *np) | ||
1208 | { | ||
1209 | pnv_pci_init_ioda_phb(np, PNV_PHB_IODA2); | ||
1015 | } | 1210 | } |
1016 | 1211 | ||
1017 | void __init pnv_pci_init_ioda_hub(struct device_node *np) | 1212 | void __init pnv_pci_init_ioda_hub(struct device_node *np) |
@@ -1034,6 +1229,6 @@ void __init pnv_pci_init_ioda_hub(struct device_node *np) | |||
1034 | for_each_child_of_node(np, phbn) { | 1229 | for_each_child_of_node(np, phbn) { |
1035 | /* Look for IODA1 PHBs */ | 1230 | /* Look for IODA1 PHBs */ |
1036 | if (of_device_is_compatible(phbn, "ibm,ioda-phb")) | 1231 | if (of_device_is_compatible(phbn, "ibm,ioda-phb")) |
1037 | pnv_pci_init_ioda1_phb(phbn); | 1232 | pnv_pci_init_ioda_phb(phbn, PNV_PHB_IODA1); |
1038 | } | 1233 | } |
1039 | } | 1234 | } |
diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c index 7db8771a40f5..92b37a0186c9 100644 --- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c +++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <asm/prom.h> | 26 | #include <asm/prom.h> |
27 | #include <asm/pci-bridge.h> | 27 | #include <asm/pci-bridge.h> |
28 | #include <asm/machdep.h> | 28 | #include <asm/machdep.h> |
29 | #include <asm/msi_bitmap.h> | ||
29 | #include <asm/ppc-pci.h> | 30 | #include <asm/ppc-pci.h> |
30 | #include <asm/opal.h> | 31 | #include <asm/opal.h> |
31 | #include <asm/iommu.h> | 32 | #include <asm/iommu.h> |
@@ -41,8 +42,8 @@ | |||
41 | 42 | ||
42 | #ifdef CONFIG_PCI_MSI | 43 | #ifdef CONFIG_PCI_MSI |
43 | static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | 44 | static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, |
44 | unsigned int hwirq, unsigned int is_64, | 45 | unsigned int hwirq, unsigned int virq, |
45 | struct msi_msg *msg) | 46 | unsigned int is_64, struct msi_msg *msg) |
46 | { | 47 | { |
47 | if (WARN_ON(!is_64)) | 48 | if (WARN_ON(!is_64)) |
48 | return -ENXIO; | 49 | return -ENXIO; |
@@ -55,7 +56,7 @@ static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | |||
55 | 56 | ||
56 | static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) | 57 | static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) |
57 | { | 58 | { |
58 | unsigned int bmap_size; | 59 | unsigned int count; |
59 | const __be32 *prop = of_get_property(phb->hose->dn, | 60 | const __be32 *prop = of_get_property(phb->hose->dn, |
60 | "ibm,opal-msi-ranges", NULL); | 61 | "ibm,opal-msi-ranges", NULL); |
61 | if (!prop) | 62 | if (!prop) |
@@ -67,10 +68,8 @@ static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) | |||
67 | if (of_device_is_compatible(phb->hose->dn, "ibm,p5ioc2-pcix")) | 68 | if (of_device_is_compatible(phb->hose->dn, "ibm,p5ioc2-pcix")) |
68 | return; | 69 | return; |
69 | phb->msi_base = be32_to_cpup(prop); | 70 | phb->msi_base = be32_to_cpup(prop); |
70 | phb->msi_count = be32_to_cpup(prop + 1); | 71 | count = be32_to_cpup(prop + 1); |
71 | bmap_size = BITS_TO_LONGS(phb->msi_count) * sizeof(unsigned long); | 72 | if (msi_bitmap_alloc(&phb->msi_bmp, count, phb->hose->dn)) { |
72 | phb->msi_map = zalloc_maybe_bootmem(bmap_size, GFP_KERNEL); | ||
73 | if (!phb->msi_map) { | ||
74 | pr_err("PCI %d: Failed to allocate MSI bitmap !\n", | 73 | pr_err("PCI %d: Failed to allocate MSI bitmap !\n", |
75 | phb->hose->global_number); | 74 | phb->hose->global_number); |
76 | return; | 75 | return; |
@@ -78,7 +77,7 @@ static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) | |||
78 | phb->msi_setup = pnv_pci_p5ioc2_msi_setup; | 77 | phb->msi_setup = pnv_pci_p5ioc2_msi_setup; |
79 | phb->msi32_support = 0; | 78 | phb->msi32_support = 0; |
80 | pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n", | 79 | pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n", |
81 | phb->msi_count, phb->msi_base); | 80 | count, phb->msi_base); |
82 | } | 81 | } |
83 | #else | 82 | #else |
84 | static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) { } | 83 | static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) { } |
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index b8b8e0bd9897..55dfca844ddf 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <asm/prom.h> | 26 | #include <asm/prom.h> |
27 | #include <asm/pci-bridge.h> | 27 | #include <asm/pci-bridge.h> |
28 | #include <asm/machdep.h> | 28 | #include <asm/machdep.h> |
29 | #include <asm/msi_bitmap.h> | ||
29 | #include <asm/ppc-pci.h> | 30 | #include <asm/ppc-pci.h> |
30 | #include <asm/opal.h> | 31 | #include <asm/opal.h> |
31 | #include <asm/iommu.h> | 32 | #include <asm/iommu.h> |
@@ -47,43 +48,7 @@ static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type) | |||
47 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | 48 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); |
48 | struct pnv_phb *phb = hose->private_data; | 49 | struct pnv_phb *phb = hose->private_data; |
49 | 50 | ||
50 | return (phb && phb->msi_map) ? 0 : -ENODEV; | 51 | return (phb && phb->msi_bmp.bitmap) ? 0 : -ENODEV; |
51 | } | ||
52 | |||
53 | static unsigned int pnv_get_one_msi(struct pnv_phb *phb) | ||
54 | { | ||
55 | unsigned long flags; | ||
56 | unsigned int id, rc; | ||
57 | |||
58 | spin_lock_irqsave(&phb->lock, flags); | ||
59 | |||
60 | id = find_next_zero_bit(phb->msi_map, phb->msi_count, phb->msi_next); | ||
61 | if (id >= phb->msi_count && phb->msi_next) | ||
62 | id = find_next_zero_bit(phb->msi_map, phb->msi_count, 0); | ||
63 | if (id >= phb->msi_count) { | ||
64 | rc = 0; | ||
65 | goto out; | ||
66 | } | ||
67 | __set_bit(id, phb->msi_map); | ||
68 | rc = id + phb->msi_base; | ||
69 | out: | ||
70 | spin_unlock_irqrestore(&phb->lock, flags); | ||
71 | return rc; | ||
72 | } | ||
73 | |||
74 | static void pnv_put_msi(struct pnv_phb *phb, unsigned int hwirq) | ||
75 | { | ||
76 | unsigned long flags; | ||
77 | unsigned int id; | ||
78 | |||
79 | if (WARN_ON(hwirq < phb->msi_base || | ||
80 | hwirq >= (phb->msi_base + phb->msi_count))) | ||
81 | return; | ||
82 | id = hwirq - phb->msi_base; | ||
83 | |||
84 | spin_lock_irqsave(&phb->lock, flags); | ||
85 | __clear_bit(id, phb->msi_map); | ||
86 | spin_unlock_irqrestore(&phb->lock, flags); | ||
87 | } | 52 | } |
88 | 53 | ||
89 | static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | 54 | static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) |
@@ -92,7 +57,8 @@ static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
92 | struct pnv_phb *phb = hose->private_data; | 57 | struct pnv_phb *phb = hose->private_data; |
93 | struct msi_desc *entry; | 58 | struct msi_desc *entry; |
94 | struct msi_msg msg; | 59 | struct msi_msg msg; |
95 | unsigned int hwirq, virq; | 60 | int hwirq; |
61 | unsigned int virq; | ||
96 | int rc; | 62 | int rc; |
97 | 63 | ||
98 | if (WARN_ON(!phb)) | 64 | if (WARN_ON(!phb)) |
@@ -104,25 +70,25 @@ static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
104 | pci_name(pdev)); | 70 | pci_name(pdev)); |
105 | return -ENXIO; | 71 | return -ENXIO; |
106 | } | 72 | } |
107 | hwirq = pnv_get_one_msi(phb); | 73 | hwirq = msi_bitmap_alloc_hwirqs(&phb->msi_bmp, 1); |
108 | if (!hwirq) { | 74 | if (hwirq < 0) { |
109 | pr_warn("%s: Failed to find a free MSI\n", | 75 | pr_warn("%s: Failed to find a free MSI\n", |
110 | pci_name(pdev)); | 76 | pci_name(pdev)); |
111 | return -ENOSPC; | 77 | return -ENOSPC; |
112 | } | 78 | } |
113 | virq = irq_create_mapping(NULL, hwirq); | 79 | virq = irq_create_mapping(NULL, phb->msi_base + hwirq); |
114 | if (virq == NO_IRQ) { | 80 | if (virq == NO_IRQ) { |
115 | pr_warn("%s: Failed to map MSI to linux irq\n", | 81 | pr_warn("%s: Failed to map MSI to linux irq\n", |
116 | pci_name(pdev)); | 82 | pci_name(pdev)); |
117 | pnv_put_msi(phb, hwirq); | 83 | msi_bitmap_free_hwirqs(&phb->msi_bmp, hwirq, 1); |
118 | return -ENOMEM; | 84 | return -ENOMEM; |
119 | } | 85 | } |
120 | rc = phb->msi_setup(phb, pdev, hwirq, entry->msi_attrib.is_64, | 86 | rc = phb->msi_setup(phb, pdev, phb->msi_base + hwirq, |
121 | &msg); | 87 | virq, entry->msi_attrib.is_64, &msg); |
122 | if (rc) { | 88 | if (rc) { |
123 | pr_warn("%s: Failed to setup MSI\n", pci_name(pdev)); | 89 | pr_warn("%s: Failed to setup MSI\n", pci_name(pdev)); |
124 | irq_dispose_mapping(virq); | 90 | irq_dispose_mapping(virq); |
125 | pnv_put_msi(phb, hwirq); | 91 | msi_bitmap_free_hwirqs(&phb->msi_bmp, hwirq, 1); |
126 | return rc; | 92 | return rc; |
127 | } | 93 | } |
128 | irq_set_msi_desc(virq, entry); | 94 | irq_set_msi_desc(virq, entry); |
@@ -144,7 +110,8 @@ static void pnv_teardown_msi_irqs(struct pci_dev *pdev) | |||
144 | if (entry->irq == NO_IRQ) | 110 | if (entry->irq == NO_IRQ) |
145 | continue; | 111 | continue; |
146 | irq_set_msi_desc(entry->irq, NULL); | 112 | irq_set_msi_desc(entry->irq, NULL); |
147 | pnv_put_msi(phb, virq_to_hw(entry->irq)); | 113 | msi_bitmap_free_hwirqs(&phb->msi_bmp, |
114 | virq_to_hw(entry->irq) - phb->msi_base, 1); | ||
148 | irq_dispose_mapping(entry->irq); | 115 | irq_dispose_mapping(entry->irq); |
149 | } | 116 | } |
150 | } | 117 | } |
@@ -362,48 +329,6 @@ struct pci_ops pnv_pci_ops = { | |||
362 | .write = pnv_pci_write_config, | 329 | .write = pnv_pci_write_config, |
363 | }; | 330 | }; |
364 | 331 | ||
365 | |||
366 | static void pnv_tce_invalidate(struct iommu_table *tbl, | ||
367 | u64 *startp, u64 *endp) | ||
368 | { | ||
369 | u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index; | ||
370 | unsigned long start, end, inc; | ||
371 | |||
372 | start = __pa(startp); | ||
373 | end = __pa(endp); | ||
374 | |||
375 | |||
376 | /* BML uses this case for p6/p7/galaxy2: Shift addr and put in node */ | ||
377 | if (tbl->it_busno) { | ||
378 | start <<= 12; | ||
379 | end <<= 12; | ||
380 | inc = 128 << 12; | ||
381 | start |= tbl->it_busno; | ||
382 | end |= tbl->it_busno; | ||
383 | } | ||
384 | /* p7ioc-style invalidation, 2 TCEs per write */ | ||
385 | else if (tbl->it_type & TCE_PCI_SWINV_PAIR) { | ||
386 | start |= (1ull << 63); | ||
387 | end |= (1ull << 63); | ||
388 | inc = 16; | ||
389 | } | ||
390 | /* Default (older HW) */ | ||
391 | else | ||
392 | inc = 128; | ||
393 | |||
394 | end |= inc - 1; /* round up end to be different than start */ | ||
395 | |||
396 | mb(); /* Ensure above stores are visible */ | ||
397 | while (start <= end) { | ||
398 | __raw_writeq(start, invalidate); | ||
399 | start += inc; | ||
400 | } | ||
401 | /* The iommu layer will do another mb() for us on build() and | ||
402 | * we don't care on free() | ||
403 | */ | ||
404 | } | ||
405 | |||
406 | |||
407 | static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, | 332 | static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, |
408 | unsigned long uaddr, enum dma_data_direction direction, | 333 | unsigned long uaddr, enum dma_data_direction direction, |
409 | struct dma_attrs *attrs) | 334 | struct dma_attrs *attrs) |
@@ -428,7 +353,7 @@ static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, | |||
428 | * of flags if that becomes the case | 353 | * of flags if that becomes the case |
429 | */ | 354 | */ |
430 | if (tbl->it_type & TCE_PCI_SWINV_CREATE) | 355 | if (tbl->it_type & TCE_PCI_SWINV_CREATE) |
431 | pnv_tce_invalidate(tbl, tces, tcep - 1); | 356 | pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1); |
432 | 357 | ||
433 | return 0; | 358 | return 0; |
434 | } | 359 | } |
@@ -442,8 +367,8 @@ static void pnv_tce_free(struct iommu_table *tbl, long index, long npages) | |||
442 | while (npages--) | 367 | while (npages--) |
443 | *(tcep++) = 0; | 368 | *(tcep++) = 0; |
444 | 369 | ||
445 | if (tbl->it_type & TCE_PCI_SWINV_FREE) | 370 | if (tbl->it_type & TCE_PCI_SWINV_CREATE) |
446 | pnv_tce_invalidate(tbl, tces, tcep - 1); | 371 | pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1); |
447 | } | 372 | } |
448 | 373 | ||
449 | static unsigned long pnv_tce_get(struct iommu_table *tbl, long index) | 374 | static unsigned long pnv_tce_get(struct iommu_table *tbl, long index) |
@@ -525,7 +450,7 @@ static void pnv_pci_dma_dev_setup(struct pci_dev *pdev) | |||
525 | pnv_pci_dma_fallback_setup(hose, pdev); | 450 | pnv_pci_dma_fallback_setup(hose, pdev); |
526 | } | 451 | } |
527 | 452 | ||
528 | /* Fixup wrong class code in p7ioc root complex */ | 453 | /* Fixup wrong class code in p7ioc and p8 root complex */ |
529 | static void pnv_p7ioc_rc_quirk(struct pci_dev *dev) | 454 | static void pnv_p7ioc_rc_quirk(struct pci_dev *dev) |
530 | { | 455 | { |
531 | dev->class = PCI_CLASS_BRIDGE_PCI << 8; | 456 | dev->class = PCI_CLASS_BRIDGE_PCI << 8; |
@@ -591,6 +516,10 @@ void __init pnv_pci_init(void) | |||
591 | if (!found_ioda) | 516 | if (!found_ioda) |
592 | for_each_compatible_node(np, NULL, "ibm,p5ioc2") | 517 | for_each_compatible_node(np, NULL, "ibm,p5ioc2") |
593 | pnv_pci_init_p5ioc2_hub(np); | 518 | pnv_pci_init_p5ioc2_hub(np); |
519 | |||
520 | /* Look for ioda2 built-in PHB3's */ | ||
521 | for_each_compatible_node(np, NULL, "ibm,ioda2-phb") | ||
522 | pnv_pci_init_ioda2_phb(np); | ||
594 | } | 523 | } |
595 | 524 | ||
596 | /* Setup the linkage between OF nodes and PHBs */ | 525 | /* Setup the linkage between OF nodes and PHBs */ |
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 7cfb7c883deb..48dc4bb856a1 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h | |||
@@ -4,9 +4,9 @@ | |||
4 | struct pci_dn; | 4 | struct pci_dn; |
5 | 5 | ||
6 | enum pnv_phb_type { | 6 | enum pnv_phb_type { |
7 | PNV_PHB_P5IOC2, | 7 | PNV_PHB_P5IOC2 = 0, |
8 | PNV_PHB_IODA1, | 8 | PNV_PHB_IODA1 = 1, |
9 | PNV_PHB_IODA2, | 9 | PNV_PHB_IODA2 = 2, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | /* Precise PHB model for error management */ | 12 | /* Precise PHB model for error management */ |
@@ -14,6 +14,7 @@ enum pnv_phb_model { | |||
14 | PNV_PHB_MODEL_UNKNOWN, | 14 | PNV_PHB_MODEL_UNKNOWN, |
15 | PNV_PHB_MODEL_P5IOC2, | 15 | PNV_PHB_MODEL_P5IOC2, |
16 | PNV_PHB_MODEL_P7IOC, | 16 | PNV_PHB_MODEL_P7IOC, |
17 | PNV_PHB_MODEL_PHB3, | ||
17 | }; | 18 | }; |
18 | 19 | ||
19 | #define PNV_PCI_DIAG_BUF_SIZE 4096 | 20 | #define PNV_PCI_DIAG_BUF_SIZE 4096 |
@@ -22,8 +23,10 @@ enum pnv_phb_model { | |||
22 | #define PNV_IODA_PE_BUS_ALL (1 << 2) /* PE has subordinate buses */ | 23 | #define PNV_IODA_PE_BUS_ALL (1 << 2) /* PE has subordinate buses */ |
23 | 24 | ||
24 | /* Data associated with a PE, including IOMMU tracking etc.. */ | 25 | /* Data associated with a PE, including IOMMU tracking etc.. */ |
26 | struct pnv_phb; | ||
25 | struct pnv_ioda_pe { | 27 | struct pnv_ioda_pe { |
26 | unsigned long flags; | 28 | unsigned long flags; |
29 | struct pnv_phb *phb; | ||
27 | 30 | ||
28 | /* A PE can be associated with a single device or an | 31 | /* A PE can be associated with a single device or an |
29 | * entire bus (& children). In the former case, pdev | 32 | * entire bus (& children). In the former case, pdev |
@@ -73,15 +76,13 @@ struct pnv_phb { | |||
73 | spinlock_t lock; | 76 | spinlock_t lock; |
74 | 77 | ||
75 | #ifdef CONFIG_PCI_MSI | 78 | #ifdef CONFIG_PCI_MSI |
76 | unsigned long *msi_map; | ||
77 | unsigned int msi_base; | 79 | unsigned int msi_base; |
78 | unsigned int msi_count; | ||
79 | unsigned int msi_next; | ||
80 | unsigned int msi32_support; | 80 | unsigned int msi32_support; |
81 | struct msi_bitmap msi_bmp; | ||
81 | #endif | 82 | #endif |
82 | int (*msi_setup)(struct pnv_phb *phb, struct pci_dev *dev, | 83 | int (*msi_setup)(struct pnv_phb *phb, struct pci_dev *dev, |
83 | unsigned int hwirq, unsigned int is_64, | 84 | unsigned int hwirq, unsigned int virq, |
84 | struct msi_msg *msg); | 85 | unsigned int is_64, struct msi_msg *msg); |
85 | void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev); | 86 | void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev); |
86 | void (*fixup_phb)(struct pci_controller *hose); | 87 | void (*fixup_phb)(struct pci_controller *hose); |
87 | u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn); | 88 | u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn); |
@@ -109,6 +110,10 @@ struct pnv_phb { | |||
109 | unsigned int *io_segmap; | 110 | unsigned int *io_segmap; |
110 | struct pnv_ioda_pe *pe_array; | 111 | struct pnv_ioda_pe *pe_array; |
111 | 112 | ||
113 | /* IRQ chip */ | ||
114 | int irq_chip_init; | ||
115 | struct irq_chip irq_chip; | ||
116 | |||
112 | /* Sorted list of used PE's based | 117 | /* Sorted list of used PE's based |
113 | * on the sequence of creation | 118 | * on the sequence of creation |
114 | */ | 119 | */ |
@@ -150,6 +155,7 @@ extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl, | |||
150 | u64 dma_offset); | 155 | u64 dma_offset); |
151 | extern void pnv_pci_init_p5ioc2_hub(struct device_node *np); | 156 | extern void pnv_pci_init_p5ioc2_hub(struct device_node *np); |
152 | extern void pnv_pci_init_ioda_hub(struct device_node *np); | 157 | extern void pnv_pci_init_ioda_hub(struct device_node *np); |
153 | 158 | extern void pnv_pci_init_ioda2_phb(struct device_node *np); | |
154 | 159 | extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, | |
160 | u64 *startp, u64 *endp); | ||
155 | #endif /* __POWERNV_PCI_H */ | 161 | #endif /* __POWERNV_PCI_H */ |
diff --git a/arch/powerpc/platforms/prep/Kconfig b/arch/powerpc/platforms/prep/Kconfig deleted file mode 100644 index 1547f66235d9..000000000000 --- a/arch/powerpc/platforms/prep/Kconfig +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | config PPC_PREP | ||
2 | bool "PowerPC Reference Platform (PReP) based machines" | ||
3 | depends on 6xx && BROKEN | ||
4 | select HAVE_PCSPKR_PLATFORM | ||
5 | select MPIC | ||
6 | select PPC_I8259 | ||
7 | select PPC_INDIRECT_PCI | ||
8 | select PPC_UDBG_16550 | ||
9 | select PPC_NATIVE | ||
10 | default n | ||
11 | |||
12 | config PREP_RESIDUAL | ||
13 | bool "Support for PReP Residual Data" | ||
14 | depends on PPC_PREP | ||
15 | help | ||
16 | Some PReP systems have residual data passed to the kernel by the | ||
17 | firmware. This allows detection of memory size, devices present and | ||
18 | other useful pieces of information. Sometimes this information is | ||
19 | not present or incorrect, in which case it could lead to the machine | ||
20 | behaving incorrectly. If this happens, either disable PREP_RESIDUAL | ||
21 | or pass the 'noresidual' option to the kernel. | ||
22 | |||
23 | If you are running a PReP system, say Y here, otherwise say N. | ||
diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c index 6cc58201db8c..177a2f70700c 100644 --- a/arch/powerpc/platforms/ps3/htab.c +++ b/arch/powerpc/platforms/ps3/htab.c | |||
@@ -46,7 +46,7 @@ static DEFINE_SPINLOCK(ps3_htab_lock); | |||
46 | 46 | ||
47 | static long ps3_hpte_insert(unsigned long hpte_group, unsigned long vpn, | 47 | static long ps3_hpte_insert(unsigned long hpte_group, unsigned long vpn, |
48 | unsigned long pa, unsigned long rflags, unsigned long vflags, | 48 | unsigned long pa, unsigned long rflags, unsigned long vflags, |
49 | int psize, int ssize) | 49 | int psize, int apsize, int ssize) |
50 | { | 50 | { |
51 | int result; | 51 | int result; |
52 | u64 hpte_v, hpte_r; | 52 | u64 hpte_v, hpte_r; |
@@ -62,8 +62,8 @@ static long ps3_hpte_insert(unsigned long hpte_group, unsigned long vpn, | |||
62 | */ | 62 | */ |
63 | vflags &= ~HPTE_V_SECONDARY; | 63 | vflags &= ~HPTE_V_SECONDARY; |
64 | 64 | ||
65 | hpte_v = hpte_encode_v(vpn, psize, ssize) | vflags | HPTE_V_VALID; | 65 | hpte_v = hpte_encode_v(vpn, psize, apsize, ssize) | vflags | HPTE_V_VALID; |
66 | hpte_r = hpte_encode_r(ps3_mm_phys_to_lpar(pa), psize) | rflags; | 66 | hpte_r = hpte_encode_r(ps3_mm_phys_to_lpar(pa), psize, apsize) | rflags; |
67 | 67 | ||
68 | spin_lock_irqsave(&ps3_htab_lock, flags); | 68 | spin_lock_irqsave(&ps3_htab_lock, flags); |
69 | 69 | ||
@@ -117,7 +117,7 @@ static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp, | |||
117 | unsigned long flags; | 117 | unsigned long flags; |
118 | long ret; | 118 | long ret; |
119 | 119 | ||
120 | want_v = hpte_encode_v(vpn, psize, ssize); | 120 | want_v = hpte_encode_avpn(vpn, psize, ssize); |
121 | 121 | ||
122 | spin_lock_irqsave(&ps3_htab_lock, flags); | 122 | spin_lock_irqsave(&ps3_htab_lock, flags); |
123 | 123 | ||
diff --git a/arch/powerpc/platforms/ps3/time.c b/arch/powerpc/platforms/ps3/time.c index 40b5cb433005..cba1e6be68e5 100644 --- a/arch/powerpc/platforms/ps3/time.c +++ b/arch/powerpc/platforms/ps3/time.c | |||
@@ -89,10 +89,8 @@ static int __init ps3_rtc_init(void) | |||
89 | return -ENODEV; | 89 | return -ENODEV; |
90 | 90 | ||
91 | pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0); | 91 | pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0); |
92 | if (IS_ERR(pdev)) | ||
93 | return PTR_ERR(pdev); | ||
94 | 92 | ||
95 | return 0; | 93 | return PTR_RET(pdev); |
96 | } | 94 | } |
97 | 95 | ||
98 | module_init(ps3_rtc_init); | 96 | module_init(ps3_rtc_init); |
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c index aa3693f7fb27..8c80588abacc 100644 --- a/arch/powerpc/platforms/pseries/firmware.c +++ b/arch/powerpc/platforms/pseries/firmware.c | |||
@@ -28,18 +28,18 @@ | |||
28 | 28 | ||
29 | #include "pseries.h" | 29 | #include "pseries.h" |
30 | 30 | ||
31 | typedef struct { | 31 | struct hypertas_fw_feature { |
32 | unsigned long val; | 32 | unsigned long val; |
33 | char * name; | 33 | char * name; |
34 | } firmware_feature_t; | 34 | }; |
35 | 35 | ||
36 | /* | 36 | /* |
37 | * The names in this table match names in rtas/ibm,hypertas-functions. If the | 37 | * The names in this table match names in rtas/ibm,hypertas-functions. If the |
38 | * entry ends in a '*', only upto the '*' is matched. Otherwise the entire | 38 | * entry ends in a '*', only upto the '*' is matched. Otherwise the entire |
39 | * string must match. | 39 | * string must match. |
40 | */ | 40 | */ |
41 | static __initdata firmware_feature_t | 41 | static __initdata struct hypertas_fw_feature |
42 | firmware_features_table[FIRMWARE_MAX_FEATURES] = { | 42 | hypertas_fw_features_table[] = { |
43 | {FW_FEATURE_PFT, "hcall-pft"}, | 43 | {FW_FEATURE_PFT, "hcall-pft"}, |
44 | {FW_FEATURE_TCE, "hcall-tce"}, | 44 | {FW_FEATURE_TCE, "hcall-tce"}, |
45 | {FW_FEATURE_SPRG0, "hcall-sprg0"}, | 45 | {FW_FEATURE_SPRG0, "hcall-sprg0"}, |
@@ -69,20 +69,18 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = { | |||
69 | * device-tree/ibm,hypertas-functions. Ultimately this functionality may | 69 | * device-tree/ibm,hypertas-functions. Ultimately this functionality may |
70 | * be moved into prom.c prom_init(). | 70 | * be moved into prom.c prom_init(). |
71 | */ | 71 | */ |
72 | void __init fw_feature_init(const char *hypertas, unsigned long len) | 72 | void __init fw_hypertas_feature_init(const char *hypertas, unsigned long len) |
73 | { | 73 | { |
74 | const char *s; | 74 | const char *s; |
75 | int i; | 75 | int i; |
76 | 76 | ||
77 | pr_debug(" -> fw_feature_init()\n"); | 77 | pr_debug(" -> fw_hypertas_feature_init()\n"); |
78 | 78 | ||
79 | for (s = hypertas; s < hypertas + len; s += strlen(s) + 1) { | 79 | for (s = hypertas; s < hypertas + len; s += strlen(s) + 1) { |
80 | for (i = 0; i < FIRMWARE_MAX_FEATURES; i++) { | 80 | for (i = 0; i < ARRAY_SIZE(hypertas_fw_features_table); i++) { |
81 | const char *name = firmware_features_table[i].name; | 81 | const char *name = hypertas_fw_features_table[i].name; |
82 | size_t size; | 82 | size_t size; |
83 | /* check value against table of strings */ | 83 | |
84 | if (!name) | ||
85 | continue; | ||
86 | /* | 84 | /* |
87 | * If there is a '*' at the end of name, only check | 85 | * If there is a '*' at the end of name, only check |
88 | * upto there | 86 | * upto there |
@@ -96,10 +94,40 @@ void __init fw_feature_init(const char *hypertas, unsigned long len) | |||
96 | 94 | ||
97 | /* we have a match */ | 95 | /* we have a match */ |
98 | powerpc_firmware_features |= | 96 | powerpc_firmware_features |= |
99 | firmware_features_table[i].val; | 97 | hypertas_fw_features_table[i].val; |
100 | break; | 98 | break; |
101 | } | 99 | } |
102 | } | 100 | } |
103 | 101 | ||
104 | pr_debug(" <- fw_feature_init()\n"); | 102 | pr_debug(" <- fw_hypertas_feature_init()\n"); |
103 | } | ||
104 | |||
105 | struct vec5_fw_feature { | ||
106 | unsigned long val; | ||
107 | unsigned int feature; | ||
108 | }; | ||
109 | |||
110 | static __initdata struct vec5_fw_feature | ||
111 | vec5_fw_features_table[] = { | ||
112 | {FW_FEATURE_TYPE1_AFFINITY, OV5_TYPE1_AFFINITY}, | ||
113 | {FW_FEATURE_PRRN, OV5_PRRN}, | ||
114 | }; | ||
115 | |||
116 | void __init fw_vec5_feature_init(const char *vec5, unsigned long len) | ||
117 | { | ||
118 | unsigned int index, feat; | ||
119 | int i; | ||
120 | |||
121 | pr_debug(" -> fw_vec5_feature_init()\n"); | ||
122 | |||
123 | for (i = 0; i < ARRAY_SIZE(vec5_fw_features_table); i++) { | ||
124 | index = OV5_INDX(vec5_fw_features_table[i].feature); | ||
125 | feat = OV5_FEAT(vec5_fw_features_table[i].feature); | ||
126 | |||
127 | if (vec5[index] & feat) | ||
128 | powerpc_firmware_features |= | ||
129 | vec5_fw_features_table[i].val; | ||
130 | } | ||
131 | |||
132 | pr_debug(" <- fw_vec5_feature_init()\n"); | ||
105 | } | 133 | } |
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 2372c609fa2b..9a432de363b8 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c | |||
@@ -72,6 +72,7 @@ unsigned long memory_block_size_bytes(void) | |||
72 | return get_memblock_size(); | 72 | return get_memblock_size(); |
73 | } | 73 | } |
74 | 74 | ||
75 | #ifdef CONFIG_MEMORY_HOTREMOVE | ||
75 | static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) | 76 | static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) |
76 | { | 77 | { |
77 | unsigned long start, start_pfn; | 78 | unsigned long start, start_pfn; |
@@ -153,6 +154,17 @@ static int pseries_remove_memory(struct device_node *np) | |||
153 | ret = pseries_remove_memblock(base, lmb_size); | 154 | ret = pseries_remove_memblock(base, lmb_size); |
154 | return ret; | 155 | return ret; |
155 | } | 156 | } |
157 | #else | ||
158 | static inline int pseries_remove_memblock(unsigned long base, | ||
159 | unsigned int memblock_size) | ||
160 | { | ||
161 | return -EOPNOTSUPP; | ||
162 | } | ||
163 | static inline int pseries_remove_memory(struct device_node *np) | ||
164 | { | ||
165 | return -EOPNOTSUPP; | ||
166 | } | ||
167 | #endif /* CONFIG_MEMORY_HOTREMOVE */ | ||
156 | 168 | ||
157 | static int pseries_add_memory(struct device_node *np) | 169 | static int pseries_add_memory(struct device_node *np) |
158 | { | 170 | { |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 1b2a174e7c59..86ae364900d6 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -924,6 +924,13 @@ static void restore_default_window(struct pci_dev *dev, | |||
924 | __restore_default_window(pci_dev_to_eeh_dev(dev), ddw_restore_token); | 924 | __restore_default_window(pci_dev_to_eeh_dev(dev), ddw_restore_token); |
925 | } | 925 | } |
926 | 926 | ||
927 | struct failed_ddw_pdn { | ||
928 | struct device_node *pdn; | ||
929 | struct list_head list; | ||
930 | }; | ||
931 | |||
932 | static LIST_HEAD(failed_ddw_pdn_list); | ||
933 | |||
927 | /* | 934 | /* |
928 | * If the PE supports dynamic dma windows, and there is space for a table | 935 | * If the PE supports dynamic dma windows, and there is space for a table |
929 | * that can map all pages in a linear offset, then setup such a table, | 936 | * that can map all pages in a linear offset, then setup such a table, |
@@ -951,6 +958,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) | |||
951 | struct dynamic_dma_window_prop *ddwprop; | 958 | struct dynamic_dma_window_prop *ddwprop; |
952 | const void *dma_window = NULL; | 959 | const void *dma_window = NULL; |
953 | unsigned long liobn, offset, size; | 960 | unsigned long liobn, offset, size; |
961 | struct failed_ddw_pdn *fpdn; | ||
954 | 962 | ||
955 | mutex_lock(&direct_window_init_mutex); | 963 | mutex_lock(&direct_window_init_mutex); |
956 | 964 | ||
@@ -959,6 +967,18 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) | |||
959 | goto out_unlock; | 967 | goto out_unlock; |
960 | 968 | ||
961 | /* | 969 | /* |
970 | * If we already went through this for a previous function of | ||
971 | * the same device and failed, we don't want to muck with the | ||
972 | * DMA window again, as it will race with in-flight operations | ||
973 | * and can lead to EEHs. The above mutex protects access to the | ||
974 | * list. | ||
975 | */ | ||
976 | list_for_each_entry(fpdn, &failed_ddw_pdn_list, list) { | ||
977 | if (!strcmp(fpdn->pdn->full_name, pdn->full_name)) | ||
978 | goto out_unlock; | ||
979 | } | ||
980 | |||
981 | /* | ||
962 | * the ibm,ddw-applicable property holds the tokens for: | 982 | * the ibm,ddw-applicable property holds the tokens for: |
963 | * ibm,query-pe-dma-window | 983 | * ibm,query-pe-dma-window |
964 | * ibm,create-pe-dma-window | 984 | * ibm,create-pe-dma-window |
@@ -1114,6 +1134,12 @@ out_restore_window: | |||
1114 | if (ddw_restore_token) | 1134 | if (ddw_restore_token) |
1115 | restore_default_window(dev, ddw_restore_token); | 1135 | restore_default_window(dev, ddw_restore_token); |
1116 | 1136 | ||
1137 | fpdn = kzalloc(sizeof(*fpdn), GFP_KERNEL); | ||
1138 | if (!fpdn) | ||
1139 | goto out_unlock; | ||
1140 | fpdn->pdn = pdn; | ||
1141 | list_add(&fpdn->list, &failed_ddw_pdn_list); | ||
1142 | |||
1117 | out_unlock: | 1143 | out_unlock: |
1118 | mutex_unlock(&direct_window_init_mutex); | 1144 | mutex_unlock(&direct_window_init_mutex); |
1119 | return dma_addr; | 1145 | return dma_addr; |
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 0da39fed355a..6d62072a7d5a 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
@@ -109,7 +109,7 @@ void vpa_init(int cpu) | |||
109 | static long pSeries_lpar_hpte_insert(unsigned long hpte_group, | 109 | static long pSeries_lpar_hpte_insert(unsigned long hpte_group, |
110 | unsigned long vpn, unsigned long pa, | 110 | unsigned long vpn, unsigned long pa, |
111 | unsigned long rflags, unsigned long vflags, | 111 | unsigned long rflags, unsigned long vflags, |
112 | int psize, int ssize) | 112 | int psize, int apsize, int ssize) |
113 | { | 113 | { |
114 | unsigned long lpar_rc; | 114 | unsigned long lpar_rc; |
115 | unsigned long flags; | 115 | unsigned long flags; |
@@ -121,8 +121,8 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group, | |||
121 | "pa=%016lx, rflags=%lx, vflags=%lx, psize=%d)\n", | 121 | "pa=%016lx, rflags=%lx, vflags=%lx, psize=%d)\n", |
122 | hpte_group, vpn, pa, rflags, vflags, psize); | 122 | hpte_group, vpn, pa, rflags, vflags, psize); |
123 | 123 | ||
124 | hpte_v = hpte_encode_v(vpn, psize, ssize) | vflags | HPTE_V_VALID; | 124 | hpte_v = hpte_encode_v(vpn, psize, apsize, ssize) | vflags | HPTE_V_VALID; |
125 | hpte_r = hpte_encode_r(pa, psize) | rflags; | 125 | hpte_r = hpte_encode_r(pa, psize, apsize) | rflags; |
126 | 126 | ||
127 | if (!(vflags & HPTE_V_BOLTED)) | 127 | if (!(vflags & HPTE_V_BOLTED)) |
128 | pr_devel(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); | 128 | pr_devel(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); |
@@ -155,7 +155,7 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group, | |||
155 | */ | 155 | */ |
156 | if (unlikely(lpar_rc != H_SUCCESS)) { | 156 | if (unlikely(lpar_rc != H_SUCCESS)) { |
157 | if (!(vflags & HPTE_V_BOLTED)) | 157 | if (!(vflags & HPTE_V_BOLTED)) |
158 | pr_devel(" lpar err %lu\n", lpar_rc); | 158 | pr_devel(" lpar err %ld\n", lpar_rc); |
159 | return -2; | 159 | return -2; |
160 | } | 160 | } |
161 | if (!(vflags & HPTE_V_BOLTED)) | 161 | if (!(vflags & HPTE_V_BOLTED)) |
@@ -186,7 +186,13 @@ static long pSeries_lpar_hpte_remove(unsigned long hpte_group) | |||
186 | (0x1UL << 4), &dummy1, &dummy2); | 186 | (0x1UL << 4), &dummy1, &dummy2); |
187 | if (lpar_rc == H_SUCCESS) | 187 | if (lpar_rc == H_SUCCESS) |
188 | return i; | 188 | return i; |
189 | BUG_ON(lpar_rc != H_NOT_FOUND); | 189 | |
190 | /* | ||
191 | * The test for adjunct partition is performed before the | ||
192 | * ANDCOND test. H_RESOURCE may be returned, so we need to | ||
193 | * check for that as well. | ||
194 | */ | ||
195 | BUG_ON(lpar_rc != H_NOT_FOUND && lpar_rc != H_RESOURCE); | ||
190 | 196 | ||
191 | slot_offset++; | 197 | slot_offset++; |
192 | slot_offset &= 0x7; | 198 | slot_offset &= 0x7; |
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index 6573808cc5f3..3d01eee9ffb1 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c | |||
@@ -37,14 +37,16 @@ struct update_props_workarea { | |||
37 | #define UPDATE_DT_NODE 0x02000000 | 37 | #define UPDATE_DT_NODE 0x02000000 |
38 | #define ADD_DT_NODE 0x03000000 | 38 | #define ADD_DT_NODE 0x03000000 |
39 | 39 | ||
40 | static int mobility_rtas_call(int token, char *buf) | 40 | #define MIGRATION_SCOPE (1) |
41 | |||
42 | static int mobility_rtas_call(int token, char *buf, s32 scope) | ||
41 | { | 43 | { |
42 | int rc; | 44 | int rc; |
43 | 45 | ||
44 | spin_lock(&rtas_data_buf_lock); | 46 | spin_lock(&rtas_data_buf_lock); |
45 | 47 | ||
46 | memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE); | 48 | memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE); |
47 | rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, 1); | 49 | rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, scope); |
48 | memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE); | 50 | memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE); |
49 | 51 | ||
50 | spin_unlock(&rtas_data_buf_lock); | 52 | spin_unlock(&rtas_data_buf_lock); |
@@ -123,7 +125,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop, | |||
123 | return 0; | 125 | return 0; |
124 | } | 126 | } |
125 | 127 | ||
126 | static int update_dt_node(u32 phandle) | 128 | static int update_dt_node(u32 phandle, s32 scope) |
127 | { | 129 | { |
128 | struct update_props_workarea *upwa; | 130 | struct update_props_workarea *upwa; |
129 | struct device_node *dn; | 131 | struct device_node *dn; |
@@ -132,6 +134,7 @@ static int update_dt_node(u32 phandle) | |||
132 | char *prop_data; | 134 | char *prop_data; |
133 | char *rtas_buf; | 135 | char *rtas_buf; |
134 | int update_properties_token; | 136 | int update_properties_token; |
137 | u32 vd; | ||
135 | 138 | ||
136 | update_properties_token = rtas_token("ibm,update-properties"); | 139 | update_properties_token = rtas_token("ibm,update-properties"); |
137 | if (update_properties_token == RTAS_UNKNOWN_SERVICE) | 140 | if (update_properties_token == RTAS_UNKNOWN_SERVICE) |
@@ -151,19 +154,31 @@ static int update_dt_node(u32 phandle) | |||
151 | upwa->phandle = phandle; | 154 | upwa->phandle = phandle; |
152 | 155 | ||
153 | do { | 156 | do { |
154 | rc = mobility_rtas_call(update_properties_token, rtas_buf); | 157 | rc = mobility_rtas_call(update_properties_token, rtas_buf, |
158 | scope); | ||
155 | if (rc < 0) | 159 | if (rc < 0) |
156 | break; | 160 | break; |
157 | 161 | ||
158 | prop_data = rtas_buf + sizeof(*upwa); | 162 | prop_data = rtas_buf + sizeof(*upwa); |
159 | 163 | ||
160 | for (i = 0; i < upwa->nprops; i++) { | 164 | /* The first element of the buffer is the path of the node |
165 | * being updated in the form of a 8 byte string length | ||
166 | * followed by the string. Skip past this to get to the | ||
167 | * properties being updated. | ||
168 | */ | ||
169 | vd = *prop_data++; | ||
170 | prop_data += vd; | ||
171 | |||
172 | /* The path we skipped over is counted as one of the elements | ||
173 | * returned so start counting at one. | ||
174 | */ | ||
175 | for (i = 1; i < upwa->nprops; i++) { | ||
161 | char *prop_name; | 176 | char *prop_name; |
162 | u32 vd; | ||
163 | 177 | ||
164 | prop_name = prop_data + 1; | 178 | prop_name = prop_data; |
165 | prop_data += strlen(prop_name) + 1; | 179 | prop_data += strlen(prop_name) + 1; |
166 | vd = *prop_data++; | 180 | vd = *(u32 *)prop_data; |
181 | prop_data += sizeof(vd); | ||
167 | 182 | ||
168 | switch (vd) { | 183 | switch (vd) { |
169 | case 0x00000000: | 184 | case 0x00000000: |
@@ -219,7 +234,7 @@ static int add_dt_node(u32 parent_phandle, u32 drc_index) | |||
219 | return rc; | 234 | return rc; |
220 | } | 235 | } |
221 | 236 | ||
222 | static int pseries_devicetree_update(void) | 237 | int pseries_devicetree_update(s32 scope) |
223 | { | 238 | { |
224 | char *rtas_buf; | 239 | char *rtas_buf; |
225 | u32 *data; | 240 | u32 *data; |
@@ -235,7 +250,7 @@ static int pseries_devicetree_update(void) | |||
235 | return -ENOMEM; | 250 | return -ENOMEM; |
236 | 251 | ||
237 | do { | 252 | do { |
238 | rc = mobility_rtas_call(update_nodes_token, rtas_buf); | 253 | rc = mobility_rtas_call(update_nodes_token, rtas_buf, scope); |
239 | if (rc && rc != 1) | 254 | if (rc && rc != 1) |
240 | break; | 255 | break; |
241 | 256 | ||
@@ -256,7 +271,7 @@ static int pseries_devicetree_update(void) | |||
256 | delete_dt_node(phandle); | 271 | delete_dt_node(phandle); |
257 | break; | 272 | break; |
258 | case UPDATE_DT_NODE: | 273 | case UPDATE_DT_NODE: |
259 | update_dt_node(phandle); | 274 | update_dt_node(phandle, scope); |
260 | break; | 275 | break; |
261 | case ADD_DT_NODE: | 276 | case ADD_DT_NODE: |
262 | drc_index = *data++; | 277 | drc_index = *data++; |
@@ -276,7 +291,7 @@ void post_mobility_fixup(void) | |||
276 | int rc; | 291 | int rc; |
277 | int activate_fw_token; | 292 | int activate_fw_token; |
278 | 293 | ||
279 | rc = pseries_devicetree_update(); | 294 | rc = pseries_devicetree_update(MIGRATION_SCOPE); |
280 | if (rc) { | 295 | if (rc) { |
281 | printk(KERN_ERR "Initial post-mobility device tree update " | 296 | printk(KERN_ERR "Initial post-mobility device tree update " |
282 | "failed: %d\n", rc); | 297 | "failed: %d\n", rc); |
@@ -292,7 +307,7 @@ void post_mobility_fixup(void) | |||
292 | 307 | ||
293 | rc = rtas_call(activate_fw_token, 0, 1, NULL); | 308 | rc = rtas_call(activate_fw_token, 0, 1, NULL); |
294 | if (!rc) { | 309 | if (!rc) { |
295 | rc = pseries_devicetree_update(); | 310 | rc = pseries_devicetree_update(MIGRATION_SCOPE); |
296 | if (rc) | 311 | if (rc) |
297 | printk(KERN_ERR "Secondary post-mobility device tree " | 312 | printk(KERN_ERR "Secondary post-mobility device tree " |
298 | "update failed: %d\n", rc); | 313 | "update failed: %d\n", rc); |
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h index f368668d97b3..f35787b6a5e0 100644 --- a/arch/powerpc/platforms/pseries/plpar_wrappers.h +++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h | |||
@@ -58,40 +58,39 @@ static inline long extended_cede_processor(unsigned long latency_hint) | |||
58 | static inline long vpa_call(unsigned long flags, unsigned long cpu, | 58 | static inline long vpa_call(unsigned long flags, unsigned long cpu, |
59 | unsigned long vpa) | 59 | unsigned long vpa) |
60 | { | 60 | { |
61 | /* flags are in bits 16-18 (counting from most significant bit) */ | 61 | flags = flags << H_VPA_FUNC_SHIFT; |
62 | flags = flags << (63 - 18); | ||
63 | 62 | ||
64 | return plpar_hcall_norets(H_REGISTER_VPA, flags, cpu, vpa); | 63 | return plpar_hcall_norets(H_REGISTER_VPA, flags, cpu, vpa); |
65 | } | 64 | } |
66 | 65 | ||
67 | static inline long unregister_vpa(unsigned long cpu) | 66 | static inline long unregister_vpa(unsigned long cpu) |
68 | { | 67 | { |
69 | return vpa_call(0x5, cpu, 0); | 68 | return vpa_call(H_VPA_DEREG_VPA, cpu, 0); |
70 | } | 69 | } |
71 | 70 | ||
72 | static inline long register_vpa(unsigned long cpu, unsigned long vpa) | 71 | static inline long register_vpa(unsigned long cpu, unsigned long vpa) |
73 | { | 72 | { |
74 | return vpa_call(0x1, cpu, vpa); | 73 | return vpa_call(H_VPA_REG_VPA, cpu, vpa); |
75 | } | 74 | } |
76 | 75 | ||
77 | static inline long unregister_slb_shadow(unsigned long cpu) | 76 | static inline long unregister_slb_shadow(unsigned long cpu) |
78 | { | 77 | { |
79 | return vpa_call(0x7, cpu, 0); | 78 | return vpa_call(H_VPA_DEREG_SLB, cpu, 0); |
80 | } | 79 | } |
81 | 80 | ||
82 | static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa) | 81 | static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa) |
83 | { | 82 | { |
84 | return vpa_call(0x3, cpu, vpa); | 83 | return vpa_call(H_VPA_REG_SLB, cpu, vpa); |
85 | } | 84 | } |
86 | 85 | ||
87 | static inline long unregister_dtl(unsigned long cpu) | 86 | static inline long unregister_dtl(unsigned long cpu) |
88 | { | 87 | { |
89 | return vpa_call(0x6, cpu, 0); | 88 | return vpa_call(H_VPA_DEREG_DTL, cpu, 0); |
90 | } | 89 | } |
91 | 90 | ||
92 | static inline long register_dtl(unsigned long cpu, unsigned long vpa) | 91 | static inline long register_dtl(unsigned long cpu, unsigned long vpa) |
93 | { | 92 | { |
94 | return vpa_call(0x2, cpu, vpa); | 93 | return vpa_call(H_VPA_REG_DTL, cpu, vpa); |
95 | } | 94 | } |
96 | 95 | ||
97 | static inline long plpar_page_set_loaned(unsigned long vpa) | 96 | static inline long plpar_page_set_loaned(unsigned long vpa) |
diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c index 4d806b419606..4644efa06941 100644 --- a/arch/powerpc/platforms/pseries/processor_idle.c +++ b/arch/powerpc/platforms/pseries/processor_idle.c | |||
@@ -23,8 +23,8 @@ | |||
23 | #include "pseries.h" | 23 | #include "pseries.h" |
24 | 24 | ||
25 | struct cpuidle_driver pseries_idle_driver = { | 25 | struct cpuidle_driver pseries_idle_driver = { |
26 | .name = "pseries_idle", | 26 | .name = "pseries_idle", |
27 | .owner = THIS_MODULE, | 27 | .owner = THIS_MODULE, |
28 | }; | 28 | }; |
29 | 29 | ||
30 | #define MAX_IDLE_STATE_COUNT 2 | 30 | #define MAX_IDLE_STATE_COUNT 2 |
@@ -33,10 +33,8 @@ static int max_idle_state = MAX_IDLE_STATE_COUNT - 1; | |||
33 | static struct cpuidle_device __percpu *pseries_cpuidle_devices; | 33 | static struct cpuidle_device __percpu *pseries_cpuidle_devices; |
34 | static struct cpuidle_state *cpuidle_state_table; | 34 | static struct cpuidle_state *cpuidle_state_table; |
35 | 35 | ||
36 | static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before) | 36 | static inline void idle_loop_prolog(unsigned long *in_purr) |
37 | { | 37 | { |
38 | |||
39 | *kt_before = ktime_get(); | ||
40 | *in_purr = mfspr(SPRN_PURR); | 38 | *in_purr = mfspr(SPRN_PURR); |
41 | /* | 39 | /* |
42 | * Indicate to the HV that we are idle. Now would be | 40 | * Indicate to the HV that we are idle. Now would be |
@@ -45,12 +43,10 @@ static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before) | |||
45 | get_lppaca()->idle = 1; | 43 | get_lppaca()->idle = 1; |
46 | } | 44 | } |
47 | 45 | ||
48 | static inline s64 idle_loop_epilog(unsigned long in_purr, ktime_t kt_before) | 46 | static inline void idle_loop_epilog(unsigned long in_purr) |
49 | { | 47 | { |
50 | get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr; | 48 | get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr; |
51 | get_lppaca()->idle = 0; | 49 | get_lppaca()->idle = 0; |
52 | |||
53 | return ktime_to_us(ktime_sub(ktime_get(), kt_before)); | ||
54 | } | 50 | } |
55 | 51 | ||
56 | static int snooze_loop(struct cpuidle_device *dev, | 52 | static int snooze_loop(struct cpuidle_device *dev, |
@@ -58,10 +54,9 @@ static int snooze_loop(struct cpuidle_device *dev, | |||
58 | int index) | 54 | int index) |
59 | { | 55 | { |
60 | unsigned long in_purr; | 56 | unsigned long in_purr; |
61 | ktime_t kt_before; | ||
62 | int cpu = dev->cpu; | 57 | int cpu = dev->cpu; |
63 | 58 | ||
64 | idle_loop_prolog(&in_purr, &kt_before); | 59 | idle_loop_prolog(&in_purr); |
65 | local_irq_enable(); | 60 | local_irq_enable(); |
66 | set_thread_flag(TIF_POLLING_NRFLAG); | 61 | set_thread_flag(TIF_POLLING_NRFLAG); |
67 | 62 | ||
@@ -75,8 +70,8 @@ static int snooze_loop(struct cpuidle_device *dev, | |||
75 | clear_thread_flag(TIF_POLLING_NRFLAG); | 70 | clear_thread_flag(TIF_POLLING_NRFLAG); |
76 | smp_mb(); | 71 | smp_mb(); |
77 | 72 | ||
78 | dev->last_residency = | 73 | idle_loop_epilog(in_purr); |
79 | (int)idle_loop_epilog(in_purr, kt_before); | 74 | |
80 | return index; | 75 | return index; |
81 | } | 76 | } |
82 | 77 | ||
@@ -102,9 +97,8 @@ static int dedicated_cede_loop(struct cpuidle_device *dev, | |||
102 | int index) | 97 | int index) |
103 | { | 98 | { |
104 | unsigned long in_purr; | 99 | unsigned long in_purr; |
105 | ktime_t kt_before; | ||
106 | 100 | ||
107 | idle_loop_prolog(&in_purr, &kt_before); | 101 | idle_loop_prolog(&in_purr); |
108 | get_lppaca()->donate_dedicated_cpu = 1; | 102 | get_lppaca()->donate_dedicated_cpu = 1; |
109 | 103 | ||
110 | ppc64_runlatch_off(); | 104 | ppc64_runlatch_off(); |
@@ -112,8 +106,9 @@ static int dedicated_cede_loop(struct cpuidle_device *dev, | |||
112 | check_and_cede_processor(); | 106 | check_and_cede_processor(); |
113 | 107 | ||
114 | get_lppaca()->donate_dedicated_cpu = 0; | 108 | get_lppaca()->donate_dedicated_cpu = 0; |
115 | dev->last_residency = | 109 | |
116 | (int)idle_loop_epilog(in_purr, kt_before); | 110 | idle_loop_epilog(in_purr); |
111 | |||
117 | return index; | 112 | return index; |
118 | } | 113 | } |
119 | 114 | ||
@@ -122,9 +117,8 @@ static int shared_cede_loop(struct cpuidle_device *dev, | |||
122 | int index) | 117 | int index) |
123 | { | 118 | { |
124 | unsigned long in_purr; | 119 | unsigned long in_purr; |
125 | ktime_t kt_before; | ||
126 | 120 | ||
127 | idle_loop_prolog(&in_purr, &kt_before); | 121 | idle_loop_prolog(&in_purr); |
128 | 122 | ||
129 | /* | 123 | /* |
130 | * Yield the processor to the hypervisor. We return if | 124 | * Yield the processor to the hypervisor. We return if |
@@ -135,8 +129,8 @@ static int shared_cede_loop(struct cpuidle_device *dev, | |||
135 | */ | 129 | */ |
136 | check_and_cede_processor(); | 130 | check_and_cede_processor(); |
137 | 131 | ||
138 | dev->last_residency = | 132 | idle_loop_epilog(in_purr); |
139 | (int)idle_loop_epilog(in_purr, kt_before); | 133 | |
140 | return index; | 134 | return index; |
141 | } | 135 | } |
142 | 136 | ||
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 9a3dda07566f..8af71e4cc17f 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h | |||
@@ -19,7 +19,10 @@ extern void request_event_sources_irqs(struct device_node *np, | |||
19 | 19 | ||
20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
21 | 21 | ||
22 | extern void __init fw_feature_init(const char *hypertas, unsigned long len); | 22 | extern void __init fw_hypertas_feature_init(const char *hypertas, |
23 | unsigned long len); | ||
24 | extern void __init fw_vec5_feature_init(const char *hypertas, | ||
25 | unsigned long len); | ||
23 | 26 | ||
24 | struct pt_regs; | 27 | struct pt_regs; |
25 | 28 | ||
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index d6491bd481d0..f93cdf55628c 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c | |||
@@ -452,7 +452,7 @@ static int proc_ppc64_create_ofdt(void) | |||
452 | 452 | ||
453 | ent = proc_create("powerpc/ofdt", S_IWUSR, NULL, &ofdt_fops); | 453 | ent = proc_create("powerpc/ofdt", S_IWUSR, NULL, &ofdt_fops); |
454 | if (ent) | 454 | if (ent) |
455 | ent->size = 0; | 455 | proc_set_size(ent, 0); |
456 | 456 | ||
457 | return 0; | 457 | return 0; |
458 | } | 458 | } |
diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c index 47f3cda2a68b..b502ab61aafa 100644 --- a/arch/powerpc/platforms/pseries/scanlog.c +++ b/arch/powerpc/platforms/pseries/scanlog.c | |||
@@ -41,13 +41,12 @@ | |||
41 | 41 | ||
42 | 42 | ||
43 | static unsigned int ibm_scan_log_dump; /* RTAS token */ | 43 | static unsigned int ibm_scan_log_dump; /* RTAS token */ |
44 | static struct proc_dir_entry *proc_ppc64_scan_log_dump; /* The proc file */ | 44 | static unsigned int *scanlog_buffer; /* The data buffer */ |
45 | 45 | ||
46 | static ssize_t scanlog_read(struct file *file, char __user *buf, | 46 | static ssize_t scanlog_read(struct file *file, char __user *buf, |
47 | size_t count, loff_t *ppos) | 47 | size_t count, loff_t *ppos) |
48 | { | 48 | { |
49 | struct proc_dir_entry *dp = PDE(file_inode(file)); | 49 | unsigned int *data = scanlog_buffer; |
50 | unsigned int *data = (unsigned int *)dp->data; | ||
51 | int status; | 50 | int status; |
52 | unsigned long len, off; | 51 | unsigned long len, off; |
53 | unsigned int wait_time; | 52 | unsigned int wait_time; |
@@ -135,8 +134,7 @@ static ssize_t scanlog_write(struct file * file, const char __user * buf, | |||
135 | 134 | ||
136 | static int scanlog_open(struct inode * inode, struct file * file) | 135 | static int scanlog_open(struct inode * inode, struct file * file) |
137 | { | 136 | { |
138 | struct proc_dir_entry *dp = PDE(inode); | 137 | unsigned int *data = scanlog_buffer; |
139 | unsigned int *data = (unsigned int *)dp->data; | ||
140 | 138 | ||
141 | if (data[0] != 0) { | 139 | if (data[0] != 0) { |
142 | /* This imperfect test stops a second copy of the | 140 | /* This imperfect test stops a second copy of the |
@@ -152,11 +150,9 @@ static int scanlog_open(struct inode * inode, struct file * file) | |||
152 | 150 | ||
153 | static int scanlog_release(struct inode * inode, struct file * file) | 151 | static int scanlog_release(struct inode * inode, struct file * file) |
154 | { | 152 | { |
155 | struct proc_dir_entry *dp = PDE(inode); | 153 | unsigned int *data = scanlog_buffer; |
156 | unsigned int *data = (unsigned int *)dp->data; | ||
157 | 154 | ||
158 | data[0] = 0; | 155 | data[0] = 0; |
159 | |||
160 | return 0; | 156 | return 0; |
161 | } | 157 | } |
162 | 158 | ||
@@ -172,7 +168,6 @@ const struct file_operations scanlog_fops = { | |||
172 | static int __init scanlog_init(void) | 168 | static int __init scanlog_init(void) |
173 | { | 169 | { |
174 | struct proc_dir_entry *ent; | 170 | struct proc_dir_entry *ent; |
175 | void *data; | ||
176 | int err = -ENOMEM; | 171 | int err = -ENOMEM; |
177 | 172 | ||
178 | ibm_scan_log_dump = rtas_token("ibm,scan-log-dump"); | 173 | ibm_scan_log_dump = rtas_token("ibm,scan-log-dump"); |
@@ -180,29 +175,24 @@ static int __init scanlog_init(void) | |||
180 | return -ENODEV; | 175 | return -ENODEV; |
181 | 176 | ||
182 | /* Ideally we could allocate a buffer < 4G */ | 177 | /* Ideally we could allocate a buffer < 4G */ |
183 | data = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); | 178 | scanlog_buffer = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); |
184 | if (!data) | 179 | if (!scanlog_buffer) |
185 | goto err; | 180 | goto err; |
186 | 181 | ||
187 | ent = proc_create_data("powerpc/rtas/scan-log-dump", S_IRUSR, NULL, | 182 | ent = proc_create("powerpc/rtas/scan-log-dump", S_IRUSR, NULL, |
188 | &scanlog_fops, data); | 183 | &scanlog_fops); |
189 | if (!ent) | 184 | if (!ent) |
190 | goto err; | 185 | goto err; |
191 | |||
192 | proc_ppc64_scan_log_dump = ent; | ||
193 | |||
194 | return 0; | 186 | return 0; |
195 | err: | 187 | err: |
196 | kfree(data); | 188 | kfree(scanlog_buffer); |
197 | return err; | 189 | return err; |
198 | } | 190 | } |
199 | 191 | ||
200 | static void __exit scanlog_cleanup(void) | 192 | static void __exit scanlog_cleanup(void) |
201 | { | 193 | { |
202 | if (proc_ppc64_scan_log_dump) { | 194 | remove_proc_entry("powerpc/rtas/scan-log-dump", NULL); |
203 | kfree(proc_ppc64_scan_log_dump->data); | 195 | kfree(scanlog_buffer); |
204 | remove_proc_entry("scan-log-dump", proc_ppc64_scan_log_dump->parent); | ||
205 | } | ||
206 | } | 196 | } |
207 | 197 | ||
208 | module_init(scanlog_init); | 198 | module_init(scanlog_init); |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 8bcc9ca6682f..ac932a9eb440 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -628,25 +628,39 @@ static void __init pSeries_init_early(void) | |||
628 | * Called very early, MMU is off, device-tree isn't unflattened | 628 | * Called very early, MMU is off, device-tree isn't unflattened |
629 | */ | 629 | */ |
630 | 630 | ||
631 | static int __init pSeries_probe_hypertas(unsigned long node, | 631 | static int __init pseries_probe_fw_features(unsigned long node, |
632 | const char *uname, int depth, | 632 | const char *uname, int depth, |
633 | void *data) | 633 | void *data) |
634 | { | 634 | { |
635 | const char *hypertas; | 635 | const char *prop; |
636 | unsigned long len; | 636 | unsigned long len; |
637 | static int hypertas_found; | ||
638 | static int vec5_found; | ||
637 | 639 | ||
638 | if (depth != 1 || | 640 | if (depth != 1) |
639 | (strcmp(uname, "rtas") != 0 && strcmp(uname, "rtas@0") != 0)) | ||
640 | return 0; | 641 | return 0; |
641 | 642 | ||
642 | hypertas = of_get_flat_dt_prop(node, "ibm,hypertas-functions", &len); | 643 | if (!strcmp(uname, "rtas") || !strcmp(uname, "rtas@0")) { |
643 | if (!hypertas) | 644 | prop = of_get_flat_dt_prop(node, "ibm,hypertas-functions", |
644 | return 1; | 645 | &len); |
646 | if (prop) { | ||
647 | powerpc_firmware_features |= FW_FEATURE_LPAR; | ||
648 | fw_hypertas_feature_init(prop, len); | ||
649 | } | ||
645 | 650 | ||
646 | powerpc_firmware_features |= FW_FEATURE_LPAR; | 651 | hypertas_found = 1; |
647 | fw_feature_init(hypertas, len); | 652 | } |
648 | 653 | ||
649 | return 1; | 654 | if (!strcmp(uname, "chosen")) { |
655 | prop = of_get_flat_dt_prop(node, "ibm,architecture-vec-5", | ||
656 | &len); | ||
657 | if (prop) | ||
658 | fw_vec5_feature_init(prop, len); | ||
659 | |||
660 | vec5_found = 1; | ||
661 | } | ||
662 | |||
663 | return hypertas_found && vec5_found; | ||
650 | } | 664 | } |
651 | 665 | ||
652 | static int __init pSeries_probe(void) | 666 | static int __init pSeries_probe(void) |
@@ -669,7 +683,7 @@ static int __init pSeries_probe(void) | |||
669 | pr_debug("pSeries detected, looking for LPAR capability...\n"); | 683 | pr_debug("pSeries detected, looking for LPAR capability...\n"); |
670 | 684 | ||
671 | /* Now try to figure out if we are running on LPAR */ | 685 | /* Now try to figure out if we are running on LPAR */ |
672 | of_scan_flat_dt(pSeries_probe_hypertas, NULL); | 686 | of_scan_flat_dt(pseries_probe_fw_features, NULL); |
673 | 687 | ||
674 | if (firmware_has_feature(FW_FEATURE_LPAR)) | 688 | if (firmware_has_feature(FW_FEATURE_LPAR)) |
675 | hpte_init_lpar(); | 689 | hpte_init_lpar(); |
diff --git a/arch/powerpc/platforms/wsp/Kconfig b/arch/powerpc/platforms/wsp/Kconfig index 79d2225b7608..422a175b10ee 100644 --- a/arch/powerpc/platforms/wsp/Kconfig +++ b/arch/powerpc/platforms/wsp/Kconfig | |||
@@ -9,7 +9,6 @@ config PPC_WSP | |||
9 | select PCI | 9 | select PCI |
10 | select PPC_IO_WORKAROUNDS if PCI | 10 | select PPC_IO_WORKAROUNDS if PCI |
11 | select PPC_INDIRECT_PIO if PCI | 11 | select PPC_INDIRECT_PIO if PCI |
12 | select PPC_WSP_COPRO | ||
13 | default n | 12 | default n |
14 | 13 | ||
15 | menu "WSP platform selection" | 14 | menu "WSP platform selection" |
@@ -29,7 +28,3 @@ config PPC_CHROMA | |||
29 | default y | 28 | default y |
30 | 29 | ||
31 | endmenu | 30 | endmenu |
32 | |||
33 | config PPC_A2_DD2 | ||
34 | bool "Support for DD2 based A2/WSP systems" | ||
35 | depends on PPC_A2 | ||
diff --git a/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig index a84fecf63c4d..ab4cb5476472 100644 --- a/arch/powerpc/sysdev/Kconfig +++ b/arch/powerpc/sysdev/Kconfig | |||
@@ -19,6 +19,7 @@ config PPC_MSI_BITMAP | |||
19 | default y if MPIC | 19 | default y if MPIC |
20 | default y if FSL_PCI | 20 | default y if FSL_PCI |
21 | default y if PPC4xx_MSI | 21 | default y if PPC4xx_MSI |
22 | default y if POWERNV_MSI | ||
22 | 23 | ||
23 | source "arch/powerpc/sysdev/xics/Kconfig" | 24 | source "arch/powerpc/sysdev/xics/Kconfig" |
24 | 25 | ||
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 178c99427b1c..ab02db3d02d8 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c | |||
@@ -333,6 +333,8 @@ static int fsl_of_msi_remove(struct platform_device *ofdev) | |||
333 | return 0; | 333 | return 0; |
334 | } | 334 | } |
335 | 335 | ||
336 | static struct lock_class_key fsl_msi_irq_class; | ||
337 | |||
336 | static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev, | 338 | static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev, |
337 | int offset, int irq_index) | 339 | int offset, int irq_index) |
338 | { | 340 | { |
@@ -351,7 +353,7 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev, | |||
351 | dev_err(&dev->dev, "No memory for MSI cascade data\n"); | 353 | dev_err(&dev->dev, "No memory for MSI cascade data\n"); |
352 | return -ENOMEM; | 354 | return -ENOMEM; |
353 | } | 355 | } |
354 | 356 | irq_set_lockdep_class(virt_msir, &fsl_msi_irq_class); | |
355 | msi->msi_virqs[irq_index] = virt_msir; | 357 | msi->msi_virqs[irq_index] = virt_msir; |
356 | cascade_data->index = offset; | 358 | cascade_data->index = offset; |
357 | cascade_data->msi_data = msi; | 359 | cascade_data->msi_data = msi; |
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 682084dba19b..cffe7edac858 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
@@ -54,16 +54,63 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev) | |||
54 | return; | 54 | return; |
55 | } | 55 | } |
56 | 56 | ||
57 | static int __init fsl_pcie_check_link(struct pci_controller *hose) | 57 | static int fsl_indirect_read_config(struct pci_bus *, unsigned int, |
58 | int, int, u32 *); | ||
59 | |||
60 | static int fsl_pcie_check_link(struct pci_controller *hose) | ||
58 | { | 61 | { |
59 | u32 val; | 62 | u32 val = 0; |
63 | |||
64 | if (hose->indirect_type & PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK) { | ||
65 | if (hose->ops->read == fsl_indirect_read_config) { | ||
66 | struct pci_bus bus; | ||
67 | bus.number = 0; | ||
68 | bus.sysdata = hose; | ||
69 | bus.ops = hose->ops; | ||
70 | indirect_read_config(&bus, 0, PCIE_LTSSM, 4, &val); | ||
71 | } else | ||
72 | early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val); | ||
73 | if (val < PCIE_LTSSM_L0) | ||
74 | return 1; | ||
75 | } else { | ||
76 | struct ccsr_pci __iomem *pci = hose->private_data; | ||
77 | /* for PCIe IP rev 3.0 or greater use CSR0 for link state */ | ||
78 | val = (in_be32(&pci->pex_csr0) & PEX_CSR0_LTSSM_MASK) | ||
79 | >> PEX_CSR0_LTSSM_SHIFT; | ||
80 | if (val != PEX_CSR0_LTSSM_L0) | ||
81 | return 1; | ||
82 | } | ||
60 | 83 | ||
61 | early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val); | ||
62 | if (val < PCIE_LTSSM_L0) | ||
63 | return 1; | ||
64 | return 0; | 84 | return 0; |
65 | } | 85 | } |
66 | 86 | ||
87 | static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn, | ||
88 | int offset, int len, u32 *val) | ||
89 | { | ||
90 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
91 | |||
92 | if (fsl_pcie_check_link(hose)) | ||
93 | hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK; | ||
94 | else | ||
95 | hose->indirect_type &= ~PPC_INDIRECT_TYPE_NO_PCIE_LINK; | ||
96 | |||
97 | return indirect_read_config(bus, devfn, offset, len, val); | ||
98 | } | ||
99 | |||
100 | static struct pci_ops fsl_indirect_pci_ops = | ||
101 | { | ||
102 | .read = fsl_indirect_read_config, | ||
103 | .write = indirect_write_config, | ||
104 | }; | ||
105 | |||
106 | static void __init fsl_setup_indirect_pci(struct pci_controller* hose, | ||
107 | resource_size_t cfg_addr, | ||
108 | resource_size_t cfg_data, u32 flags) | ||
109 | { | ||
110 | setup_indirect_pci(hose, cfg_addr, cfg_data, flags); | ||
111 | hose->ops = &fsl_indirect_pci_ops; | ||
112 | } | ||
113 | |||
67 | #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx) | 114 | #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx) |
68 | 115 | ||
69 | #define MAX_PHYS_ADDR_BITS 40 | 116 | #define MAX_PHYS_ADDR_BITS 40 |
@@ -106,7 +153,7 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci, | |||
106 | flags |= 0x10000000; /* enable relaxed ordering */ | 153 | flags |= 0x10000000; /* enable relaxed ordering */ |
107 | 154 | ||
108 | for (i = 0; size > 0; i++) { | 155 | for (i = 0; size > 0; i++) { |
109 | unsigned int bits = min(__ilog2(size), | 156 | unsigned int bits = min(ilog2(size), |
110 | __ffs(pci_addr | phys_addr)); | 157 | __ffs(pci_addr | phys_addr)); |
111 | 158 | ||
112 | if (index + i >= 5) | 159 | if (index + i >= 5) |
@@ -126,10 +173,9 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci, | |||
126 | } | 173 | } |
127 | 174 | ||
128 | /* atmu setup for fsl pci/pcie controller */ | 175 | /* atmu setup for fsl pci/pcie controller */ |
129 | static void setup_pci_atmu(struct pci_controller *hose, | 176 | static void setup_pci_atmu(struct pci_controller *hose) |
130 | struct resource *rsrc) | ||
131 | { | 177 | { |
132 | struct ccsr_pci __iomem *pci; | 178 | struct ccsr_pci __iomem *pci = hose->private_data; |
133 | int i, j, n, mem_log, win_idx = 3, start_idx = 1, end_idx = 4; | 179 | int i, j, n, mem_log, win_idx = 3, start_idx = 1, end_idx = 4; |
134 | u64 mem, sz, paddr_hi = 0; | 180 | u64 mem, sz, paddr_hi = 0; |
135 | u64 paddr_lo = ULLONG_MAX; | 181 | u64 paddr_lo = ULLONG_MAX; |
@@ -140,15 +186,6 @@ static void setup_pci_atmu(struct pci_controller *hose, | |||
140 | const u64 *reg; | 186 | const u64 *reg; |
141 | int len; | 187 | int len; |
142 | 188 | ||
143 | pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n", | ||
144 | (u64)rsrc->start, (u64)resource_size(rsrc)); | ||
145 | |||
146 | pci = ioremap(rsrc->start, resource_size(rsrc)); | ||
147 | if (!pci) { | ||
148 | dev_err(hose->parent, "Unable to map ATMU registers\n"); | ||
149 | return; | ||
150 | } | ||
151 | |||
152 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { | 189 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { |
153 | if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) { | 190 | if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) { |
154 | win_idx = 2; | 191 | win_idx = 2; |
@@ -196,7 +233,7 @@ static void setup_pci_atmu(struct pci_controller *hose, | |||
196 | out_be32(&pci->pow[j].powbar, (hose->io_base_phys >> 12)); | 233 | out_be32(&pci->pow[j].powbar, (hose->io_base_phys >> 12)); |
197 | /* Enable, IO R/W */ | 234 | /* Enable, IO R/W */ |
198 | out_be32(&pci->pow[j].powar, 0x80088000 | 235 | out_be32(&pci->pow[j].powar, 0x80088000 |
199 | | (__ilog2(hose->io_resource.end | 236 | | (ilog2(hose->io_resource.end |
200 | - hose->io_resource.start + 1) - 1)); | 237 | - hose->io_resource.start + 1) - 1)); |
201 | } | 238 | } |
202 | } | 239 | } |
@@ -207,12 +244,12 @@ static void setup_pci_atmu(struct pci_controller *hose, | |||
207 | 244 | ||
208 | if (paddr_hi == paddr_lo) { | 245 | if (paddr_hi == paddr_lo) { |
209 | pr_err("%s: No outbound window space\n", name); | 246 | pr_err("%s: No outbound window space\n", name); |
210 | goto out; | 247 | return; |
211 | } | 248 | } |
212 | 249 | ||
213 | if (paddr_lo == 0) { | 250 | if (paddr_lo == 0) { |
214 | pr_err("%s: No space for inbound window\n", name); | 251 | pr_err("%s: No space for inbound window\n", name); |
215 | goto out; | 252 | return; |
216 | } | 253 | } |
217 | 254 | ||
218 | /* setup PCSRBAR/PEXCSRBAR */ | 255 | /* setup PCSRBAR/PEXCSRBAR */ |
@@ -261,7 +298,7 @@ static void setup_pci_atmu(struct pci_controller *hose, | |||
261 | } | 298 | } |
262 | 299 | ||
263 | sz = min(mem, paddr_lo); | 300 | sz = min(mem, paddr_lo); |
264 | mem_log = __ilog2_u64(sz); | 301 | mem_log = ilog2(sz); |
265 | 302 | ||
266 | /* PCIe can overmap inbound & outbound since RX & TX are separated */ | 303 | /* PCIe can overmap inbound & outbound since RX & TX are separated */ |
267 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { | 304 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { |
@@ -290,7 +327,7 @@ static void setup_pci_atmu(struct pci_controller *hose, | |||
290 | * SWIOTLB and access the full range of memory | 327 | * SWIOTLB and access the full range of memory |
291 | */ | 328 | */ |
292 | if (sz != mem) { | 329 | if (sz != mem) { |
293 | mem_log = __ilog2_u64(mem); | 330 | mem_log = ilog2(mem); |
294 | 331 | ||
295 | /* Size window up if we dont fit in exact power-of-2 */ | 332 | /* Size window up if we dont fit in exact power-of-2 */ |
296 | if ((1ull << mem_log) != mem) | 333 | if ((1ull << mem_log) != mem) |
@@ -327,7 +364,7 @@ static void setup_pci_atmu(struct pci_controller *hose, | |||
327 | sz -= 1ull << mem_log; | 364 | sz -= 1ull << mem_log; |
328 | 365 | ||
329 | if (sz) { | 366 | if (sz) { |
330 | mem_log = __ilog2_u64(sz); | 367 | mem_log = ilog2(sz); |
331 | piwar |= (mem_log - 1); | 368 | piwar |= (mem_log - 1); |
332 | 369 | ||
333 | out_be32(&pci->piw[win_idx].pitar, paddr >> 12); | 370 | out_be32(&pci->piw[win_idx].pitar, paddr >> 12); |
@@ -358,9 +395,6 @@ static void setup_pci_atmu(struct pci_controller *hose, | |||
358 | pr_info("%s: DMA window size is 0x%llx\n", name, | 395 | pr_info("%s: DMA window size is 0x%llx\n", name, |
359 | (u64)hose->dma_window_size); | 396 | (u64)hose->dma_window_size); |
360 | } | 397 | } |
361 | |||
362 | out: | ||
363 | iounmap(pci); | ||
364 | } | 398 | } |
365 | 399 | ||
366 | static void __init setup_pci_cmd(struct pci_controller *hose) | 400 | static void __init setup_pci_cmd(struct pci_controller *hose) |
@@ -429,6 +463,7 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary) | |||
429 | const int *bus_range; | 463 | const int *bus_range; |
430 | u8 hdr_type, progif; | 464 | u8 hdr_type, progif; |
431 | struct device_node *dev; | 465 | struct device_node *dev; |
466 | struct ccsr_pci __iomem *pci; | ||
432 | 467 | ||
433 | dev = pdev->dev.of_node; | 468 | dev = pdev->dev.of_node; |
434 | 469 | ||
@@ -461,8 +496,18 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary) | |||
461 | hose->first_busno = bus_range ? bus_range[0] : 0x0; | 496 | hose->first_busno = bus_range ? bus_range[0] : 0x0; |
462 | hose->last_busno = bus_range ? bus_range[1] : 0xff; | 497 | hose->last_busno = bus_range ? bus_range[1] : 0xff; |
463 | 498 | ||
464 | setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4, | 499 | pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n", |
465 | PPC_INDIRECT_TYPE_BIG_ENDIAN); | 500 | (u64)rsrc.start, (u64)resource_size(&rsrc)); |
501 | |||
502 | pci = hose->private_data = ioremap(rsrc.start, resource_size(&rsrc)); | ||
503 | if (!hose->private_data) | ||
504 | goto no_bridge; | ||
505 | |||
506 | fsl_setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4, | ||
507 | PPC_INDIRECT_TYPE_BIG_ENDIAN); | ||
508 | |||
509 | if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0) | ||
510 | hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK; | ||
466 | 511 | ||
467 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { | 512 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { |
468 | /* For PCIE read HEADER_TYPE to identify controler mode */ | 513 | /* For PCIE read HEADER_TYPE to identify controler mode */ |
@@ -500,11 +545,12 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary) | |||
500 | pci_process_bridge_OF_ranges(hose, dev, is_primary); | 545 | pci_process_bridge_OF_ranges(hose, dev, is_primary); |
501 | 546 | ||
502 | /* Setup PEX window registers */ | 547 | /* Setup PEX window registers */ |
503 | setup_pci_atmu(hose, &rsrc); | 548 | setup_pci_atmu(hose); |
504 | 549 | ||
505 | return 0; | 550 | return 0; |
506 | 551 | ||
507 | no_bridge: | 552 | no_bridge: |
553 | iounmap(hose->private_data); | ||
508 | /* unmap cfg_data & cfg_addr separately if not on same page */ | 554 | /* unmap cfg_data & cfg_addr separately if not on same page */ |
509 | if (((unsigned long)hose->cfg_data & PAGE_MASK) != | 555 | if (((unsigned long)hose->cfg_data & PAGE_MASK) != |
510 | ((unsigned long)hose->cfg_addr & PAGE_MASK)) | 556 | ((unsigned long)hose->cfg_addr & PAGE_MASK)) |
@@ -681,6 +727,7 @@ static int __init mpc83xx_pcie_setup(struct pci_controller *hose, | |||
681 | WARN_ON(hose->dn->data); | 727 | WARN_ON(hose->dn->data); |
682 | hose->dn->data = pcie; | 728 | hose->dn->data = pcie; |
683 | hose->ops = &mpc83xx_pcie_ops; | 729 | hose->ops = &mpc83xx_pcie_ops; |
730 | hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK; | ||
684 | 731 | ||
685 | out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAH, 0); | 732 | out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAH, 0); |
686 | out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, 0); | 733 | out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, 0); |
@@ -766,8 +813,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev) | |||
766 | if (ret) | 813 | if (ret) |
767 | goto err0; | 814 | goto err0; |
768 | } else { | 815 | } else { |
769 | setup_indirect_pci(hose, rsrc_cfg.start, | 816 | fsl_setup_indirect_pci(hose, rsrc_cfg.start, |
770 | rsrc_cfg.start + 4, 0); | 817 | rsrc_cfg.start + 4, 0); |
771 | } | 818 | } |
772 | 819 | ||
773 | printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. " | 820 | printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. " |
@@ -836,6 +883,7 @@ static const struct of_device_id pci_ids[] = { | |||
836 | { .compatible = "fsl,qoriq-pcie-v2.2", }, | 883 | { .compatible = "fsl,qoriq-pcie-v2.2", }, |
837 | { .compatible = "fsl,qoriq-pcie-v2.3", }, | 884 | { .compatible = "fsl,qoriq-pcie-v2.3", }, |
838 | { .compatible = "fsl,qoriq-pcie-v2.4", }, | 885 | { .compatible = "fsl,qoriq-pcie-v2.4", }, |
886 | { .compatible = "fsl,qoriq-pcie-v3.0", }, | ||
839 | 887 | ||
840 | /* | 888 | /* |
841 | * The following entries are for compatibility with older device | 889 | * The following entries are for compatibility with older device |
@@ -927,7 +975,7 @@ static int fsl_pci_resume(struct device *dev) | |||
927 | return -ENODEV; | 975 | return -ENODEV; |
928 | } | 976 | } |
929 | 977 | ||
930 | setup_pci_atmu(hose, &pci_rsrc); | 978 | setup_pci_atmu(hose); |
931 | 979 | ||
932 | return 0; | 980 | return 0; |
933 | } | 981 | } |
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h index c495c00c8740..72b5625330e2 100644 --- a/arch/powerpc/sysdev/fsl_pci.h +++ b/arch/powerpc/sysdev/fsl_pci.h | |||
@@ -14,9 +14,12 @@ | |||
14 | #ifndef __POWERPC_FSL_PCI_H | 14 | #ifndef __POWERPC_FSL_PCI_H |
15 | #define __POWERPC_FSL_PCI_H | 15 | #define __POWERPC_FSL_PCI_H |
16 | 16 | ||
17 | struct platform_device; | ||
18 | |||
17 | #define PCIE_LTSSM 0x0404 /* PCIE Link Training and Status */ | 19 | #define PCIE_LTSSM 0x0404 /* PCIE Link Training and Status */ |
18 | #define PCIE_LTSSM_L0 0x16 /* L0 state */ | 20 | #define PCIE_LTSSM_L0 0x16 /* L0 state */ |
19 | #define PCIE_IP_REV_2_2 0x02080202 /* PCIE IP block version Rev2.2 */ | 21 | #define PCIE_IP_REV_2_2 0x02080202 /* PCIE IP block version Rev2.2 */ |
22 | #define PCIE_IP_REV_3_0 0x02080300 /* PCIE IP block version Rev3.0 */ | ||
20 | #define PIWAR_EN 0x80000000 /* Enable */ | 23 | #define PIWAR_EN 0x80000000 /* Enable */ |
21 | #define PIWAR_PF 0x20000000 /* prefetch */ | 24 | #define PIWAR_PF 0x20000000 /* prefetch */ |
22 | #define PIWAR_TGI_LOCAL 0x00f00000 /* target - local memory */ | 25 | #define PIWAR_TGI_LOCAL 0x00f00000 /* target - local memory */ |
@@ -89,6 +92,16 @@ struct ccsr_pci { | |||
89 | __be32 pex_err_cap_r1; /* 0x.e2c - PCIE error capture register 0 */ | 92 | __be32 pex_err_cap_r1; /* 0x.e2c - PCIE error capture register 0 */ |
90 | __be32 pex_err_cap_r2; /* 0x.e30 - PCIE error capture register 0 */ | 93 | __be32 pex_err_cap_r2; /* 0x.e30 - PCIE error capture register 0 */ |
91 | __be32 pex_err_cap_r3; /* 0x.e34 - PCIE error capture register 0 */ | 94 | __be32 pex_err_cap_r3; /* 0x.e34 - PCIE error capture register 0 */ |
95 | u8 res_e38[200]; | ||
96 | __be32 pdb_stat; /* 0x.f00 - PCIE Debug Status */ | ||
97 | u8 res_f04[16]; | ||
98 | __be32 pex_csr0; /* 0x.f14 - PEX Control/Status register 0*/ | ||
99 | #define PEX_CSR0_LTSSM_MASK 0xFC | ||
100 | #define PEX_CSR0_LTSSM_SHIFT 2 | ||
101 | #define PEX_CSR0_LTSSM_L0 0x11 | ||
102 | __be32 pex_csr1; /* 0x.f18 - PEX Control/Status register 1*/ | ||
103 | u8 res_f1c[228]; | ||
104 | |||
92 | }; | 105 | }; |
93 | 106 | ||
94 | extern int fsl_add_bridge(struct platform_device *pdev, int is_primary); | 107 | extern int fsl_add_bridge(struct platform_device *pdev, int is_primary); |
diff --git a/arch/powerpc/sysdev/indirect_pci.c b/arch/powerpc/sysdev/indirect_pci.c index 82fdad885d20..c6c8b526a4f6 100644 --- a/arch/powerpc/sysdev/indirect_pci.c +++ b/arch/powerpc/sysdev/indirect_pci.c | |||
@@ -20,9 +20,8 @@ | |||
20 | #include <asm/pci-bridge.h> | 20 | #include <asm/pci-bridge.h> |
21 | #include <asm/machdep.h> | 21 | #include <asm/machdep.h> |
22 | 22 | ||
23 | static int | 23 | int indirect_read_config(struct pci_bus *bus, unsigned int devfn, |
24 | indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | 24 | int offset, int len, u32 *val) |
25 | int len, u32 *val) | ||
26 | { | 25 | { |
27 | struct pci_controller *hose = pci_bus_to_host(bus); | 26 | struct pci_controller *hose = pci_bus_to_host(bus); |
28 | volatile void __iomem *cfg_data; | 27 | volatile void __iomem *cfg_data; |
@@ -78,9 +77,8 @@ indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | |||
78 | return PCIBIOS_SUCCESSFUL; | 77 | return PCIBIOS_SUCCESSFUL; |
79 | } | 78 | } |
80 | 79 | ||
81 | static int | 80 | int indirect_write_config(struct pci_bus *bus, unsigned int devfn, |
82 | indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset, | 81 | int offset, int len, u32 val) |
83 | int len, u32 val) | ||
84 | { | 82 | { |
85 | struct pci_controller *hose = pci_bus_to_host(bus); | 83 | struct pci_controller *hose = pci_bus_to_host(bus); |
86 | volatile void __iomem *cfg_data; | 84 | volatile void __iomem *cfg_data; |
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index 0f6af41ebb44..4a25c26f0bf4 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c | |||
@@ -214,15 +214,27 @@ static struct platform_device * __init mv64x60_eth_register_shared_pdev( | |||
214 | struct device_node *np, int id) | 214 | struct device_node *np, int id) |
215 | { | 215 | { |
216 | struct platform_device *pdev; | 216 | struct platform_device *pdev; |
217 | struct resource r[1]; | 217 | struct resource r[2]; |
218 | int err; | 218 | int err; |
219 | 219 | ||
220 | err = of_address_to_resource(np, 0, &r[0]); | 220 | err = of_address_to_resource(np, 0, &r[0]); |
221 | if (err) | 221 | if (err) |
222 | return ERR_PTR(err); | 222 | return ERR_PTR(err); |
223 | 223 | ||
224 | /* register an orion mdio bus driver */ | ||
225 | r[1].start = r[0].start + 0x4; | ||
226 | r[1].end = r[0].start + 0x84 - 1; | ||
227 | r[1].flags = IORESOURCE_MEM; | ||
228 | |||
229 | if (id == 0) { | ||
230 | pdev = platform_device_register_simple("orion-mdio", -1, &r[1], 1); | ||
231 | if (!pdev) | ||
232 | return pdev; | ||
233 | } | ||
234 | |||
224 | pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, id, | 235 | pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, id, |
225 | r, 1); | 236 | &r[0], 1); |
237 | |||
226 | return pdev; | 238 | return pdev; |
227 | } | 239 | } |
228 | 240 | ||
diff --git a/arch/powerpc/sysdev/qe_lib/Kconfig b/arch/powerpc/sysdev/qe_lib/Kconfig index 41ac3dfac98e..3c251993bacd 100644 --- a/arch/powerpc/sysdev/qe_lib/Kconfig +++ b/arch/powerpc/sysdev/qe_lib/Kconfig | |||
@@ -22,6 +22,6 @@ config UCC | |||
22 | 22 | ||
23 | config QE_USB | 23 | config QE_USB |
24 | bool | 24 | bool |
25 | default y if USB_GADGET_FSL_QE | 25 | default y if USB_FSL_QE |
26 | help | 26 | help |
27 | QE USB Controller support | 27 | QE USB Controller support |
diff --git a/arch/powerpc/sysdev/rtc_cmos_setup.c b/arch/powerpc/sysdev/rtc_cmos_setup.c index 9afba924e94f..af79e1ea74b6 100644 --- a/arch/powerpc/sysdev/rtc_cmos_setup.c +++ b/arch/powerpc/sysdev/rtc_cmos_setup.c | |||
@@ -62,10 +62,7 @@ static int __init add_rtc(void) | |||
62 | pd = platform_device_register_simple("rtc_cmos", -1, | 62 | pd = platform_device_register_simple("rtc_cmos", -1, |
63 | &res[0], num_res); | 63 | &res[0], num_res); |
64 | 64 | ||
65 | if (IS_ERR(pd)) | 65 | return PTR_RET(pd); |
66 | return PTR_ERR(pd); | ||
67 | |||
68 | return 0; | ||
69 | } | 66 | } |
70 | fs_initcall(add_rtc); | 67 | fs_initcall(add_rtc); |
71 | 68 | ||
diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c index 20b328bb494d..7cd728b3b5e4 100644 --- a/arch/powerpc/sysdev/xics/icp-native.c +++ b/arch/powerpc/sysdev/xics/icp-native.c | |||
@@ -87,7 +87,7 @@ static void icp_native_set_cpu_priority(unsigned char cppr) | |||
87 | iosync(); | 87 | iosync(); |
88 | } | 88 | } |
89 | 89 | ||
90 | static void icp_native_eoi(struct irq_data *d) | 90 | void icp_native_eoi(struct irq_data *d) |
91 | { | 91 | { |
92 | unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); | 92 | unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); |
93 | 93 | ||
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 13f85defabed..96bf5bd30fbc 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
@@ -1430,7 +1430,7 @@ static void excprint(struct pt_regs *fp) | |||
1430 | printf(" sp: %lx\n", fp->gpr[1]); | 1430 | printf(" sp: %lx\n", fp->gpr[1]); |
1431 | printf(" msr: %lx\n", fp->msr); | 1431 | printf(" msr: %lx\n", fp->msr); |
1432 | 1432 | ||
1433 | if (trap == 0x300 || trap == 0x380 || trap == 0x600) { | 1433 | if (trap == 0x300 || trap == 0x380 || trap == 0x600 || trap == 0x200) { |
1434 | printf(" dar: %lx\n", fp->dar); | 1434 | printf(" dar: %lx\n", fp->dar); |
1435 | if (trap != 0x380) | 1435 | if (trap != 0x380) |
1436 | printf(" dsisr: %lx\n", fp->dsisr); | 1436 | printf(" dsisr: %lx\n", fp->dsisr); |
@@ -2947,7 +2947,7 @@ static void sysrq_handle_xmon(int key) | |||
2947 | 2947 | ||
2948 | static struct sysrq_key_op sysrq_xmon_op = { | 2948 | static struct sysrq_key_op sysrq_xmon_op = { |
2949 | .handler = sysrq_handle_xmon, | 2949 | .handler = sysrq_handle_xmon, |
2950 | .help_msg = "Xmon", | 2950 | .help_msg = "xmon(x)", |
2951 | .action_msg = "Entering xmon", | 2951 | .action_msg = "Entering xmon", |
2952 | }; | 2952 | }; |
2953 | 2953 | ||