diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-19 18:38:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-19 18:38:41 -0400 |
commit | d5e2d00898bdfed9586472679760fc81a2ca2d02 (patch) | |
tree | 55ac781983bf7144230ad8a5a995ce02b6ac39a1 | |
parent | 31e182363b39d84031eadf0caf6d99fd9eb056f0 (diff) | |
parent | 6e669f085d595cb6053920832c89f1a13067db44 (diff) |
Merge tag 'powerpc-4.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc updates from Michael Ellerman:
"This was delayed a day or two by some build-breakage on old toolchains
which we've now fixed.
There's two PCI commits both acked by Bjorn.
There's one commit to mm/hugepage.c which is (co)authored by Kirill.
Highlights:
- Restructure Linux PTE on Book3S/64 to Radix format from Paul
Mackerras
- Book3s 64 MMU cleanup in preparation for Radix MMU from Aneesh
Kumar K.V
- Add POWER9 cputable entry from Michael Neuling
- FPU/Altivec/VSX save/restore optimisations from Cyril Bur
- Add support for new ftrace ABI on ppc64le from Torsten Duwe
Various cleanups & minor fixes from:
- Adam Buchbinder, Andrew Donnellan, Balbir Singh, Christophe Leroy,
Cyril Bur, Luis Henriques, Madhavan Srinivasan, Pan Xinhui, Russell
Currey, Sukadev Bhattiprolu, Suraj Jitindar Singh.
General:
- atomics: Allow architectures to define their own __atomic_op_*
helpers from Boqun Feng
- Implement atomic{, 64}_*_return_* variants and acquire/release/
relaxed variants for (cmp)xchg from Boqun Feng
- Add powernv_defconfig from Jeremy Kerr
- Fix BUG_ON() reporting in real mode from Balbir Singh
- Add xmon command to dump OPAL msglog from Andrew Donnellan
- Add xmon command to dump process/task similar to ps(1) from Douglas
Miller
- Clean up memory hotplug failure paths from David Gibson
pci/eeh:
- Redesign SR-IOV on PowerNV to give absolute isolation between VFs
from Wei Yang.
- EEH Support for SRIOV VFs from Wei Yang and Gavin Shan.
- PCI/IOV: Rename and export virtfn_{add, remove} from Wei Yang
- PCI: Add pcibios_bus_add_device() weak function from Wei Yang
- MAINTAINERS: Update EEH details and maintainership from Russell
Currey
cxl:
- Support added to the CXL driver for running on both bare-metal and
hypervisor systems, from Christophe Lombard and Frederic Barrat.
- Ignore probes for virtual afu pci devices from Vaibhav Jain
perf:
- Export Power8 generic and cache events to sysfs from Sukadev
Bhattiprolu
- hv-24x7: Fix usage with chip events, display change in counter
values, display domain indices in sysfs, eliminate domain suffix in
event names, from Sukadev Bhattiprolu
Freescale:
- Updates from Scott: "Highlights include 8xx optimizations, 32-bit
checksum optimizations, 86xx consolidation, e5500/e6500 cpu
hotplug, more fman and other dt bits, and minor fixes/cleanup"
* tag 'powerpc-4.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (179 commits)
powerpc: Fix unrecoverable SLB miss during restore_math()
powerpc/8xx: Fix do_mtspr_cpu6() build on older compilers
powerpc/rcpm: Fix build break when SMP=n
powerpc/book3e-64: Use hardcoded mttmr opcode
powerpc/fsl/dts: Add "jedec,spi-nor" flash compatible
powerpc/T104xRDB: add tdm riser card node to device tree
powerpc32: PAGE_EXEC required for inittext
powerpc/mpc85xx: Add pcsphy nodes to FManV3 device tree
powerpc/mpc85xx: Add MDIO bus muxing support to the board device tree(s)
powerpc/86xx: Introduce and use common dtsi
powerpc/86xx: Update device tree
powerpc/86xx: Move dts files to fsl directory
powerpc/86xx: Switch to kconfig fragments approach
powerpc/86xx: Update defconfigs
powerpc/86xx: Consolidate common platform code
powerpc32: Remove one insn in mulhdu
powerpc32: small optimisation in flush_icache_range()
powerpc: Simplify test in __dma_sync()
powerpc32: move xxxxx_dcache_range() functions inline
powerpc32: Remove clear_pages() and define clear_page() inline
...
324 files changed, 14760 insertions, 7155 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl index b07e86d4597f..7fd737eed38a 100644 --- a/Documentation/ABI/testing/sysfs-class-cxl +++ b/Documentation/ABI/testing/sysfs-class-cxl | |||
@@ -159,7 +159,7 @@ Description: read only | |||
159 | Decimal value of the Per Process MMIO space length. | 159 | Decimal value of the Per Process MMIO space length. |
160 | Users: https://github.com/ibm-capi/libcxl | 160 | Users: https://github.com/ibm-capi/libcxl |
161 | 161 | ||
162 | What: /sys/class/cxl/<afu>m/pp_mmio_off | 162 | What: /sys/class/cxl/<afu>m/pp_mmio_off (not in a guest) |
163 | Date: September 2014 | 163 | Date: September 2014 |
164 | Contact: linuxppc-dev@lists.ozlabs.org | 164 | Contact: linuxppc-dev@lists.ozlabs.org |
165 | Description: read only | 165 | Description: read only |
@@ -183,7 +183,7 @@ Description: read only | |||
183 | Identifies the revision level of the PSL. | 183 | Identifies the revision level of the PSL. |
184 | Users: https://github.com/ibm-capi/libcxl | 184 | Users: https://github.com/ibm-capi/libcxl |
185 | 185 | ||
186 | What: /sys/class/cxl/<card>/base_image | 186 | What: /sys/class/cxl/<card>/base_image (not in a guest) |
187 | Date: September 2014 | 187 | Date: September 2014 |
188 | Contact: linuxppc-dev@lists.ozlabs.org | 188 | Contact: linuxppc-dev@lists.ozlabs.org |
189 | Description: read only | 189 | Description: read only |
@@ -193,7 +193,7 @@ Description: read only | |||
193 | during the initial program load. | 193 | during the initial program load. |
194 | Users: https://github.com/ibm-capi/libcxl | 194 | Users: https://github.com/ibm-capi/libcxl |
195 | 195 | ||
196 | What: /sys/class/cxl/<card>/image_loaded | 196 | What: /sys/class/cxl/<card>/image_loaded (not in a guest) |
197 | Date: September 2014 | 197 | Date: September 2014 |
198 | Contact: linuxppc-dev@lists.ozlabs.org | 198 | Contact: linuxppc-dev@lists.ozlabs.org |
199 | Description: read only | 199 | Description: read only |
@@ -201,7 +201,7 @@ Description: read only | |||
201 | onto the card. | 201 | onto the card. |
202 | Users: https://github.com/ibm-capi/libcxl | 202 | Users: https://github.com/ibm-capi/libcxl |
203 | 203 | ||
204 | What: /sys/class/cxl/<card>/load_image_on_perst | 204 | What: /sys/class/cxl/<card>/load_image_on_perst (not in a guest) |
205 | Date: December 2014 | 205 | Date: December 2014 |
206 | Contact: linuxppc-dev@lists.ozlabs.org | 206 | Contact: linuxppc-dev@lists.ozlabs.org |
207 | Description: read/write | 207 | Description: read/write |
@@ -224,7 +224,7 @@ Description: write only | |||
224 | to reload the FPGA depending on load_image_on_perst. | 224 | to reload the FPGA depending on load_image_on_perst. |
225 | Users: https://github.com/ibm-capi/libcxl | 225 | Users: https://github.com/ibm-capi/libcxl |
226 | 226 | ||
227 | What: /sys/class/cxl/<card>/perst_reloads_same_image | 227 | What: /sys/class/cxl/<card>/perst_reloads_same_image (not in a guest) |
228 | Date: July 2015 | 228 | Date: July 2015 |
229 | Contact: linuxppc-dev@lists.ozlabs.org | 229 | Contact: linuxppc-dev@lists.ozlabs.org |
230 | Description: read/write | 230 | Description: read/write |
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt index 1fc5328c0651..55c2c03fc81e 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt | |||
@@ -315,6 +315,16 @@ PROPERTIES | |||
315 | Value type: <phandle> | 315 | Value type: <phandle> |
316 | Definition: A phandle for 1EEE1588 timer. | 316 | Definition: A phandle for 1EEE1588 timer. |
317 | 317 | ||
318 | - pcsphy-handle | ||
319 | Usage required for "fsl,fman-memac" MACs | ||
320 | Value type: <phandle> | ||
321 | Definition: A phandle for pcsphy. | ||
322 | |||
323 | - tbi-handle | ||
324 | Usage required for "fsl,fman-dtsec" MACs | ||
325 | Value type: <phandle> | ||
326 | Definition: A phandle for tbiphy. | ||
327 | |||
318 | EXAMPLE | 328 | EXAMPLE |
319 | 329 | ||
320 | fman1_tx28: port@a8000 { | 330 | fman1_tx28: port@a8000 { |
@@ -340,6 +350,7 @@ ethernet@e0000 { | |||
340 | reg = <0xe0000 0x1000>; | 350 | reg = <0xe0000 0x1000>; |
341 | fsl,fman-ports = <&fman1_rx8 &fman1_tx28>; | 351 | fsl,fman-ports = <&fman1_rx8 &fman1_tx28>; |
342 | ptp-timer = <&ptp-timer>; | 352 | ptp-timer = <&ptp-timer>; |
353 | tbi-handle = <&tbi0>; | ||
343 | }; | 354 | }; |
344 | 355 | ||
345 | ============================================================================ | 356 | ============================================================================ |
@@ -415,6 +426,13 @@ PROPERTIES | |||
415 | The settings and programming routines for internal/external | 426 | The settings and programming routines for internal/external |
416 | MDIO are different. Must be included for internal MDIO. | 427 | MDIO are different. Must be included for internal MDIO. |
417 | 428 | ||
429 | For internal PHY device on internal mdio bus, a PHY node should be created. | ||
430 | See the definition of the PHY node in booting-without-of.txt for an | ||
431 | example of how to define a PHY (Internal PHY has no interrupt line). | ||
432 | - For "fsl,fman-mdio" compatible internal mdio bus, the PHY is TBI PHY. | ||
433 | - For "fsl,fman-memac-mdio" compatible internal mdio bus, the PHY is PCS PHY, | ||
434 | PCS PHY addr must be '0'. | ||
435 | |||
418 | EXAMPLE | 436 | EXAMPLE |
419 | 437 | ||
420 | Example for FMan v2 external MDIO: | 438 | Example for FMan v2 external MDIO: |
@@ -425,12 +443,29 @@ mdio@f1000 { | |||
425 | interrupts = <101 2 0 0>; | 443 | interrupts = <101 2 0 0>; |
426 | }; | 444 | }; |
427 | 445 | ||
446 | Example for FMan v2 internal MDIO: | ||
447 | |||
448 | mdio@e3120 { | ||
449 | compatible = "fsl,fman-mdio"; | ||
450 | reg = <0xe3120 0xee0>; | ||
451 | fsl,fman-internal-mdio; | ||
452 | |||
453 | tbi1: tbi-phy@8 { | ||
454 | reg = <0x8>; | ||
455 | device_type = "tbi-phy"; | ||
456 | }; | ||
457 | }; | ||
458 | |||
428 | Example for FMan v3 internal MDIO: | 459 | Example for FMan v3 internal MDIO: |
429 | 460 | ||
430 | mdio@f1000 { | 461 | mdio@f1000 { |
431 | compatible = "fsl,fman-memac-mdio"; | 462 | compatible = "fsl,fman-memac-mdio"; |
432 | reg = <0xf1000 0x1000>; | 463 | reg = <0xf1000 0x1000>; |
433 | fsl,fman-internal-mdio; | 464 | fsl,fman-internal-mdio; |
465 | |||
466 | pcsphy6: ethernet-phy@0 { | ||
467 | reg = <0x0>; | ||
468 | }; | ||
434 | }; | 469 | }; |
435 | 470 | ||
436 | ============================================================================= | 471 | ============================================================================= |
@@ -568,6 +603,7 @@ fman@400000 { | |||
568 | cell-index = <0>; | 603 | cell-index = <0>; |
569 | reg = <0xe0000 0x1000>; | 604 | reg = <0xe0000 0x1000>; |
570 | fsl,fman-ports = <&fman1_rx_0x8 &fman1_tx_0x28>; | 605 | fsl,fman-ports = <&fman1_rx_0x8 &fman1_tx_0x28>; |
606 | tbi-handle = <&tbi5>; | ||
571 | }; | 607 | }; |
572 | 608 | ||
573 | ethernet@e2000 { | 609 | ethernet@e2000 { |
@@ -575,6 +611,7 @@ fman@400000 { | |||
575 | cell-index = <1>; | 611 | cell-index = <1>; |
576 | reg = <0xe2000 0x1000>; | 612 | reg = <0xe2000 0x1000>; |
577 | fsl,fman-ports = <&fman1_rx_0x9 &fman1_tx_0x29>; | 613 | fsl,fman-ports = <&fman1_rx_0x9 &fman1_tx_0x29>; |
614 | tbi-handle = <&tbi6>; | ||
578 | }; | 615 | }; |
579 | 616 | ||
580 | ethernet@e4000 { | 617 | ethernet@e4000 { |
@@ -582,6 +619,7 @@ fman@400000 { | |||
582 | cell-index = <2>; | 619 | cell-index = <2>; |
583 | reg = <0xe4000 0x1000>; | 620 | reg = <0xe4000 0x1000>; |
584 | fsl,fman-ports = <&fman1_rx_0xa &fman1_tx_0x2a>; | 621 | fsl,fman-ports = <&fman1_rx_0xa &fman1_tx_0x2a>; |
622 | tbi-handle = <&tbi7>; | ||
585 | }; | 623 | }; |
586 | 624 | ||
587 | ethernet@e6000 { | 625 | ethernet@e6000 { |
@@ -589,6 +627,7 @@ fman@400000 { | |||
589 | cell-index = <3>; | 627 | cell-index = <3>; |
590 | reg = <0xe6000 0x1000>; | 628 | reg = <0xe6000 0x1000>; |
591 | fsl,fman-ports = <&fman1_rx_0xb &fman1_tx_0x2b>; | 629 | fsl,fman-ports = <&fman1_rx_0xb &fman1_tx_0x2b>; |
630 | tbi-handle = <&tbi8>; | ||
592 | }; | 631 | }; |
593 | 632 | ||
594 | ethernet@e8000 { | 633 | ethernet@e8000 { |
@@ -596,6 +635,7 @@ fman@400000 { | |||
596 | cell-index = <4>; | 635 | cell-index = <4>; |
597 | reg = <0xf0000 0x1000>; | 636 | reg = <0xf0000 0x1000>; |
598 | fsl,fman-ports = <&fman1_rx_0xc &fman1_tx_0x2c>; | 637 | fsl,fman-ports = <&fman1_rx_0xc &fman1_tx_0x2c>; |
638 | tbi-handle = <&tbi9>; | ||
599 | 639 | ||
600 | ethernet@f0000 { | 640 | ethernet@f0000 { |
601 | cell-index = <8>; | 641 | cell-index = <8>; |
diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt new file mode 100644 index 000000000000..e284e4e1ccd5 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt | |||
@@ -0,0 +1,63 @@ | |||
1 | * Run Control and Power Management | ||
2 | ------------------------------------------- | ||
3 | The RCPM performs all device-level tasks associated with device run control | ||
4 | and power management. | ||
5 | |||
6 | Required properites: | ||
7 | - reg : Offset and length of the register set of the RCPM block. | ||
8 | - fsl,#rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the | ||
9 | fsl,rcpm-wakeup property. | ||
10 | - compatible : Must contain a chip-specific RCPM block compatible string | ||
11 | and (if applicable) may contain a chassis-version RCPM compatible | ||
12 | string. Chip-specific strings are of the form "fsl,<chip>-rcpm", | ||
13 | such as: | ||
14 | * "fsl,p2041-rcpm" | ||
15 | * "fsl,p5020-rcpm" | ||
16 | * "fsl,t4240-rcpm" | ||
17 | |||
18 | Chassis-version strings are of the form "fsl,qoriq-rcpm-<version>", | ||
19 | such as: | ||
20 | * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm | ||
21 | * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm | ||
22 | * "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm | ||
23 | |||
24 | All references to "1.0" and "2.0" refer to the QorIQ chassis version to | ||
25 | which the chip complies. | ||
26 | Chassis Version Example Chips | ||
27 | --------------- ------------------------------- | ||
28 | 1.0 p4080, p5020, p5040, p2041, p3041 | ||
29 | 2.0 t4240, b4860, b4420 | ||
30 | 2.1 t1040, ls1021 | ||
31 | |||
32 | Example: | ||
33 | The RCPM node for T4240: | ||
34 | rcpm: global-utilities@e2000 { | ||
35 | compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0"; | ||
36 | reg = <0xe2000 0x1000>; | ||
37 | fsl,#rcpm-wakeup-cells = <2>; | ||
38 | }; | ||
39 | |||
40 | * Freescale RCPM Wakeup Source Device Tree Bindings | ||
41 | ------------------------------------------- | ||
42 | Required fsl,rcpm-wakeup property should be added to a device node if the device | ||
43 | can be used as a wakeup source. | ||
44 | |||
45 | - fsl,rcpm-wakeup: Consists of a phandle to the rcpm node and the IPPDEXPCR | ||
46 | register cells. The number of IPPDEXPCR register cells is defined in | ||
47 | "fsl,#rcpm-wakeup-cells" in the rcpm node. The first register cell is | ||
48 | the bit mask that should be set in IPPDEXPCR0, and the second register | ||
49 | cell is for IPPDEXPCR1, and so on. | ||
50 | |||
51 | Note: IPPDEXPCR(IP Powerdown Exception Control Register) provides a | ||
52 | mechanism for keeping certain blocks awake during STANDBY and MEM, in | ||
53 | order to use them as wake-up sources. | ||
54 | |||
55 | Example: | ||
56 | lpuart0: serial@2950000 { | ||
57 | compatible = "fsl,ls1021a-lpuart"; | ||
58 | reg = <0x0 0x2950000 0x0 0x1000>; | ||
59 | interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; | ||
60 | clocks = <&sysclk>; | ||
61 | clock-names = "ipg"; | ||
62 | fsl,rcpm-wakeup = <&rcpm 0x0 0x40000000>; | ||
63 | }; | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index eef242ee576b..1f780d907718 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -2620,7 +2620,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
2620 | nolapic_timer [X86-32,APIC] Do not use the local APIC timer. | 2620 | nolapic_timer [X86-32,APIC] Do not use the local APIC timer. |
2621 | 2621 | ||
2622 | noltlbs [PPC] Do not use large page/tlb entries for kernel | 2622 | noltlbs [PPC] Do not use large page/tlb entries for kernel |
2623 | lowmem mapping on PPC40x. | 2623 | lowmem mapping on PPC40x and PPC8xx |
2624 | 2624 | ||
2625 | nomca [IA-64] Disable machine check abort handling | 2625 | nomca [IA-64] Disable machine check abort handling |
2626 | 2626 | ||
diff --git a/Documentation/powerpc/cxl.txt b/Documentation/powerpc/cxl.txt index 205c1b81625c..d5506ba0fef7 100644 --- a/Documentation/powerpc/cxl.txt +++ b/Documentation/powerpc/cxl.txt | |||
@@ -116,6 +116,8 @@ Work Element Descriptor (WED) | |||
116 | User API | 116 | User API |
117 | ======== | 117 | ======== |
118 | 118 | ||
119 | 1. AFU character devices | ||
120 | |||
119 | For AFUs operating in AFU directed mode, two character device | 121 | For AFUs operating in AFU directed mode, two character device |
120 | files will be created. /dev/cxl/afu0.0m will correspond to a | 122 | files will be created. /dev/cxl/afu0.0m will correspond to a |
121 | master context and /dev/cxl/afu0.0s will correspond to a slave | 123 | master context and /dev/cxl/afu0.0s will correspond to a slave |
@@ -362,6 +364,59 @@ read | |||
362 | reserved fields: | 364 | reserved fields: |
363 | For future extensions and padding | 365 | For future extensions and padding |
364 | 366 | ||
367 | |||
368 | 2. Card character device (powerVM guest only) | ||
369 | |||
370 | In a powerVM guest, an extra character device is created for the | ||
371 | card. The device is only used to write (flash) a new image on the | ||
372 | FPGA accelerator. Once the image is written and verified, the | ||
373 | device tree is updated and the card is reset to reload the updated | ||
374 | image. | ||
375 | |||
376 | open | ||
377 | ---- | ||
378 | |||
379 | Opens the device and allocates a file descriptor to be used with | ||
380 | the rest of the API. The device can only be opened once. | ||
381 | |||
382 | ioctl | ||
383 | ----- | ||
384 | |||
385 | CXL_IOCTL_DOWNLOAD_IMAGE: | ||
386 | CXL_IOCTL_VALIDATE_IMAGE: | ||
387 | Starts and controls flashing a new FPGA image. Partial | ||
388 | reconfiguration is not supported (yet), so the image must contain | ||
389 | a copy of the PSL and AFU(s). Since an image can be quite large, | ||
390 | the caller may have to iterate, splitting the image in smaller | ||
391 | chunks. | ||
392 | |||
393 | Takes a pointer to a struct cxl_adapter_image: | ||
394 | struct cxl_adapter_image { | ||
395 | __u64 flags; | ||
396 | __u64 data; | ||
397 | __u64 len_data; | ||
398 | __u64 len_image; | ||
399 | __u64 reserved1; | ||
400 | __u64 reserved2; | ||
401 | __u64 reserved3; | ||
402 | __u64 reserved4; | ||
403 | }; | ||
404 | |||
405 | flags: | ||
406 | These flags indicate which optional fields are present in | ||
407 | this struct. Currently all fields are mandatory. | ||
408 | |||
409 | data: | ||
410 | Pointer to a buffer with part of the image to write to the | ||
411 | card. | ||
412 | |||
413 | len_data: | ||
414 | Size of the buffer pointed to by data. | ||
415 | |||
416 | len_image: | ||
417 | Full size of the image. | ||
418 | |||
419 | |||
365 | Sysfs Class | 420 | Sysfs Class |
366 | =========== | 421 | =========== |
367 | 422 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 74acd99f19c4..0cbfc69a2303 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -4250,13 +4250,6 @@ M: Maxim Levitsky <maximlevitsky@gmail.com> | |||
4250 | S: Maintained | 4250 | S: Maintained |
4251 | F: drivers/media/rc/ene_ir.* | 4251 | F: drivers/media/rc/ene_ir.* |
4252 | 4252 | ||
4253 | ENHANCED ERROR HANDLING (EEH) | ||
4254 | M: Gavin Shan <shangw@linux.vnet.ibm.com> | ||
4255 | L: linuxppc-dev@lists.ozlabs.org | ||
4256 | S: Supported | ||
4257 | F: Documentation/powerpc/eeh-pci-error-recovery.txt | ||
4258 | F: arch/powerpc/kernel/eeh*.c | ||
4259 | |||
4260 | EPSON S1D13XXX FRAMEBUFFER DRIVER | 4253 | EPSON S1D13XXX FRAMEBUFFER DRIVER |
4261 | M: Kristoffer Ericson <kristoffer.ericson@gmail.com> | 4254 | M: Kristoffer Ericson <kristoffer.ericson@gmail.com> |
4262 | S: Maintained | 4255 | S: Maintained |
@@ -8315,6 +8308,15 @@ L: linux-pci@vger.kernel.org | |||
8315 | S: Supported | 8308 | S: Supported |
8316 | F: Documentation/PCI/pci-error-recovery.txt | 8309 | F: Documentation/PCI/pci-error-recovery.txt |
8317 | 8310 | ||
8311 | PCI ENHANCED ERROR HANDLING (EEH) FOR POWERPC | ||
8312 | M: Russell Currey <ruscur@russell.cc> | ||
8313 | L: linuxppc-dev@lists.ozlabs.org | ||
8314 | S: Supported | ||
8315 | F: Documentation/powerpc/eeh-pci-error-recovery.txt | ||
8316 | F: arch/powerpc/kernel/eeh*.c | ||
8317 | F: arch/powerpc/platforms/*/eeh*.c | ||
8318 | F: arch/powerpc/include/*/eeh*.h | ||
8319 | |||
8318 | PCI SUBSYSTEM | 8320 | PCI SUBSYSTEM |
8319 | M: Bjorn Helgaas <bhelgaas@google.com> | 8321 | M: Bjorn Helgaas <bhelgaas@google.com> |
8320 | L: linux-pci@vger.kernel.org | 8322 | L: linux-pci@vger.kernel.org |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index a030e5ecb10b..7cd32c038286 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -94,6 +94,7 @@ config PPC | |||
94 | select OF_RESERVED_MEM | 94 | select OF_RESERVED_MEM |
95 | select HAVE_FTRACE_MCOUNT_RECORD | 95 | select HAVE_FTRACE_MCOUNT_RECORD |
96 | select HAVE_DYNAMIC_FTRACE | 96 | select HAVE_DYNAMIC_FTRACE |
97 | select HAVE_DYNAMIC_FTRACE_WITH_REGS if MPROFILE_KERNEL | ||
97 | select HAVE_FUNCTION_TRACER | 98 | select HAVE_FUNCTION_TRACER |
98 | select HAVE_FUNCTION_GRAPH_TRACER | 99 | select HAVE_FUNCTION_GRAPH_TRACER |
99 | select SYSCTL_EXCEPTION_TRACE | 100 | select SYSCTL_EXCEPTION_TRACE |
@@ -304,7 +305,7 @@ config ZONE_DMA32 | |||
304 | config PGTABLE_LEVELS | 305 | config PGTABLE_LEVELS |
305 | int | 306 | int |
306 | default 2 if !PPC64 | 307 | default 2 if !PPC64 |
307 | default 3 if PPC_64K_PAGES | 308 | default 3 if PPC_64K_PAGES && !PPC_BOOK3S_64 |
308 | default 4 | 309 | default 4 |
309 | 310 | ||
310 | source "init/Kconfig" | 311 | source "init/Kconfig" |
@@ -374,6 +375,24 @@ config PPC_TRANSACTIONAL_MEM | |||
374 | ---help--- | 375 | ---help--- |
375 | Support user-mode Transactional Memory on POWERPC. | 376 | Support user-mode Transactional Memory on POWERPC. |
376 | 377 | ||
378 | config DISABLE_MPROFILE_KERNEL | ||
379 | bool "Disable use of mprofile-kernel for kernel tracing" | ||
380 | depends on PPC64 && CPU_LITTLE_ENDIAN | ||
381 | default y | ||
382 | help | ||
383 | Selecting this options disables use of the mprofile-kernel ABI for | ||
384 | kernel tracing. That will cause options such as live patching | ||
385 | (CONFIG_LIVEPATCH) which depend on CONFIG_DYNAMIC_FTRACE_WITH_REGS to | ||
386 | be disabled also. | ||
387 | |||
388 | If you have a toolchain which supports mprofile-kernel, then you can | ||
389 | enable this. Otherwise leave it disabled. If you're not sure, say | ||
390 | "N". | ||
391 | |||
392 | config MPROFILE_KERNEL | ||
393 | depends on PPC64 && CPU_LITTLE_ENDIAN | ||
394 | def_bool !DISABLE_MPROFILE_KERNEL | ||
395 | |||
377 | config IOMMU_HELPER | 396 | config IOMMU_HELPER |
378 | def_bool PPC64 | 397 | def_bool PPC64 |
379 | 398 | ||
@@ -390,7 +409,7 @@ config SWIOTLB | |||
390 | config HOTPLUG_CPU | 409 | config HOTPLUG_CPU |
391 | bool "Support for enabling/disabling CPUs" | 410 | bool "Support for enabling/disabling CPUs" |
392 | depends on SMP && (PPC_PSERIES || \ | 411 | depends on SMP && (PPC_PSERIES || \ |
393 | PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC)) | 412 | PPC_PMAC || PPC_POWERNV || FSL_SOC_BOOKE) |
394 | ---help--- | 413 | ---help--- |
395 | Say Y here to be able to disable and re-enable individual | 414 | Say Y here to be able to disable and re-enable individual |
396 | CPUs at runtime on SMP machines. | 415 | CPUs at runtime on SMP machines. |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 96efd8213c1c..709a22a3e824 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -133,6 +133,21 @@ else | |||
133 | CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64 | 133 | CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64 |
134 | endif | 134 | endif |
135 | 135 | ||
136 | ifdef CONFIG_MPROFILE_KERNEL | ||
137 | ifeq ($(shell $(srctree)/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh $(CC) -I$(srctree)/include -D__KERNEL__),OK) | ||
138 | CC_FLAGS_FTRACE := -pg -mprofile-kernel | ||
139 | KBUILD_CPPFLAGS += -DCC_USING_MPROFILE_KERNEL | ||
140 | else | ||
141 | # If the user asked for mprofile-kernel but the toolchain doesn't | ||
142 | # support it, emit a warning and deliberately break the build later | ||
143 | # with mprofile-kernel-not-supported. We would prefer to make this an | ||
144 | # error right here, but then the user would never be able to run | ||
145 | # oldconfig to change their configuration. | ||
146 | $(warning Compiler does not support mprofile-kernel, set CONFIG_DISABLE_MPROFILE_KERNEL) | ||
147 | CC_FLAGS_FTRACE := -mprofile-kernel-not-supported | ||
148 | endif | ||
149 | endif | ||
150 | |||
136 | CFLAGS-$(CONFIG_CELL_CPU) += $(call cc-option,-mcpu=cell) | 151 | CFLAGS-$(CONFIG_CELL_CPU) += $(call cc-option,-mcpu=cell) |
137 | CFLAGS-$(CONFIG_POWER4_CPU) += $(call cc-option,-mcpu=power4) | 152 | CFLAGS-$(CONFIG_POWER4_CPU) += $(call cc-option,-mcpu=power4) |
138 | CFLAGS-$(CONFIG_POWER5_CPU) += $(call cc-option,-mcpu=power5) | 153 | CFLAGS-$(CONFIG_POWER5_CPU) += $(call cc-option,-mcpu=power5) |
@@ -310,6 +325,16 @@ corenet64_smp_defconfig: | |||
310 | $(call merge_into_defconfig,corenet_basic_defconfig,\ | 325 | $(call merge_into_defconfig,corenet_basic_defconfig,\ |
311 | 85xx-64bit 85xx-smp altivec 85xx-hw fsl-emb-nonhw) | 326 | 85xx-64bit 85xx-smp altivec 85xx-hw fsl-emb-nonhw) |
312 | 327 | ||
328 | PHONY += mpc86xx_defconfig | ||
329 | mpc86xx_defconfig: | ||
330 | $(call merge_into_defconfig,mpc86xx_basic_defconfig,\ | ||
331 | 86xx-hw fsl-emb-nonhw) | ||
332 | |||
333 | PHONY += mpc86xx_smp_defconfig | ||
334 | mpc86xx_smp_defconfig: | ||
335 | $(call merge_into_defconfig,mpc86xx_basic_defconfig,\ | ||
336 | 86xx-smp 86xx-hw fsl-emb-nonhw) | ||
337 | |||
313 | define archhelp | 338 | define archhelp |
314 | @echo '* zImage - Build default images selected by kernel config' | 339 | @echo '* zImage - Build default images selected by kernel config' |
315 | @echo ' zImage.* - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)' | 340 | @echo ' zImage.* - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)' |
diff --git a/arch/powerpc/boot/dts/fsl/b4860qds.dts b/arch/powerpc/boot/dts/fsl/b4860qds.dts index ba8c9bea33ac..a8bc419959ca 100644 --- a/arch/powerpc/boot/dts/fsl/b4860qds.dts +++ b/arch/powerpc/boot/dts/fsl/b4860qds.dts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * B4860DS Device Tree Source | 2 | * B4860DS Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2012 Freescale Semiconductor Inc. | 4 | * Copyright 2012 - 2015 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: |
@@ -39,12 +39,69 @@ | |||
39 | model = "fsl,B4860QDS"; | 39 | model = "fsl,B4860QDS"; |
40 | compatible = "fsl,B4860QDS"; | 40 | compatible = "fsl,B4860QDS"; |
41 | 41 | ||
42 | aliases { | ||
43 | phy_sgmii_1e = &phy_sgmii_1e; | ||
44 | phy_sgmii_1f = &phy_sgmii_1f; | ||
45 | phy_xaui_slot1 = &phy_xaui_slot1; | ||
46 | phy_xaui_slot2 = &phy_xaui_slot2; | ||
47 | }; | ||
48 | |||
42 | ifc: localbus@ffe124000 { | 49 | ifc: localbus@ffe124000 { |
43 | board-control@3,0 { | 50 | board-control@3,0 { |
44 | compatible = "fsl,b4860qds-fpga", "fsl,fpga-qixis"; | 51 | compatible = "fsl,b4860qds-fpga", "fsl,fpga-qixis"; |
45 | }; | 52 | }; |
46 | }; | 53 | }; |
47 | 54 | ||
55 | soc@ffe000000 { | ||
56 | fman@400000 { | ||
57 | ethernet@e8000 { | ||
58 | phy-handle = <&phy_sgmii_1e>; | ||
59 | phy-connection-type = "sgmii"; | ||
60 | }; | ||
61 | |||
62 | ethernet@ea000 { | ||
63 | phy-handle = <&phy_sgmii_1f>; | ||
64 | phy-connection-type = "sgmii"; | ||
65 | }; | ||
66 | |||
67 | ethernet@f0000 { | ||
68 | phy-handle = <&phy_xaui_slot1>; | ||
69 | phy-connection-type = "xgmii"; | ||
70 | }; | ||
71 | |||
72 | ethernet@f2000 { | ||
73 | phy-handle = <&phy_xaui_slot2>; | ||
74 | phy-connection-type = "xgmii"; | ||
75 | }; | ||
76 | |||
77 | mdio@fc000 { | ||
78 | phy_sgmii_1e: ethernet-phy@1e { | ||
79 | reg = <0x1e>; | ||
80 | status = "disabled"; | ||
81 | }; | ||
82 | |||
83 | phy_sgmii_1f: ethernet-phy@1f { | ||
84 | reg = <0x1f>; | ||
85 | status = "disabled"; | ||
86 | }; | ||
87 | }; | ||
88 | |||
89 | mdio@fd000 { | ||
90 | phy_xaui_slot1: xaui-phy@slot1 { | ||
91 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
92 | reg = <0x7>; | ||
93 | status = "disabled"; | ||
94 | }; | ||
95 | |||
96 | phy_xaui_slot2: xaui-phy@slot2 { | ||
97 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
98 | reg = <0x6>; | ||
99 | status = "disabled"; | ||
100 | }; | ||
101 | }; | ||
102 | }; | ||
103 | }; | ||
104 | |||
48 | rio: rapidio@ffe0c0000 { | 105 | rio: rapidio@ffe0c0000 { |
49 | reg = <0xf 0xfe0c0000 0 0x11000>; | 106 | reg = <0xf 0xfe0c0000 0 0x11000>; |
50 | 107 | ||
@@ -55,7 +112,6 @@ | |||
55 | ranges = <0 0 0xc 0x30000000 0 0x10000000>; | 112 | ranges = <0 0 0xc 0x30000000 0 0x10000000>; |
56 | }; | 113 | }; |
57 | }; | 114 | }; |
58 | |||
59 | }; | 115 | }; |
60 | 116 | ||
61 | /include/ "b4860si-post.dtsi" | 117 | /include/ "b4860si-post.dtsi" |
diff --git a/arch/powerpc/boot/dts/fsl/b4qds.dtsi b/arch/powerpc/boot/dts/fsl/b4qds.dtsi index 64557742fb99..3785ef826d07 100644 --- a/arch/powerpc/boot/dts/fsl/b4qds.dtsi +++ b/arch/powerpc/boot/dts/fsl/b4qds.dtsi | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * B4420DS Device Tree Source | 2 | * B4420DS Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2012 - 2014 Freescale Semiconductor, Inc. | 4 | * Copyright 2012 - 2015 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: |
@@ -39,6 +39,13 @@ | |||
39 | #size-cells = <2>; | 39 | #size-cells = <2>; |
40 | interrupt-parent = <&mpic>; | 40 | interrupt-parent = <&mpic>; |
41 | 41 | ||
42 | aliases { | ||
43 | phy_sgmii_10 = &phy_sgmii_10; | ||
44 | phy_sgmii_11 = &phy_sgmii_11; | ||
45 | phy_sgmii_1c = &phy_sgmii_1c; | ||
46 | phy_sgmii_1d = &phy_sgmii_1d; | ||
47 | }; | ||
48 | |||
42 | ifc: localbus@ffe124000 { | 49 | ifc: localbus@ffe124000 { |
43 | reg = <0xf 0xfe124000 0 0x2000>; | 50 | reg = <0xf 0xfe124000 0 0x2000>; |
44 | ranges = <0 0 0xf 0xe8000000 0x08000000 | 51 | ranges = <0 0 0xf 0xe8000000 0x08000000 |
@@ -135,7 +142,7 @@ | |||
135 | flash@0 { | 142 | flash@0 { |
136 | #address-cells = <1>; | 143 | #address-cells = <1>; |
137 | #size-cells = <1>; | 144 | #size-cells = <1>; |
138 | compatible = "sst,sst25wf040"; | 145 | compatible = "sst,sst25wf040", "jedec,spi-nor"; |
139 | reg = <0>; | 146 | reg = <0>; |
140 | spi-max-frequency = <40000000>; /* input clock */ | 147 | spi-max-frequency = <40000000>; /* input clock */ |
141 | }; | 148 | }; |
@@ -210,6 +217,47 @@ | |||
210 | phy_type = "ulpi"; | 217 | phy_type = "ulpi"; |
211 | }; | 218 | }; |
212 | 219 | ||
220 | fman@400000 { | ||
221 | ethernet@e0000 { | ||
222 | phy-handle = <&phy_sgmii_10>; | ||
223 | phy-connection-type = "sgmii"; | ||
224 | }; | ||
225 | |||
226 | ethernet@e2000 { | ||
227 | phy-handle = <&phy_sgmii_11>; | ||
228 | phy-connection-type = "sgmii"; | ||
229 | }; | ||
230 | |||
231 | ethernet@e4000 { | ||
232 | phy-handle = <&phy_sgmii_1c>; | ||
233 | phy-connection-type = "sgmii"; | ||
234 | }; | ||
235 | |||
236 | ethernet@e6000 { | ||
237 | phy-handle = <&phy_sgmii_1d>; | ||
238 | phy-connection-type = "sgmii"; | ||
239 | }; | ||
240 | |||
241 | mdio@fc000 { | ||
242 | phy_sgmii_10: ethernet-phy@10 { | ||
243 | reg = <0x10>; | ||
244 | }; | ||
245 | |||
246 | phy_sgmii_11: ethernet-phy@11 { | ||
247 | reg = <0x11>; | ||
248 | }; | ||
249 | |||
250 | phy_sgmii_1c: ethernet-phy@1c { | ||
251 | reg = <0x1c>; | ||
252 | status = "disabled"; | ||
253 | }; | ||
254 | |||
255 | phy_sgmii_1d: ethernet-phy@1d { | ||
256 | reg = <0x1d>; | ||
257 | status = "disabled"; | ||
258 | }; | ||
259 | }; | ||
260 | }; | ||
213 | }; | 261 | }; |
214 | 262 | ||
215 | pci0: pcie@ffe200000 { | 263 | pci0: pcie@ffe200000 { |
@@ -226,7 +274,6 @@ | |||
226 | 0 0x00010000>; | 274 | 0 0x00010000>; |
227 | }; | 275 | }; |
228 | }; | 276 | }; |
229 | |||
230 | }; | 277 | }; |
231 | 278 | ||
232 | /include/ "b4si-post.dtsi" | 279 | /include/ "b4si-post.dtsi" |
diff --git a/arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi b/arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi index f4d96d277ed5..53f8b956340f 100644 --- a/arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi | |||
@@ -53,7 +53,7 @@ | |||
53 | flash@0 { | 53 | flash@0 { |
54 | #address-cells = <1>; | 54 | #address-cells = <1>; |
55 | #size-cells = <1>; | 55 | #size-cells = <1>; |
56 | compatible = "spansion,s25sl12801"; | 56 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
57 | reg = <0>; | 57 | reg = <0>; |
58 | spi-max-frequency = <50000000>; | 58 | spi-max-frequency = <50000000>; |
59 | 59 | ||
diff --git a/arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi b/arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi index 7a13bf2aa439..fead484a8180 100644 --- a/arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi +++ b/arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi | |||
@@ -55,7 +55,7 @@ | |||
55 | flash@0 { | 55 | flash@0 { |
56 | #address-cells = <1>; | 56 | #address-cells = <1>; |
57 | #size-cells = <1>; | 57 | #size-cells = <1>; |
58 | compatible = "spansion,s25sl12801"; | 58 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
59 | reg = <0>; | 59 | reg = <0>; |
60 | spi-max-frequency = <30000000>; | 60 | spi-max-frequency = <30000000>; |
61 | }; | 61 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/c293pcie.dts b/arch/powerpc/boot/dts/fsl/c293pcie.dts index 53ab4db9e79c..66709788429d 100644 --- a/arch/powerpc/boot/dts/fsl/c293pcie.dts +++ b/arch/powerpc/boot/dts/fsl/c293pcie.dts | |||
@@ -167,7 +167,7 @@ | |||
167 | flash@0 { | 167 | flash@0 { |
168 | #address-cells = <1>; | 168 | #address-cells = <1>; |
169 | #size-cells = <1>; | 169 | #size-cells = <1>; |
170 | compatible = "spansion,s25sl12801"; | 170 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
171 | reg = <0>; | 171 | reg = <0>; |
172 | spi-max-frequency = <50000000>; | 172 | spi-max-frequency = <50000000>; |
173 | 173 | ||
diff --git a/arch/powerpc/boot/dts/fsl/gef_ppc9a.dts b/arch/powerpc/boot/dts/fsl/gef_ppc9a.dts new file mode 100644 index 000000000000..0424fc2bd0e0 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/gef_ppc9a.dts | |||
@@ -0,0 +1,216 @@ | |||
1 | /* | ||
2 | * GE PPC9A Device Tree Source | ||
3 | * | ||
4 | * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | * Based on: SBS CM6 Device Tree Source | ||
12 | * Copyright 2007 SBS Technologies GmbH & Co. KG | ||
13 | * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source) | ||
14 | * Copyright 2006 Freescale Semiconductor Inc. | ||
15 | */ | ||
16 | |||
17 | /* | ||
18 | * Compiled with dtc -I dts -O dtb -o gef_ppc9a.dtb gef_ppc9a.dts | ||
19 | */ | ||
20 | |||
21 | /include/ "mpc8641si-pre.dtsi" | ||
22 | |||
23 | / { | ||
24 | model = "GEF_PPC9A"; | ||
25 | compatible = "gef,ppc9a"; | ||
26 | |||
27 | memory { | ||
28 | device_type = "memory"; | ||
29 | reg = <0x0 0x40000000>; // set by uboot | ||
30 | }; | ||
31 | |||
32 | lbc: localbus@fef05000 { | ||
33 | reg = <0xfef05000 0x1000>; | ||
34 | |||
35 | ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash | ||
36 | 1 0 0xe8000000 0x08000000 // Paged Flash 0 | ||
37 | 2 0 0xe0000000 0x08000000 // Paged Flash 1 | ||
38 | 3 0 0xfc100000 0x00020000 // NVRAM | ||
39 | 4 0 0xfc000000 0x00008000 // FPGA | ||
40 | 5 0 0xfc008000 0x00008000 // AFIX FPGA | ||
41 | 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit) | ||
42 | 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit) | ||
43 | |||
44 | /* flash@0,0 is a mirror of part of the memory in flash@1,0 | ||
45 | flash@0,0 { | ||
46 | compatible = "gef,ppc9a-firmware-mirror", "cfi-flash"; | ||
47 | reg = <0x0 0x0 0x1000000>; | ||
48 | bank-width = <4>; | ||
49 | device-width = <2>; | ||
50 | #address-cells = <1>; | ||
51 | #size-cells = <1>; | ||
52 | partition@0 { | ||
53 | label = "firmware"; | ||
54 | reg = <0x0 0x1000000>; | ||
55 | read-only; | ||
56 | }; | ||
57 | }; | ||
58 | */ | ||
59 | |||
60 | flash@1,0 { | ||
61 | compatible = "gef,ppc9a-paged-flash", "cfi-flash"; | ||
62 | reg = <0x1 0x0 0x8000000>; | ||
63 | bank-width = <4>; | ||
64 | device-width = <2>; | ||
65 | #address-cells = <1>; | ||
66 | #size-cells = <1>; | ||
67 | partition@0 { | ||
68 | label = "user"; | ||
69 | reg = <0x0 0x7800000>; | ||
70 | }; | ||
71 | partition@7800000 { | ||
72 | label = "firmware"; | ||
73 | reg = <0x7800000 0x800000>; | ||
74 | read-only; | ||
75 | }; | ||
76 | }; | ||
77 | |||
78 | nvram@3,0 { | ||
79 | device_type = "nvram"; | ||
80 | compatible = "simtek,stk14ca8"; | ||
81 | reg = <0x3 0x0 0x20000>; | ||
82 | }; | ||
83 | |||
84 | fpga@4,0 { | ||
85 | compatible = "gef,ppc9a-fpga-regs"; | ||
86 | reg = <0x4 0x0 0x40>; | ||
87 | }; | ||
88 | |||
89 | wdt@4,2000 { | ||
90 | compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00", | ||
91 | "gef,fpga-wdt"; | ||
92 | reg = <0x4 0x2000 0x8>; | ||
93 | interrupts = <0x1a 0x4>; | ||
94 | interrupt-parent = <&gef_pic>; | ||
95 | }; | ||
96 | /* Second watchdog available, driver currently supports one. | ||
97 | wdt@4,2010 { | ||
98 | compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00", | ||
99 | "gef,fpga-wdt"; | ||
100 | reg = <0x4 0x2010 0x8>; | ||
101 | interrupts = <0x1b 0x4>; | ||
102 | interrupt-parent = <&gef_pic>; | ||
103 | }; | ||
104 | */ | ||
105 | gef_pic: pic@4,4000 { | ||
106 | #interrupt-cells = <1>; | ||
107 | interrupt-controller; | ||
108 | compatible = "gef,ppc9a-fpga-pic", "gef,fpga-pic-1.00"; | ||
109 | reg = <0x4 0x4000 0x20>; | ||
110 | interrupts = <0x8 0x9 0 0>; | ||
111 | |||
112 | }; | ||
113 | gef_gpio: gpio@7,14000 { | ||
114 | #gpio-cells = <2>; | ||
115 | compatible = "gef,ppc9a-gpio", "gef,sbc610-gpio"; | ||
116 | reg = <0x7 0x14000 0x24>; | ||
117 | gpio-controller; | ||
118 | }; | ||
119 | }; | ||
120 | |||
121 | soc: soc@fef00000 { | ||
122 | ranges = <0x0 0xfef00000 0x00100000>; | ||
123 | |||
124 | i2c@3000 { | ||
125 | hwmon@48 { | ||
126 | compatible = "national,lm92"; | ||
127 | reg = <0x48>; | ||
128 | }; | ||
129 | |||
130 | hwmon@4c { | ||
131 | compatible = "adi,adt7461"; | ||
132 | reg = <0x4c>; | ||
133 | }; | ||
134 | |||
135 | rtc@51 { | ||
136 | compatible = "epson,rx8581"; | ||
137 | reg = <0x00000051>; | ||
138 | }; | ||
139 | |||
140 | eti@6b { | ||
141 | compatible = "dallas,ds1682"; | ||
142 | reg = <0x6b>; | ||
143 | }; | ||
144 | }; | ||
145 | |||
146 | enet0: ethernet@24000 { | ||
147 | tbi-handle = <&tbi0>; | ||
148 | phy-handle = <&phy0>; | ||
149 | phy-connection-type = "gmii"; | ||
150 | }; | ||
151 | |||
152 | mdio@24520 { | ||
153 | phy0: ethernet-phy@0 { | ||
154 | interrupt-parent = <&gef_pic>; | ||
155 | interrupts = <0x9 0x4>; | ||
156 | reg = <1>; | ||
157 | }; | ||
158 | phy2: ethernet-phy@2 { | ||
159 | interrupt-parent = <&gef_pic>; | ||
160 | interrupts = <0x8 0x4>; | ||
161 | reg = <3>; | ||
162 | }; | ||
163 | tbi0: tbi-phy@11 { | ||
164 | reg = <0x11>; | ||
165 | device_type = "tbi-phy"; | ||
166 | }; | ||
167 | }; | ||
168 | |||
169 | enet1: ethernet@26000 { | ||
170 | tbi-handle = <&tbi2>; | ||
171 | phy-handle = <&phy2>; | ||
172 | phy-connection-type = "gmii"; | ||
173 | }; | ||
174 | |||
175 | mdio@26520 { | ||
176 | tbi2: tbi-phy@11 { | ||
177 | reg = <0x11>; | ||
178 | device_type = "tbi-phy"; | ||
179 | }; | ||
180 | }; | ||
181 | |||
182 | enet2: ethernet@25000 { | ||
183 | status = "disabled"; | ||
184 | }; | ||
185 | |||
186 | mdio@25520 { | ||
187 | status = "disabled"; | ||
188 | }; | ||
189 | |||
190 | enet3: ethernet@27000 { | ||
191 | status = "disabled"; | ||
192 | }; | ||
193 | |||
194 | mdio@27520 { | ||
195 | status = "disabled"; | ||
196 | }; | ||
197 | }; | ||
198 | |||
199 | pci0: pcie@fef08000 { | ||
200 | reg = <0xfef08000 0x1000>; | ||
201 | ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000 | ||
202 | 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>; | ||
203 | |||
204 | pcie@0 { | ||
205 | ranges = <0x02000000 0x0 0x80000000 | ||
206 | 0x02000000 0x0 0x80000000 | ||
207 | 0x0 0x40000000 | ||
208 | |||
209 | 0x01000000 0x0 0x00000000 | ||
210 | 0x01000000 0x0 0x00000000 | ||
211 | 0x0 0x00400000>; | ||
212 | }; | ||
213 | }; | ||
214 | }; | ||
215 | |||
216 | /include/ "mpc8641si-post.dtsi" | ||
diff --git a/arch/powerpc/boot/dts/fsl/gef_sbc310.dts b/arch/powerpc/boot/dts/fsl/gef_sbc310.dts new file mode 100644 index 000000000000..84b3d38f880e --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/gef_sbc310.dts | |||
@@ -0,0 +1,260 @@ | |||
1 | /* | ||
2 | * GE SBC310 Device Tree Source | ||
3 | * | ||
4 | * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | * Based on: SBS CM6 Device Tree Source | ||
12 | * Copyright 2007 SBS Technologies GmbH & Co. KG | ||
13 | * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source) | ||
14 | * Copyright 2006 Freescale Semiconductor Inc. | ||
15 | */ | ||
16 | |||
17 | /* | ||
18 | * Compiled with dtc -I dts -O dtb -o gef_sbc310.dtb gef_sbc310.dts | ||
19 | */ | ||
20 | |||
21 | /include/ "mpc8641si-pre.dtsi" | ||
22 | |||
23 | / { | ||
24 | model = "GEF_SBC310"; | ||
25 | compatible = "gef,sbc310"; | ||
26 | |||
27 | aliases { | ||
28 | pci1 = &pci1; | ||
29 | }; | ||
30 | |||
31 | memory { | ||
32 | device_type = "memory"; | ||
33 | reg = <0x0 0x40000000>; // set by uboot | ||
34 | }; | ||
35 | |||
36 | lbc: localbus@fef05000 { | ||
37 | reg = <0xfef05000 0x1000>; | ||
38 | |||
39 | ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash | ||
40 | 1 0 0xe0000000 0x08000000 // Paged Flash 0 | ||
41 | 2 0 0xe8000000 0x08000000 // Paged Flash 1 | ||
42 | 3 0 0xfc100000 0x00020000 // NVRAM | ||
43 | 4 0 0xfc000000 0x00010000>; // FPGA | ||
44 | |||
45 | /* flash@0,0 is a mirror of part of the memory in flash@1,0 | ||
46 | flash@0,0 { | ||
47 | compatible = "gef,sbc310-firmware-mirror", "cfi-flash"; | ||
48 | reg = <0x0 0x0 0x01000000>; | ||
49 | bank-width = <2>; | ||
50 | device-width = <2>; | ||
51 | #address-cells = <1>; | ||
52 | #size-cells = <1>; | ||
53 | partition@0 { | ||
54 | label = "firmware"; | ||
55 | reg = <0x0 0x01000000>; | ||
56 | read-only; | ||
57 | }; | ||
58 | }; | ||
59 | */ | ||
60 | |||
61 | flash@1,0 { | ||
62 | compatible = "gef,sbc310-paged-flash", "cfi-flash"; | ||
63 | reg = <0x1 0x0 0x8000000>; | ||
64 | bank-width = <2>; | ||
65 | device-width = <2>; | ||
66 | #address-cells = <1>; | ||
67 | #size-cells = <1>; | ||
68 | partition@0 { | ||
69 | label = "user"; | ||
70 | reg = <0x0 0x7800000>; | ||
71 | }; | ||
72 | partition@7800000 { | ||
73 | label = "firmware"; | ||
74 | reg = <0x7800000 0x800000>; | ||
75 | read-only; | ||
76 | }; | ||
77 | }; | ||
78 | |||
79 | nvram@3,0 { | ||
80 | device_type = "nvram"; | ||
81 | compatible = "simtek,stk14ca8"; | ||
82 | reg = <0x3 0x0 0x20000>; | ||
83 | }; | ||
84 | |||
85 | fpga@4,0 { | ||
86 | compatible = "gef,fpga-regs"; | ||
87 | reg = <0x4 0x0 0x40>; | ||
88 | }; | ||
89 | |||
90 | wdt@4,2000 { | ||
91 | compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00", | ||
92 | "gef,fpga-wdt"; | ||
93 | reg = <0x4 0x2000 0x8>; | ||
94 | interrupts = <0x1a 0x4>; | ||
95 | interrupt-parent = <&gef_pic>; | ||
96 | }; | ||
97 | /* | ||
98 | wdt@4,2010 { | ||
99 | compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00", | ||
100 | "gef,fpga-wdt"; | ||
101 | reg = <0x4 0x2010 0x8>; | ||
102 | interrupts = <0x1b 0x4>; | ||
103 | interrupt-parent = <&gef_pic>; | ||
104 | }; | ||
105 | */ | ||
106 | gef_pic: pic@4,4000 { | ||
107 | #interrupt-cells = <1>; | ||
108 | interrupt-controller; | ||
109 | compatible = "gef,sbc310-fpga-pic", "gef,fpga-pic"; | ||
110 | reg = <0x4 0x4000 0x20>; | ||
111 | interrupts = <0x8 0x9 0 0>; | ||
112 | |||
113 | }; | ||
114 | gef_gpio: gpio@4,8000 { | ||
115 | #gpio-cells = <2>; | ||
116 | compatible = "gef,sbc310-gpio"; | ||
117 | reg = <0x4 0x8000 0x24>; | ||
118 | gpio-controller; | ||
119 | }; | ||
120 | }; | ||
121 | |||
122 | soc: soc@fef00000 { | ||
123 | ranges = <0x0 0xfef00000 0x00100000>; | ||
124 | |||
125 | i2c@3000 { | ||
126 | rtc@51 { | ||
127 | compatible = "epson,rx8581"; | ||
128 | reg = <0x00000051>; | ||
129 | }; | ||
130 | }; | ||
131 | |||
132 | i2c@3100 { | ||
133 | hwmon@48 { | ||
134 | compatible = "national,lm92"; | ||
135 | reg = <0x48>; | ||
136 | }; | ||
137 | |||
138 | hwmon@4c { | ||
139 | compatible = "adi,adt7461"; | ||
140 | reg = <0x4c>; | ||
141 | }; | ||
142 | |||
143 | eti@6b { | ||
144 | compatible = "dallas,ds1682"; | ||
145 | reg = <0x6b>; | ||
146 | }; | ||
147 | }; | ||
148 | |||
149 | enet0: ethernet@24000 { | ||
150 | tbi-handle = <&tbi0>; | ||
151 | phy-handle = <&phy0>; | ||
152 | phy-connection-type = "gmii"; | ||
153 | }; | ||
154 | |||
155 | mdio@24520 { | ||
156 | phy0: ethernet-phy@0 { | ||
157 | interrupt-parent = <&gef_pic>; | ||
158 | interrupts = <0x9 0x4>; | ||
159 | reg = <1>; | ||
160 | }; | ||
161 | phy2: ethernet-phy@2 { | ||
162 | interrupt-parent = <&gef_pic>; | ||
163 | interrupts = <0x8 0x4>; | ||
164 | reg = <3>; | ||
165 | }; | ||
166 | tbi0: tbi-phy@11 { | ||
167 | reg = <0x11>; | ||
168 | device_type = "tbi-phy"; | ||
169 | }; | ||
170 | }; | ||
171 | |||
172 | enet1: ethernet@26000 { | ||
173 | tbi-handle = <&tbi2>; | ||
174 | phy-handle = <&phy2>; | ||
175 | phy-connection-type = "gmii"; | ||
176 | }; | ||
177 | |||
178 | mdio@26520 { | ||
179 | tbi2: tbi-phy@11 { | ||
180 | reg = <0x11>; | ||
181 | device_type = "tbi-phy"; | ||
182 | }; | ||
183 | }; | ||
184 | |||
185 | enet2: ethernet@25000 { | ||
186 | status = "disabled"; | ||
187 | }; | ||
188 | |||
189 | mdio@25520 { | ||
190 | status = "disabled"; | ||
191 | }; | ||
192 | |||
193 | enet3: ethernet@27000 { | ||
194 | status = "disabled"; | ||
195 | }; | ||
196 | |||
197 | mdio@27520 { | ||
198 | status = "disabled"; | ||
199 | }; | ||
200 | }; | ||
201 | |||
202 | pci0: pcie@fef08000 { | ||
203 | reg = <0xfef08000 0x1000>; | ||
204 | ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000 | ||
205 | 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>; | ||
206 | interrupt-map-mask = <0xff00 0x0 0x0 0x7>; | ||
207 | interrupt-map = < | ||
208 | 0x0000 0x0 0x0 0x1 &mpic 0x0 0x2 | ||
209 | 0x0000 0x0 0x0 0x2 &mpic 0x1 0x2 | ||
210 | 0x0000 0x0 0x0 0x3 &mpic 0x2 0x2 | ||
211 | 0x0000 0x0 0x0 0x4 &mpic 0x3 0x2 | ||
212 | >; | ||
213 | |||
214 | pcie@0 { | ||
215 | ranges = <0x02000000 0x0 0x80000000 | ||
216 | 0x02000000 0x0 0x80000000 | ||
217 | 0x0 0x40000000 | ||
218 | |||
219 | 0x01000000 0x0 0x00000000 | ||
220 | 0x01000000 0x0 0x00000000 | ||
221 | 0x0 0x00400000>; | ||
222 | }; | ||
223 | }; | ||
224 | |||
225 | pci1: pcie@fef09000 { | ||
226 | compatible = "fsl,mpc8641-pcie"; | ||
227 | device_type = "pci"; | ||
228 | #size-cells = <2>; | ||
229 | #address-cells = <3>; | ||
230 | reg = <0xfef09000 0x1000>; | ||
231 | bus-range = <0x0 0xff>; | ||
232 | ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0x0 0x20000000 | ||
233 | 0x01000000 0x0 0x00000000 0xfe400000 0x0 0x00400000>; | ||
234 | clock-frequency = <100000000>; | ||
235 | interrupts = <0x19 0x2 0 0>; | ||
236 | interrupt-map-mask = <0xf800 0x0 0x0 0x7>; | ||
237 | interrupt-map = < | ||
238 | 0x0000 0x0 0x0 0x1 &mpic 0x4 0x2 | ||
239 | 0x0000 0x0 0x0 0x2 &mpic 0x5 0x2 | ||
240 | 0x0000 0x0 0x0 0x3 &mpic 0x6 0x2 | ||
241 | 0x0000 0x0 0x0 0x4 &mpic 0x7 0x2 | ||
242 | >; | ||
243 | |||
244 | pcie@0 { | ||
245 | reg = <0 0 0 0 0>; | ||
246 | #size-cells = <2>; | ||
247 | #address-cells = <3>; | ||
248 | device_type = "pci"; | ||
249 | ranges = <0x02000000 0x0 0xc0000000 | ||
250 | 0x02000000 0x0 0xc0000000 | ||
251 | 0x0 0x20000000 | ||
252 | |||
253 | 0x01000000 0x0 0x00000000 | ||
254 | 0x01000000 0x0 0x00000000 | ||
255 | 0x0 0x00400000>; | ||
256 | }; | ||
257 | }; | ||
258 | }; | ||
259 | |||
260 | /include/ "mpc8641si-post.dtsi" | ||
diff --git a/arch/powerpc/boot/dts/fsl/gef_sbc610.dts b/arch/powerpc/boot/dts/fsl/gef_sbc610.dts new file mode 100644 index 000000000000..974446acce23 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/gef_sbc610.dts | |||
@@ -0,0 +1,214 @@ | |||
1 | /* | ||
2 | * GE SBC610 Device Tree Source | ||
3 | * | ||
4 | * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | * Based on: SBS CM6 Device Tree Source | ||
12 | * Copyright 2007 SBS Technologies GmbH & Co. KG | ||
13 | * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source) | ||
14 | * Copyright 2006 Freescale Semiconductor Inc. | ||
15 | */ | ||
16 | |||
17 | /* | ||
18 | * Compiled with dtc -I dts -O dtb -o gef_sbc610.dtb gef_sbc610.dts | ||
19 | */ | ||
20 | |||
21 | /include/ "mpc8641si-pre.dtsi" | ||
22 | |||
23 | / { | ||
24 | model = "GEF_SBC610"; | ||
25 | compatible = "gef,sbc610"; | ||
26 | |||
27 | memory { | ||
28 | device_type = "memory"; | ||
29 | reg = <0x0 0x40000000>; // set by uboot | ||
30 | }; | ||
31 | |||
32 | lbc: localbus@fef05000 { | ||
33 | reg = <0xfef05000 0x1000>; | ||
34 | |||
35 | ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash | ||
36 | 1 0 0xe8000000 0x08000000 // Paged Flash 0 | ||
37 | 2 0 0xe0000000 0x08000000 // Paged Flash 1 | ||
38 | 3 0 0xfc100000 0x00020000 // NVRAM | ||
39 | 4 0 0xfc000000 0x00008000 // FPGA | ||
40 | 5 0 0xfc008000 0x00008000 // AFIX FPGA | ||
41 | 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit) | ||
42 | 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit) | ||
43 | |||
44 | /* flash@0,0 is a mirror of part of the memory in flash@1,0 | ||
45 | flash@0,0 { | ||
46 | compatible = "gef,sbc610-firmware-mirror", "cfi-flash"; | ||
47 | reg = <0x0 0x0 0x1000000>; | ||
48 | bank-width = <4>; | ||
49 | device-width = <2>; | ||
50 | #address-cells = <1>; | ||
51 | #size-cells = <1>; | ||
52 | partition@0 { | ||
53 | label = "firmware"; | ||
54 | reg = <0x0 0x1000000>; | ||
55 | read-only; | ||
56 | }; | ||
57 | }; | ||
58 | */ | ||
59 | |||
60 | flash@1,0 { | ||
61 | compatible = "gef,sbc610-paged-flash", "cfi-flash"; | ||
62 | reg = <0x1 0x0 0x8000000>; | ||
63 | bank-width = <4>; | ||
64 | device-width = <2>; | ||
65 | #address-cells = <1>; | ||
66 | #size-cells = <1>; | ||
67 | partition@0 { | ||
68 | label = "user"; | ||
69 | reg = <0x0 0x7800000>; | ||
70 | }; | ||
71 | partition@7800000 { | ||
72 | label = "firmware"; | ||
73 | reg = <0x7800000 0x800000>; | ||
74 | read-only; | ||
75 | }; | ||
76 | }; | ||
77 | |||
78 | nvram@3,0 { | ||
79 | device_type = "nvram"; | ||
80 | compatible = "simtek,stk14ca8"; | ||
81 | reg = <0x3 0x0 0x20000>; | ||
82 | }; | ||
83 | |||
84 | fpga@4,0 { | ||
85 | compatible = "gef,fpga-regs"; | ||
86 | reg = <0x4 0x0 0x40>; | ||
87 | }; | ||
88 | |||
89 | wdt@4,2000 { | ||
90 | compatible = "gef,fpga-wdt"; | ||
91 | reg = <0x4 0x2000 0x8>; | ||
92 | interrupts = <0x1a 0x4>; | ||
93 | interrupt-parent = <&gef_pic>; | ||
94 | }; | ||
95 | /* Second watchdog available, driver currently supports one. | ||
96 | wdt@4,2010 { | ||
97 | compatible = "gef,fpga-wdt"; | ||
98 | reg = <0x4 0x2010 0x8>; | ||
99 | interrupts = <0x1b 0x4>; | ||
100 | interrupt-parent = <&gef_pic>; | ||
101 | }; | ||
102 | */ | ||
103 | gef_pic: pic@4,4000 { | ||
104 | #interrupt-cells = <1>; | ||
105 | interrupt-controller; | ||
106 | compatible = "gef,fpga-pic"; | ||
107 | reg = <0x4 0x4000 0x20>; | ||
108 | interrupts = <0x8 0x9 0 0>; | ||
109 | |||
110 | }; | ||
111 | gef_gpio: gpio@7,14000 { | ||
112 | #gpio-cells = <2>; | ||
113 | compatible = "gef,sbc610-gpio"; | ||
114 | reg = <0x7 0x14000 0x24>; | ||
115 | gpio-controller; | ||
116 | }; | ||
117 | }; | ||
118 | |||
119 | soc: soc@fef00000 { | ||
120 | ranges = <0x0 0xfef00000 0x00100000>; | ||
121 | |||
122 | i2c@3000 { | ||
123 | hwmon@48 { | ||
124 | compatible = "national,lm92"; | ||
125 | reg = <0x48>; | ||
126 | }; | ||
127 | |||
128 | hwmon@4c { | ||
129 | compatible = "adi,adt7461"; | ||
130 | reg = <0x4c>; | ||
131 | }; | ||
132 | |||
133 | rtc@51 { | ||
134 | compatible = "epson,rx8581"; | ||
135 | reg = <0x00000051>; | ||
136 | }; | ||
137 | |||
138 | eti@6b { | ||
139 | compatible = "dallas,ds1682"; | ||
140 | reg = <0x6b>; | ||
141 | }; | ||
142 | }; | ||
143 | |||
144 | enet0: ethernet@24000 { | ||
145 | tbi-handle = <&tbi0>; | ||
146 | phy-handle = <&phy0>; | ||
147 | phy-connection-type = "gmii"; | ||
148 | }; | ||
149 | |||
150 | mdio@24520 { | ||
151 | phy0: ethernet-phy@0 { | ||
152 | interrupt-parent = <&gef_pic>; | ||
153 | interrupts = <0x9 0x4>; | ||
154 | reg = <1>; | ||
155 | }; | ||
156 | phy2: ethernet-phy@2 { | ||
157 | interrupt-parent = <&gef_pic>; | ||
158 | interrupts = <0x8 0x4>; | ||
159 | reg = <3>; | ||
160 | }; | ||
161 | tbi0: tbi-phy@11 { | ||
162 | reg = <0x11>; | ||
163 | device_type = "tbi-phy"; | ||
164 | }; | ||
165 | }; | ||
166 | |||
167 | enet1: ethernet@26000 { | ||
168 | tbi-handle = <&tbi2>; | ||
169 | phy-handle = <&phy2>; | ||
170 | phy-connection-type = "gmii"; | ||
171 | }; | ||
172 | |||
173 | mdio@26520 { | ||
174 | tbi2: tbi-phy@11 { | ||
175 | reg = <0x11>; | ||
176 | device_type = "tbi-phy"; | ||
177 | }; | ||
178 | }; | ||
179 | |||
180 | enet2: ethernet@25000 { | ||
181 | status = "disabled"; | ||
182 | }; | ||
183 | |||
184 | mdio@25520 { | ||
185 | status = "disabled"; | ||
186 | }; | ||
187 | |||
188 | enet3: ethernet@27000 { | ||
189 | status = "disabled"; | ||
190 | }; | ||
191 | |||
192 | mdio@27520 { | ||
193 | status = "disabled"; | ||
194 | }; | ||
195 | }; | ||
196 | |||
197 | pci0: pcie@fef08000 { | ||
198 | reg = <0xfef08000 0x1000>; | ||
199 | ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000 | ||
200 | 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>; | ||
201 | |||
202 | pcie@0 { | ||
203 | ranges = <0x02000000 0x0 0x80000000 | ||
204 | 0x02000000 0x0 0x80000000 | ||
205 | 0x0 0x40000000 | ||
206 | |||
207 | 0x01000000 0x0 0x00000000 | ||
208 | 0x01000000 0x0 0x00000000 | ||
209 | 0x0 0x00400000>; | ||
210 | }; | ||
211 | }; | ||
212 | }; | ||
213 | |||
214 | /include/ "mpc8641si-post.dtsi" | ||
diff --git a/arch/powerpc/boot/dts/fsl/kmcoge4.dts b/arch/powerpc/boot/dts/fsl/kmcoge4.dts index 6858ec9ef295..2d4b64fcee88 100644 --- a/arch/powerpc/boot/dts/fsl/kmcoge4.dts +++ b/arch/powerpc/boot/dts/fsl/kmcoge4.dts | |||
@@ -63,7 +63,7 @@ | |||
63 | flash@0 { | 63 | flash@0 { |
64 | #address-cells = <1>; | 64 | #address-cells = <1>; |
65 | #size-cells = <1>; | 65 | #size-cells = <1>; |
66 | compatible = "spansion,s25fl256s1"; | 66 | compatible = "spansion,s25fl256s1", "jedec,spi-nor"; |
67 | reg = <0>; | 67 | reg = <0>; |
68 | spi-max-frequency = <20000000>; /* input clock */ | 68 | spi-max-frequency = <20000000>; /* input clock */ |
69 | }; | 69 | }; |
@@ -77,7 +77,7 @@ | |||
77 | flash@2 { | 77 | flash@2 { |
78 | #address-cells = <1>; | 78 | #address-cells = <1>; |
79 | #size-cells = <1>; | 79 | #size-cells = <1>; |
80 | compatible = "micron,m25p32"; | 80 | compatible = "micron,m25p32", "jedec,spi-nor"; |
81 | reg = <2>; | 81 | reg = <2>; |
82 | spi-max-frequency = <15000000>; | 82 | spi-max-frequency = <15000000>; |
83 | }; | 83 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi b/arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi index 937ad7e46119..a925fe49a73e 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi | |||
@@ -142,7 +142,7 @@ | |||
142 | flash@0 { | 142 | flash@0 { |
143 | #address-cells = <1>; | 143 | #address-cells = <1>; |
144 | #size-cells = <1>; | 144 | #size-cells = <1>; |
145 | compatible = "spansion,s25sl12801"; | 145 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
146 | reg = <0>; | 146 | reg = <0>; |
147 | spi-max-frequency = <40000000>; | 147 | spi-max-frequency = <40000000>; |
148 | partition@u-boot { | 148 | partition@u-boot { |
@@ -166,17 +166,17 @@ | |||
166 | }; | 166 | }; |
167 | }; | 167 | }; |
168 | flash@1 { | 168 | flash@1 { |
169 | compatible = "spansion,s25sl12801"; | 169 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
170 | reg = <1>; | 170 | reg = <1>; |
171 | spi-max-frequency = <40000000>; | 171 | spi-max-frequency = <40000000>; |
172 | }; | 172 | }; |
173 | flash@2 { | 173 | flash@2 { |
174 | compatible = "spansion,s25sl12801"; | 174 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
175 | reg = <2>; | 175 | reg = <2>; |
176 | spi-max-frequency = <40000000>; | 176 | spi-max-frequency = <40000000>; |
177 | }; | 177 | }; |
178 | flash@3 { | 178 | flash@3 { |
179 | compatible = "spansion,s25sl12801"; | 179 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
180 | reg = <3>; | 180 | reg = <3>; |
181 | spi-max-frequency = <40000000>; | 181 | spi-max-frequency = <40000000>; |
182 | }; | 182 | }; |
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/fsl/mpc8641_hpcn.dts index 1c03060dd0b8..554001f2e96a 100644 --- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts +++ b/arch/powerpc/boot/dts/fsl/mpc8641_hpcn.dts | |||
@@ -9,65 +9,23 @@ | |||
9 | * option) any later version. | 9 | * option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | /dts-v1/; | 12 | /include/ "mpc8641si-pre.dtsi" |
13 | 13 | ||
14 | / { | 14 | / { |
15 | model = "MPC8641HPCN"; | 15 | model = "MPC8641HPCN"; |
16 | compatible = "fsl,mpc8641hpcn"; | 16 | compatible = "fsl,mpc8641hpcn"; |
17 | #address-cells = <1>; | ||
18 | #size-cells = <1>; | ||
19 | 17 | ||
20 | aliases { | 18 | aliases { |
21 | ethernet0 = &enet0; | ||
22 | ethernet1 = &enet1; | ||
23 | ethernet2 = &enet2; | ||
24 | ethernet3 = &enet3; | ||
25 | serial0 = &serial0; | ||
26 | serial1 = &serial1; | ||
27 | pci0 = &pci0; | ||
28 | pci1 = &pci1; | 19 | pci1 = &pci1; |
29 | }; | 20 | }; |
30 | 21 | ||
31 | cpus { | ||
32 | #address-cells = <1>; | ||
33 | #size-cells = <0>; | ||
34 | |||
35 | PowerPC,8641@0 { | ||
36 | device_type = "cpu"; | ||
37 | reg = <0>; | ||
38 | d-cache-line-size = <32>; | ||
39 | i-cache-line-size = <32>; | ||
40 | d-cache-size = <32768>; // L1 | ||
41 | i-cache-size = <32768>; // L1 | ||
42 | timebase-frequency = <0>; // From uboot | ||
43 | bus-frequency = <0>; // From uboot | ||
44 | clock-frequency = <0>; // From uboot | ||
45 | }; | ||
46 | PowerPC,8641@1 { | ||
47 | device_type = "cpu"; | ||
48 | reg = <1>; | ||
49 | d-cache-line-size = <32>; | ||
50 | i-cache-line-size = <32>; | ||
51 | d-cache-size = <32768>; | ||
52 | i-cache-size = <32768>; | ||
53 | timebase-frequency = <0>; // From uboot | ||
54 | bus-frequency = <0>; // From uboot | ||
55 | clock-frequency = <0>; // From uboot | ||
56 | }; | ||
57 | }; | ||
58 | |||
59 | memory { | 22 | memory { |
60 | device_type = "memory"; | 23 | device_type = "memory"; |
61 | reg = <0x00000000 0x40000000>; // 1G at 0x0 | 24 | reg = <0x00000000 0x40000000>; // 1G at 0x0 |
62 | }; | 25 | }; |
63 | 26 | ||
64 | localbus@ffe05000 { | 27 | lbc: localbus@ffe05000 { |
65 | #address-cells = <2>; | ||
66 | #size-cells = <1>; | ||
67 | compatible = "fsl,mpc8641-localbus", "simple-bus"; | ||
68 | reg = <0xffe05000 0x1000>; | 28 | reg = <0xffe05000 0x1000>; |
69 | interrupts = <19 2>; | ||
70 | interrupt-parent = <&mpic>; | ||
71 | 29 | ||
72 | ranges = <0 0 0xef800000 0x00800000 | 30 | ranges = <0 0 0xef800000 0x00800000 |
73 | 2 0 0xffdf8000 0x00008000 | 31 | 2 0 0xffdf8000 0x00008000 |
@@ -101,253 +59,75 @@ | |||
101 | }; | 59 | }; |
102 | }; | 60 | }; |
103 | 61 | ||
104 | soc8641@ffe00000 { | 62 | soc: soc8641@ffe00000 { |
105 | #address-cells = <1>; | ||
106 | #size-cells = <1>; | ||
107 | device_type = "soc"; | ||
108 | compatible = "simple-bus"; | ||
109 | ranges = <0x00000000 0xffe00000 0x00100000>; | 63 | ranges = <0x00000000 0xffe00000 0x00100000>; |
110 | bus-frequency = <0>; | ||
111 | |||
112 | mcm-law@0 { | ||
113 | compatible = "fsl,mcm-law"; | ||
114 | reg = <0x0 0x1000>; | ||
115 | fsl,num-laws = <10>; | ||
116 | }; | ||
117 | |||
118 | mcm@1000 { | ||
119 | compatible = "fsl,mpc8641-mcm", "fsl,mcm"; | ||
120 | reg = <0x1000 0x1000>; | ||
121 | interrupts = <17 2>; | ||
122 | interrupt-parent = <&mpic>; | ||
123 | }; | ||
124 | 64 | ||
125 | i2c@3000 { | 65 | enet0: ethernet@24000 { |
126 | #address-cells = <1>; | 66 | tbi-handle = <&tbi0>; |
127 | #size-cells = <0>; | 67 | phy-handle = <&phy0>; |
128 | cell-index = <0>; | 68 | phy-connection-type = "rgmii-id"; |
129 | compatible = "fsl-i2c"; | ||
130 | reg = <0x3000 0x100>; | ||
131 | interrupts = <43 2>; | ||
132 | interrupt-parent = <&mpic>; | ||
133 | dfsrr; | ||
134 | }; | ||
135 | |||
136 | i2c@3100 { | ||
137 | #address-cells = <1>; | ||
138 | #size-cells = <0>; | ||
139 | cell-index = <1>; | ||
140 | compatible = "fsl-i2c"; | ||
141 | reg = <0x3100 0x100>; | ||
142 | interrupts = <43 2>; | ||
143 | interrupt-parent = <&mpic>; | ||
144 | dfsrr; | ||
145 | }; | 69 | }; |
146 | 70 | ||
147 | dma@21300 { | 71 | mdio@24520 { |
148 | #address-cells = <1>; | 72 | phy0: ethernet-phy@0 { |
149 | #size-cells = <1>; | 73 | interrupts = <10 1 0 0>; |
150 | compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; | 74 | reg = <0>; |
151 | reg = <0x21300 0x4>; | ||
152 | ranges = <0x0 0x21100 0x200>; | ||
153 | cell-index = <0>; | ||
154 | dma-channel@0 { | ||
155 | compatible = "fsl,mpc8641-dma-channel", | ||
156 | "fsl,eloplus-dma-channel"; | ||
157 | reg = <0x0 0x80>; | ||
158 | cell-index = <0>; | ||
159 | interrupt-parent = <&mpic>; | ||
160 | interrupts = <20 2>; | ||
161 | }; | 75 | }; |
162 | dma-channel@80 { | 76 | phy1: ethernet-phy@1 { |
163 | compatible = "fsl,mpc8641-dma-channel", | 77 | interrupts = <10 1 0 0>; |
164 | "fsl,eloplus-dma-channel"; | 78 | reg = <1>; |
165 | reg = <0x80 0x80>; | ||
166 | cell-index = <1>; | ||
167 | interrupt-parent = <&mpic>; | ||
168 | interrupts = <21 2>; | ||
169 | }; | 79 | }; |
170 | dma-channel@100 { | 80 | phy2: ethernet-phy@2 { |
171 | compatible = "fsl,mpc8641-dma-channel", | 81 | interrupts = <10 1 0 0>; |
172 | "fsl,eloplus-dma-channel"; | 82 | reg = <2>; |
173 | reg = <0x100 0x80>; | ||
174 | cell-index = <2>; | ||
175 | interrupt-parent = <&mpic>; | ||
176 | interrupts = <22 2>; | ||
177 | }; | 83 | }; |
178 | dma-channel@180 { | 84 | phy3: ethernet-phy@3 { |
179 | compatible = "fsl,mpc8641-dma-channel", | 85 | interrupts = <10 1 0 0>; |
180 | "fsl,eloplus-dma-channel"; | 86 | reg = <3>; |
181 | reg = <0x180 0x80>; | ||
182 | cell-index = <3>; | ||
183 | interrupt-parent = <&mpic>; | ||
184 | interrupts = <23 2>; | ||
185 | }; | 87 | }; |
186 | }; | 88 | tbi0: tbi-phy@11 { |
187 | 89 | reg = <0x11>; | |
188 | enet0: ethernet@24000 { | 90 | device_type = "tbi-phy"; |
189 | #address-cells = <1>; | ||
190 | #size-cells = <1>; | ||
191 | cell-index = <0>; | ||
192 | device_type = "network"; | ||
193 | model = "TSEC"; | ||
194 | compatible = "gianfar"; | ||
195 | reg = <0x24000 0x1000>; | ||
196 | ranges = <0x0 0x24000 0x1000>; | ||
197 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
198 | interrupts = <29 2 30 2 34 2>; | ||
199 | interrupt-parent = <&mpic>; | ||
200 | tbi-handle = <&tbi0>; | ||
201 | phy-handle = <&phy0>; | ||
202 | phy-connection-type = "rgmii-id"; | ||
203 | |||
204 | mdio@520 { | ||
205 | #address-cells = <1>; | ||
206 | #size-cells = <0>; | ||
207 | compatible = "fsl,gianfar-mdio"; | ||
208 | reg = <0x520 0x20>; | ||
209 | |||
210 | phy0: ethernet-phy@0 { | ||
211 | interrupt-parent = <&mpic>; | ||
212 | interrupts = <10 1>; | ||
213 | reg = <0>; | ||
214 | }; | ||
215 | phy1: ethernet-phy@1 { | ||
216 | interrupt-parent = <&mpic>; | ||
217 | interrupts = <10 1>; | ||
218 | reg = <1>; | ||
219 | }; | ||
220 | phy2: ethernet-phy@2 { | ||
221 | interrupt-parent = <&mpic>; | ||
222 | interrupts = <10 1>; | ||
223 | reg = <2>; | ||
224 | }; | ||
225 | phy3: ethernet-phy@3 { | ||
226 | interrupt-parent = <&mpic>; | ||
227 | interrupts = <10 1>; | ||
228 | reg = <3>; | ||
229 | }; | ||
230 | tbi0: tbi-phy@11 { | ||
231 | reg = <0x11>; | ||
232 | device_type = "tbi-phy"; | ||
233 | }; | ||
234 | }; | 91 | }; |
235 | }; | 92 | }; |
236 | 93 | ||
237 | enet1: ethernet@25000 { | 94 | enet1: ethernet@25000 { |
238 | #address-cells = <1>; | ||
239 | #size-cells = <1>; | ||
240 | cell-index = <1>; | ||
241 | device_type = "network"; | ||
242 | model = "TSEC"; | ||
243 | compatible = "gianfar"; | ||
244 | reg = <0x25000 0x1000>; | ||
245 | ranges = <0x0 0x25000 0x1000>; | ||
246 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
247 | interrupts = <35 2 36 2 40 2>; | ||
248 | interrupt-parent = <&mpic>; | ||
249 | tbi-handle = <&tbi1>; | 95 | tbi-handle = <&tbi1>; |
250 | phy-handle = <&phy1>; | 96 | phy-handle = <&phy1>; |
251 | phy-connection-type = "rgmii-id"; | 97 | phy-connection-type = "rgmii-id"; |
98 | }; | ||
252 | 99 | ||
253 | mdio@520 { | 100 | mdio@25520 { |
254 | #address-cells = <1>; | 101 | tbi1: tbi-phy@11 { |
255 | #size-cells = <0>; | 102 | reg = <0x11>; |
256 | compatible = "fsl,gianfar-tbi"; | 103 | device_type = "tbi-phy"; |
257 | reg = <0x520 0x20>; | ||
258 | |||
259 | tbi1: tbi-phy@11 { | ||
260 | reg = <0x11>; | ||
261 | device_type = "tbi-phy"; | ||
262 | }; | ||
263 | }; | 104 | }; |
264 | }; | 105 | }; |
265 | 106 | ||
266 | enet2: ethernet@26000 { | 107 | enet2: ethernet@26000 { |
267 | #address-cells = <1>; | ||
268 | #size-cells = <1>; | ||
269 | cell-index = <2>; | ||
270 | device_type = "network"; | ||
271 | model = "TSEC"; | ||
272 | compatible = "gianfar"; | ||
273 | reg = <0x26000 0x1000>; | ||
274 | ranges = <0x0 0x26000 0x1000>; | ||
275 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
276 | interrupts = <31 2 32 2 33 2>; | ||
277 | interrupt-parent = <&mpic>; | ||
278 | tbi-handle = <&tbi2>; | 108 | tbi-handle = <&tbi2>; |
279 | phy-handle = <&phy2>; | 109 | phy-handle = <&phy2>; |
280 | phy-connection-type = "rgmii-id"; | 110 | phy-connection-type = "rgmii-id"; |
111 | }; | ||
281 | 112 | ||
282 | mdio@520 { | 113 | mdio@26520 { |
283 | #address-cells = <1>; | 114 | tbi2: tbi-phy@11 { |
284 | #size-cells = <0>; | 115 | reg = <0x11>; |
285 | compatible = "fsl,gianfar-tbi"; | 116 | device_type = "tbi-phy"; |
286 | reg = <0x520 0x20>; | ||
287 | |||
288 | tbi2: tbi-phy@11 { | ||
289 | reg = <0x11>; | ||
290 | device_type = "tbi-phy"; | ||
291 | }; | ||
292 | }; | 117 | }; |
293 | }; | 118 | }; |
294 | 119 | ||
295 | enet3: ethernet@27000 { | 120 | enet3: ethernet@27000 { |
296 | #address-cells = <1>; | ||
297 | #size-cells = <1>; | ||
298 | cell-index = <3>; | ||
299 | device_type = "network"; | ||
300 | model = "TSEC"; | ||
301 | compatible = "gianfar"; | ||
302 | reg = <0x27000 0x1000>; | ||
303 | ranges = <0x0 0x27000 0x1000>; | ||
304 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
305 | interrupts = <37 2 38 2 39 2>; | ||
306 | interrupt-parent = <&mpic>; | ||
307 | tbi-handle = <&tbi3>; | 121 | tbi-handle = <&tbi3>; |
308 | phy-handle = <&phy3>; | 122 | phy-handle = <&phy3>; |
309 | phy-connection-type = "rgmii-id"; | 123 | phy-connection-type = "rgmii-id"; |
310 | |||
311 | mdio@520 { | ||
312 | #address-cells = <1>; | ||
313 | #size-cells = <0>; | ||
314 | compatible = "fsl,gianfar-tbi"; | ||
315 | reg = <0x520 0x20>; | ||
316 | |||
317 | tbi3: tbi-phy@11 { | ||
318 | reg = <0x11>; | ||
319 | device_type = "tbi-phy"; | ||
320 | }; | ||
321 | }; | ||
322 | }; | 124 | }; |
323 | 125 | ||
324 | serial0: serial@4500 { | 126 | mdio@27520 { |
325 | cell-index = <0>; | 127 | tbi3: tbi-phy@11 { |
326 | device_type = "serial"; | 128 | reg = <0x11>; |
327 | compatible = "fsl,ns16550", "ns16550"; | 129 | device_type = "tbi-phy"; |
328 | reg = <0x4500 0x100>; | 130 | }; |
329 | clock-frequency = <0>; | ||
330 | interrupts = <42 2>; | ||
331 | interrupt-parent = <&mpic>; | ||
332 | }; | ||
333 | |||
334 | serial1: serial@4600 { | ||
335 | cell-index = <1>; | ||
336 | device_type = "serial"; | ||
337 | compatible = "fsl,ns16550", "ns16550"; | ||
338 | reg = <0x4600 0x100>; | ||
339 | clock-frequency = <0>; | ||
340 | interrupts = <28 2>; | ||
341 | interrupt-parent = <&mpic>; | ||
342 | }; | ||
343 | |||
344 | mpic: pic@40000 { | ||
345 | interrupt-controller; | ||
346 | #address-cells = <0>; | ||
347 | #interrupt-cells = <2>; | ||
348 | reg = <0x40000 0x40000>; | ||
349 | compatible = "chrp,open-pic"; | ||
350 | device_type = "open-pic"; | ||
351 | }; | 131 | }; |
352 | 132 | ||
353 | rmu: rmu@d3000 { | 133 | rmu: rmu@d3000 { |
@@ -361,50 +141,35 @@ | |||
361 | compatible = "fsl,srio-msg-unit"; | 141 | compatible = "fsl,srio-msg-unit"; |
362 | reg = <0x0 0x100>; | 142 | reg = <0x0 0x100>; |
363 | interrupts = < | 143 | interrupts = < |
364 | 53 2 /* msg1_tx_irq */ | 144 | 53 2 0 0 /* msg1_tx_irq */ |
365 | 54 2>;/* msg1_rx_irq */ | 145 | 54 2 0 0>;/* msg1_rx_irq */ |
366 | }; | 146 | }; |
367 | message-unit@100 { | 147 | message-unit@100 { |
368 | compatible = "fsl,srio-msg-unit"; | 148 | compatible = "fsl,srio-msg-unit"; |
369 | reg = <0x100 0x100>; | 149 | reg = <0x100 0x100>; |
370 | interrupts = < | 150 | interrupts = < |
371 | 55 2 /* msg2_tx_irq */ | 151 | 55 2 0 0 /* msg2_tx_irq */ |
372 | 56 2>;/* msg2_rx_irq */ | 152 | 56 2 0 0>;/* msg2_rx_irq */ |
373 | }; | 153 | }; |
374 | doorbell-unit@400 { | 154 | doorbell-unit@400 { |
375 | compatible = "fsl,srio-dbell-unit"; | 155 | compatible = "fsl,srio-dbell-unit"; |
376 | reg = <0x400 0x80>; | 156 | reg = <0x400 0x80>; |
377 | interrupts = < | 157 | interrupts = < |
378 | 49 2 /* bell_outb_irq */ | 158 | 49 2 0 0 /* bell_outb_irq */ |
379 | 50 2>;/* bell_inb_irq */ | 159 | 50 2 0 0>;/* bell_inb_irq */ |
380 | }; | 160 | }; |
381 | port-write-unit@4e0 { | 161 | port-write-unit@4e0 { |
382 | compatible = "fsl,srio-port-write-unit"; | 162 | compatible = "fsl,srio-port-write-unit"; |
383 | reg = <0x4e0 0x20>; | 163 | reg = <0x4e0 0x20>; |
384 | interrupts = <48 2>; | 164 | interrupts = <48 2 0 0>; |
385 | }; | 165 | }; |
386 | }; | 166 | }; |
387 | |||
388 | global-utilities@e0000 { | ||
389 | compatible = "fsl,mpc8641-guts"; | ||
390 | reg = <0xe0000 0x1000>; | ||
391 | fsl,has-rstcr; | ||
392 | }; | ||
393 | }; | 167 | }; |
394 | 168 | ||
395 | pci0: pcie@ffe08000 { | 169 | pci0: pcie@ffe08000 { |
396 | compatible = "fsl,mpc8641-pcie"; | ||
397 | device_type = "pci"; | ||
398 | #interrupt-cells = <1>; | ||
399 | #size-cells = <2>; | ||
400 | #address-cells = <3>; | ||
401 | reg = <0xffe08000 0x1000>; | 170 | reg = <0xffe08000 0x1000>; |
402 | bus-range = <0x0 0xff>; | ||
403 | ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000 | 171 | ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000 |
404 | 0x01000000 0x0 0x00000000 0xffc00000 0x0 0x00010000>; | 172 | 0x01000000 0x0 0x00000000 0xffc00000 0x0 0x00010000>; |
405 | clock-frequency = <33333333>; | ||
406 | interrupt-parent = <&mpic>; | ||
407 | interrupts = <24 2>; | ||
408 | interrupt-map-mask = <0xff00 0 0 7>; | 173 | interrupt-map-mask = <0xff00 0 0 7>; |
409 | interrupt-map = < | 174 | interrupt-map = < |
410 | /* IDSEL 0x11 func 0 - PCI slot 1 */ | 175 | /* IDSEL 0x11 func 0 - PCI slot 1 */ |
@@ -522,10 +287,6 @@ | |||
522 | >; | 287 | >; |
523 | 288 | ||
524 | pcie@0 { | 289 | pcie@0 { |
525 | reg = <0 0 0 0 0>; | ||
526 | #size-cells = <2>; | ||
527 | #address-cells = <3>; | ||
528 | device_type = "pci"; | ||
529 | ranges = <0x02000000 0x0 0x80000000 | 290 | ranges = <0x02000000 0x0 0x80000000 |
530 | 0x02000000 0x0 0x80000000 | 291 | 0x02000000 0x0 0x80000000 |
531 | 0x0 0x20000000 | 292 | 0x0 0x20000000 |
@@ -545,7 +306,6 @@ | |||
545 | 0x0 0x00010000>; | 306 | 0x0 0x00010000>; |
546 | isa@1e { | 307 | isa@1e { |
547 | device_type = "isa"; | 308 | device_type = "isa"; |
548 | #interrupt-cells = <2>; | ||
549 | #size-cells = <1>; | 309 | #size-cells = <1>; |
550 | #address-cells = <2>; | 310 | #address-cells = <2>; |
551 | reg = <0xf000 0 0 0 0>; | 311 | reg = <0xf000 0 0 0 0>; |
@@ -562,8 +322,7 @@ | |||
562 | #address-cells = <0>; | 322 | #address-cells = <0>; |
563 | #interrupt-cells = <2>; | 323 | #interrupt-cells = <2>; |
564 | compatible = "chrp,iic"; | 324 | compatible = "chrp,iic"; |
565 | interrupts = <9 2>; | 325 | interrupts = <9 2 0 0>; |
566 | interrupt-parent = <&mpic>; | ||
567 | }; | 326 | }; |
568 | 327 | ||
569 | i8042@60 { | 328 | i8042@60 { |
@@ -571,8 +330,7 @@ | |||
571 | #address-cells = <1>; | 330 | #address-cells = <1>; |
572 | reg = <1 0x60 1 1 0x64 1>; | 331 | reg = <1 0x60 1 1 0x64 1>; |
573 | interrupts = <1 3 12 3>; | 332 | interrupts = <1 3 12 3>; |
574 | interrupt-parent = | 333 | interrupt-parent = <&i8259>; |
575 | <&i8259>; | ||
576 | 334 | ||
577 | keyboard@0 { | 335 | keyboard@0 { |
578 | reg = <0>; | 336 | reg = <0>; |
@@ -603,16 +361,14 @@ | |||
603 | pci1: pcie@ffe09000 { | 361 | pci1: pcie@ffe09000 { |
604 | compatible = "fsl,mpc8641-pcie"; | 362 | compatible = "fsl,mpc8641-pcie"; |
605 | device_type = "pci"; | 363 | device_type = "pci"; |
606 | #interrupt-cells = <1>; | ||
607 | #size-cells = <2>; | 364 | #size-cells = <2>; |
608 | #address-cells = <3>; | 365 | #address-cells = <3>; |
609 | reg = <0xffe09000 0x1000>; | 366 | reg = <0xffe09000 0x1000>; |
610 | bus-range = <0 0xff>; | 367 | bus-range = <0 0xff>; |
611 | ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000 | 368 | ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000 |
612 | 0x01000000 0x0 0x00000000 0xffc10000 0x0 0x00010000>; | 369 | 0x01000000 0x0 0x00000000 0xffc10000 0x0 0x00010000>; |
613 | clock-frequency = <33333333>; | 370 | clock-frequency = <100000000>; |
614 | interrupt-parent = <&mpic>; | 371 | interrupts = <25 2 0 0>; |
615 | interrupts = <25 2>; | ||
616 | interrupt-map-mask = <0xf800 0 0 7>; | 372 | interrupt-map-mask = <0xf800 0 0 7>; |
617 | interrupt-map = < | 373 | interrupt-map = < |
618 | /* IDSEL 0x0 */ | 374 | /* IDSEL 0x0 */ |
@@ -644,8 +400,7 @@ | |||
644 | rapidio@ffec0000 { | 400 | rapidio@ffec0000 { |
645 | reg = <0xffec0000 0x11000>; | 401 | reg = <0xffec0000 0x11000>; |
646 | compatible = "fsl,srio"; | 402 | compatible = "fsl,srio"; |
647 | interrupt-parent = <&mpic>; | 403 | interrupts = <48 2 0 0>; |
648 | interrupts = <48 2>; | ||
649 | #address-cells = <2>; | 404 | #address-cells = <2>; |
650 | #size-cells = <2>; | 405 | #size-cells = <2>; |
651 | fsl,srio-rmu-handle = <&rmu>; | 406 | fsl,srio-rmu-handle = <&rmu>; |
@@ -661,3 +416,5 @@ | |||
661 | */ | 416 | */ |
662 | 417 | ||
663 | }; | 418 | }; |
419 | |||
420 | /include/ "mpc8641si-post.dtsi" | ||
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts b/arch/powerpc/boot/dts/fsl/mpc8641_hpcn_36b.dts index bb575e28042a..fec58671a6d6 100644 --- a/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts +++ b/arch/powerpc/boot/dts/fsl/mpc8641_hpcn_36b.dts | |||
@@ -9,7 +9,7 @@ | |||
9 | * option) any later version. | 9 | * option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | /dts-v1/; | 12 | /include/ "mpc8641si-pre.dtsi" |
13 | 13 | ||
14 | / { | 14 | / { |
15 | model = "MPC8641HPCN"; | 15 | model = "MPC8641HPCN"; |
@@ -18,56 +18,16 @@ | |||
18 | #size-cells = <2>; | 18 | #size-cells = <2>; |
19 | 19 | ||
20 | aliases { | 20 | aliases { |
21 | ethernet0 = &enet0; | ||
22 | ethernet1 = &enet1; | ||
23 | ethernet2 = &enet2; | ||
24 | ethernet3 = &enet3; | ||
25 | serial0 = &serial0; | ||
26 | serial1 = &serial1; | ||
27 | pci0 = &pci0; | ||
28 | pci1 = &pci1; | 21 | pci1 = &pci1; |
29 | }; | 22 | }; |
30 | 23 | ||
31 | cpus { | ||
32 | #address-cells = <1>; | ||
33 | #size-cells = <0>; | ||
34 | |||
35 | PowerPC,8641@0 { | ||
36 | device_type = "cpu"; | ||
37 | reg = <0>; | ||
38 | d-cache-line-size = <32>; // 32 bytes | ||
39 | i-cache-line-size = <32>; // 32 bytes | ||
40 | d-cache-size = <32768>; // L1, 32K | ||
41 | i-cache-size = <32768>; // L1, 32K | ||
42 | timebase-frequency = <0>; // 33 MHz, from uboot | ||
43 | bus-frequency = <0>; // From uboot | ||
44 | clock-frequency = <0>; // From uboot | ||
45 | }; | ||
46 | PowerPC,8641@1 { | ||
47 | device_type = "cpu"; | ||
48 | reg = <1>; | ||
49 | d-cache-line-size = <32>; // 32 bytes | ||
50 | i-cache-line-size = <32>; // 32 bytes | ||
51 | d-cache-size = <32768>; // L1, 32K | ||
52 | i-cache-size = <32768>; // L1, 32K | ||
53 | timebase-frequency = <0>; // 33 MHz, from uboot | ||
54 | bus-frequency = <0>; // From uboot | ||
55 | clock-frequency = <0>; // From uboot | ||
56 | }; | ||
57 | }; | ||
58 | |||
59 | memory { | 24 | memory { |
60 | device_type = "memory"; | 25 | device_type = "memory"; |
61 | reg = <0x0 0x00000000 0x0 0x40000000>; // 1G at 0x0 | 26 | reg = <0x0 0x00000000 0x0 0x40000000>; // 1G at 0x0 |
62 | }; | 27 | }; |
63 | 28 | ||
64 | localbus@fffe05000 { | 29 | lbc: localbus@fffe05000 { |
65 | #address-cells = <2>; | ||
66 | #size-cells = <1>; | ||
67 | compatible = "fsl,mpc8641-localbus", "simple-bus"; | ||
68 | reg = <0x0f 0xffe05000 0x0 0x1000>; | 30 | reg = <0x0f 0xffe05000 0x0 0x1000>; |
69 | interrupts = <19 2>; | ||
70 | interrupt-parent = <&mpic>; | ||
71 | 31 | ||
72 | ranges = <0 0 0xf 0xef800000 0x00800000 | 32 | ranges = <0 0 0xf 0xef800000 0x00800000 |
73 | 2 0 0xf 0xffdf8000 0x00008000 | 33 | 2 0 0xf 0xffdf8000 0x00008000 |
@@ -101,276 +61,82 @@ | |||
101 | }; | 61 | }; |
102 | }; | 62 | }; |
103 | 63 | ||
104 | soc8641@fffe00000 { | 64 | soc: soc8641@fffe00000 { |
105 | #address-cells = <1>; | ||
106 | #size-cells = <1>; | ||
107 | device_type = "soc"; | ||
108 | compatible = "simple-bus"; | ||
109 | ranges = <0x00000000 0x0f 0xffe00000 0x00100000>; | 65 | ranges = <0x00000000 0x0f 0xffe00000 0x00100000>; |
110 | bus-frequency = <0>; | ||
111 | 66 | ||
112 | mcm-law@0 { | 67 | enet0: ethernet@24000 { |
113 | compatible = "fsl,mcm-law"; | 68 | tbi-handle = <&tbi0>; |
114 | reg = <0x0 0x1000>; | 69 | phy-handle = <&phy0>; |
115 | fsl,num-laws = <10>; | 70 | phy-connection-type = "rgmii-id"; |
116 | }; | ||
117 | |||
118 | mcm@1000 { | ||
119 | compatible = "fsl,mpc8641-mcm", "fsl,mcm"; | ||
120 | reg = <0x1000 0x1000>; | ||
121 | interrupts = <17 2>; | ||
122 | interrupt-parent = <&mpic>; | ||
123 | }; | ||
124 | |||
125 | i2c@3000 { | ||
126 | #address-cells = <1>; | ||
127 | #size-cells = <0>; | ||
128 | cell-index = <0>; | ||
129 | compatible = "fsl-i2c"; | ||
130 | reg = <0x3000 0x100>; | ||
131 | interrupts = <43 2>; | ||
132 | interrupt-parent = <&mpic>; | ||
133 | dfsrr; | ||
134 | }; | ||
135 | |||
136 | i2c@3100 { | ||
137 | #address-cells = <1>; | ||
138 | #size-cells = <0>; | ||
139 | cell-index = <1>; | ||
140 | compatible = "fsl-i2c"; | ||
141 | reg = <0x3100 0x100>; | ||
142 | interrupts = <43 2>; | ||
143 | interrupt-parent = <&mpic>; | ||
144 | dfsrr; | ||
145 | }; | 71 | }; |
146 | 72 | ||
147 | dma@21300 { | 73 | mdio@24520 { |
148 | #address-cells = <1>; | 74 | phy0: ethernet-phy@0 { |
149 | #size-cells = <1>; | 75 | interrupts = <10 1 0 0>; |
150 | compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; | 76 | reg = <0>; |
151 | reg = <0x21300 0x4>; | ||
152 | ranges = <0x0 0x21100 0x200>; | ||
153 | cell-index = <0>; | ||
154 | dma-channel@0 { | ||
155 | compatible = "fsl,mpc8641-dma-channel", | ||
156 | "fsl,eloplus-dma-channel"; | ||
157 | reg = <0x0 0x80>; | ||
158 | cell-index = <0>; | ||
159 | interrupt-parent = <&mpic>; | ||
160 | interrupts = <20 2>; | ||
161 | }; | 77 | }; |
162 | dma-channel@80 { | 78 | phy1: ethernet-phy@1 { |
163 | compatible = "fsl,mpc8641-dma-channel", | 79 | interrupts = <10 1 0 0>; |
164 | "fsl,eloplus-dma-channel"; | 80 | reg = <1>; |
165 | reg = <0x80 0x80>; | ||
166 | cell-index = <1>; | ||
167 | interrupt-parent = <&mpic>; | ||
168 | interrupts = <21 2>; | ||
169 | }; | 81 | }; |
170 | dma-channel@100 { | 82 | phy2: ethernet-phy@2 { |
171 | compatible = "fsl,mpc8641-dma-channel", | 83 | interrupts = <10 1 0 0>; |
172 | "fsl,eloplus-dma-channel"; | 84 | reg = <2>; |
173 | reg = <0x100 0x80>; | ||
174 | cell-index = <2>; | ||
175 | interrupt-parent = <&mpic>; | ||
176 | interrupts = <22 2>; | ||
177 | }; | 85 | }; |
178 | dma-channel@180 { | 86 | phy3: ethernet-phy@3 { |
179 | compatible = "fsl,mpc8641-dma-channel", | 87 | interrupts = <10 1 0 0>; |
180 | "fsl,eloplus-dma-channel"; | 88 | reg = <3>; |
181 | reg = <0x180 0x80>; | ||
182 | cell-index = <3>; | ||
183 | interrupt-parent = <&mpic>; | ||
184 | interrupts = <23 2>; | ||
185 | }; | 89 | }; |
186 | }; | 90 | tbi0: tbi-phy@11 { |
187 | 91 | reg = <0x11>; | |
188 | enet0: ethernet@24000 { | 92 | device_type = "tbi-phy"; |
189 | #address-cells = <1>; | ||
190 | #size-cells = <1>; | ||
191 | cell-index = <0>; | ||
192 | device_type = "network"; | ||
193 | model = "TSEC"; | ||
194 | compatible = "gianfar"; | ||
195 | reg = <0x24000 0x1000>; | ||
196 | ranges = <0x0 0x24000 0x1000>; | ||
197 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
198 | interrupts = <29 2 30 2 34 2>; | ||
199 | interrupt-parent = <&mpic>; | ||
200 | tbi-handle = <&tbi0>; | ||
201 | phy-handle = <&phy0>; | ||
202 | phy-connection-type = "rgmii-id"; | ||
203 | |||
204 | mdio@520 { | ||
205 | #address-cells = <1>; | ||
206 | #size-cells = <0>; | ||
207 | compatible = "fsl,gianfar-mdio"; | ||
208 | reg = <0x520 0x20>; | ||
209 | |||
210 | phy0: ethernet-phy@0 { | ||
211 | interrupt-parent = <&mpic>; | ||
212 | interrupts = <10 1>; | ||
213 | reg = <0>; | ||
214 | }; | ||
215 | phy1: ethernet-phy@1 { | ||
216 | interrupt-parent = <&mpic>; | ||
217 | interrupts = <10 1>; | ||
218 | reg = <1>; | ||
219 | }; | ||
220 | phy2: ethernet-phy@2 { | ||
221 | interrupt-parent = <&mpic>; | ||
222 | interrupts = <10 1>; | ||
223 | reg = <2>; | ||
224 | }; | ||
225 | phy3: ethernet-phy@3 { | ||
226 | interrupt-parent = <&mpic>; | ||
227 | interrupts = <10 1>; | ||
228 | reg = <3>; | ||
229 | }; | ||
230 | tbi0: tbi-phy@11 { | ||
231 | reg = <0x11>; | ||
232 | device_type = "tbi-phy"; | ||
233 | }; | ||
234 | }; | 93 | }; |
235 | }; | 94 | }; |
236 | 95 | ||
237 | enet1: ethernet@25000 { | 96 | enet1: ethernet@25000 { |
238 | #address-cells = <1>; | ||
239 | #size-cells = <1>; | ||
240 | cell-index = <1>; | ||
241 | device_type = "network"; | ||
242 | model = "TSEC"; | ||
243 | compatible = "gianfar"; | ||
244 | reg = <0x25000 0x1000>; | ||
245 | ranges = <0x0 0x25000 0x1000>; | ||
246 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
247 | interrupts = <35 2 36 2 40 2>; | ||
248 | interrupt-parent = <&mpic>; | ||
249 | tbi-handle = <&tbi1>; | 97 | tbi-handle = <&tbi1>; |
250 | phy-handle = <&phy1>; | 98 | phy-handle = <&phy1>; |
251 | phy-connection-type = "rgmii-id"; | 99 | phy-connection-type = "rgmii-id"; |
100 | }; | ||
252 | 101 | ||
253 | mdio@520 { | 102 | mdio@25520 { |
254 | #address-cells = <1>; | 103 | tbi1: tbi-phy@11 { |
255 | #size-cells = <0>; | 104 | reg = <0x11>; |
256 | compatible = "fsl,gianfar-tbi"; | 105 | device_type = "tbi-phy"; |
257 | reg = <0x520 0x20>; | ||
258 | |||
259 | tbi1: tbi-phy@11 { | ||
260 | reg = <0x11>; | ||
261 | device_type = "tbi-phy"; | ||
262 | }; | ||
263 | }; | 106 | }; |
264 | }; | 107 | }; |
265 | 108 | ||
266 | enet2: ethernet@26000 { | 109 | enet2: ethernet@26000 { |
267 | #address-cells = <1>; | ||
268 | #size-cells = <1>; | ||
269 | cell-index = <2>; | ||
270 | device_type = "network"; | ||
271 | model = "TSEC"; | ||
272 | compatible = "gianfar"; | ||
273 | reg = <0x26000 0x1000>; | ||
274 | ranges = <0x0 0x26000 0x1000>; | ||
275 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
276 | interrupts = <31 2 32 2 33 2>; | ||
277 | interrupt-parent = <&mpic>; | ||
278 | tbi-handle = <&tbi2>; | 110 | tbi-handle = <&tbi2>; |
279 | phy-handle = <&phy2>; | 111 | phy-handle = <&phy2>; |
280 | phy-connection-type = "rgmii-id"; | 112 | phy-connection-type = "rgmii-id"; |
113 | }; | ||
281 | 114 | ||
282 | mdio@520 { | 115 | mdio@26520 { |
283 | #address-cells = <1>; | 116 | tbi2: tbi-phy@11 { |
284 | #size-cells = <0>; | 117 | reg = <0x11>; |
285 | compatible = "fsl,gianfar-tbi"; | 118 | device_type = "tbi-phy"; |
286 | reg = <0x520 0x20>; | ||
287 | |||
288 | tbi2: tbi-phy@11 { | ||
289 | reg = <0x11>; | ||
290 | device_type = "tbi-phy"; | ||
291 | }; | ||
292 | }; | 119 | }; |
293 | }; | 120 | }; |
294 | 121 | ||
295 | enet3: ethernet@27000 { | 122 | enet3: ethernet@27000 { |
296 | #address-cells = <1>; | ||
297 | #size-cells = <1>; | ||
298 | cell-index = <3>; | ||
299 | device_type = "network"; | ||
300 | model = "TSEC"; | ||
301 | compatible = "gianfar"; | ||
302 | reg = <0x27000 0x1000>; | ||
303 | ranges = <0x0 0x27000 0x1000>; | ||
304 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
305 | interrupts = <37 2 38 2 39 2>; | ||
306 | interrupt-parent = <&mpic>; | ||
307 | tbi-handle = <&tbi3>; | 123 | tbi-handle = <&tbi3>; |
308 | phy-handle = <&phy3>; | 124 | phy-handle = <&phy3>; |
309 | phy-connection-type = "rgmii-id"; | 125 | phy-connection-type = "rgmii-id"; |
310 | |||
311 | mdio@520 { | ||
312 | #address-cells = <1>; | ||
313 | #size-cells = <0>; | ||
314 | compatible = "fsl,gianfar-tbi"; | ||
315 | reg = <0x520 0x20>; | ||
316 | |||
317 | tbi3: tbi-phy@11 { | ||
318 | reg = <0x11>; | ||
319 | device_type = "tbi-phy"; | ||
320 | }; | ||
321 | }; | ||
322 | }; | 126 | }; |
323 | 127 | ||
324 | serial0: serial@4500 { | 128 | mdio@27520 { |
325 | cell-index = <0>; | 129 | tbi3: tbi-phy@11 { |
326 | device_type = "serial"; | 130 | reg = <0x11>; |
327 | compatible = "fsl,ns16550", "ns16550"; | 131 | device_type = "tbi-phy"; |
328 | reg = <0x4500 0x100>; | 132 | }; |
329 | clock-frequency = <0>; | ||
330 | interrupts = <42 2>; | ||
331 | interrupt-parent = <&mpic>; | ||
332 | }; | ||
333 | |||
334 | serial1: serial@4600 { | ||
335 | cell-index = <1>; | ||
336 | device_type = "serial"; | ||
337 | compatible = "fsl,ns16550", "ns16550"; | ||
338 | reg = <0x4600 0x100>; | ||
339 | clock-frequency = <0>; | ||
340 | interrupts = <28 2>; | ||
341 | interrupt-parent = <&mpic>; | ||
342 | }; | ||
343 | |||
344 | mpic: pic@40000 { | ||
345 | interrupt-controller; | ||
346 | #address-cells = <0>; | ||
347 | #interrupt-cells = <2>; | ||
348 | reg = <0x40000 0x40000>; | ||
349 | compatible = "chrp,open-pic"; | ||
350 | device_type = "open-pic"; | ||
351 | }; | ||
352 | |||
353 | global-utilities@e0000 { | ||
354 | compatible = "fsl,mpc8641-guts"; | ||
355 | reg = <0xe0000 0x1000>; | ||
356 | fsl,has-rstcr; | ||
357 | }; | 133 | }; |
358 | }; | 134 | }; |
359 | 135 | ||
360 | pci0: pcie@fffe08000 { | 136 | pci0: pcie@fffe08000 { |
361 | cell-index = <0>; | ||
362 | compatible = "fsl,mpc8641-pcie"; | ||
363 | device_type = "pci"; | ||
364 | #interrupt-cells = <1>; | ||
365 | #size-cells = <2>; | ||
366 | #address-cells = <3>; | ||
367 | reg = <0x0f 0xffe08000 0x0 0x1000>; | 137 | reg = <0x0f 0xffe08000 0x0 0x1000>; |
368 | bus-range = <0x0 0xff>; | ||
369 | ranges = <0x02000000 0x0 0xe0000000 0x0c 0x00000000 0x0 0x20000000 | 138 | ranges = <0x02000000 0x0 0xe0000000 0x0c 0x00000000 0x0 0x20000000 |
370 | 0x01000000 0x0 0x00000000 0x0f 0xffc00000 0x0 0x00010000>; | 139 | 0x01000000 0x0 0x00000000 0x0f 0xffc00000 0x0 0x00010000>; |
371 | clock-frequency = <33333333>; | ||
372 | interrupt-parent = <&mpic>; | ||
373 | interrupts = <24 2>; | ||
374 | interrupt-map-mask = <0xff00 0 0 7>; | 140 | interrupt-map-mask = <0xff00 0 0 7>; |
375 | interrupt-map = < | 141 | interrupt-map = < |
376 | /* IDSEL 0x11 func 0 - PCI slot 1 */ | 142 | /* IDSEL 0x11 func 0 - PCI slot 1 */ |
@@ -488,10 +254,6 @@ | |||
488 | >; | 254 | >; |
489 | 255 | ||
490 | pcie@0 { | 256 | pcie@0 { |
491 | reg = <0 0 0 0 0>; | ||
492 | #size-cells = <2>; | ||
493 | #address-cells = <3>; | ||
494 | device_type = "pci"; | ||
495 | ranges = <0x02000000 0x0 0xe0000000 | 257 | ranges = <0x02000000 0x0 0xe0000000 |
496 | 0x02000000 0x0 0xe0000000 | 258 | 0x02000000 0x0 0xe0000000 |
497 | 0x0 0x20000000 | 259 | 0x0 0x20000000 |
@@ -511,7 +273,6 @@ | |||
511 | 0x0 0x00010000>; | 273 | 0x0 0x00010000>; |
512 | isa@1e { | 274 | isa@1e { |
513 | device_type = "isa"; | 275 | device_type = "isa"; |
514 | #interrupt-cells = <2>; | ||
515 | #size-cells = <1>; | 276 | #size-cells = <1>; |
516 | #address-cells = <2>; | 277 | #address-cells = <2>; |
517 | reg = <0xf000 0 0 0 0>; | 278 | reg = <0xf000 0 0 0 0>; |
@@ -528,8 +289,7 @@ | |||
528 | #address-cells = <0>; | 289 | #address-cells = <0>; |
529 | #interrupt-cells = <2>; | 290 | #interrupt-cells = <2>; |
530 | compatible = "chrp,iic"; | 291 | compatible = "chrp,iic"; |
531 | interrupts = <9 2>; | 292 | interrupts = <9 2 0 0>; |
532 | interrupt-parent = <&mpic>; | ||
533 | }; | 293 | }; |
534 | 294 | ||
535 | i8042@60 { | 295 | i8042@60 { |
@@ -537,8 +297,7 @@ | |||
537 | #address-cells = <1>; | 297 | #address-cells = <1>; |
538 | reg = <1 0x60 1 1 0x64 1>; | 298 | reg = <1 0x60 1 1 0x64 1>; |
539 | interrupts = <1 3 12 3>; | 299 | interrupts = <1 3 12 3>; |
540 | interrupt-parent = | 300 | interrupt-parent = <&i8259>; |
541 | <&i8259>; | ||
542 | 301 | ||
543 | keyboard@0 { | 302 | keyboard@0 { |
544 | reg = <0>; | 303 | reg = <0>; |
@@ -567,19 +326,16 @@ | |||
567 | }; | 326 | }; |
568 | 327 | ||
569 | pci1: pcie@fffe09000 { | 328 | pci1: pcie@fffe09000 { |
570 | cell-index = <1>; | ||
571 | compatible = "fsl,mpc8641-pcie"; | 329 | compatible = "fsl,mpc8641-pcie"; |
572 | device_type = "pci"; | 330 | device_type = "pci"; |
573 | #interrupt-cells = <1>; | ||
574 | #size-cells = <2>; | 331 | #size-cells = <2>; |
575 | #address-cells = <3>; | 332 | #address-cells = <3>; |
576 | reg = <0x0f 0xffe09000 0x0 0x1000>; | 333 | reg = <0x0f 0xffe09000 0x0 0x1000>; |
577 | bus-range = <0x0 0xff>; | 334 | bus-range = <0x0 0xff>; |
578 | ranges = <0x02000000 0x0 0xe0000000 0x0c 0x20000000 0x0 0x20000000 | 335 | ranges = <0x02000000 0x0 0xe0000000 0x0c 0x20000000 0x0 0x20000000 |
579 | 0x01000000 0x0 0x00000000 0x0f 0xffc10000 0x0 0x00010000>; | 336 | 0x01000000 0x0 0x00000000 0x0f 0xffc10000 0x0 0x00010000>; |
580 | clock-frequency = <33333333>; | 337 | clock-frequency = <100000000>; |
581 | interrupt-parent = <&mpic>; | 338 | interrupts = <25 2 0 0>; |
582 | interrupts = <25 2>; | ||
583 | interrupt-map-mask = <0xf800 0 0 7>; | 339 | interrupt-map-mask = <0xf800 0 0 7>; |
584 | interrupt-map = < | 340 | interrupt-map = < |
585 | /* IDSEL 0x0 */ | 341 | /* IDSEL 0x0 */ |
@@ -603,3 +359,5 @@ | |||
603 | }; | 359 | }; |
604 | }; | 360 | }; |
605 | }; | 361 | }; |
362 | |||
363 | /include/ "mpc8641si-post.dtsi" | ||
diff --git a/arch/powerpc/boot/dts/fsl/mpc8641si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8641si-post.dtsi new file mode 100644 index 000000000000..70889d8e8850 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/mpc8641si-post.dtsi | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | * MPC8641 Silicon/SoC Device Tree Source (post include) | ||
3 | * | ||
4 | * Copyright 2016 Elettra-Sincrotrone Trieste S.C.p.A. | ||
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 | &lbc { | ||
14 | #address-cells = <2>; | ||
15 | #size-cells = <1>; | ||
16 | compatible = "fsl,mpc8641-localbus", "simple-bus"; | ||
17 | interrupts = <19 2 0 0>; | ||
18 | }; | ||
19 | |||
20 | &soc { | ||
21 | #address-cells = <1>; | ||
22 | #size-cells = <1>; | ||
23 | device_type = "soc"; | ||
24 | compatible = "fsl,mpc8641-soc", "simple-bus"; | ||
25 | bus-frequency = <0>; | ||
26 | |||
27 | mcm-law@0 { | ||
28 | compatible = "fsl,mcm-law"; | ||
29 | reg = <0x0 0x1000>; | ||
30 | fsl,num-laws = <10>; | ||
31 | }; | ||
32 | |||
33 | mcm@1000 { | ||
34 | compatible = "fsl,mpc8641-mcm", "fsl,mcm"; | ||
35 | reg = <0x1000 0x1000>; | ||
36 | interrupts = <17 2 0 0>; | ||
37 | }; | ||
38 | |||
39 | /include/ "pq3-i2c-0.dtsi" | ||
40 | /include/ "pq3-i2c-1.dtsi" | ||
41 | /include/ "pq3-duart-0.dtsi" | ||
42 | serial@4600 { | ||
43 | interrupts = <28 2 0 0>; | ||
44 | }; | ||
45 | /include/ "pq3-dma-0.dtsi" | ||
46 | dma@21300 { | ||
47 | compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; | ||
48 | }; | ||
49 | dma-channel@0 { | ||
50 | compatible = "fsl,mpc8641-dma-channel", "fsl,eloplus-dma-channel"; | ||
51 | }; | ||
52 | dma-channel@80 { | ||
53 | compatible = "fsl,mpc8641-dma-channel", "fsl,eloplus-dma-channel"; | ||
54 | }; | ||
55 | dma-channel@100 { | ||
56 | compatible = "fsl,mpc8641-dma-channel", "fsl,eloplus-dma-channel"; | ||
57 | }; | ||
58 | dma-channel@180 { | ||
59 | compatible = "fsl,mpc8641-dma-channel", "fsl,eloplus-dma-channel"; | ||
60 | }; | ||
61 | |||
62 | /include/ "pq3-etsec1-0.dtsi" | ||
63 | ethernet@24000 { | ||
64 | model = "TSEC"; | ||
65 | }; | ||
66 | /include/ "pq3-etsec1-1.dtsi" | ||
67 | ethernet@25000 { | ||
68 | model = "TSEC"; | ||
69 | }; | ||
70 | /include/ "pq3-etsec1-2.dtsi" | ||
71 | ethernet@26000 { | ||
72 | model = "TSEC"; | ||
73 | }; | ||
74 | /include/ "pq3-etsec1-3.dtsi" | ||
75 | ethernet@27000 { | ||
76 | model = "TSEC"; | ||
77 | }; | ||
78 | |||
79 | /include/ "qoriq-mpic.dtsi" | ||
80 | msi@41600 { | ||
81 | compatible = "fsl,mpc8641-msi", "fsl,mpic-msi"; | ||
82 | }; | ||
83 | msi@41800 { | ||
84 | compatible = "fsl,mpc8641-msi", "fsl,mpic-msi"; | ||
85 | }; | ||
86 | msi@41a00 { | ||
87 | compatible = "fsl,mpc8641-msi", "fsl,mpic-msi"; | ||
88 | }; | ||
89 | |||
90 | global-utilities@e0000 { | ||
91 | compatible = "fsl,mpc8641-guts"; | ||
92 | reg = <0xe0000 0x1000>; | ||
93 | fsl,has-rstcr; | ||
94 | }; | ||
95 | }; | ||
96 | |||
97 | &pci0 { | ||
98 | compatible = "fsl,mpc8641-pcie"; | ||
99 | device_type = "pci"; | ||
100 | #size-cells = <2>; | ||
101 | #address-cells = <3>; | ||
102 | bus-range = <0x0 0xff>; | ||
103 | clock-frequency = <100000000>; | ||
104 | interrupts = <24 2 0 0>; | ||
105 | interrupt-map-mask = <0xf800 0x0 0x0 0x7>; | ||
106 | |||
107 | interrupt-map = < | ||
108 | 0x0000 0x0 0x0 0x1 &mpic 0x0 0x1 | ||
109 | 0x0000 0x0 0x0 0x2 &mpic 0x1 0x1 | ||
110 | 0x0000 0x0 0x0 0x3 &mpic 0x2 0x1 | ||
111 | 0x0000 0x0 0x0 0x4 &mpic 0x3 0x1 | ||
112 | >; | ||
113 | |||
114 | pcie@0 { | ||
115 | reg = <0 0 0 0 0>; | ||
116 | #size-cells = <2>; | ||
117 | #address-cells = <3>; | ||
118 | device_type = "pci"; | ||
119 | }; | ||
120 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/mpc8641si-pre.dtsi b/arch/powerpc/boot/dts/fsl/mpc8641si-pre.dtsi new file mode 100644 index 000000000000..9e03328561d3 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/mpc8641si-pre.dtsi | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * MPC8641 Silicon/SoC Device Tree Source (pre include) | ||
3 | * | ||
4 | * Copyright 2016 Elettra-Sincrotrone Trieste S.C.p.A. | ||
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 | /dts-v1/; | ||
14 | |||
15 | / { | ||
16 | #address-cells = <1>; | ||
17 | #size-cells = <1>; | ||
18 | interrupt-parent = <&mpic>; | ||
19 | |||
20 | aliases { | ||
21 | ethernet0 = &enet0; | ||
22 | ethernet1 = &enet1; | ||
23 | ethernet2 = &enet2; | ||
24 | ethernet3 = &enet3; | ||
25 | serial0 = &serial0; | ||
26 | serial1 = &serial1; | ||
27 | pci0 = &pci0; | ||
28 | }; | ||
29 | |||
30 | cpus { | ||
31 | #address-cells = <1>; | ||
32 | #size-cells = <0>; | ||
33 | |||
34 | PowerPC,8641@0 { | ||
35 | device_type = "cpu"; | ||
36 | reg = <0>; | ||
37 | d-cache-line-size = <32>; | ||
38 | i-cache-line-size = <32>; | ||
39 | d-cache-size = <32768>; | ||
40 | i-cache-size = <32768>; | ||
41 | timebase-frequency = <0>; | ||
42 | bus-frequency = <0>; | ||
43 | clock-frequency = <0>; | ||
44 | }; | ||
45 | |||
46 | PowerPC,8641@1 { | ||
47 | device_type = "cpu"; | ||
48 | reg = <1>; | ||
49 | d-cache-line-size = <32>; | ||
50 | i-cache-line-size = <32>; | ||
51 | d-cache-size = <32768>; | ||
52 | i-cache-size = <32768>; | ||
53 | timebase-frequency = <0>; | ||
54 | bus-frequency = <0>; | ||
55 | clock-frequency = <0>; | ||
56 | }; | ||
57 | }; | ||
58 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/mvme2500.dts b/arch/powerpc/boot/dts/fsl/mvme2500.dts index c7bc1a0c7194..69559e970e99 100644 --- a/arch/powerpc/boot/dts/fsl/mvme2500.dts +++ b/arch/powerpc/boot/dts/fsl/mvme2500.dts | |||
@@ -70,12 +70,12 @@ | |||
70 | fsl,espi-num-chipselects = <2>; | 70 | fsl,espi-num-chipselects = <2>; |
71 | 71 | ||
72 | flash@0 { | 72 | flash@0 { |
73 | compatible = "atmel,at25df641"; | 73 | compatible = "atmel,at25df641", "jedec,spi-nor"; |
74 | reg = <0>; | 74 | reg = <0>; |
75 | spi-max-frequency = <10000000>; | 75 | spi-max-frequency = <10000000>; |
76 | }; | 76 | }; |
77 | flash@1 { | 77 | flash@1 { |
78 | compatible = "atmel,at25df641"; | 78 | compatible = "atmel,at25df641", "jedec,spi-nor"; |
79 | reg = <1>; | 79 | reg = <1>; |
80 | spi-max-frequency = <10000000>; | 80 | spi-max-frequency = <10000000>; |
81 | }; | 81 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi index 14b629505038..a8e4ba070104 100644 --- a/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi | |||
@@ -110,7 +110,7 @@ | |||
110 | flash@0 { | 110 | flash@0 { |
111 | #address-cells = <1>; | 111 | #address-cells = <1>; |
112 | #size-cells = <1>; | 112 | #size-cells = <1>; |
113 | compatible = "spansion,s25sl12801"; | 113 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
114 | reg = <0>; | 114 | reg = <0>; |
115 | spi-max-frequency = <40000000>; | 115 | spi-max-frequency = <40000000>; |
116 | 116 | ||
diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi b/arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi index c952cd37cf6d..25f81eea60e0 100644 --- a/arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi | |||
@@ -151,7 +151,7 @@ | |||
151 | flash@0 { | 151 | flash@0 { |
152 | #address-cells = <1>; | 152 | #address-cells = <1>; |
153 | #size-cells = <1>; | 153 | #size-cells = <1>; |
154 | compatible = "spansion,s25sl12801"; | 154 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
155 | reg = <0>; | 155 | reg = <0>; |
156 | spi-max-frequency = <40000000>; /* input clock */ | 156 | spi-max-frequency = <40000000>; /* input clock */ |
157 | 157 | ||
diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts b/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts index 740553c090a3..f2dc6c09be52 100644 --- a/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts +++ b/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts | |||
@@ -155,7 +155,7 @@ | |||
155 | flash@0 { | 155 | flash@0 { |
156 | #address-cells = <1>; | 156 | #address-cells = <1>; |
157 | #size-cells = <1>; | 157 | #size-cells = <1>; |
158 | compatible = "spansion,s25sl12801"; | 158 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
159 | reg = <0>; | 159 | reg = <0>; |
160 | /* input clock */ | 160 | /* input clock */ |
161 | spi-max-frequency = <40000000>; | 161 | spi-max-frequency = <40000000>; |
diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1020rdb.dtsi index 1fb7e0e0940f..703142ee6627 100644 --- a/arch/powerpc/boot/dts/fsl/p1020rdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1020rdb.dtsi | |||
@@ -148,7 +148,7 @@ | |||
148 | flash@0 { | 148 | flash@0 { |
149 | #address-cells = <1>; | 149 | #address-cells = <1>; |
150 | #size-cells = <1>; | 150 | #size-cells = <1>; |
151 | compatible = "spansion,s25sl12801"; | 151 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
152 | reg = <0>; | 152 | reg = <0>; |
153 | spi-max-frequency = <40000000>; /* input clock */ | 153 | spi-max-frequency = <40000000>; /* input clock */ |
154 | 154 | ||
diff --git a/arch/powerpc/boot/dts/fsl/p1021mds.dts b/arch/powerpc/boot/dts/fsl/p1021mds.dts index 27fdfd7dc7c7..291454c75dda 100644 --- a/arch/powerpc/boot/dts/fsl/p1021mds.dts +++ b/arch/powerpc/boot/dts/fsl/p1021mds.dts | |||
@@ -123,7 +123,7 @@ | |||
123 | flash@0 { | 123 | flash@0 { |
124 | #address-cells = <1>; | 124 | #address-cells = <1>; |
125 | #size-cells = <1>; | 125 | #size-cells = <1>; |
126 | compatible = "spansion,s25sl12801"; | 126 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
127 | reg = <0>; | 127 | reg = <0>; |
128 | spi-max-frequency = <40000000>; /* input clock */ | 128 | spi-max-frequency = <40000000>; /* input clock */ |
129 | 129 | ||
diff --git a/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi b/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi index e8a0f95fb24a..18f9b31602d0 100644 --- a/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi | |||
@@ -150,7 +150,7 @@ | |||
150 | flash@0 { | 150 | flash@0 { |
151 | #address-cells = <1>; | 151 | #address-cells = <1>; |
152 | #size-cells = <1>; | 152 | #size-cells = <1>; |
153 | compatible = "spansion,s25sl12801"; | 153 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
154 | reg = <0>; | 154 | reg = <0>; |
155 | spi-max-frequency = <40000000>; /* input clock */ | 155 | spi-max-frequency = <40000000>; /* input clock */ |
156 | 156 | ||
diff --git a/arch/powerpc/boot/dts/fsl/p1022ds.dtsi b/arch/powerpc/boot/dts/fsl/p1022ds.dtsi index 149da0f123ee..ddefbf64f7f8 100644 --- a/arch/powerpc/boot/dts/fsl/p1022ds.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1022ds.dtsi | |||
@@ -160,7 +160,7 @@ | |||
160 | flash@0 { | 160 | flash@0 { |
161 | #address-cells = <1>; | 161 | #address-cells = <1>; |
162 | #size-cells = <1>; | 162 | #size-cells = <1>; |
163 | compatible = "spansion,s25sl12801"; | 163 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
164 | reg = <0>; | 164 | reg = <0>; |
165 | spi-max-frequency = <40000000>; /* input clock */ | 165 | spi-max-frequency = <40000000>; /* input clock */ |
166 | 166 | ||
diff --git a/arch/powerpc/boot/dts/fsl/p1022rdk.dts b/arch/powerpc/boot/dts/fsl/p1022rdk.dts index 04c16337268a..d505d7c51903 100644 --- a/arch/powerpc/boot/dts/fsl/p1022rdk.dts +++ b/arch/powerpc/boot/dts/fsl/p1022rdk.dts | |||
@@ -86,7 +86,7 @@ | |||
86 | flash@0 { | 86 | flash@0 { |
87 | #address-cells = <1>; | 87 | #address-cells = <1>; |
88 | #size-cells = <1>; | 88 | #size-cells = <1>; |
89 | compatible = "spansion,m25p80"; | 89 | compatible = "spansion,m25p80", "jedec,spi-nor"; |
90 | reg = <0>; | 90 | reg = <0>; |
91 | spi-max-frequency = <1000000>; | 91 | spi-max-frequency = <1000000>; |
92 | partition@0 { | 92 | partition@0 { |
diff --git a/arch/powerpc/boot/dts/fsl/p1024rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1024rdb.dtsi index b05dcb40f800..b4d05867f707 100644 --- a/arch/powerpc/boot/dts/fsl/p1024rdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1024rdb.dtsi | |||
@@ -129,7 +129,7 @@ | |||
129 | flash@0 { | 129 | flash@0 { |
130 | #address-cells = <1>; | 130 | #address-cells = <1>; |
131 | #size-cells = <1>; | 131 | #size-cells = <1>; |
132 | compatible = "spansion,m25p80"; | 132 | compatible = "spansion,m25p80", "jedec,spi-nor"; |
133 | reg = <0>; | 133 | reg = <0>; |
134 | spi-max-frequency = <40000000>; | 134 | spi-max-frequency = <40000000>; |
135 | 135 | ||
diff --git a/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi index f50256482297..d44bb12debb0 100644 --- a/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi | |||
@@ -137,7 +137,7 @@ | |||
137 | flash@0 { | 137 | flash@0 { |
138 | #address-cells = <1>; | 138 | #address-cells = <1>; |
139 | #size-cells = <1>; | 139 | #size-cells = <1>; |
140 | compatible = "spansion,s25sl12801"; | 140 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
141 | reg = <0>; | 141 | reg = <0>; |
142 | spi-max-frequency = <40000000>; /* input clock */ | 142 | spi-max-frequency = <40000000>; /* input clock */ |
143 | 143 | ||
diff --git a/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi b/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi index ad2e242365cc..03c9afc82436 100644 --- a/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi +++ b/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi | |||
@@ -151,7 +151,7 @@ | |||
151 | flash@0 { | 151 | flash@0 { |
152 | #address-cells = <1>; | 152 | #address-cells = <1>; |
153 | #size-cells = <1>; | 153 | #size-cells = <1>; |
154 | compatible = "spansion,m25p80"; | 154 | compatible = "spansion,m25p80", "jedec,spi-nor"; |
155 | reg = <0>; | 155 | reg = <0>; |
156 | spi-max-frequency = <40000000>; | 156 | spi-max-frequency = <40000000>; |
157 | 157 | ||
diff --git a/arch/powerpc/boot/dts/fsl/p2020rdb.dts b/arch/powerpc/boot/dts/fsl/p2020rdb.dts index 70cf09019ce5..435a319958cb 100644 --- a/arch/powerpc/boot/dts/fsl/p2020rdb.dts +++ b/arch/powerpc/boot/dts/fsl/p2020rdb.dts | |||
@@ -155,7 +155,7 @@ | |||
155 | flash@0 { | 155 | flash@0 { |
156 | #address-cells = <1>; | 156 | #address-cells = <1>; |
157 | #size-cells = <1>; | 157 | #size-cells = <1>; |
158 | compatible = "spansion,s25sl12801"; | 158 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
159 | reg = <0>; | 159 | reg = <0>; |
160 | spi-max-frequency = <40000000>; | 160 | spi-max-frequency = <40000000>; |
161 | 161 | ||
diff --git a/arch/powerpc/boot/dts/fsl/p2041rdb.dts b/arch/powerpc/boot/dts/fsl/p2041rdb.dts index e9bd89406c4c..e50fea95a853 100644 --- a/arch/powerpc/boot/dts/fsl/p2041rdb.dts +++ b/arch/powerpc/boot/dts/fsl/p2041rdb.dts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * P2041RDB Device Tree Source | 2 | * P2041RDB Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2011 - 2014 Freescale Semiconductor Inc. | 4 | * Copyright 2011 - 2015 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: |
@@ -41,6 +41,19 @@ | |||
41 | #size-cells = <2>; | 41 | #size-cells = <2>; |
42 | interrupt-parent = <&mpic>; | 42 | interrupt-parent = <&mpic>; |
43 | 43 | ||
44 | aliases { | ||
45 | phy_rgmii_0 = &phy_rgmii_0; | ||
46 | phy_rgmii_1 = &phy_rgmii_1; | ||
47 | phy_sgmii_2 = &phy_sgmii_2; | ||
48 | phy_sgmii_3 = &phy_sgmii_3; | ||
49 | phy_sgmii_4 = &phy_sgmii_4; | ||
50 | phy_sgmii_1c = &phy_sgmii_1c; | ||
51 | phy_sgmii_1d = &phy_sgmii_1d; | ||
52 | phy_sgmii_1e = &phy_sgmii_1e; | ||
53 | phy_sgmii_1f = &phy_sgmii_1f; | ||
54 | phy_xgmii_2 = &phy_xgmii_2; | ||
55 | }; | ||
56 | |||
44 | memory { | 57 | memory { |
45 | device_type = "memory"; | 58 | device_type = "memory"; |
46 | }; | 59 | }; |
@@ -83,7 +96,7 @@ | |||
83 | flash@0 { | 96 | flash@0 { |
84 | #address-cells = <1>; | 97 | #address-cells = <1>; |
85 | #size-cells = <1>; | 98 | #size-cells = <1>; |
86 | compatible = "spansion,s25sl12801"; | 99 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
87 | reg = <0>; | 100 | reg = <0>; |
88 | spi-max-frequency = <40000000>; /* input clock */ | 101 | spi-max-frequency = <40000000>; /* input clock */ |
89 | partition@u-boot { | 102 | partition@u-boot { |
@@ -137,6 +150,83 @@ | |||
137 | usb1: usb@211000 { | 150 | usb1: usb@211000 { |
138 | dr_mode = "host"; | 151 | dr_mode = "host"; |
139 | }; | 152 | }; |
153 | |||
154 | fman@400000 { | ||
155 | ethernet@e0000 { | ||
156 | phy-handle = <&phy_sgmii_2>; | ||
157 | phy-connection-type = "sgmii"; | ||
158 | }; | ||
159 | |||
160 | mdio@e1120 { | ||
161 | phy_rgmii_0: ethernet-phy@0 { | ||
162 | reg = <0x0>; | ||
163 | }; | ||
164 | |||
165 | phy_rgmii_1: ethernet-phy@1 { | ||
166 | reg = <0x1>; | ||
167 | }; | ||
168 | |||
169 | phy_sgmii_2: ethernet-phy@2 { | ||
170 | reg = <0x2>; | ||
171 | }; | ||
172 | |||
173 | phy_sgmii_3: ethernet-phy@3 { | ||
174 | reg = <0x3>; | ||
175 | }; | ||
176 | |||
177 | phy_sgmii_4: ethernet-phy@4 { | ||
178 | reg = <0x4>; | ||
179 | }; | ||
180 | |||
181 | phy_sgmii_1c: ethernet-phy@1c { | ||
182 | reg = <0x1c>; | ||
183 | }; | ||
184 | |||
185 | phy_sgmii_1d: ethernet-phy@1d { | ||
186 | reg = <0x1d>; | ||
187 | }; | ||
188 | |||
189 | phy_sgmii_1e: ethernet-phy@1e { | ||
190 | reg = <0x1e>; | ||
191 | }; | ||
192 | |||
193 | phy_sgmii_1f: ethernet-phy@1f { | ||
194 | reg = <0x1f>; | ||
195 | }; | ||
196 | }; | ||
197 | |||
198 | ethernet@e2000 { | ||
199 | phy-handle = <&phy_sgmii_3>; | ||
200 | phy-connection-type = "sgmii"; | ||
201 | }; | ||
202 | |||
203 | ethernet@e4000 { | ||
204 | phy-handle = <&phy_sgmii_4>; | ||
205 | phy-connection-type = "sgmii"; | ||
206 | }; | ||
207 | |||
208 | ethernet@e6000 { | ||
209 | phy-handle = <&phy_rgmii_1>; | ||
210 | phy-connection-type = "rgmii"; | ||
211 | }; | ||
212 | |||
213 | ethernet@e8000 { | ||
214 | phy-handle = <&phy_rgmii_0>; | ||
215 | phy-connection-type = "rgmii"; | ||
216 | }; | ||
217 | |||
218 | ethernet@f0000 { | ||
219 | phy-handle = <&phy_xgmii_2>; | ||
220 | phy-connection-type = "xgmii"; | ||
221 | }; | ||
222 | |||
223 | mdio@f1000 { | ||
224 | phy_xgmii_2: ethernet-phy@0 { | ||
225 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
226 | reg = <0x0>; | ||
227 | }; | ||
228 | }; | ||
229 | }; | ||
140 | }; | 230 | }; |
141 | 231 | ||
142 | rio: rapidio@ffe0c0000 { | 232 | rio: rapidio@ffe0c0000 { |
diff --git a/arch/powerpc/boot/dts/fsl/p3041ds.dts b/arch/powerpc/boot/dts/fsl/p3041ds.dts index f2b1d40334d4..40748e415adb 100644 --- a/arch/powerpc/boot/dts/fsl/p3041ds.dts +++ b/arch/powerpc/boot/dts/fsl/p3041ds.dts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * P3041DS Device Tree Source | 2 | * P3041DS Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2010 - 2014 Freescale Semiconductor Inc. | 4 | * Copyright 2010 - 2015 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: |
@@ -41,6 +41,20 @@ | |||
41 | #size-cells = <2>; | 41 | #size-cells = <2>; |
42 | interrupt-parent = <&mpic>; | 42 | interrupt-parent = <&mpic>; |
43 | 43 | ||
44 | aliases{ | ||
45 | phy_rgmii_0 = &phy_rgmii_0; | ||
46 | phy_rgmii_1 = &phy_rgmii_1; | ||
47 | phy_sgmii_1c = &phy_sgmii_1c; | ||
48 | phy_sgmii_1d = &phy_sgmii_1d; | ||
49 | phy_sgmii_1e = &phy_sgmii_1e; | ||
50 | phy_sgmii_1f = &phy_sgmii_1f; | ||
51 | phy_xgmii_1 = &phy_xgmii_1; | ||
52 | phy_xgmii_2 = &phy_xgmii_2; | ||
53 | emi1_rgmii = &hydra_mdio_rgmii; | ||
54 | emi1_sgmii = &hydra_mdio_sgmii; | ||
55 | emi2_xgmii = &hydra_mdio_xgmii; | ||
56 | }; | ||
57 | |||
44 | memory { | 58 | memory { |
45 | device_type = "memory"; | 59 | device_type = "memory"; |
46 | }; | 60 | }; |
@@ -83,7 +97,7 @@ | |||
83 | flash@0 { | 97 | flash@0 { |
84 | #address-cells = <1>; | 98 | #address-cells = <1>; |
85 | #size-cells = <1>; | 99 | #size-cells = <1>; |
86 | compatible = "spansion,s25sl12801"; | 100 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
87 | reg = <0>; | 101 | reg = <0>; |
88 | spi-max-frequency = <35000000>; /* input clock */ | 102 | spi-max-frequency = <35000000>; /* input clock */ |
89 | partition@u-boot { | 103 | partition@u-boot { |
@@ -150,6 +164,52 @@ | |||
150 | reg = <0x4c>; | 164 | reg = <0x4c>; |
151 | }; | 165 | }; |
152 | }; | 166 | }; |
167 | |||
168 | fman@400000{ | ||
169 | ethernet@e0000 { | ||
170 | phy-handle = <&phy_sgmii_1c>; | ||
171 | phy-connection-type = "sgmii"; | ||
172 | }; | ||
173 | |||
174 | ethernet@e2000 { | ||
175 | phy-handle = <&phy_sgmii_1d>; | ||
176 | phy-connection-type = "sgmii"; | ||
177 | }; | ||
178 | |||
179 | ethernet@e4000 { | ||
180 | phy-handle = <&phy_sgmii_1e>; | ||
181 | phy-connection-type = "sgmii"; | ||
182 | }; | ||
183 | |||
184 | ethernet@e6000 { | ||
185 | phy-handle = <&phy_sgmii_1f>; | ||
186 | phy-connection-type = "sgmii"; | ||
187 | }; | ||
188 | |||
189 | ethernet@e8000 { | ||
190 | phy-handle = <&phy_rgmii_1>; | ||
191 | phy-connection-type = "rgmii"; | ||
192 | }; | ||
193 | |||
194 | ethernet@f0000 { | ||
195 | phy-handle = <&phy_xgmii_1>; | ||
196 | phy-connection-type = "xgmii"; | ||
197 | }; | ||
198 | |||
199 | hydra_mdio_xgmii: mdio@f1000 { | ||
200 | status = "disabled"; | ||
201 | |||
202 | phy_xgmii_1: ethernet-phy@4 { | ||
203 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
204 | reg = <0x4>; | ||
205 | }; | ||
206 | |||
207 | phy_xgmii_2: ethernet-phy@0 { | ||
208 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
209 | reg = <0x0>; | ||
210 | }; | ||
211 | }; | ||
212 | }; | ||
153 | }; | 213 | }; |
154 | 214 | ||
155 | rio: rapidio@ffe0c0000 { | 215 | rio: rapidio@ffe0c0000 { |
@@ -215,8 +275,58 @@ | |||
215 | }; | 275 | }; |
216 | 276 | ||
217 | board-control@3,0 { | 277 | board-control@3,0 { |
278 | #address-cells = <1>; | ||
279 | #size-cells = <1>; | ||
218 | compatible = "fsl,p3041ds-fpga", "fsl,fpga-ngpixis"; | 280 | compatible = "fsl,p3041ds-fpga", "fsl,fpga-ngpixis"; |
219 | reg = <3 0 0x30>; | 281 | reg = <3 0 0x30>; |
282 | ranges = <0 3 0 0x30>; | ||
283 | |||
284 | mdio-mux-emi1 { | ||
285 | #address-cells = <1>; | ||
286 | #size-cells = <0>; | ||
287 | compatible = "mdio-mux-mmioreg", "mdio-mux"; | ||
288 | mdio-parent-bus = <&mdio0>; | ||
289 | reg = <9 1>; | ||
290 | mux-mask = <0x78>; | ||
291 | |||
292 | hydra_mdio_rgmii: rgmii-mdio@8 { | ||
293 | #address-cells = <1>; | ||
294 | #size-cells = <0>; | ||
295 | reg = <8>; | ||
296 | status = "disabled"; | ||
297 | |||
298 | phy_rgmii_0: ethernet-phy@0 { | ||
299 | reg = <0x0>; | ||
300 | }; | ||
301 | |||
302 | phy_rgmii_1: ethernet-phy@1 { | ||
303 | reg = <0x1>; | ||
304 | }; | ||
305 | }; | ||
306 | |||
307 | hydra_mdio_sgmii: sgmii-mdio@28 { | ||
308 | #address-cells = <1>; | ||
309 | #size-cells = <0>; | ||
310 | reg = <0x28>; | ||
311 | status = "disabled"; | ||
312 | |||
313 | phy_sgmii_1c: ethernet-phy@1c { | ||
314 | reg = <0x1c>; | ||
315 | }; | ||
316 | |||
317 | phy_sgmii_1d: ethernet-phy@1d { | ||
318 | reg = <0x1d>; | ||
319 | }; | ||
320 | |||
321 | phy_sgmii_1e: ethernet-phy@1e { | ||
322 | reg = <0x1e>; | ||
323 | }; | ||
324 | |||
325 | phy_sgmii_1f: ethernet-phy@1f { | ||
326 | reg = <0x1f>; | ||
327 | }; | ||
328 | }; | ||
329 | }; | ||
220 | }; | 330 | }; |
221 | }; | 331 | }; |
222 | 332 | ||
diff --git a/arch/powerpc/boot/dts/fsl/p4080ds.dts b/arch/powerpc/boot/dts/fsl/p4080ds.dts index 28a55c5e7099..816b9788d5f6 100644 --- a/arch/powerpc/boot/dts/fsl/p4080ds.dts +++ b/arch/powerpc/boot/dts/fsl/p4080ds.dts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * P4080DS Device Tree Source | 2 | * P4080DS Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2009 - 2014 Freescale Semiconductor Inc. | 4 | * Copyright 2009 - 2015 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: |
@@ -41,6 +41,20 @@ | |||
41 | #size-cells = <2>; | 41 | #size-cells = <2>; |
42 | interrupt-parent = <&mpic>; | 42 | interrupt-parent = <&mpic>; |
43 | 43 | ||
44 | aliases { | ||
45 | phy_rgmii = &phyrgmii; | ||
46 | phy5_slot3 = &phy5slot3; | ||
47 | phy6_slot3 = &phy6slot3; | ||
48 | phy7_slot3 = &phy7slot3; | ||
49 | phy8_slot3 = &phy8slot3; | ||
50 | emi1_slot3 = &p4080mdio2; | ||
51 | emi1_slot4 = &p4080mdio1; | ||
52 | emi1_slot5 = &p4080mdio3; | ||
53 | emi1_rgmii = &p4080mdio0; | ||
54 | emi2_slot4 = &p4080xmdio1; | ||
55 | emi2_slot5 = &p4080xmdio3; | ||
56 | }; | ||
57 | |||
44 | memory { | 58 | memory { |
45 | device_type = "memory"; | 59 | device_type = "memory"; |
46 | }; | 60 | }; |
@@ -84,7 +98,7 @@ | |||
84 | flash@0 { | 98 | flash@0 { |
85 | #address-cells = <1>; | 99 | #address-cells = <1>; |
86 | #size-cells = <1>; | 100 | #size-cells = <1>; |
87 | compatible = "spansion,s25sl12801"; | 101 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
88 | reg = <0>; | 102 | reg = <0>; |
89 | spi-max-frequency = <40000000>; /* input clock */ | 103 | spi-max-frequency = <40000000>; /* input clock */ |
90 | partition@u-boot { | 104 | partition@u-boot { |
@@ -137,6 +151,60 @@ | |||
137 | dr_mode = "host"; | 151 | dr_mode = "host"; |
138 | phy_type = "ulpi"; | 152 | phy_type = "ulpi"; |
139 | }; | 153 | }; |
154 | |||
155 | fman@400000 { | ||
156 | ethernet@e0000 { | ||
157 | phy-handle = <&phy0>; | ||
158 | phy-connection-type = "sgmii"; | ||
159 | }; | ||
160 | |||
161 | ethernet@e2000 { | ||
162 | phy-handle = <&phy1>; | ||
163 | phy-connection-type = "sgmii"; | ||
164 | }; | ||
165 | |||
166 | ethernet@e4000 { | ||
167 | phy-handle = <&phy2>; | ||
168 | phy-connection-type = "sgmii"; | ||
169 | }; | ||
170 | |||
171 | ethernet@e6000 { | ||
172 | phy-handle = <&phy3>; | ||
173 | phy-connection-type = "sgmii"; | ||
174 | }; | ||
175 | |||
176 | ethernet@f0000 { | ||
177 | phy-handle = <&phy10>; | ||
178 | phy-connection-type = "xgmii"; | ||
179 | }; | ||
180 | }; | ||
181 | |||
182 | fman@500000 { | ||
183 | ethernet@e0000 { | ||
184 | phy-handle = <&phy5>; | ||
185 | phy-connection-type = "sgmii"; | ||
186 | }; | ||
187 | |||
188 | ethernet@e2000 { | ||
189 | phy-handle = <&phy6>; | ||
190 | phy-connection-type = "sgmii"; | ||
191 | }; | ||
192 | |||
193 | ethernet@e4000 { | ||
194 | phy-handle = <&phy7>; | ||
195 | phy-connection-type = "sgmii"; | ||
196 | }; | ||
197 | |||
198 | ethernet@e6000 { | ||
199 | phy-handle = <&phy8>; | ||
200 | phy-connection-type = "sgmii"; | ||
201 | }; | ||
202 | |||
203 | ethernet@f0000 { | ||
204 | phy-handle = <&phy11>; | ||
205 | phy-connection-type = "xgmii"; | ||
206 | }; | ||
207 | }; | ||
140 | }; | 208 | }; |
141 | 209 | ||
142 | rio: rapidio@ffe0c0000 { | 210 | rio: rapidio@ffe0c0000 { |
@@ -213,6 +281,120 @@ | |||
213 | }; | 281 | }; |
214 | }; | 282 | }; |
215 | 283 | ||
284 | mdio-mux-emi1 { | ||
285 | #address-cells = <1>; | ||
286 | #size-cells = <0>; | ||
287 | compatible = "mdio-mux-gpio", "mdio-mux"; | ||
288 | mdio-parent-bus = <&mdio0>; | ||
289 | gpios = <&gpio0 1 0>, <&gpio0 0 0>; | ||
290 | |||
291 | p4080mdio0: mdio@0 { | ||
292 | #address-cells = <1>; | ||
293 | #size-cells = <0>; | ||
294 | reg = <0>; | ||
295 | |||
296 | phyrgmii: ethernet-phy@0 { | ||
297 | reg = <0x0>; | ||
298 | }; | ||
299 | }; | ||
300 | |||
301 | p4080mdio1: mdio@1 { | ||
302 | #address-cells = <1>; | ||
303 | #size-cells = <0>; | ||
304 | reg = <1>; | ||
305 | |||
306 | phy5: ethernet-phy@1c { | ||
307 | reg = <0x1c>; | ||
308 | }; | ||
309 | |||
310 | phy6: ethernet-phy@1d { | ||
311 | reg = <0x1d>; | ||
312 | }; | ||
313 | |||
314 | phy7: ethernet-phy@1e { | ||
315 | reg = <0x1e>; | ||
316 | }; | ||
317 | |||
318 | phy8: ethernet-phy@1f { | ||
319 | reg = <0x1f>; | ||
320 | }; | ||
321 | }; | ||
322 | |||
323 | p4080mdio2: mdio@2 { | ||
324 | #address-cells = <1>; | ||
325 | #size-cells = <0>; | ||
326 | reg = <2>; | ||
327 | status = "disabled"; | ||
328 | |||
329 | phy5slot3: ethernet-phy@1c { | ||
330 | reg = <0x1c>; | ||
331 | }; | ||
332 | |||
333 | phy6slot3: ethernet-phy@1d { | ||
334 | reg = <0x1d>; | ||
335 | }; | ||
336 | |||
337 | phy7slot3: ethernet-phy@1e { | ||
338 | reg = <0x1e>; | ||
339 | }; | ||
340 | |||
341 | phy8slot3: ethernet-phy@1f { | ||
342 | reg = <0x1f>; | ||
343 | }; | ||
344 | }; | ||
345 | |||
346 | p4080mdio3: mdio@3 { | ||
347 | #address-cells = <1>; | ||
348 | #size-cells = <0>; | ||
349 | reg = <3>; | ||
350 | |||
351 | phy0: ethernet-phy@1c { | ||
352 | reg = <0x1c>; | ||
353 | }; | ||
354 | |||
355 | phy1: ethernet-phy@1d { | ||
356 | reg = <0x1d>; | ||
357 | }; | ||
358 | |||
359 | phy2: ethernet-phy@1e { | ||
360 | reg = <0x1e>; | ||
361 | }; | ||
362 | |||
363 | phy3: ethernet-phy@1f { | ||
364 | reg = <0x1f>; | ||
365 | }; | ||
366 | }; | ||
367 | }; | ||
368 | |||
369 | mdio-mux-emi2 { | ||
370 | #address-cells = <1>; | ||
371 | #size-cells = <0>; | ||
372 | compatible = "mdio-mux-gpio", "mdio-mux"; | ||
373 | mdio-parent-bus = <&xmdio0>; | ||
374 | gpios = <&gpio0 3 0>, <&gpio0 2 0>; | ||
375 | |||
376 | p4080xmdio1: mdio@1 { | ||
377 | #address-cells = <1>; | ||
378 | #size-cells = <0>; | ||
379 | reg = <1>; | ||
380 | |||
381 | phy11: ethernet-phy@0 { | ||
382 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
383 | reg = <0x0>; | ||
384 | }; | ||
385 | }; | ||
386 | |||
387 | p4080xmdio3: mdio@3 { | ||
388 | #address-cells = <1>; | ||
389 | #size-cells = <0>; | ||
390 | reg = <3>; | ||
391 | |||
392 | phy10: ethernet-phy@4 { | ||
393 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
394 | reg = <0x4>; | ||
395 | }; | ||
396 | }; | ||
397 | }; | ||
216 | }; | 398 | }; |
217 | 399 | ||
218 | /include/ "p4080si-post.dtsi" | 400 | /include/ "p4080si-post.dtsi" |
diff --git a/arch/powerpc/boot/dts/fsl/p5020ds.dts b/arch/powerpc/boot/dts/fsl/p5020ds.dts index 920dc77b9c43..cd6f37386111 100644 --- a/arch/powerpc/boot/dts/fsl/p5020ds.dts +++ b/arch/powerpc/boot/dts/fsl/p5020ds.dts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * P5020DS Device Tree Source | 2 | * P5020DS Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2010 - 2014 Freescale Semiconductor Inc. | 4 | * Copyright 2010 - 2015 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: |
@@ -41,6 +41,20 @@ | |||
41 | #size-cells = <2>; | 41 | #size-cells = <2>; |
42 | interrupt-parent = <&mpic>; | 42 | interrupt-parent = <&mpic>; |
43 | 43 | ||
44 | aliases { | ||
45 | phy_rgmii_0 = &phy_rgmii_0; | ||
46 | phy_rgmii_1 = &phy_rgmii_1; | ||
47 | phy_sgmii_1c = &phy_sgmii_1c; | ||
48 | phy_sgmii_1d = &phy_sgmii_1d; | ||
49 | phy_sgmii_1e = &phy_sgmii_1e; | ||
50 | phy_sgmii_1f = &phy_sgmii_1f; | ||
51 | phy_xgmii_1 = &phy_xgmii_1; | ||
52 | phy_xgmii_2 = &phy_xgmii_2; | ||
53 | emi1_rgmii = &hydra_mdio_rgmii; | ||
54 | emi1_sgmii = &hydra_mdio_sgmii; | ||
55 | emi2_xgmii = &hydra_mdio_xgmii; | ||
56 | }; | ||
57 | |||
44 | memory { | 58 | memory { |
45 | device_type = "memory"; | 59 | device_type = "memory"; |
46 | }; | 60 | }; |
@@ -83,7 +97,7 @@ | |||
83 | flash@0 { | 97 | flash@0 { |
84 | #address-cells = <1>; | 98 | #address-cells = <1>; |
85 | #size-cells = <1>; | 99 | #size-cells = <1>; |
86 | compatible = "spansion,s25sl12801"; | 100 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
87 | reg = <0>; | 101 | reg = <0>; |
88 | spi-max-frequency = <40000000>; /* input clock */ | 102 | spi-max-frequency = <40000000>; /* input clock */ |
89 | partition@u-boot { | 103 | partition@u-boot { |
@@ -150,6 +164,52 @@ | |||
150 | reg = <0x4c>; | 164 | reg = <0x4c>; |
151 | }; | 165 | }; |
152 | }; | 166 | }; |
167 | |||
168 | fman@400000 { | ||
169 | ethernet@e0000 { | ||
170 | phy-handle = <&phy_sgmii_1c>; | ||
171 | phy-connection-type = "sgmii"; | ||
172 | }; | ||
173 | |||
174 | ethernet@e2000 { | ||
175 | phy-handle = <&phy_sgmii_1d>; | ||
176 | phy-connection-type = "sgmii"; | ||
177 | }; | ||
178 | |||
179 | ethernet@e4000 { | ||
180 | phy-handle = <&phy_sgmii_1e>; | ||
181 | phy-connection-type = "sgmii"; | ||
182 | }; | ||
183 | |||
184 | ethernet@e6000 { | ||
185 | phy-handle = <&phy_sgmii_1f>; | ||
186 | phy-connection-type = "sgmii"; | ||
187 | }; | ||
188 | |||
189 | ethernet@e8000 { | ||
190 | phy-handle = <&phy_rgmii_1>; | ||
191 | phy-connection-type = "rgmii"; | ||
192 | }; | ||
193 | |||
194 | ethernet@f0000 { | ||
195 | phy-handle = <&phy_xgmii_1>; | ||
196 | phy-connection-type = "xgmii"; | ||
197 | }; | ||
198 | |||
199 | hydra_mdio_xgmii: mdio@f1000 { | ||
200 | status = "disabled"; | ||
201 | |||
202 | phy_xgmii_1: ethernet-phy@4 { | ||
203 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
204 | reg = <0x4>; | ||
205 | }; | ||
206 | |||
207 | phy_xgmii_2: ethernet-phy@0 { | ||
208 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
209 | reg = <0x0>; | ||
210 | }; | ||
211 | }; | ||
212 | }; | ||
153 | }; | 213 | }; |
154 | 214 | ||
155 | rio: rapidio@ffe0c0000 { | 215 | rio: rapidio@ffe0c0000 { |
@@ -215,8 +275,58 @@ | |||
215 | }; | 275 | }; |
216 | 276 | ||
217 | board-control@3,0 { | 277 | board-control@3,0 { |
278 | #address-cells = <1>; | ||
279 | #size-cells = <1>; | ||
218 | compatible = "fsl,p5020ds-fpga", "fsl,fpga-ngpixis"; | 280 | compatible = "fsl,p5020ds-fpga", "fsl,fpga-ngpixis"; |
219 | reg = <3 0 0x30>; | 281 | reg = <3 0 0x30>; |
282 | ranges = <0 3 0 0x30>; | ||
283 | |||
284 | mdio-mux-emi1 { | ||
285 | #address-cells = <1>; | ||
286 | #size-cells = <0>; | ||
287 | compatible = "mdio-mux-mmioreg", "mdio-mux"; | ||
288 | mdio-parent-bus = <&mdio0>; | ||
289 | reg = <9 1>; | ||
290 | mux-mask = <0x78>; | ||
291 | |||
292 | hydra_mdio_rgmii: rgmii-mdio@8 { | ||
293 | #address-cells = <1>; | ||
294 | #size-cells = <0>; | ||
295 | reg = <8>; | ||
296 | status = "disabled"; | ||
297 | |||
298 | phy_rgmii_0: ethernet-phy@0 { | ||
299 | reg = <0x0>; | ||
300 | }; | ||
301 | |||
302 | phy_rgmii_1: ethernet-phy@1 { | ||
303 | reg = <0x1>; | ||
304 | }; | ||
305 | }; | ||
306 | |||
307 | hydra_mdio_sgmii: sgmii-mdio@28 { | ||
308 | #address-cells = <1>; | ||
309 | #size-cells = <0>; | ||
310 | reg = <0x28>; | ||
311 | status = "disabled"; | ||
312 | |||
313 | phy_sgmii_1c: ethernet-phy@1c { | ||
314 | reg = <0x1c>; | ||
315 | }; | ||
316 | |||
317 | phy_sgmii_1d: ethernet-phy@1d { | ||
318 | reg = <0x1d>; | ||
319 | }; | ||
320 | |||
321 | phy_sgmii_1e: ethernet-phy@1e { | ||
322 | reg = <0x1e>; | ||
323 | }; | ||
324 | |||
325 | phy_sgmii_1f: ethernet-phy@1f { | ||
326 | reg = <0x1f>; | ||
327 | }; | ||
328 | }; | ||
329 | }; | ||
220 | }; | 330 | }; |
221 | }; | 331 | }; |
222 | 332 | ||
diff --git a/arch/powerpc/boot/dts/fsl/p5040ds.dts b/arch/powerpc/boot/dts/fsl/p5040ds.dts index e169cc297ea3..45084738cf4e 100644 --- a/arch/powerpc/boot/dts/fsl/p5040ds.dts +++ b/arch/powerpc/boot/dts/fsl/p5040ds.dts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * P5040DS Device Tree Source | 2 | * P5040DS Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2012 - 2014 Freescale Semiconductor Inc. | 4 | * Copyright 2012 - 2015 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: |
@@ -41,6 +41,32 @@ | |||
41 | #size-cells = <2>; | 41 | #size-cells = <2>; |
42 | interrupt-parent = <&mpic>; | 42 | interrupt-parent = <&mpic>; |
43 | 43 | ||
44 | aliases{ | ||
45 | phy_sgmii_slot2_1c = &phy_sgmii_slot2_1c; | ||
46 | phy_sgmii_slot2_1d = &phy_sgmii_slot2_1d; | ||
47 | phy_sgmii_slot2_1e = &phy_sgmii_slot2_1e; | ||
48 | phy_sgmii_slot2_1f = &phy_sgmii_slot2_1f; | ||
49 | phy_sgmii_slot3_1c = &phy_sgmii_slot3_1c; | ||
50 | phy_sgmii_slot3_1d = &phy_sgmii_slot3_1d; | ||
51 | phy_sgmii_slot3_1e = &phy_sgmii_slot3_1e; | ||
52 | phy_sgmii_slot3_1f = &phy_sgmii_slot3_1f; | ||
53 | phy_sgmii_slot5_1c = &phy_sgmii_slot5_1c; | ||
54 | phy_sgmii_slot5_1d = &phy_sgmii_slot5_1d; | ||
55 | phy_sgmii_slot5_1e = &phy_sgmii_slot5_1e; | ||
56 | phy_sgmii_slot5_1f = &phy_sgmii_slot5_1f; | ||
57 | phy_sgmii_slot6_1c = &phy_sgmii_slot6_1c; | ||
58 | phy_sgmii_slot6_1d = &phy_sgmii_slot6_1d; | ||
59 | phy_sgmii_slot6_1e = &phy_sgmii_slot6_1e; | ||
60 | phy_sgmii_slot6_1f = &phy_sgmii_slot6_1f; | ||
61 | hydra_rg = &hydra_rg; | ||
62 | hydra_sg_slot2 = &hydra_sg_slot2; | ||
63 | hydra_sg_slot3 = &hydra_sg_slot3; | ||
64 | hydra_sg_slot5 = &hydra_sg_slot5; | ||
65 | hydra_sg_slot6 = &hydra_sg_slot6; | ||
66 | hydra_xg_slot1 = &hydra_xg_slot1; | ||
67 | hydra_xg_slot2 = &hydra_xg_slot2; | ||
68 | }; | ||
69 | |||
44 | memory { | 70 | memory { |
45 | device_type = "memory"; | 71 | device_type = "memory"; |
46 | }; | 72 | }; |
@@ -83,7 +109,7 @@ | |||
83 | flash@0 { | 109 | flash@0 { |
84 | #address-cells = <1>; | 110 | #address-cells = <1>; |
85 | #size-cells = <1>; | 111 | #size-cells = <1>; |
86 | compatible = "spansion,s25sl12801"; | 112 | compatible = "spansion,s25sl12801", "jedec,spi-nor"; |
87 | reg = <0>; | 113 | reg = <0>; |
88 | spi-max-frequency = <40000000>; /* input clock */ | 114 | spi-max-frequency = <40000000>; /* input clock */ |
89 | partition@u-boot { | 115 | partition@u-boot { |
@@ -147,6 +173,62 @@ | |||
147 | reg = <0x4c>; | 173 | reg = <0x4c>; |
148 | }; | 174 | }; |
149 | }; | 175 | }; |
176 | |||
177 | fman@400000 { | ||
178 | ethernet@e0000 { | ||
179 | phy-connection-type = "sgmii"; | ||
180 | }; | ||
181 | |||
182 | ethernet@e2000 { | ||
183 | phy-connection-type = "sgmii"; | ||
184 | }; | ||
185 | |||
186 | ethernet@e4000 { | ||
187 | phy-connection-type = "sgmii"; | ||
188 | }; | ||
189 | |||
190 | ethernet@e6000 { | ||
191 | phy-connection-type = "sgmii"; | ||
192 | }; | ||
193 | |||
194 | ethernet@e8000 { | ||
195 | phy-handle = <&phy_rgmii_0>; | ||
196 | phy-connection-type = "rgmii"; | ||
197 | }; | ||
198 | |||
199 | ethernet@f0000 { | ||
200 | phy-handle = <&phy_xgmii_slot_2>; | ||
201 | phy-connection-type = "xgmii"; | ||
202 | }; | ||
203 | }; | ||
204 | |||
205 | fman@500000 { | ||
206 | ethernet@e0000 { | ||
207 | phy-connection-type = "sgmii"; | ||
208 | }; | ||
209 | |||
210 | ethernet@e2000 { | ||
211 | phy-connection-type = "sgmii"; | ||
212 | }; | ||
213 | |||
214 | ethernet@e4000 { | ||
215 | phy-connection-type = "sgmii"; | ||
216 | }; | ||
217 | |||
218 | ethernet@e6000 { | ||
219 | phy-connection-type = "sgmii"; | ||
220 | }; | ||
221 | |||
222 | ethernet@e8000 { | ||
223 | phy-handle = <&phy_rgmii_1>; | ||
224 | phy-connection-type = "rgmii"; | ||
225 | }; | ||
226 | |||
227 | ethernet@f0000 { | ||
228 | phy-handle = <&phy_xgmii_slot_1>; | ||
229 | phy-connection-type = "xgmii"; | ||
230 | }; | ||
231 | }; | ||
150 | }; | 232 | }; |
151 | 233 | ||
152 | lbc: localbus@ffe124000 { | 234 | lbc: localbus@ffe124000 { |
@@ -200,8 +282,158 @@ | |||
200 | }; | 282 | }; |
201 | 283 | ||
202 | board-control@3,0 { | 284 | board-control@3,0 { |
285 | #address-cells = <1>; | ||
286 | #size-cells = <1>; | ||
203 | compatible = "fsl,p5040ds-fpga", "fsl,fpga-ngpixis"; | 287 | compatible = "fsl,p5040ds-fpga", "fsl,fpga-ngpixis"; |
204 | reg = <3 0 0x40>; | 288 | reg = <3 0 0x40>; |
289 | ranges = <0 3 0 0x40>; | ||
290 | |||
291 | mdio-mux-emi1 { | ||
292 | #address-cells = <1>; | ||
293 | #size-cells = <0>; | ||
294 | compatible = "mdio-mux-mmioreg", "mdio-mux"; | ||
295 | mdio-parent-bus = <&mdio0>; | ||
296 | reg = <9 1>; | ||
297 | mux-mask = <0x78>; | ||
298 | |||
299 | hydra_rg:rgmii-mdio@8 { | ||
300 | #address-cells = <1>; | ||
301 | #size-cells = <0>; | ||
302 | reg = <8>; | ||
303 | status = "disabled"; | ||
304 | |||
305 | phy_rgmii_0: ethernet-phy@0 { | ||
306 | reg = <0x0>; | ||
307 | }; | ||
308 | |||
309 | phy_rgmii_1: ethernet-phy@1 { | ||
310 | reg = <0x1>; | ||
311 | }; | ||
312 | }; | ||
313 | |||
314 | hydra_sg_slot2: sgmii-mdio@28 { | ||
315 | #address-cells = <1>; | ||
316 | #size-cells = <0>; | ||
317 | reg = <0x28>; | ||
318 | status = "disabled"; | ||
319 | |||
320 | phy_sgmii_slot2_1c: ethernet-phy@1c { | ||
321 | reg = <0x1c>; | ||
322 | }; | ||
323 | |||
324 | phy_sgmii_slot2_1d: ethernet-phy@1d { | ||
325 | reg = <0x1d>; | ||
326 | }; | ||
327 | |||
328 | phy_sgmii_slot2_1e: ethernet-phy@1e { | ||
329 | reg = <0x1e>; | ||
330 | }; | ||
331 | |||
332 | phy_sgmii_slot2_1f: ethernet-phy@1f { | ||
333 | reg = <0x1f>; | ||
334 | }; | ||
335 | }; | ||
336 | |||
337 | hydra_sg_slot3: sgmii-mdio@68 { | ||
338 | #address-cells = <1>; | ||
339 | #size-cells = <0>; | ||
340 | reg = <0x68>; | ||
341 | status = "disabled"; | ||
342 | |||
343 | phy_sgmii_slot3_1c: ethernet-phy@1c { | ||
344 | reg = <0x1c>; | ||
345 | }; | ||
346 | |||
347 | phy_sgmii_slot3_1d: ethernet-phy@1d { | ||
348 | reg = <0x1d>; | ||
349 | }; | ||
350 | |||
351 | phy_sgmii_slot3_1e: ethernet-phy@1e { | ||
352 | reg = <0x1e>; | ||
353 | }; | ||
354 | |||
355 | phy_sgmii_slot3_1f: ethernet-phy@1f { | ||
356 | reg = <0x1f>; | ||
357 | }; | ||
358 | }; | ||
359 | |||
360 | hydra_sg_slot5: sgmii-mdio@38 { | ||
361 | #address-cells = <1>; | ||
362 | #size-cells = <0>; | ||
363 | reg = <0x38>; | ||
364 | status = "disabled"; | ||
365 | |||
366 | phy_sgmii_slot5_1c: ethernet-phy@1c { | ||
367 | reg = <0x1c>; | ||
368 | }; | ||
369 | |||
370 | phy_sgmii_slot5_1d: ethernet-phy@1d { | ||
371 | reg = <0x1d>; | ||
372 | }; | ||
373 | |||
374 | phy_sgmii_slot5_1e: ethernet-phy@1e { | ||
375 | reg = <0x1e>; | ||
376 | }; | ||
377 | |||
378 | phy_sgmii_slot5_1f: ethernet-phy@1f { | ||
379 | reg = <0x1f>; | ||
380 | }; | ||
381 | }; | ||
382 | hydra_sg_slot6: sgmii-mdio@48 { | ||
383 | #address-cells = <1>; | ||
384 | #size-cells = <0>; | ||
385 | reg = <0x48>; | ||
386 | status = "disabled"; | ||
387 | |||
388 | phy_sgmii_slot6_1c: ethernet-phy@1c { | ||
389 | reg = <0x1c>; | ||
390 | }; | ||
391 | |||
392 | phy_sgmii_slot6_1d: ethernet-phy@1d { | ||
393 | reg = <0x1d>; | ||
394 | }; | ||
395 | |||
396 | phy_sgmii_slot6_1e: ethernet-phy@1e { | ||
397 | reg = <0x1e>; | ||
398 | }; | ||
399 | |||
400 | phy_sgmii_slot6_1f: ethernet-phy@1f { | ||
401 | reg = <0x1f>; | ||
402 | }; | ||
403 | }; | ||
404 | }; | ||
405 | |||
406 | mdio-mux-emi2 { | ||
407 | #address-cells = <1>; | ||
408 | #size-cells = <0>; | ||
409 | compatible = "mdio-mux-mmioreg", "mdio-mux"; | ||
410 | mdio-parent-bus = <&xmdio0>; | ||
411 | reg = <9 1>; | ||
412 | mux-mask = <0x06>; | ||
413 | |||
414 | hydra_xg_slot1: hydra-xg-slot1@0 { | ||
415 | #address-cells = <1>; | ||
416 | #size-cells = <0>; | ||
417 | reg = <0>; | ||
418 | status = "disabled"; | ||
419 | |||
420 | phy_xgmii_slot_1: ethernet-phy@0 { | ||
421 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
422 | reg = <4>; | ||
423 | }; | ||
424 | }; | ||
425 | |||
426 | hydra_xg_slot2: hydra-xg-slot2@2 { | ||
427 | #address-cells = <1>; | ||
428 | #size-cells = <0>; | ||
429 | reg = <2>; | ||
430 | |||
431 | phy_xgmii_slot_2: ethernet-phy@4 { | ||
432 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
433 | reg = <0>; | ||
434 | }; | ||
435 | }; | ||
436 | }; | ||
205 | }; | 437 | }; |
206 | }; | 438 | }; |
207 | 439 | ||
diff --git a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi index 2f227b1345ad..e2bd9313e632 100644 --- a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi | |||
@@ -420,6 +420,7 @@ | |||
420 | fsl,iommu-parent = <&pamu4>; | 420 | fsl,iommu-parent = <&pamu4>; |
421 | }; | 421 | }; |
422 | 422 | ||
423 | /include/ "qoriq-raid1.0-0.dtsi" | ||
423 | /include/ "qoriq-qman1.dtsi" | 424 | /include/ "qoriq-qman1.dtsi" |
424 | /include/ "qoriq-bman1.dtsi" | 425 | /include/ "qoriq-bman1.dtsi" |
425 | 426 | ||
diff --git a/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi index 0659d5bb69b8..dbd57750fc02 100644 --- a/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi | |||
@@ -73,6 +73,12 @@ | |||
73 | rtic_d = &rtic_d; | 73 | rtic_d = &rtic_d; |
74 | sec_mon = &sec_mon; | 74 | sec_mon = &sec_mon; |
75 | 75 | ||
76 | raideng = &raideng; | ||
77 | raideng_jr0 = &raideng_jr0; | ||
78 | raideng_jr1 = &raideng_jr1; | ||
79 | raideng_jr2 = &raideng_jr2; | ||
80 | raideng_jr3 = &raideng_jr3; | ||
81 | |||
76 | fman0 = &fman0; | 82 | fman0 = &fman0; |
77 | fman1 = &fman1; | 83 | fman1 = &fman1; |
78 | ethernet0 = &enet0; | 84 | ethernet0 = &enet0; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi index 2e441fab6d8f..e1a961f05dcd 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi | |||
@@ -55,6 +55,7 @@ fman@400000 { | |||
55 | reg = <0xe0000 0x1000>; | 55 | reg = <0xe0000 0x1000>; |
56 | fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>; | 56 | fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>; |
57 | ptp-timer = <&ptp_timer0>; | 57 | ptp-timer = <&ptp_timer0>; |
58 | pcsphy-handle = <&pcsphy0>; | ||
58 | }; | 59 | }; |
59 | 60 | ||
60 | mdio@e1000 { | 61 | mdio@e1000 { |
@@ -62,5 +63,9 @@ fman@400000 { | |||
62 | #size-cells = <0>; | 63 | #size-cells = <0>; |
63 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 64 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
64 | reg = <0xe1000 0x1000>; | 65 | reg = <0xe1000 0x1000>; |
66 | |||
67 | pcsphy0: ethernet-phy@0 { | ||
68 | reg = <0x0>; | ||
69 | }; | ||
65 | }; | 70 | }; |
66 | }; | 71 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi index 0b8f87f79d15..c288f3c6c637 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi | |||
@@ -52,6 +52,7 @@ fman@400000 { | |||
52 | compatible = "fsl,fman-memac"; | 52 | compatible = "fsl,fman-memac"; |
53 | reg = <0xf0000 0x1000>; | 53 | reg = <0xf0000 0x1000>; |
54 | fsl,fman-ports = <&fman0_rx_0x10 &fman0_tx_0x30>; | 54 | fsl,fman-ports = <&fman0_rx_0x10 &fman0_tx_0x30>; |
55 | pcsphy-handle = <&pcsphy6>; | ||
55 | }; | 56 | }; |
56 | 57 | ||
57 | mdio@f1000 { | 58 | mdio@f1000 { |
@@ -59,5 +60,9 @@ fman@400000 { | |||
59 | #size-cells = <0>; | 60 | #size-cells = <0>; |
60 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 61 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
61 | reg = <0xf1000 0x1000>; | 62 | reg = <0xf1000 0x1000>; |
63 | |||
64 | pcsphy6: ethernet-phy@0 { | ||
65 | reg = <0x0>; | ||
66 | }; | ||
62 | }; | 67 | }; |
63 | }; | 68 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi index ba6f2275d3f6..94f3e7175012 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi | |||
@@ -55,6 +55,7 @@ fman@400000 { | |||
55 | reg = <0xe2000 0x1000>; | 55 | reg = <0xe2000 0x1000>; |
56 | fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>; | 56 | fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>; |
57 | ptp-timer = <&ptp_timer0>; | 57 | ptp-timer = <&ptp_timer0>; |
58 | pcsphy-handle = <&pcsphy1>; | ||
58 | }; | 59 | }; |
59 | 60 | ||
60 | mdio@e3000 { | 61 | mdio@e3000 { |
@@ -62,5 +63,9 @@ fman@400000 { | |||
62 | #size-cells = <0>; | 63 | #size-cells = <0>; |
63 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 64 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
64 | reg = <0xe3000 0x1000>; | 65 | reg = <0xe3000 0x1000>; |
66 | |||
67 | pcsphy1: ethernet-phy@0 { | ||
68 | reg = <0x0>; | ||
69 | }; | ||
65 | }; | 70 | }; |
66 | }; | 71 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi index 886003805592..94a76982d214 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi | |||
@@ -52,6 +52,7 @@ fman@400000 { | |||
52 | compatible = "fsl,fman-memac"; | 52 | compatible = "fsl,fman-memac"; |
53 | reg = <0xf2000 0x1000>; | 53 | reg = <0xf2000 0x1000>; |
54 | fsl,fman-ports = <&fman0_rx_0x11 &fman0_tx_0x31>; | 54 | fsl,fman-ports = <&fman0_rx_0x11 &fman0_tx_0x31>; |
55 | pcsphy-handle = <&pcsphy7>; | ||
55 | }; | 56 | }; |
56 | 57 | ||
57 | mdio@f3000 { | 58 | mdio@f3000 { |
@@ -59,5 +60,9 @@ fman@400000 { | |||
59 | #size-cells = <0>; | 60 | #size-cells = <0>; |
60 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 61 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
61 | reg = <0xf3000 0x1000>; | 62 | reg = <0xf3000 0x1000>; |
63 | |||
64 | pcsphy7: ethernet-phy@0 { | ||
65 | reg = <0x0>; | ||
66 | }; | ||
62 | }; | 67 | }; |
63 | }; | 68 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi index ace9c13648ce..b5ff5f71c6b8 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi | |||
@@ -51,6 +51,7 @@ fman@400000 { | |||
51 | reg = <0xe0000 0x1000>; | 51 | reg = <0xe0000 0x1000>; |
52 | fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>; | 52 | fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>; |
53 | ptp-timer = <&ptp_timer0>; | 53 | ptp-timer = <&ptp_timer0>; |
54 | pcsphy-handle = <&pcsphy0>; | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | mdio@e1000 { | 57 | mdio@e1000 { |
@@ -58,5 +59,9 @@ fman@400000 { | |||
58 | #size-cells = <0>; | 59 | #size-cells = <0>; |
59 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 60 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
60 | reg = <0xe1000 0x1000>; | 61 | reg = <0xe1000 0x1000>; |
62 | |||
63 | pcsphy0: ethernet-phy@0 { | ||
64 | reg = <0x0>; | ||
65 | }; | ||
61 | }; | 66 | }; |
62 | }; | 67 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi index a4fc28654b31..ee44182c6348 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi | |||
@@ -51,6 +51,7 @@ fman@400000 { | |||
51 | reg = <0xe2000 0x1000>; | 51 | reg = <0xe2000 0x1000>; |
52 | fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>; | 52 | fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>; |
53 | ptp-timer = <&ptp_timer0>; | 53 | ptp-timer = <&ptp_timer0>; |
54 | pcsphy-handle = <&pcsphy1>; | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | mdio@e3000 { | 57 | mdio@e3000 { |
@@ -58,5 +59,9 @@ fman@400000 { | |||
58 | #size-cells = <0>; | 59 | #size-cells = <0>; |
59 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 60 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
60 | reg = <0xe3000 0x1000>; | 61 | reg = <0xe3000 0x1000>; |
62 | |||
63 | pcsphy1: ethernet-phy@0 { | ||
64 | reg = <0x0>; | ||
65 | }; | ||
61 | }; | 66 | }; |
62 | }; | 67 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi index 78596faadf99..f05f0d775039 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi | |||
@@ -51,6 +51,7 @@ fman@400000 { | |||
51 | reg = <0xe4000 0x1000>; | 51 | reg = <0xe4000 0x1000>; |
52 | fsl,fman-ports = <&fman0_rx_0x0a &fman0_tx_0x2a>; | 52 | fsl,fman-ports = <&fman0_rx_0x0a &fman0_tx_0x2a>; |
53 | ptp-timer = <&ptp_timer0>; | 53 | ptp-timer = <&ptp_timer0>; |
54 | pcsphy-handle = <&pcsphy2>; | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | mdio@e5000 { | 57 | mdio@e5000 { |
@@ -58,5 +59,9 @@ fman@400000 { | |||
58 | #size-cells = <0>; | 59 | #size-cells = <0>; |
59 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 60 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
60 | reg = <0xe5000 0x1000>; | 61 | reg = <0xe5000 0x1000>; |
62 | |||
63 | pcsphy2: ethernet-phy@0 { | ||
64 | reg = <0x0>; | ||
65 | }; | ||
61 | }; | 66 | }; |
62 | }; | 67 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi index af93abd86d78..a9114ec51075 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi | |||
@@ -51,6 +51,7 @@ fman@400000 { | |||
51 | reg = <0xe6000 0x1000>; | 51 | reg = <0xe6000 0x1000>; |
52 | fsl,fman-ports = <&fman0_rx_0x0b &fman0_tx_0x2b>; | 52 | fsl,fman-ports = <&fman0_rx_0x0b &fman0_tx_0x2b>; |
53 | ptp-timer = <&ptp_timer0>; | 53 | ptp-timer = <&ptp_timer0>; |
54 | pcsphy-handle = <&pcsphy3>; | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | mdio@e7000 { | 57 | mdio@e7000 { |
@@ -58,5 +59,9 @@ fman@400000 { | |||
58 | #size-cells = <0>; | 59 | #size-cells = <0>; |
59 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 60 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
60 | reg = <0xe7000 0x1000>; | 61 | reg = <0xe7000 0x1000>; |
62 | |||
63 | pcsphy3: ethernet-phy@0 { | ||
64 | reg = <0x0>; | ||
65 | }; | ||
61 | }; | 66 | }; |
62 | }; | 67 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi index 97cffd74bf3d..44dd00ac7367 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi | |||
@@ -51,6 +51,7 @@ fman@400000 { | |||
51 | reg = <0xe8000 0x1000>; | 51 | reg = <0xe8000 0x1000>; |
52 | fsl,fman-ports = <&fman0_rx_0x0c &fman0_tx_0x2c>; | 52 | fsl,fman-ports = <&fman0_rx_0x0c &fman0_tx_0x2c>; |
53 | ptp-timer = <&ptp_timer0>; | 53 | ptp-timer = <&ptp_timer0>; |
54 | pcsphy-handle = <&pcsphy4>; | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | mdio@e9000 { | 57 | mdio@e9000 { |
@@ -58,5 +59,9 @@ fman@400000 { | |||
58 | #size-cells = <0>; | 59 | #size-cells = <0>; |
59 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 60 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
60 | reg = <0xe9000 0x1000>; | 61 | reg = <0xe9000 0x1000>; |
62 | |||
63 | pcsphy4: ethernet-phy@0 { | ||
64 | reg = <0x0>; | ||
65 | }; | ||
61 | }; | 66 | }; |
62 | }; | 67 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi index 232c5c277bdb..5b1b84b58602 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi | |||
@@ -51,6 +51,7 @@ fman@400000 { | |||
51 | reg = <0xea000 0x1000>; | 51 | reg = <0xea000 0x1000>; |
52 | fsl,fman-ports = <&fman0_rx_0x0d &fman0_tx_0x2d>; | 52 | fsl,fman-ports = <&fman0_rx_0x0d &fman0_tx_0x2d>; |
53 | ptp-timer = <&ptp_timer0>; | 53 | ptp-timer = <&ptp_timer0>; |
54 | pcsphy-handle = <&pcsphy5>; | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | mdio@eb000 { | 57 | mdio@eb000 { |
@@ -58,5 +59,9 @@ fman@400000 { | |||
58 | #size-cells = <0>; | 59 | #size-cells = <0>; |
59 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 60 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
60 | reg = <0xeb000 0x1000>; | 61 | reg = <0xeb000 0x1000>; |
62 | |||
63 | pcsphy5: ethernet-phy@0 { | ||
64 | reg = <0x0>; | ||
65 | }; | ||
61 | }; | 66 | }; |
62 | }; | 67 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi index 89d64ee282b0..0e1daaef9e74 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi | |||
@@ -52,6 +52,7 @@ fman@500000 { | |||
52 | compatible = "fsl,fman-memac"; | 52 | compatible = "fsl,fman-memac"; |
53 | reg = <0xf0000 0x1000>; | 53 | reg = <0xf0000 0x1000>; |
54 | fsl,fman-ports = <&fman1_rx_0x10 &fman1_tx_0x30>; | 54 | fsl,fman-ports = <&fman1_rx_0x10 &fman1_tx_0x30>; |
55 | pcsphy-handle = <&pcsphy14>; | ||
55 | }; | 56 | }; |
56 | 57 | ||
57 | mdio@f1000 { | 58 | mdio@f1000 { |
@@ -59,5 +60,9 @@ fman@500000 { | |||
59 | #size-cells = <0>; | 60 | #size-cells = <0>; |
60 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 61 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
61 | reg = <0xf1000 0x1000>; | 62 | reg = <0xf1000 0x1000>; |
63 | |||
64 | pcsphy14: ethernet-phy@0 { | ||
65 | reg = <0x0>; | ||
66 | }; | ||
62 | }; | 67 | }; |
63 | }; | 68 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi index 7fa9260889c6..68c5ef779266 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi | |||
@@ -52,6 +52,7 @@ fman@500000 { | |||
52 | compatible = "fsl,fman-memac"; | 52 | compatible = "fsl,fman-memac"; |
53 | reg = <0xf2000 0x1000>; | 53 | reg = <0xf2000 0x1000>; |
54 | fsl,fman-ports = <&fman1_rx_0x11 &fman1_tx_0x31>; | 54 | fsl,fman-ports = <&fman1_rx_0x11 &fman1_tx_0x31>; |
55 | pcsphy-handle = <&pcsphy15>; | ||
55 | }; | 56 | }; |
56 | 57 | ||
57 | mdio@f3000 { | 58 | mdio@f3000 { |
@@ -59,5 +60,9 @@ fman@500000 { | |||
59 | #size-cells = <0>; | 60 | #size-cells = <0>; |
60 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 61 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
61 | reg = <0xf3000 0x1000>; | 62 | reg = <0xf3000 0x1000>; |
63 | |||
64 | pcsphy15: ethernet-phy@0 { | ||
65 | reg = <0x0>; | ||
66 | }; | ||
62 | }; | 67 | }; |
63 | }; | 68 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi index 3d236662bf07..605363cc1117 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi | |||
@@ -51,6 +51,7 @@ fman@500000 { | |||
51 | reg = <0xe0000 0x1000>; | 51 | reg = <0xe0000 0x1000>; |
52 | fsl,fman-ports = <&fman1_rx_0x08 &fman1_tx_0x28>; | 52 | fsl,fman-ports = <&fman1_rx_0x08 &fman1_tx_0x28>; |
53 | ptp-timer = <&ptp_timer1>; | 53 | ptp-timer = <&ptp_timer1>; |
54 | pcsphy-handle = <&pcsphy8>; | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | mdio@e1000 { | 57 | mdio@e1000 { |
@@ -58,5 +59,9 @@ fman@500000 { | |||
58 | #size-cells = <0>; | 59 | #size-cells = <0>; |
59 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 60 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
60 | reg = <0xe1000 0x1000>; | 61 | reg = <0xe1000 0x1000>; |
62 | |||
63 | pcsphy8: ethernet-phy@0 { | ||
64 | reg = <0x0>; | ||
65 | }; | ||
61 | }; | 66 | }; |
62 | }; | 67 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi index 97dc2eedd462..1955dfa13634 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi | |||
@@ -51,6 +51,7 @@ fman@500000 { | |||
51 | reg = <0xe2000 0x1000>; | 51 | reg = <0xe2000 0x1000>; |
52 | fsl,fman-ports = <&fman1_rx_0x09 &fman1_tx_0x29>; | 52 | fsl,fman-ports = <&fman1_rx_0x09 &fman1_tx_0x29>; |
53 | ptp-timer = <&ptp_timer1>; | 53 | ptp-timer = <&ptp_timer1>; |
54 | pcsphy-handle = <&pcsphy9>; | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | mdio@e3000 { | 57 | mdio@e3000 { |
@@ -58,5 +59,9 @@ fman@500000 { | |||
58 | #size-cells = <0>; | 59 | #size-cells = <0>; |
59 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 60 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
60 | reg = <0xe3000 0x1000>; | 61 | reg = <0xe3000 0x1000>; |
62 | |||
63 | pcsphy9: ethernet-phy@0 { | ||
64 | reg = <0x0>; | ||
65 | }; | ||
61 | }; | 66 | }; |
62 | }; | 67 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi index f084dd2f0bec..2c1476454ee0 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi | |||
@@ -51,6 +51,7 @@ fman@500000 { | |||
51 | reg = <0xe4000 0x1000>; | 51 | reg = <0xe4000 0x1000>; |
52 | fsl,fman-ports = <&fman1_rx_0x0a &fman1_tx_0x2a>; | 52 | fsl,fman-ports = <&fman1_rx_0x0a &fman1_tx_0x2a>; |
53 | ptp-timer = <&ptp_timer1>; | 53 | ptp-timer = <&ptp_timer1>; |
54 | pcsphy-handle = <&pcsphy10>; | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | mdio@e5000 { | 57 | mdio@e5000 { |
@@ -58,5 +59,9 @@ fman@500000 { | |||
58 | #size-cells = <0>; | 59 | #size-cells = <0>; |
59 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 60 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
60 | reg = <0xe5000 0x1000>; | 61 | reg = <0xe5000 0x1000>; |
62 | |||
63 | pcsphy10: ethernet-phy@0 { | ||
64 | reg = <0x0>; | ||
65 | }; | ||
61 | }; | 66 | }; |
62 | }; | 67 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi index bb627b3bf3db..b8b541ff5fb0 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi | |||
@@ -51,6 +51,7 @@ fman@500000 { | |||
51 | reg = <0xe6000 0x1000>; | 51 | reg = <0xe6000 0x1000>; |
52 | fsl,fman-ports = <&fman1_rx_0x0b &fman1_tx_0x2b>; | 52 | fsl,fman-ports = <&fman1_rx_0x0b &fman1_tx_0x2b>; |
53 | ptp-timer = <&ptp_timer1>; | 53 | ptp-timer = <&ptp_timer1>; |
54 | pcsphy-handle = <&pcsphy11>; | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | mdio@e7000 { | 57 | mdio@e7000 { |
@@ -58,5 +59,9 @@ fman@500000 { | |||
58 | #size-cells = <0>; | 59 | #size-cells = <0>; |
59 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 60 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
60 | reg = <0xe7000 0x1000>; | 61 | reg = <0xe7000 0x1000>; |
62 | |||
63 | pcsphy11: ethernet-phy@0 { | ||
64 | reg = <0x0>; | ||
65 | }; | ||
61 | }; | 66 | }; |
62 | }; | 67 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi index 821ed12225d4..4b2cfddd1b15 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi | |||
@@ -51,6 +51,7 @@ fman@500000 { | |||
51 | reg = <0xe8000 0x1000>; | 51 | reg = <0xe8000 0x1000>; |
52 | fsl,fman-ports = <&fman1_rx_0x0c &fman1_tx_0x2c>; | 52 | fsl,fman-ports = <&fman1_rx_0x0c &fman1_tx_0x2c>; |
53 | ptp-timer = <&ptp_timer1>; | 53 | ptp-timer = <&ptp_timer1>; |
54 | pcsphy-handle = <&pcsphy12>; | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | mdio@e9000 { | 57 | mdio@e9000 { |
@@ -58,5 +59,9 @@ fman@500000 { | |||
58 | #size-cells = <0>; | 59 | #size-cells = <0>; |
59 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 60 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
60 | reg = <0xe9000 0x1000>; | 61 | reg = <0xe9000 0x1000>; |
62 | |||
63 | pcsphy12: ethernet-phy@0 { | ||
64 | reg = <0x0>; | ||
65 | }; | ||
61 | }; | 66 | }; |
62 | }; | 67 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi index e245f1a1e42a..0a52ddf7cc17 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi | |||
@@ -51,6 +51,7 @@ fman@500000 { | |||
51 | reg = <0xea000 0x1000>; | 51 | reg = <0xea000 0x1000>; |
52 | fsl,fman-ports = <&fman1_rx_0x0d &fman1_tx_0x2d>; | 52 | fsl,fman-ports = <&fman1_rx_0x0d &fman1_tx_0x2d>; |
53 | ptp-timer = <&ptp_timer1>; | 53 | ptp-timer = <&ptp_timer1>; |
54 | pcsphy-handle = <&pcsphy13>; | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | mdio@eb000 { | 57 | mdio@eb000 { |
@@ -58,5 +59,9 @@ fman@500000 { | |||
58 | #size-cells = <0>; | 59 | #size-cells = <0>; |
59 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; | 60 | compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
60 | reg = <0xeb000 0x1000>; | 61 | reg = <0xeb000 0x1000>; |
62 | |||
63 | pcsphy13: ethernet-phy@0 { | ||
64 | reg = <0x0>; | ||
65 | }; | ||
61 | }; | 66 | }; |
62 | }; | 67 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/sbc8641d.dts b/arch/powerpc/boot/dts/fsl/sbc8641d.dts new file mode 100644 index 000000000000..0a9733cd418d --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/sbc8641d.dts | |||
@@ -0,0 +1,203 @@ | |||
1 | /* | ||
2 | * SBC8641D Device Tree Source | ||
3 | * | ||
4 | * Copyright 2008 Wind River Systems Inc. | ||
5 | * | ||
6 | * Paul Gortmaker (see MAINTAINERS for contact information) | ||
7 | * | ||
8 | * Based largely on the mpc8641_hpcn.dts by Freescale Semiconductor Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | */ | ||
15 | |||
16 | /include/ "mpc8641si-pre.dtsi" | ||
17 | |||
18 | / { | ||
19 | model = "SBC8641D"; | ||
20 | compatible = "wind,sbc8641"; | ||
21 | |||
22 | aliases { | ||
23 | pci1 = &pci1; | ||
24 | }; | ||
25 | |||
26 | memory { | ||
27 | device_type = "memory"; | ||
28 | reg = <0x00000000 0x20000000>; // 512M at 0x0 | ||
29 | }; | ||
30 | |||
31 | lbc: localbus@f8005000 { | ||
32 | reg = <0xf8005000 0x1000>; | ||
33 | |||
34 | ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash | ||
35 | 1 0 0xf0000000 0x00010000 // 64KB EEPROM | ||
36 | 2 0 0xf1000000 0x00100000 // EPLD (1MB) | ||
37 | 3 0 0xe0000000 0x04000000 // 64MB LB SDRAM (CS3) | ||
38 | 4 0 0xe4000000 0x04000000 // 64MB LB SDRAM (CS4) | ||
39 | 6 0 0xf4000000 0x00100000 // LCD display (1MB) | ||
40 | 7 0 0xe8000000 0x04000000>; // 64MB OneNAND | ||
41 | |||
42 | flash@0,0 { | ||
43 | compatible = "cfi-flash"; | ||
44 | reg = <0 0 0x01000000>; | ||
45 | bank-width = <2>; | ||
46 | device-width = <2>; | ||
47 | #address-cells = <1>; | ||
48 | #size-cells = <1>; | ||
49 | partition@0 { | ||
50 | label = "dtb"; | ||
51 | reg = <0x00000000 0x00100000>; | ||
52 | read-only; | ||
53 | }; | ||
54 | partition@300000 { | ||
55 | label = "kernel"; | ||
56 | reg = <0x00100000 0x00400000>; | ||
57 | read-only; | ||
58 | }; | ||
59 | partition@400000 { | ||
60 | label = "fs"; | ||
61 | reg = <0x00500000 0x00a00000>; | ||
62 | }; | ||
63 | partition@700000 { | ||
64 | label = "firmware"; | ||
65 | reg = <0x00f00000 0x00100000>; | ||
66 | read-only; | ||
67 | }; | ||
68 | }; | ||
69 | |||
70 | epld@2,0 { | ||
71 | compatible = "wrs,epld-localbus"; | ||
72 | #address-cells = <2>; | ||
73 | #size-cells = <1>; | ||
74 | reg = <2 0 0x100000>; | ||
75 | ranges = <0 0 5 0 1 // User switches | ||
76 | 1 0 5 1 1 // Board ID/Rev | ||
77 | 3 0 5 3 1>; // LEDs | ||
78 | }; | ||
79 | }; | ||
80 | |||
81 | soc: soc@f8000000 { | ||
82 | ranges = <0x00000000 0xf8000000 0x00100000>; | ||
83 | |||
84 | enet0: ethernet@24000 { | ||
85 | tbi-handle = <&tbi0>; | ||
86 | phy-handle = <&phy0>; | ||
87 | phy-connection-type = "rgmii-id"; | ||
88 | }; | ||
89 | |||
90 | mdio@24520 { | ||
91 | phy0: ethernet-phy@1f { | ||
92 | reg = <0x1f>; | ||
93 | }; | ||
94 | phy1: ethernet-phy@0 { | ||
95 | reg = <0>; | ||
96 | }; | ||
97 | phy2: ethernet-phy@1 { | ||
98 | reg = <1>; | ||
99 | }; | ||
100 | phy3: ethernet-phy@2 { | ||
101 | reg = <2>; | ||
102 | }; | ||
103 | tbi0: tbi-phy@11 { | ||
104 | reg = <0x11>; | ||
105 | device_type = "tbi-phy"; | ||
106 | }; | ||
107 | }; | ||
108 | |||
109 | enet1: ethernet@25000 { | ||
110 | tbi-handle = <&tbi1>; | ||
111 | phy-handle = <&phy1>; | ||
112 | phy-connection-type = "rgmii-id"; | ||
113 | }; | ||
114 | |||
115 | mdio@25520 { | ||
116 | tbi1: tbi-phy@11 { | ||
117 | reg = <0x11>; | ||
118 | device_type = "tbi-phy"; | ||
119 | }; | ||
120 | }; | ||
121 | |||
122 | enet2: ethernet@26000 { | ||
123 | tbi-handle = <&tbi2>; | ||
124 | phy-handle = <&phy2>; | ||
125 | phy-connection-type = "rgmii-id"; | ||
126 | }; | ||
127 | |||
128 | mdio@26520 { | ||
129 | tbi2: tbi-phy@11 { | ||
130 | reg = <0x11>; | ||
131 | device_type = "tbi-phy"; | ||
132 | }; | ||
133 | }; | ||
134 | |||
135 | enet3: ethernet@27000 { | ||
136 | tbi-handle = <&tbi3>; | ||
137 | phy-handle = <&phy3>; | ||
138 | phy-connection-type = "rgmii-id"; | ||
139 | }; | ||
140 | |||
141 | mdio@27520 { | ||
142 | tbi3: tbi-phy@11 { | ||
143 | reg = <0x11>; | ||
144 | device_type = "tbi-phy"; | ||
145 | }; | ||
146 | }; | ||
147 | }; | ||
148 | |||
149 | pci0: pcie@f8008000 { | ||
150 | reg = <0xf8008000 0x1000>; | ||
151 | ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000 | ||
152 | 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>; | ||
153 | interrupt-map-mask = <0xff00 0 0 7>; | ||
154 | |||
155 | pcie@0 { | ||
156 | ranges = <0x02000000 0x0 0x80000000 | ||
157 | 0x02000000 0x0 0x80000000 | ||
158 | 0x0 0x20000000 | ||
159 | |||
160 | 0x01000000 0x0 0x00000000 | ||
161 | 0x01000000 0x0 0x00000000 | ||
162 | 0x0 0x00100000>; | ||
163 | }; | ||
164 | |||
165 | }; | ||
166 | |||
167 | pci1: pcie@f8009000 { | ||
168 | compatible = "fsl,mpc8641-pcie"; | ||
169 | device_type = "pci"; | ||
170 | #size-cells = <2>; | ||
171 | #address-cells = <3>; | ||
172 | reg = <0xf8009000 0x1000>; | ||
173 | bus-range = <0 0xff>; | ||
174 | ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000 | ||
175 | 0x01000000 0x0 0x00000000 0xe3000000 0x0 0x00100000>; | ||
176 | clock-frequency = <100000000>; | ||
177 | interrupts = <25 2 0 0>; | ||
178 | interrupt-map-mask = <0xf800 0 0 7>; | ||
179 | interrupt-map = < | ||
180 | /* IDSEL 0x0 */ | ||
181 | 0x0000 0 0 1 &mpic 4 1 | ||
182 | 0x0000 0 0 2 &mpic 5 1 | ||
183 | 0x0000 0 0 3 &mpic 6 1 | ||
184 | 0x0000 0 0 4 &mpic 7 1 | ||
185 | >; | ||
186 | |||
187 | pcie@0 { | ||
188 | reg = <0 0 0 0 0>; | ||
189 | #size-cells = <2>; | ||
190 | #address-cells = <3>; | ||
191 | device_type = "pci"; | ||
192 | ranges = <0x02000000 0x0 0xa0000000 | ||
193 | 0x02000000 0x0 0xa0000000 | ||
194 | 0x0 0x20000000 | ||
195 | |||
196 | 0x01000000 0x0 0x00000000 | ||
197 | 0x01000000 0x0 0x00000000 | ||
198 | 0x0 0x00100000>; | ||
199 | }; | ||
200 | }; | ||
201 | }; | ||
202 | |||
203 | /include/ "mpc8641si-post.dtsi" | ||
diff --git a/arch/powerpc/boot/dts/fsl/t1023rdb.dts b/arch/powerpc/boot/dts/fsl/t1023rdb.dts index 6bd842beb1dc..29757623e5ba 100644 --- a/arch/powerpc/boot/dts/fsl/t1023rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1023rdb.dts | |||
@@ -79,7 +79,7 @@ | |||
79 | flash@0 { | 79 | flash@0 { |
80 | #address-cells = <1>; | 80 | #address-cells = <1>; |
81 | #size-cells = <1>; | 81 | #size-cells = <1>; |
82 | compatible = "spansion,s25fl512s"; | 82 | compatible = "spansion,s25fl512s", "jedec,spi-nor"; |
83 | reg = <0>; | 83 | reg = <0>; |
84 | spi-max-frequency = <10000000>; /* input clk */ | 84 | spi-max-frequency = <10000000>; /* input clk */ |
85 | }; | 85 | }; |
@@ -111,6 +111,47 @@ | |||
111 | shunt-resistor = <1000>; | 111 | shunt-resistor = <1000>; |
112 | }; | 112 | }; |
113 | }; | 113 | }; |
114 | |||
115 | fman@400000 { | ||
116 | fm1mac1: ethernet@e0000 { | ||
117 | phy-handle = <&sgmii_rtk_phy2>; | ||
118 | phy-connection-type = "sgmii"; | ||
119 | sleep = <&rcpm 0x80000000>; | ||
120 | }; | ||
121 | |||
122 | fm1mac2: ethernet@e2000 { | ||
123 | sleep = <&rcpm 0x40000000>; | ||
124 | }; | ||
125 | |||
126 | fm1mac3: ethernet@e4000 { | ||
127 | phy-handle = <&sgmii_aqr_phy3>; | ||
128 | phy-connection-type = "sgmii-2500"; | ||
129 | sleep = <&rcpm 0x20000000>; | ||
130 | }; | ||
131 | |||
132 | fm1mac4: ethernet@e6000 { | ||
133 | phy-handle = <&rgmii_rtk_phy1>; | ||
134 | phy-connection-type = "rgmii"; | ||
135 | sleep = <&rcpm 0x10000000>; | ||
136 | }; | ||
137 | |||
138 | |||
139 | mdio0: mdio@fc000 { | ||
140 | rgmii_rtk_phy1: ethernet-phy@1 { | ||
141 | reg = <0x1>; | ||
142 | }; | ||
143 | sgmii_rtk_phy2: ethernet-phy@3 { | ||
144 | reg = <0x3>; | ||
145 | }; | ||
146 | }; | ||
147 | |||
148 | xmdio0: mdio@fd000 { | ||
149 | sgmii_aqr_phy3: ethernet-phy@2 { | ||
150 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
151 | reg = <0x2>; | ||
152 | }; | ||
153 | }; | ||
154 | }; | ||
114 | }; | 155 | }; |
115 | 156 | ||
116 | pci0: pcie@ffe240000 { | 157 | pci0: pcie@ffe240000 { |
diff --git a/arch/powerpc/boot/dts/fsl/t1024qds.dts b/arch/powerpc/boot/dts/fsl/t1024qds.dts index 6a3581b8e1f8..772143da367f 100644 --- a/arch/powerpc/boot/dts/fsl/t1024qds.dts +++ b/arch/powerpc/boot/dts/fsl/t1024qds.dts | |||
@@ -87,7 +87,7 @@ | |||
87 | flash@0 { | 87 | flash@0 { |
88 | #address-cells = <1>; | 88 | #address-cells = <1>; |
89 | #size-cells = <1>; | 89 | #size-cells = <1>; |
90 | compatible = "micron,n25q128a11"; /* 16MB */ | 90 | compatible = "micron,n25q128a11", "jedec,spi-nor"; /* 16MB */ |
91 | reg = <0>; | 91 | reg = <0>; |
92 | spi-max-frequency = <10000000>; | 92 | spi-max-frequency = <10000000>; |
93 | }; | 93 | }; |
@@ -95,7 +95,7 @@ | |||
95 | flash@1 { | 95 | flash@1 { |
96 | #address-cells = <1>; | 96 | #address-cells = <1>; |
97 | #size-cells = <1>; | 97 | #size-cells = <1>; |
98 | compatible = "sst,sst25wf040"; /* 512KB */ | 98 | compatible = "sst,sst25wf040", "jedec,spi-nor"; /* 512KB */ |
99 | reg = <1>; | 99 | reg = <1>; |
100 | spi-max-frequency = <10000000>; | 100 | spi-max-frequency = <10000000>; |
101 | }; | 101 | }; |
@@ -103,7 +103,7 @@ | |||
103 | flash@2 { | 103 | flash@2 { |
104 | #address-cells = <1>; | 104 | #address-cells = <1>; |
105 | #size-cells = <1>; | 105 | #size-cells = <1>; |
106 | compatible = "eon,en25s64"; /* 8MB */ | 106 | compatible = "eon,en25s64", "jedec,spi-nor"; /* 8MB */ |
107 | reg = <2>; | 107 | reg = <2>; |
108 | spi-max-frequency = <10000000>; | 108 | spi-max-frequency = <10000000>; |
109 | }; | 109 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/t1024rdb.dts b/arch/powerpc/boot/dts/fsl/t1024rdb.dts index 0ccc7d03335e..302cdd22b4bb 100644 --- a/arch/powerpc/boot/dts/fsl/t1024rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1024rdb.dts | |||
@@ -89,7 +89,7 @@ | |||
89 | flash@0 { | 89 | flash@0 { |
90 | #address-cells = <1>; | 90 | #address-cells = <1>; |
91 | #size-cells = <1>; | 91 | #size-cells = <1>; |
92 | compatible = "micron,n25q512ax3"; | 92 | compatible = "micron,n25q512ax3", "jedec,spi-nor"; |
93 | reg = <0>; | 93 | reg = <0>; |
94 | spi-max-frequency = <10000000>; /* input clk */ | 94 | spi-max-frequency = <10000000>; /* input clk */ |
95 | }; | 95 | }; |
@@ -140,6 +140,51 @@ | |||
140 | #size-cells = <0>; | 140 | #size-cells = <0>; |
141 | }; | 141 | }; |
142 | }; | 142 | }; |
143 | |||
144 | fman@400000 { | ||
145 | fm1mac1: ethernet@e0000 { | ||
146 | phy-handle = <&xg_aqr105_phy3>; | ||
147 | phy-connection-type = "xgmii"; | ||
148 | sleep = <&rcpm 0x80000000>; | ||
149 | }; | ||
150 | |||
151 | fm1mac2: ethernet@e2000 { | ||
152 | sleep = <&rcpm 0x40000000>; | ||
153 | }; | ||
154 | |||
155 | fm1mac3: ethernet@e4000 { | ||
156 | phy-handle = <&rgmii_phy2>; | ||
157 | phy-connection-type = "rgmii"; | ||
158 | sleep = <&rcpm 0x20000000>; | ||
159 | }; | ||
160 | |||
161 | fm1mac4: ethernet@e6000 { | ||
162 | phy-handle = <&rgmii_phy1>; | ||
163 | phy-connection-type = "rgmii"; | ||
164 | sleep = <&rcpm 0x10000000>; | ||
165 | }; | ||
166 | |||
167 | |||
168 | mdio0: mdio@fc000 { | ||
169 | rgmii_phy1: ethernet-phy@2 { | ||
170 | reg = <0x2>; | ||
171 | }; | ||
172 | rgmii_phy2: ethernet-phy@6 { | ||
173 | reg = <0x6>; | ||
174 | }; | ||
175 | }; | ||
176 | |||
177 | xmdio0: mdio@fd000 { | ||
178 | xg_aqr105_phy3: ethernet-phy@1 { | ||
179 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
180 | reg = <0x1>; | ||
181 | }; | ||
182 | sg_2500_aqr105_phy4: ethernet-phy@2 { | ||
183 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
184 | reg = <0x2>; | ||
185 | }; | ||
186 | }; | ||
187 | }; | ||
143 | }; | 188 | }; |
144 | 189 | ||
145 | pci0: pcie@ffe240000 { | 190 | pci0: pcie@ffe240000 { |
diff --git a/arch/powerpc/boot/dts/fsl/t1040rdb.dts b/arch/powerpc/boot/dts/fsl/t1040rdb.dts index cf194154bbdc..621f2c6ee6ad 100644 --- a/arch/powerpc/boot/dts/fsl/t1040rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1040rdb.dts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * T1040RDB Device Tree Source | 2 | * T1040RDB Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2014 Freescale Semiconductor Inc. | 4 | * Copyright 2014 - 2015 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: |
@@ -38,6 +38,36 @@ | |||
38 | / { | 38 | / { |
39 | model = "fsl,T1040RDB"; | 39 | model = "fsl,T1040RDB"; |
40 | compatible = "fsl,T1040RDB"; | 40 | compatible = "fsl,T1040RDB"; |
41 | |||
42 | aliases { | ||
43 | phy_sgmii_2 = &phy_sgmii_2; | ||
44 | }; | ||
45 | |||
46 | soc@ffe000000 { | ||
47 | fman@400000 { | ||
48 | ethernet@e0000 { | ||
49 | fixed-link = <0 1 1000 0 0>; | ||
50 | phy-connection-type = "sgmii"; | ||
51 | }; | ||
52 | |||
53 | ethernet@e2000 { | ||
54 | fixed-link = <1 1 1000 0 0>; | ||
55 | phy-connection-type = "sgmii"; | ||
56 | }; | ||
57 | |||
58 | ethernet@e4000 { | ||
59 | phy-handle = <&phy_sgmii_2>; | ||
60 | phy-connection-type = "sgmii"; | ||
61 | }; | ||
62 | |||
63 | mdio@fc000 { | ||
64 | phy_sgmii_2: ethernet-phy@03 { | ||
65 | reg = <0x03>; | ||
66 | }; | ||
67 | }; | ||
68 | }; | ||
69 | }; | ||
70 | |||
41 | ifc: localbus@ffe124000 { | 71 | ifc: localbus@ffe124000 { |
42 | cpld@3,0 { | 72 | cpld@3,0 { |
43 | compatible = "fsl,t1040rdb-cpld"; | 73 | compatible = "fsl,t1040rdb-cpld"; |
diff --git a/arch/powerpc/boot/dts/fsl/t1042rdb.dts b/arch/powerpc/boot/dts/fsl/t1042rdb.dts index 8d908e795e4d..2c138627b1b4 100644 --- a/arch/powerpc/boot/dts/fsl/t1042rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1042rdb.dts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * T1042RDB Device Tree Source | 2 | * T1042RDB Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2014 Freescale Semiconductor Inc. | 4 | * Copyright 2014 - 2015 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: |
@@ -38,6 +38,34 @@ | |||
38 | / { | 38 | / { |
39 | model = "fsl,T1042RDB"; | 39 | model = "fsl,T1042RDB"; |
40 | compatible = "fsl,T1042RDB"; | 40 | compatible = "fsl,T1042RDB"; |
41 | |||
42 | aliases { | ||
43 | phy_sgmii_2 = &phy_sgmii_2; | ||
44 | }; | ||
45 | |||
46 | soc@ffe000000 { | ||
47 | fman@400000 { | ||
48 | ethernet@e0000 { | ||
49 | status = "disabled"; | ||
50 | }; | ||
51 | |||
52 | ethernet@e2000 { | ||
53 | status = "disabled"; | ||
54 | }; | ||
55 | |||
56 | ethernet@e4000 { | ||
57 | phy-handle = <&phy_sgmii_2>; | ||
58 | phy-connection-type = "sgmii"; | ||
59 | }; | ||
60 | |||
61 | mdio@fc000 { | ||
62 | phy_sgmii_2: ethernet-phy@03 { | ||
63 | reg = <0x03>; | ||
64 | }; | ||
65 | }; | ||
66 | }; | ||
67 | }; | ||
68 | |||
41 | ifc: localbus@ffe124000 { | 69 | ifc: localbus@ffe124000 { |
42 | cpld@3,0 { | 70 | cpld@3,0 { |
43 | compatible = "fsl,t1042rdb-cpld"; | 71 | compatible = "fsl,t1042rdb-cpld"; |
diff --git a/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts b/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts index 98c001019d6a..8ec3ff45e6fc 100644 --- a/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts +++ b/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * T1042RDB_PI Device Tree Source | 2 | * T1042RDB_PI Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2014 Freescale Semiconductor Inc. | 4 | * Copyright 2014 - 2015 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: |
@@ -38,11 +38,13 @@ | |||
38 | / { | 38 | / { |
39 | model = "fsl,T1042RDB_PI"; | 39 | model = "fsl,T1042RDB_PI"; |
40 | compatible = "fsl,T1042RDB_PI"; | 40 | compatible = "fsl,T1042RDB_PI"; |
41 | |||
41 | ifc: localbus@ffe124000 { | 42 | ifc: localbus@ffe124000 { |
42 | cpld@3,0 { | 43 | cpld@3,0 { |
43 | compatible = "fsl,t1042rdb_pi-cpld"; | 44 | compatible = "fsl,t1042rdb_pi-cpld"; |
44 | }; | 45 | }; |
45 | }; | 46 | }; |
47 | |||
46 | soc: soc@ffe000000 { | 48 | soc: soc@ffe000000 { |
47 | i2c@118000 { | 49 | i2c@118000 { |
48 | rtc@68 { | 50 | rtc@68 { |
@@ -51,6 +53,20 @@ | |||
51 | interrupts = <0x2 0x1 0 0>; | 53 | interrupts = <0x2 0x1 0 0>; |
52 | }; | 54 | }; |
53 | }; | 55 | }; |
56 | |||
57 | fman@400000 { | ||
58 | ethernet@e0000 { | ||
59 | status = "disabled"; | ||
60 | }; | ||
61 | |||
62 | ethernet@e2000 { | ||
63 | status = "disabled"; | ||
64 | }; | ||
65 | |||
66 | ethernet@e4000 { | ||
67 | status = "disabled"; | ||
68 | }; | ||
69 | }; | ||
54 | }; | 70 | }; |
55 | }; | 71 | }; |
56 | 72 | ||
diff --git a/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi b/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi index 3f6d7c6a106b..8c7ea6c05de9 100644 --- a/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi | |||
@@ -104,7 +104,7 @@ | |||
104 | flash@0 { | 104 | flash@0 { |
105 | #address-cells = <1>; | 105 | #address-cells = <1>; |
106 | #size-cells = <1>; | 106 | #size-cells = <1>; |
107 | compatible = "micron,n25q512ax3"; | 107 | compatible = "micron,n25q512ax3", "jedec,spi-nor"; |
108 | reg = <0>; | 108 | reg = <0>; |
109 | /* input clock */ | 109 | /* input clock */ |
110 | spi-max-frequency = <10000000>; | 110 | spi-max-frequency = <10000000>; |
diff --git a/arch/powerpc/boot/dts/fsl/t104xqds.dtsi b/arch/powerpc/boot/dts/fsl/t104xqds.dtsi index 1498d1e4aecf..977af355b388 100644 --- a/arch/powerpc/boot/dts/fsl/t104xqds.dtsi +++ b/arch/powerpc/boot/dts/fsl/t104xqds.dtsi | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * T104xQDS Device Tree Source | 2 | * T104xQDS Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2013 - 2014 Freescale Semiconductor Inc. | 4 | * Copyright 2013 - 2015 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: |
@@ -38,6 +38,33 @@ | |||
38 | #size-cells = <2>; | 38 | #size-cells = <2>; |
39 | interrupt-parent = <&mpic>; | 39 | interrupt-parent = <&mpic>; |
40 | 40 | ||
41 | aliases { | ||
42 | emi1_rgmii0 = &t1040mdio0; | ||
43 | emi1_rgmii1 = &t1040mdio1; | ||
44 | emi1_slot3 = &t1040mdio3; | ||
45 | emi1_slot5 = &t1040mdio5; | ||
46 | emi1_slot6 = &t1040mdio6; | ||
47 | emi1_slot7 = &t1040mdio7; | ||
48 | rgmii_phy1 = &rgmii_phy1; | ||
49 | rgmii_phy2 = &rgmii_phy2; | ||
50 | phy_s3_01 = &phy_s3_01; | ||
51 | phy_s3_02 = &phy_s3_02; | ||
52 | phy_s3_03 = &phy_s3_03; | ||
53 | phy_s3_04 = &phy_s3_04; | ||
54 | phy_s5_01 = &phy_s5_01; | ||
55 | phy_s5_02 = &phy_s5_02; | ||
56 | phy_s5_03 = &phy_s5_03; | ||
57 | phy_s5_04 = &phy_s5_04; | ||
58 | phy_s6_01 = &phy_s6_01; | ||
59 | phy_s6_02 = &phy_s6_02; | ||
60 | phy_s6_03 = &phy_s6_03; | ||
61 | phy_s6_04 = &phy_s6_04; | ||
62 | phy_s7_01 = &phy_s7_01; | ||
63 | phy_s7_02 = &phy_s7_02; | ||
64 | phy_s7_03 = &phy_s7_03; | ||
65 | phy_s7_04 = &phy_s7_04; | ||
66 | }; | ||
67 | |||
41 | reserved-memory { | 68 | reserved-memory { |
42 | #address-cells = <2>; | 69 | #address-cells = <2>; |
43 | #size-cells = <2>; | 70 | #size-cells = <2>; |
@@ -85,6 +112,128 @@ | |||
85 | #size-cells = <1>; | 112 | #size-cells = <1>; |
86 | compatible = "fsl,fpga-qixis"; | 113 | compatible = "fsl,fpga-qixis"; |
87 | reg = <3 0 0x300>; | 114 | reg = <3 0 0x300>; |
115 | ranges = <0 3 0 0x300>; | ||
116 | |||
117 | mdio-mux-emi1 { | ||
118 | #address-cells = <1>; | ||
119 | #size-cells = <0>; | ||
120 | compatible = "mdio-mux-mmioreg", "mdio-mux"; | ||
121 | mdio-parent-bus = <&mdio0>; | ||
122 | reg = <0x54 1>; | ||
123 | mux-mask = <0xe0>; | ||
124 | |||
125 | t1040mdio0: mdio@0 { | ||
126 | #address-cells = <1>; | ||
127 | #size-cells = <0>; | ||
128 | reg = <0x00>; | ||
129 | status = "disabled"; | ||
130 | |||
131 | rgmii_phy1: ethernet-phy@1 { | ||
132 | reg = <0x1>; | ||
133 | }; | ||
134 | }; | ||
135 | |||
136 | t1040mdio1: mdio@20 { | ||
137 | #address-cells = <1>; | ||
138 | #size-cells = <0>; | ||
139 | reg = <0x20>; | ||
140 | status = "disabled"; | ||
141 | |||
142 | rgmii_phy2: ethernet-phy@2 { | ||
143 | reg = <0x2>; | ||
144 | }; | ||
145 | }; | ||
146 | |||
147 | t1040mdio3: mdio@60 { | ||
148 | #address-cells = <1>; | ||
149 | #size-cells = <0>; | ||
150 | reg = <0x60>; | ||
151 | status = "disabled"; | ||
152 | |||
153 | phy_s3_01: ethernet-phy@1c { | ||
154 | reg = <0x1c>; | ||
155 | }; | ||
156 | |||
157 | phy_s3_02: ethernet-phy@1d { | ||
158 | reg = <0x1d>; | ||
159 | }; | ||
160 | |||
161 | phy_s3_03: ethernet-phy@1e { | ||
162 | reg = <0x1e>; | ||
163 | }; | ||
164 | |||
165 | phy_s3_04: ethernet-phy@1f { | ||
166 | reg = <0x1f>; | ||
167 | }; | ||
168 | }; | ||
169 | |||
170 | t1040mdio5: mdio@a0 { | ||
171 | #address-cells = <1>; | ||
172 | #size-cells = <0>; | ||
173 | reg = <0xa0>; | ||
174 | |||
175 | phy_s5_01: ethernet-phy@1c { | ||
176 | reg = <0x14>; | ||
177 | }; | ||
178 | |||
179 | phy_s5_02: ethernet-phy@1d { | ||
180 | reg = <0x15>; | ||
181 | }; | ||
182 | |||
183 | phy_s5_03: ethernet-phy@1e { | ||
184 | reg = <0x16>; | ||
185 | }; | ||
186 | |||
187 | phy_s5_04: ethernet-phy@1f { | ||
188 | reg = <0x17>; | ||
189 | }; | ||
190 | }; | ||
191 | |||
192 | t1040mdio6: mdio@c0 { | ||
193 | #address-cells = <1>; | ||
194 | #size-cells = <0>; | ||
195 | reg = <0xc0>; | ||
196 | |||
197 | phy_s6_01: ethernet-phy@1c { | ||
198 | reg = <0x18>; | ||
199 | }; | ||
200 | |||
201 | phy_s6_02: ethernet-phy@1d { | ||
202 | reg = <0x19>; | ||
203 | }; | ||
204 | |||
205 | phy_s6_03: ethernet-phy@1e { | ||
206 | reg = <0x1a>; | ||
207 | }; | ||
208 | |||
209 | phy_s6_04: ethernet-phy@1f { | ||
210 | reg = <0x1b>; | ||
211 | }; | ||
212 | }; | ||
213 | |||
214 | t1040mdio7: mdio@e0 { | ||
215 | #address-cells = <1>; | ||
216 | #size-cells = <0>; | ||
217 | reg = <0xe0>; | ||
218 | status = "disabled"; | ||
219 | |||
220 | phy_s7_01: ethernet-phy@1c { | ||
221 | reg = <0x1c>; | ||
222 | }; | ||
223 | |||
224 | phy_s7_02: ethernet-phy@1d { | ||
225 | reg = <0x1d>; | ||
226 | }; | ||
227 | |||
228 | phy_s7_03: ethernet-phy@1e { | ||
229 | reg = <0x1e>; | ||
230 | }; | ||
231 | |||
232 | phy_s7_04: ethernet-phy@1f { | ||
233 | reg = <0x1f>; | ||
234 | }; | ||
235 | }; | ||
236 | }; | ||
88 | }; | 237 | }; |
89 | }; | 238 | }; |
90 | 239 | ||
@@ -112,7 +261,7 @@ | |||
112 | flash@0 { | 261 | flash@0 { |
113 | #address-cells = <1>; | 262 | #address-cells = <1>; |
114 | #size-cells = <1>; | 263 | #size-cells = <1>; |
115 | compatible = "micron,n25q128a11"; | 264 | compatible = "micron,n25q128a11", "jedec,spi-nor"; |
116 | reg = <0>; | 265 | reg = <0>; |
117 | spi-max-frequency = <10000000>; /* input clock */ | 266 | spi-max-frequency = <10000000>; /* input clock */ |
118 | }; | 267 | }; |
@@ -129,6 +278,33 @@ | |||
129 | interrupts = <0x1 0x1 0 0>; | 278 | interrupts = <0x1 0x1 0 0>; |
130 | }; | 279 | }; |
131 | }; | 280 | }; |
281 | |||
282 | fman@400000 { | ||
283 | ethernet@e0000 { | ||
284 | fixed-link = <0 1 1000 0 0>; | ||
285 | phy-connection-type = "sgmii"; | ||
286 | }; | ||
287 | |||
288 | ethernet@e2000 { | ||
289 | fixed-link = <1 1 1000 0 0>; | ||
290 | phy-connection-type = "sgmii"; | ||
291 | }; | ||
292 | |||
293 | ethernet@e4000 { | ||
294 | phy-handle = <&phy_s7_03>; | ||
295 | phy-connection-type = "sgmii"; | ||
296 | }; | ||
297 | |||
298 | ethernet@e6000 { | ||
299 | phy-handle = <&rgmii_phy1>; | ||
300 | phy-connection-type = "rgmii"; | ||
301 | }; | ||
302 | |||
303 | ethernet@e8000 { | ||
304 | phy-handle = <&rgmii_phy2>; | ||
305 | phy-connection-type = "rgmii"; | ||
306 | }; | ||
307 | }; | ||
132 | }; | 308 | }; |
133 | 309 | ||
134 | pci0: pcie@ffe240000 { | 310 | pci0: pcie@ffe240000 { |
diff --git a/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi b/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi index 830ea484295b..72691ef102ee 100644 --- a/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * T1040RDB/T1042RDB Device Tree Source | 2 | * T1040RDB/T1042RDB Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2014 Freescale Semiconductor Inc. | 4 | * Copyright 2014 - 2015 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,6 +33,12 @@ | |||
33 | */ | 33 | */ |
34 | 34 | ||
35 | / { | 35 | / { |
36 | aliases { | ||
37 | phy_rgmii_0 = &phy_rgmii_0; | ||
38 | phy_rgmii_1 = &phy_rgmii_1; | ||
39 | phy_sgmii_2 = &phy_sgmii_2; | ||
40 | }; | ||
41 | |||
36 | reserved-memory { | 42 | reserved-memory { |
37 | #address-cells = <2>; | 43 | #address-cells = <2>; |
38 | #size-cells = <2>; | 44 | #size-cells = <2>; |
@@ -103,10 +109,15 @@ | |||
103 | flash@0 { | 109 | flash@0 { |
104 | #address-cells = <1>; | 110 | #address-cells = <1>; |
105 | #size-cells = <1>; | 111 | #size-cells = <1>; |
106 | compatible = "micron,n25q512a"; | 112 | compatible = "micron,n25q512a", "jedec,spi-nor"; |
107 | reg = <0>; | 113 | reg = <0>; |
108 | spi-max-frequency = <10000000>; /* input clock */ | 114 | spi-max-frequency = <10000000>; /* input clock */ |
109 | }; | 115 | }; |
116 | slic@3 { | ||
117 | compatible = "maxim,ds26522"; | ||
118 | reg = <3>; | ||
119 | spi-max-frequency = <2000000>; /* input clock */ | ||
120 | }; | ||
110 | }; | 121 | }; |
111 | 122 | ||
112 | i2c@118000 { | 123 | i2c@118000 { |
@@ -125,6 +136,31 @@ | |||
125 | }; | 136 | }; |
126 | }; | 137 | }; |
127 | 138 | ||
139 | fman@400000 { | ||
140 | ethernet@e6000 { | ||
141 | phy-handle = <&phy_rgmii_0>; | ||
142 | phy-connection-type = "rgmii"; | ||
143 | }; | ||
144 | |||
145 | ethernet@e8000 { | ||
146 | phy-handle = <&phy_rgmii_1>; | ||
147 | phy-connection-type = "rgmii"; | ||
148 | }; | ||
149 | |||
150 | mdio0: mdio@fc000 { | ||
151 | phy_sgmii_2: ethernet-phy@03 { | ||
152 | reg = <0x03>; | ||
153 | }; | ||
154 | |||
155 | phy_rgmii_0: ethernet-phy@01 { | ||
156 | reg = <0x01>; | ||
157 | }; | ||
158 | |||
159 | phy_rgmii_1: ethernet-phy@02 { | ||
160 | reg = <0x02>; | ||
161 | }; | ||
162 | }; | ||
163 | }; | ||
128 | }; | 164 | }; |
129 | 165 | ||
130 | pci0: pcie@ffe240000 { | 166 | pci0: pcie@ffe240000 { |
diff --git a/arch/powerpc/boot/dts/fsl/t2080qds.dts b/arch/powerpc/boot/dts/fsl/t2080qds.dts index 9c8e10fe04cb..8d190e8c62ce 100644 --- a/arch/powerpc/boot/dts/fsl/t2080qds.dts +++ b/arch/powerpc/boot/dts/fsl/t2080qds.dts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * T2080QDS Device Tree Source | 2 | * T2080QDS Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2013 Freescale Semiconductor Inc. | 4 | * Copyright 2013 - 2015 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: |
@@ -42,6 +42,12 @@ | |||
42 | #size-cells = <2>; | 42 | #size-cells = <2>; |
43 | interrupt-parent = <&mpic>; | 43 | interrupt-parent = <&mpic>; |
44 | 44 | ||
45 | aliases { | ||
46 | emi1_slot1 = &t2080mdio2; | ||
47 | emi1_slot2 = &t2080mdio3; | ||
48 | emi1_slot3 = &t2080mdio4; | ||
49 | }; | ||
50 | |||
45 | rio: rapidio@ffe0c0000 { | 51 | rio: rapidio@ffe0c0000 { |
46 | reg = <0xf 0xfe0c0000 0 0x11000>; | 52 | reg = <0xf 0xfe0c0000 0 0x11000>; |
47 | 53 | ||
@@ -54,4 +60,154 @@ | |||
54 | }; | 60 | }; |
55 | }; | 61 | }; |
56 | 62 | ||
63 | &soc { | ||
64 | fman@400000 { | ||
65 | ethernet@e0000 { | ||
66 | phy-handle = <&phy_sgmii_s3_1e>; | ||
67 | phy-connection-type = "xgmii"; | ||
68 | }; | ||
69 | |||
70 | ethernet@e2000 { | ||
71 | phy-handle = <&phy_sgmii_s3_1f>; | ||
72 | phy-connection-type = "xgmii"; | ||
73 | }; | ||
74 | |||
75 | ethernet@e4000 { | ||
76 | phy-handle = <&rgmii_phy1>; | ||
77 | phy-connection-type = "rgmii"; | ||
78 | }; | ||
79 | |||
80 | ethernet@e6000 { | ||
81 | phy-handle = <&rgmii_phy2>; | ||
82 | phy-connection-type = "rgmii"; | ||
83 | }; | ||
84 | |||
85 | ethernet@e8000 { | ||
86 | phy-handle = <&phy_sgmii_s2_1e>; | ||
87 | phy-connection-type = "sgmii"; | ||
88 | }; | ||
89 | |||
90 | ethernet@ea000 { | ||
91 | phy-handle = <&phy_sgmii_s2_1d>; | ||
92 | phy-connection-type = "sgmii"; | ||
93 | }; | ||
94 | |||
95 | ethernet@f0000 { | ||
96 | phy-handle = <&phy_xaui_slot3>; | ||
97 | phy-connection-type = "xgmii"; | ||
98 | }; | ||
99 | |||
100 | ethernet@f2000 { | ||
101 | phy-handle = <&phy_sgmii_s3_1f>; | ||
102 | phy-connection-type = "xgmii"; | ||
103 | }; | ||
104 | |||
105 | mdio@fd000 { | ||
106 | phy_xaui_slot3: ethernet-phy@3 { | ||
107 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
108 | reg = <0x3>; | ||
109 | }; | ||
110 | }; | ||
111 | }; | ||
112 | }; | ||
113 | |||
114 | &boardctrl { | ||
115 | mdio-mux-emi1 { | ||
116 | compatible = "mdio-mux-mmioreg", "mdio-mux"; | ||
117 | mdio-parent-bus = <&mdio0>; | ||
118 | #address-cells = <1>; | ||
119 | #size-cells = <0>; | ||
120 | reg = <0x54 1>; | ||
121 | mux-mask = <0xe0>; | ||
122 | |||
123 | t2080mdio0: mdio@0 { | ||
124 | #address-cells = <1>; | ||
125 | #size-cells = <0>; | ||
126 | reg = <0>; | ||
127 | |||
128 | rgmii_phy1: ethernet-phy@1 { | ||
129 | reg = <0x1>; | ||
130 | }; | ||
131 | }; | ||
132 | |||
133 | t2080mdio1: mdio@20 { | ||
134 | #address-cells = <1>; | ||
135 | #size-cells = <0>; | ||
136 | reg = <0x20>; | ||
137 | |||
138 | rgmii_phy2: ethernet-phy@2 { | ||
139 | reg = <0x2>; | ||
140 | }; | ||
141 | }; | ||
142 | |||
143 | t2080mdio2: mdio@40 { | ||
144 | #address-cells = <1>; | ||
145 | #size-cells = <0>; | ||
146 | reg = <0x40>; | ||
147 | status = "disabled"; | ||
148 | |||
149 | phy_sgmii_s1_1c: ethernet-phy@1c { | ||
150 | reg = <0x1c>; | ||
151 | }; | ||
152 | |||
153 | phy_sgmii_s1_1d: ethernet-phy@1d { | ||
154 | reg = <0x1d>; | ||
155 | }; | ||
156 | |||
157 | phy_sgmii_s1_1e: ethernet-phy@1e { | ||
158 | reg = <0x1e>; | ||
159 | }; | ||
160 | |||
161 | phy_sgmii_s1_1f: ethernet-phy@1f { | ||
162 | reg = <0x1f>; | ||
163 | }; | ||
164 | }; | ||
165 | |||
166 | t2080mdio3: mdio@c0 { | ||
167 | #address-cells = <1>; | ||
168 | #size-cells = <0>; | ||
169 | reg = <0xc0>; | ||
170 | |||
171 | phy_sgmii_s2_1c: ethernet-phy@1c { | ||
172 | reg = <0x1c>; | ||
173 | }; | ||
174 | |||
175 | phy_sgmii_s2_1d: ethernet-phy@1d { | ||
176 | reg = <0x1d>; | ||
177 | }; | ||
178 | |||
179 | phy_sgmii_s2_1e: ethernet-phy@1e { | ||
180 | reg = <0x1e>; | ||
181 | }; | ||
182 | |||
183 | phy_sgmii_s2_1f: ethernet-phy@1f { | ||
184 | reg = <0x1f>; | ||
185 | }; | ||
186 | }; | ||
187 | |||
188 | t2080mdio4: mdio@60 { | ||
189 | #address-cells = <1>; | ||
190 | #size-cells = <0>; | ||
191 | reg = <0x60>; | ||
192 | status = "disabled"; | ||
193 | |||
194 | phy_sgmii_s3_1c: ethernet-phy@1c { | ||
195 | reg = <0x1c>; | ||
196 | }; | ||
197 | |||
198 | phy_sgmii_s3_1d: ethernet-phy@1d { | ||
199 | reg = <0x1d>; | ||
200 | }; | ||
201 | |||
202 | phy_sgmii_s3_1e: ethernet-phy@1e { | ||
203 | reg = <0x1e>; | ||
204 | }; | ||
205 | |||
206 | phy_sgmii_s3_1f: ethernet-phy@1f { | ||
207 | reg = <0x1f>; | ||
208 | }; | ||
209 | }; | ||
210 | }; | ||
211 | }; | ||
212 | |||
57 | /include/ "t2080si-post.dtsi" | 213 | /include/ "t2080si-post.dtsi" |
diff --git a/arch/powerpc/boot/dts/fsl/t2080rdb.dts b/arch/powerpc/boot/dts/fsl/t2080rdb.dts index 33205bf08919..836e4c965b22 100644 --- a/arch/powerpc/boot/dts/fsl/t2080rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t2080rdb.dts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * T2080PCIe-RDB Board Device Tree Source | 2 | * T2080PCIe-RDB Board Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2014 Freescale Semiconductor Inc. | 4 | * Copyright 2014 - 2015 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: |
@@ -54,4 +54,69 @@ | |||
54 | }; | 54 | }; |
55 | }; | 55 | }; |
56 | 56 | ||
57 | &soc { | ||
58 | fman@400000 { | ||
59 | ethernet@e0000 { | ||
60 | phy-handle = <&xg_aq1202_phy3>; | ||
61 | phy-connection-type = "xgmii"; | ||
62 | }; | ||
63 | |||
64 | ethernet@e2000 { | ||
65 | phy-handle = <&xg_aq1202_phy4>; | ||
66 | phy-connection-type = "xgmii"; | ||
67 | }; | ||
68 | |||
69 | ethernet@e4000 { | ||
70 | phy-handle = <&rgmii_phy1>; | ||
71 | phy-connection-type = "rgmii"; | ||
72 | }; | ||
73 | |||
74 | ethernet@e6000 { | ||
75 | phy-handle = <&rgmii_phy2>; | ||
76 | phy-connection-type = "rgmii"; | ||
77 | }; | ||
78 | |||
79 | ethernet@f0000 { | ||
80 | phy-handle = <&xg_cs4315_phy1>; | ||
81 | phy-connection-type = "xgmii"; | ||
82 | }; | ||
83 | |||
84 | ethernet@f2000 { | ||
85 | phy-handle = <&xg_cs4315_phy2>; | ||
86 | phy-connection-type = "xgmii"; | ||
87 | }; | ||
88 | |||
89 | mdio@fc000 { | ||
90 | rgmii_phy1: ethernet-phy@1 { | ||
91 | reg = <0x1>; | ||
92 | }; | ||
93 | rgmii_phy2: ethernet-phy@2 { | ||
94 | reg = <0x2>; | ||
95 | }; | ||
96 | }; | ||
97 | |||
98 | mdio@fd000 { | ||
99 | xg_cs4315_phy1: ethernet-phy@c { | ||
100 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
101 | reg = <0xc>; | ||
102 | }; | ||
103 | |||
104 | xg_cs4315_phy2: ethernet-phy@d { | ||
105 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
106 | reg = <0xd>; | ||
107 | }; | ||
108 | |||
109 | xg_aq1202_phy3: ethernet-phy@0 { | ||
110 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
111 | reg = <0x0>; | ||
112 | }; | ||
113 | |||
114 | xg_aq1202_phy4: ethernet-phy@1 { | ||
115 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
116 | reg = <0x1>; | ||
117 | }; | ||
118 | }; | ||
119 | }; | ||
120 | }; | ||
121 | |||
57 | /include/ "t2080si-post.dtsi" | 122 | /include/ "t2080si-post.dtsi" |
diff --git a/arch/powerpc/boot/dts/fsl/t2081qds.dts b/arch/powerpc/boot/dts/fsl/t2081qds.dts index b81213596dbf..fc5c4a30f7ad 100644 --- a/arch/powerpc/boot/dts/fsl/t2081qds.dts +++ b/arch/powerpc/boot/dts/fsl/t2081qds.dts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * T2081QDS Device Tree Source | 2 | * T2081QDS Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2013 Freescale Semiconductor Inc. | 4 | * Copyright 2013 - 2015 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: |
@@ -41,6 +41,225 @@ | |||
41 | #address-cells = <2>; | 41 | #address-cells = <2>; |
42 | #size-cells = <2>; | 42 | #size-cells = <2>; |
43 | interrupt-parent = <&mpic>; | 43 | interrupt-parent = <&mpic>; |
44 | |||
45 | aliases { | ||
46 | emi1_slot1 = &t2081mdio2; | ||
47 | emi1_slot2 = &t2081mdio3; | ||
48 | emi1_slot3 = &t2081mdio4; | ||
49 | emi1_slot5 = &t2081mdio5; | ||
50 | emi1_slot6 = &t2081mdio6; | ||
51 | emi1_slot7 = &t2081mdio7; | ||
52 | }; | ||
53 | }; | ||
54 | |||
55 | &soc { | ||
56 | fman@400000 { | ||
57 | ethernet@e0000 { | ||
58 | phy-handle = <&phy_sgmii_s7_1c>; | ||
59 | phy-connection-type = "sgmii"; | ||
60 | }; | ||
61 | |||
62 | ethernet@e2000 { | ||
63 | phy-handle = <&phy_sgmii_s7_1d>; | ||
64 | phy-connection-type = "sgmii"; | ||
65 | }; | ||
66 | |||
67 | ethernet@e4000 { | ||
68 | phy-handle = <&rgmii_phy1>; | ||
69 | phy-connection-type = "rgmii"; | ||
70 | }; | ||
71 | |||
72 | ethernet@e6000 { | ||
73 | phy-handle = <&rgmii_phy2>; | ||
74 | phy-connection-type = "rgmii"; | ||
75 | }; | ||
76 | |||
77 | ethernet@e8000 { | ||
78 | phy-handle = <&phy_sgmii_s3_1c>; | ||
79 | phy-connection-type = "sgmii"; | ||
80 | }; | ||
81 | |||
82 | ethernet@ea000 { | ||
83 | phy-handle = <&phy_sgmii_s7_1f>; | ||
84 | phy-connection-type = "sgmii"; | ||
85 | }; | ||
86 | |||
87 | ethernet@f0000 { | ||
88 | phy-handle = <&phy_sgmii_s2_1c>; | ||
89 | phy-connection-type = "xgmii"; | ||
90 | }; | ||
91 | |||
92 | ethernet@f2000 { | ||
93 | phy-handle = <&phy_sgmii_s7_1e>; | ||
94 | phy-connection-type = "xgmii"; | ||
95 | }; | ||
96 | }; | ||
97 | }; | ||
98 | |||
99 | &boardctrl { | ||
100 | mdio-mux-emi1 { | ||
101 | compatible = "mdio-mux-mmioreg", "mdio-mux"; | ||
102 | mdio-parent-bus = <&mdio0>; | ||
103 | #address-cells = <1>; | ||
104 | #size-cells = <0>; | ||
105 | reg = <0x54 1>; | ||
106 | mux-mask = <0xe0>; | ||
107 | |||
108 | t2081mdio0: mdio@0 { | ||
109 | #address-cells = <1>; | ||
110 | #size-cells = <0>; | ||
111 | reg = <0>; | ||
112 | |||
113 | rgmii_phy1: ethernet-phy@1 { | ||
114 | reg = <0x1>; | ||
115 | }; | ||
116 | }; | ||
117 | |||
118 | t2081mdio1: mdio@20 { | ||
119 | #address-cells = <1>; | ||
120 | #size-cells = <0>; | ||
121 | reg = <0x20>; | ||
122 | |||
123 | rgmii_phy2: ethernet-phy@2 { | ||
124 | reg = <0x2>; | ||
125 | }; | ||
126 | }; | ||
127 | |||
128 | t2081mdio2: mdio@40 { | ||
129 | #address-cells = <1>; | ||
130 | #size-cells = <0>; | ||
131 | reg = <0x40>; | ||
132 | |||
133 | phy_sgmii_s1_1c: ethernet-phy@1c { | ||
134 | reg = <0x1c>; | ||
135 | }; | ||
136 | |||
137 | phy_sgmii_s1_1d: ethernet-phy@1d { | ||
138 | reg = <0x1d>; | ||
139 | }; | ||
140 | |||
141 | phy_sgmii_s1_1e: ethernet-phy@1e { | ||
142 | reg = <0x1e>; | ||
143 | }; | ||
144 | |||
145 | phy_sgmii_s1_1f: ethernet-phy@1f { | ||
146 | reg = <0x1f>; | ||
147 | }; | ||
148 | }; | ||
149 | |||
150 | t2081mdio3: mdio@60 { | ||
151 | #address-cells = <1>; | ||
152 | #size-cells = <0>; | ||
153 | reg = <0x60>; | ||
154 | |||
155 | phy_sgmii_s2_1c: ethernet-phy@1c { | ||
156 | reg = <0x1c>; | ||
157 | }; | ||
158 | |||
159 | phy_sgmii_s2_1d: ethernet-phy@1d { | ||
160 | reg = <0x1d>; | ||
161 | }; | ||
162 | |||
163 | phy_sgmii_s2_1e: ethernet-phy@1e { | ||
164 | reg = <0x1e>; | ||
165 | }; | ||
166 | |||
167 | phy_sgmii_s2_1f: ethernet-phy@1f { | ||
168 | reg = <0x1f>; | ||
169 | }; | ||
170 | }; | ||
171 | |||
172 | t2081mdio4: mdio@80 { | ||
173 | #address-cells = <1>; | ||
174 | #size-cells = <0>; | ||
175 | reg = <0x80>; | ||
176 | status = "disabled"; | ||
177 | |||
178 | phy_sgmii_s3_1c: ethernet-phy@1c { | ||
179 | reg = <0x1c>; | ||
180 | }; | ||
181 | |||
182 | phy_sgmii_s3_1d: ethernet-phy@1d { | ||
183 | reg = <0x1d>; | ||
184 | }; | ||
185 | |||
186 | phy_sgmii_s3_1e: ethernet-phy@1e { | ||
187 | reg = <0x1e>; | ||
188 | }; | ||
189 | |||
190 | phy_sgmii_s3_1f: ethernet-phy@1f { | ||
191 | reg = <0x1f>; | ||
192 | }; | ||
193 | }; | ||
194 | |||
195 | t2081mdio5: mdio@a0 { | ||
196 | #address-cells = <1>; | ||
197 | #size-cells = <0>; | ||
198 | reg = <0xa0>; | ||
199 | status = "disabled"; | ||
200 | |||
201 | phy_sgmii_s5_1c: ethernet-phy@1c { | ||
202 | reg = <0x1c>; | ||
203 | }; | ||
204 | |||
205 | phy_sgmii_s5_1d: ethernet-phy@1d { | ||
206 | reg = <0x1d>; | ||
207 | }; | ||
208 | |||
209 | phy_sgmii_s5_1e: ethernet-phy@1e { | ||
210 | reg = <0x1e>; | ||
211 | }; | ||
212 | |||
213 | phy_sgmii_s5_1f: ethernet-phy@1f { | ||
214 | reg = <0x1f>; | ||
215 | }; | ||
216 | }; | ||
217 | |||
218 | t2081mdio6: mdio@c0 { | ||
219 | #address-cells = <1>; | ||
220 | #size-cells = <0>; | ||
221 | reg = <0xc0>; | ||
222 | status = "disabled"; | ||
223 | |||
224 | phy_sgmii_s6_1c: ethernet-phy@1c { | ||
225 | reg = <0x1c>; | ||
226 | }; | ||
227 | |||
228 | phy_sgmii_s6_1d: ethernet-phy@1d { | ||
229 | reg = <0x1d>; | ||
230 | }; | ||
231 | |||
232 | phy_sgmii_s6_1e: ethernet-phy@1e { | ||
233 | reg = <0x1e>; | ||
234 | }; | ||
235 | |||
236 | phy_sgmii_s6_1f: ethernet-phy@1f { | ||
237 | reg = <0x1f>; | ||
238 | }; | ||
239 | }; | ||
240 | |||
241 | t2081mdio7: mdio@e0 { | ||
242 | #address-cells = <1>; | ||
243 | #size-cells = <0>; | ||
244 | reg = <0xe0>; | ||
245 | |||
246 | phy_sgmii_s7_1c: ethernet-phy@1c { | ||
247 | reg = <0x1c>; | ||
248 | }; | ||
249 | |||
250 | phy_sgmii_s7_1d: ethernet-phy@1d { | ||
251 | reg = <0x1d>; | ||
252 | }; | ||
253 | |||
254 | phy_sgmii_s7_1e: ethernet-phy@1e { | ||
255 | reg = <0x1e>; | ||
256 | }; | ||
257 | |||
258 | phy_sgmii_s7_1f: ethernet-phy@1f { | ||
259 | reg = <0x1f>; | ||
260 | }; | ||
261 | }; | ||
262 | }; | ||
44 | }; | 263 | }; |
45 | 264 | ||
46 | /include/ "t2081si-post.dtsi" | 265 | /include/ "t2081si-post.dtsi" |
diff --git a/arch/powerpc/boot/dts/fsl/t208xqds.dtsi b/arch/powerpc/boot/dts/fsl/t208xqds.dtsi index 869f9159b4d1..ec080bd01b09 100644 --- a/arch/powerpc/boot/dts/fsl/t208xqds.dtsi +++ b/arch/powerpc/boot/dts/fsl/t208xqds.dtsi | |||
@@ -112,7 +112,7 @@ | |||
112 | flash@0 { | 112 | flash@0 { |
113 | #address-cells = <1>; | 113 | #address-cells = <1>; |
114 | #size-cells = <1>; | 114 | #size-cells = <1>; |
115 | compatible = "micron,n25q128a11"; /* 16MB */ | 115 | compatible = "micron,n25q128a11", "jedec,spi-nor"; /* 16MB */ |
116 | reg = <0>; | 116 | reg = <0>; |
117 | spi-max-frequency = <40000000>; /* input clock */ | 117 | spi-max-frequency = <40000000>; /* input clock */ |
118 | }; | 118 | }; |
@@ -120,7 +120,7 @@ | |||
120 | flash@1 { | 120 | flash@1 { |
121 | #address-cells = <1>; | 121 | #address-cells = <1>; |
122 | #size-cells = <1>; | 122 | #size-cells = <1>; |
123 | compatible = "sst,sst25wf040"; | 123 | compatible = "sst,sst25wf040", "jedec,spi-nor"; |
124 | reg = <1>; | 124 | reg = <1>; |
125 | spi-max-frequency = <35000000>; | 125 | spi-max-frequency = <35000000>; |
126 | }; | 126 | }; |
@@ -128,7 +128,7 @@ | |||
128 | flash@2 { | 128 | flash@2 { |
129 | #address-cells = <1>; | 129 | #address-cells = <1>; |
130 | #size-cells = <1>; | 130 | #size-cells = <1>; |
131 | compatible = "eon,en25s64"; | 131 | compatible = "eon,en25s64", "jedec,spi-nor"; |
132 | reg = <2>; | 132 | reg = <2>; |
133 | spi-max-frequency = <35000000>; | 133 | spi-max-frequency = <35000000>; |
134 | }; | 134 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/t208xrdb.dtsi b/arch/powerpc/boot/dts/fsl/t208xrdb.dtsi index 693d2a8fa01c..dc9326875778 100644 --- a/arch/powerpc/boot/dts/fsl/t208xrdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/t208xrdb.dtsi | |||
@@ -113,7 +113,7 @@ | |||
113 | flash@0 { | 113 | flash@0 { |
114 | #address-cells = <1>; | 114 | #address-cells = <1>; |
115 | #size-cells = <1>; | 115 | #size-cells = <1>; |
116 | compatible = "micron,n25q512a"; | 116 | compatible = "micron,n25q512a", "jedec,spi-nor"; |
117 | reg = <0>; | 117 | reg = <0>; |
118 | spi-max-frequency = <10000000>; /* input clock */ | 118 | spi-max-frequency = <10000000>; /* input clock */ |
119 | }; | 119 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/t4240qds.dts b/arch/powerpc/boot/dts/fsl/t4240qds.dts index c067a6533809..9573ceada07c 100644 --- a/arch/powerpc/boot/dts/fsl/t4240qds.dts +++ b/arch/powerpc/boot/dts/fsl/t4240qds.dts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * T4240QDS Device Tree Source | 2 | * T4240QDS Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2012 - 2014 Freescale Semiconductor Inc. | 4 | * Copyright 2012 - 2015 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: |
@@ -41,6 +41,44 @@ | |||
41 | #size-cells = <2>; | 41 | #size-cells = <2>; |
42 | interrupt-parent = <&mpic>; | 42 | interrupt-parent = <&mpic>; |
43 | 43 | ||
44 | aliases{ | ||
45 | phy_rgmii1 = &phyrgmii1; | ||
46 | phy_rgmii2 = &phyrgmii2; | ||
47 | phy_sgmii3 = &phy3; | ||
48 | phy_sgmii4 = &phy4; | ||
49 | phy_sgmii11 = &phy11; | ||
50 | phy_sgmii12 = &phy12; | ||
51 | sgmii_phy11 = &sgmiiphy11; | ||
52 | sgmii_phy12 = &sgmiiphy12; | ||
53 | sgmii_phy13 = &sgmiiphy13; | ||
54 | sgmii_phy14 = &sgmiiphy14; | ||
55 | sgmii_phy21 = &sgmiiphy21; | ||
56 | sgmii_phy22 = &sgmiiphy22; | ||
57 | sgmii_phy23 = &sgmiiphy23; | ||
58 | sgmii_phy24 = &sgmiiphy24; | ||
59 | sgmii_phy31 = &sgmiiphy31; | ||
60 | sgmii_phy32 = &sgmiiphy32; | ||
61 | sgmii_phy33 = &sgmiiphy33; | ||
62 | sgmii_phy34 = &sgmiiphy34; | ||
63 | sgmii_phy41 = &sgmiiphy41; | ||
64 | sgmii_phy42 = &sgmiiphy42; | ||
65 | sgmii_phy43 = &sgmiiphy43; | ||
66 | sgmii_phy44 = &sgmiiphy44; | ||
67 | phy_xfi1 = &xfiphy1; | ||
68 | phy_xfi2 = &xfiphy2; | ||
69 | phy_xfi3 = &xfiphy3; | ||
70 | phy_xfi4 = &xfiphy4; | ||
71 | xfi_pcs_mdio1 = &xfimdio0; | ||
72 | xfi_pcs_mdio2 = &xfimdio1; | ||
73 | xfi_pcs_mdio3 = &xfimdio2; | ||
74 | xfi_pcs_mdio4 = &xfimdio3; | ||
75 | emi1_rgmii = &t4240mdio0; | ||
76 | emi1_slot1 = &t4240mdio1; | ||
77 | emi1_slot2 = &t4240mdio2; | ||
78 | emi1_slot3 = &t4240mdio3; | ||
79 | emi1_slot4 = &t4240mdio4; | ||
80 | }; | ||
81 | |||
44 | ifc: localbus@ffe124000 { | 82 | ifc: localbus@ffe124000 { |
45 | reg = <0xf 0xfe124000 0 0x2000>; | 83 | reg = <0xf 0xfe124000 0 0x2000>; |
46 | ranges = <0 0 0xf 0xe8000000 0x08000000 | 84 | ranges = <0 0 0xf 0xe8000000 0x08000000 |
@@ -91,8 +129,190 @@ | |||
91 | }; | 129 | }; |
92 | 130 | ||
93 | board-control@3,0 { | 131 | board-control@3,0 { |
132 | #address-cells = <1>; | ||
133 | #size-cells = <1>; | ||
94 | compatible = "fsl,t4240qds-fpga", "fsl,fpga-qixis"; | 134 | compatible = "fsl,t4240qds-fpga", "fsl,fpga-qixis"; |
95 | reg = <3 0 0x300>; | 135 | reg = <3 0 0x300>; |
136 | ranges = <0 3 0 0x300>; | ||
137 | |||
138 | mdio-mux-emi1 { | ||
139 | #address-cells = <1>; | ||
140 | #size-cells = <0>; | ||
141 | compatible = "mdio-mux-mmioreg", "mdio-mux"; | ||
142 | mdio-parent-bus = <&mdio1>; | ||
143 | reg = <0x54 1>; | ||
144 | mux-mask = <0xe0>; | ||
145 | |||
146 | t4240mdio0: mdio@0 { | ||
147 | #address-cells = <1>; | ||
148 | #size-cells = <0>; | ||
149 | reg = <0>; | ||
150 | |||
151 | phyrgmii1: ethernet-phy@1 { | ||
152 | reg = <0x1>; | ||
153 | }; | ||
154 | |||
155 | phyrgmii2: ethernet-phy@2 { | ||
156 | reg = <0x2>; | ||
157 | }; | ||
158 | }; | ||
159 | |||
160 | t4240mdio1: mdio@20 { | ||
161 | #address-cells = <1>; | ||
162 | #size-cells = <0>; | ||
163 | reg = <0x20>; | ||
164 | status = "disabled"; | ||
165 | |||
166 | phy1: ethernet-phy@0 { | ||
167 | reg = <0x0>; | ||
168 | }; | ||
169 | |||
170 | phy2: ethernet-phy@1 { | ||
171 | reg = <0x1>; | ||
172 | }; | ||
173 | |||
174 | phy3: ethernet-phy@2 { | ||
175 | reg = <0x2>; | ||
176 | }; | ||
177 | |||
178 | phy4: ethernet-phy@3 { | ||
179 | reg = <0x3>; | ||
180 | }; | ||
181 | |||
182 | sgmiiphy11: ethernet-phy@1c { | ||
183 | reg = <0x1c>; | ||
184 | }; | ||
185 | |||
186 | sgmiiphy12: ethernet-phy@1d { | ||
187 | reg = <0x1d>; | ||
188 | }; | ||
189 | |||
190 | sgmiiphy13: ethernet-phy@1e { | ||
191 | reg = <0x1e>; | ||
192 | }; | ||
193 | |||
194 | sgmiiphy14: ethernet-phy@1f { | ||
195 | reg = <0x1f>; | ||
196 | }; | ||
197 | }; | ||
198 | |||
199 | t4240mdio2: mdio@40 { | ||
200 | #address-cells = <1>; | ||
201 | #size-cells = <0>; | ||
202 | reg = <0x40>; | ||
203 | status = "disabled"; | ||
204 | |||
205 | phy5: ethernet-phy@4 { | ||
206 | reg = <0x4>; | ||
207 | }; | ||
208 | |||
209 | phy6: ethernet-phy@5 { | ||
210 | reg = <0x5>; | ||
211 | }; | ||
212 | |||
213 | phy7: ethernet-phy@6 { | ||
214 | reg = <0x6>; | ||
215 | }; | ||
216 | |||
217 | phy8: ethernet-phy@7 { | ||
218 | reg = <0x7>; | ||
219 | }; | ||
220 | |||
221 | sgmiiphy21: ethernet-phy@1c { | ||
222 | reg = <0x1c>; | ||
223 | }; | ||
224 | |||
225 | sgmiiphy22: ethernet-phy@1d { | ||
226 | reg = <0x1d>; | ||
227 | }; | ||
228 | |||
229 | sgmiiphy23: ethernet-phy@1e { | ||
230 | reg = <0x1e>; | ||
231 | }; | ||
232 | |||
233 | sgmiiphy24: ethernet-phy@1f { | ||
234 | reg = <0x1f>; | ||
235 | }; | ||
236 | }; | ||
237 | |||
238 | t4240mdio3: mdio@60 { | ||
239 | #address-cells = <1>; | ||
240 | #size-cells = <0>; | ||
241 | reg = <0x60>; | ||
242 | status = "disabled"; | ||
243 | |||
244 | phy9: ethernet-phy@8 { | ||
245 | reg = <0x8>; | ||
246 | }; | ||
247 | |||
248 | phy10: ethernet-phy@9 { | ||
249 | reg = <0x9>; | ||
250 | }; | ||
251 | |||
252 | phy11: ethernet-phy@a { | ||
253 | reg = <0xa>; | ||
254 | }; | ||
255 | |||
256 | phy12: ethernet-phy@b { | ||
257 | reg = <0xb>; | ||
258 | }; | ||
259 | |||
260 | sgmiiphy31: ethernet-phy@1c { | ||
261 | reg = <0x1c>; | ||
262 | }; | ||
263 | |||
264 | sgmiiphy32: ethernet-phy@1d { | ||
265 | reg = <0x1d>; | ||
266 | }; | ||
267 | |||
268 | sgmiiphy33: ethernet-phy@1e { | ||
269 | reg = <0x1e>; | ||
270 | }; | ||
271 | |||
272 | sgmiiphy34: ethernet-phy@1f { | ||
273 | reg = <0x1f>; | ||
274 | }; | ||
275 | }; | ||
276 | |||
277 | t4240mdio4: mdio@80 { | ||
278 | #address-cells = <1>; | ||
279 | #size-cells = <0>; | ||
280 | reg = <0x80>; | ||
281 | status = "disabled"; | ||
282 | |||
283 | phy13: ethernet-phy@c { | ||
284 | reg = <0xc>; | ||
285 | }; | ||
286 | |||
287 | phy14: ethernet-phy@d { | ||
288 | reg = <0xd>; | ||
289 | }; | ||
290 | |||
291 | phy15: ethernet-phy@e { | ||
292 | reg = <0xe>; | ||
293 | }; | ||
294 | |||
295 | phy16: ethernet-phy@f { | ||
296 | reg = <0xf>; | ||
297 | }; | ||
298 | |||
299 | sgmiiphy41: ethernet-phy@1c { | ||
300 | reg = <0x1c>; | ||
301 | }; | ||
302 | |||
303 | sgmiiphy42: ethernet-phy@1d { | ||
304 | reg = <0x1d>; | ||
305 | }; | ||
306 | |||
307 | sgmiiphy43: ethernet-phy@1e { | ||
308 | reg = <0x1e>; | ||
309 | }; | ||
310 | |||
311 | sgmiiphy44: ethernet-phy@1f { | ||
312 | reg = <0x1f>; | ||
313 | }; | ||
314 | }; | ||
315 | }; | ||
96 | }; | 316 | }; |
97 | }; | 317 | }; |
98 | 318 | ||
@@ -138,7 +358,7 @@ | |||
138 | flash@0 { | 358 | flash@0 { |
139 | #address-cells = <1>; | 359 | #address-cells = <1>; |
140 | #size-cells = <1>; | 360 | #size-cells = <1>; |
141 | compatible = "sst,sst25wf040"; | 361 | compatible = "sst,sst25wf040", "jedec,spi-nor"; |
142 | reg = <0>; | 362 | reg = <0>; |
143 | spi-max-frequency = <40000000>; /* input clock */ | 363 | spi-max-frequency = <40000000>; /* input clock */ |
144 | }; | 364 | }; |
@@ -234,6 +454,184 @@ | |||
234 | sdhc@114000 { | 454 | sdhc@114000 { |
235 | voltage-ranges = <1800 1800 3300 3300>; | 455 | voltage-ranges = <1800 1800 3300 3300>; |
236 | }; | 456 | }; |
457 | |||
458 | fman@400000 { | ||
459 | port@83000 { | ||
460 | status = "disabled"; | ||
461 | }; | ||
462 | |||
463 | port@84000 { | ||
464 | status = "disabled"; | ||
465 | }; | ||
466 | |||
467 | port@85000 { | ||
468 | status = "disabled"; | ||
469 | }; | ||
470 | |||
471 | port@86000 { | ||
472 | status = "disabled"; | ||
473 | }; | ||
474 | |||
475 | port@87000 { | ||
476 | status = "disabled"; | ||
477 | }; | ||
478 | |||
479 | ethernet@e0000 { | ||
480 | phy-handle = <&phy5>; | ||
481 | phy-connection-type = "sgmii"; | ||
482 | }; | ||
483 | |||
484 | ethernet@e2000 { | ||
485 | phy-handle = <&phy6>; | ||
486 | phy-connection-type = "sgmii"; | ||
487 | }; | ||
488 | |||
489 | ethernet@e4000 { | ||
490 | phy-handle = <&phy7>; | ||
491 | phy-connection-type = "sgmii"; | ||
492 | }; | ||
493 | |||
494 | ethernet@e6000 { | ||
495 | phy-handle = <&phy8>; | ||
496 | phy-connection-type = "sgmii"; | ||
497 | }; | ||
498 | |||
499 | ethernet@e8000 { | ||
500 | phy-handle = <&phyrgmii2>; | ||
501 | phy-connection-type = "rgmii"; | ||
502 | }; | ||
503 | |||
504 | ethernet@ea000 { | ||
505 | phy-handle = <&phy2>; | ||
506 | phy-connection-type = "sgmii"; | ||
507 | }; | ||
508 | |||
509 | ethernet@f0000 { | ||
510 | phy-handle = <&xauiphy1>; | ||
511 | phy-connection-type = "xgmii"; | ||
512 | }; | ||
513 | |||
514 | ethernet@f2000 { | ||
515 | phy-handle = <&xauiphy2>; | ||
516 | phy-connection-type = "xgmii"; | ||
517 | }; | ||
518 | |||
519 | xfimdio0: mdio@f1000 { | ||
520 | status = "disabled"; | ||
521 | |||
522 | xfiphy1: ethernet-phy@0 { | ||
523 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
524 | reg = <0x0>; | ||
525 | }; | ||
526 | }; | ||
527 | |||
528 | xfimdio1: mdio@f3000 { | ||
529 | status = "disabled"; | ||
530 | |||
531 | xfiphy2: ethernet-phy@0 { | ||
532 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
533 | reg = <0x0>; | ||
534 | }; | ||
535 | }; | ||
536 | }; | ||
537 | |||
538 | fman@500000 { | ||
539 | port@84000 { | ||
540 | status = "disabled"; | ||
541 | }; | ||
542 | |||
543 | port@85000 { | ||
544 | status = "disabled"; | ||
545 | }; | ||
546 | |||
547 | port@86000 { | ||
548 | status = "disabled"; | ||
549 | }; | ||
550 | |||
551 | port@87000 { | ||
552 | status = "disabled"; | ||
553 | }; | ||
554 | |||
555 | ethernet@e0000 { | ||
556 | phy-handle = <&phy13>; | ||
557 | phy-connection-type = "sgmii"; | ||
558 | }; | ||
559 | |||
560 | ethernet@e2000 { | ||
561 | phy-handle = <&phy14>; | ||
562 | phy-connection-type = "sgmii"; | ||
563 | }; | ||
564 | |||
565 | ethernet@e4000 { | ||
566 | phy-handle = <&phy15>; | ||
567 | phy-connection-type = "sgmii"; | ||
568 | }; | ||
569 | |||
570 | ethernet@e6000 { | ||
571 | phy-handle = <&phy16>; | ||
572 | phy-connection-type = "sgmii"; | ||
573 | }; | ||
574 | |||
575 | ethernet@e8000 { | ||
576 | phy-handle = <&phyrgmii1>; | ||
577 | phy-connection-type = "rgmii"; | ||
578 | }; | ||
579 | |||
580 | ethernet@ea000 { | ||
581 | phy-handle = <&phy10>; | ||
582 | phy-connection-type = "sgmii"; | ||
583 | }; | ||
584 | |||
585 | ethernet@f0000 { | ||
586 | phy-handle = <&xauiphy3>; | ||
587 | phy-connection-type = "xgmii"; | ||
588 | }; | ||
589 | |||
590 | ethernet@f2000 { | ||
591 | phy-handle = <&xauiphy4>; | ||
592 | phy-connection-type = "xgmii"; | ||
593 | }; | ||
594 | |||
595 | xfimdio2: mdio@f1000 { | ||
596 | status = "disabled"; | ||
597 | |||
598 | xfiphy3: ethernet-phy@0 { | ||
599 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
600 | reg = <0x0>; | ||
601 | }; | ||
602 | }; | ||
603 | |||
604 | xfimdio3: mdio@f3000 { | ||
605 | status = "disabled"; | ||
606 | |||
607 | xfiphy4: ethernet-phy@0 { | ||
608 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
609 | reg = <0x0>; | ||
610 | }; | ||
611 | }; | ||
612 | |||
613 | mdio@fd000 { | ||
614 | xauiphy1: ethernet-phy@0 { | ||
615 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
616 | reg = <0x0>; | ||
617 | }; | ||
618 | |||
619 | xauiphy2: ethernet-phy@1 { | ||
620 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
621 | reg = <0x1>; | ||
622 | }; | ||
623 | |||
624 | xauiphy3: ethernet-phy@2 { | ||
625 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
626 | reg = <0x2>; | ||
627 | }; | ||
628 | |||
629 | xauiphy4: ethernet-phy@3 { | ||
630 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
631 | reg = <0x3>; | ||
632 | }; | ||
633 | }; | ||
634 | }; | ||
237 | }; | 635 | }; |
238 | 636 | ||
239 | pci0: pcie@ffe240000 { | 637 | pci0: pcie@ffe240000 { |
diff --git a/arch/powerpc/boot/dts/fsl/t4240rdb.dts b/arch/powerpc/boot/dts/fsl/t4240rdb.dts index 6e820a875621..cc0a264b8acb 100644 --- a/arch/powerpc/boot/dts/fsl/t4240rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t4240rdb.dts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * T4240RDB Device Tree Source | 2 | * T4240RDB Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2014 Freescale Semiconductor Inc. | 4 | * Copyright 2014 - 2015 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: |
@@ -41,6 +41,17 @@ | |||
41 | #size-cells = <2>; | 41 | #size-cells = <2>; |
42 | interrupt-parent = <&mpic>; | 42 | interrupt-parent = <&mpic>; |
43 | 43 | ||
44 | aliases { | ||
45 | sgmii_phy21 = &sgmiiphy21; | ||
46 | sgmii_phy22 = &sgmiiphy22; | ||
47 | sgmii_phy23 = &sgmiiphy23; | ||
48 | sgmii_phy24 = &sgmiiphy24; | ||
49 | sgmii_phy41 = &sgmiiphy41; | ||
50 | sgmii_phy42 = &sgmiiphy42; | ||
51 | sgmii_phy43 = &sgmiiphy43; | ||
52 | sgmii_phy44 = &sgmiiphy44; | ||
53 | }; | ||
54 | |||
44 | ifc: localbus@ffe124000 { | 55 | ifc: localbus@ffe124000 { |
45 | reg = <0xf 0xfe124000 0 0x2000>; | 56 | reg = <0xf 0xfe124000 0 0x2000>; |
46 | ranges = <0 0 0xf 0xe8000000 0x08000000 | 57 | ranges = <0 0 0xf 0xe8000000 0x08000000 |
@@ -107,7 +118,7 @@ | |||
107 | flash@0 { | 118 | flash@0 { |
108 | #address-cells = <1>; | 119 | #address-cells = <1>; |
109 | #size-cells = <1>; | 120 | #size-cells = <1>; |
110 | compatible = "sst,sst25wf040"; | 121 | compatible = "sst,sst25wf040", "jedec,spi-nor"; |
111 | reg = <0>; | 122 | reg = <0>; |
112 | spi-max-frequency = <40000000>; /* input clock */ | 123 | spi-max-frequency = <40000000>; /* input clock */ |
113 | }; | 124 | }; |
@@ -136,6 +147,142 @@ | |||
136 | sdhc@114000 { | 147 | sdhc@114000 { |
137 | voltage-ranges = <1800 1800 3300 3300>; | 148 | voltage-ranges = <1800 1800 3300 3300>; |
138 | }; | 149 | }; |
150 | |||
151 | fman@400000 { | ||
152 | ethernet@e0000 { | ||
153 | phy-handle = <&sgmiiphy21>; | ||
154 | phy-connection-type = "sgmii"; | ||
155 | }; | ||
156 | |||
157 | ethernet@e2000 { | ||
158 | phy-handle = <&sgmiiphy22>; | ||
159 | phy-connection-type = "sgmii"; | ||
160 | }; | ||
161 | |||
162 | ethernet@e4000 { | ||
163 | phy-handle = <&sgmiiphy23>; | ||
164 | phy-connection-type = "sgmii"; | ||
165 | }; | ||
166 | |||
167 | ethernet@e6000 { | ||
168 | phy-handle = <&sgmiiphy24>; | ||
169 | phy-connection-type = "sgmii"; | ||
170 | }; | ||
171 | |||
172 | ethernet@e8000 { | ||
173 | status = "disabled"; | ||
174 | }; | ||
175 | |||
176 | ethernet@ea000 { | ||
177 | status = "disabled"; | ||
178 | }; | ||
179 | |||
180 | ethernet@f0000 { | ||
181 | phy-handle = <&xfiphy1>; | ||
182 | phy-connection-type = "xgmii"; | ||
183 | }; | ||
184 | |||
185 | ethernet@f2000 { | ||
186 | phy-handle = <&xfiphy2>; | ||
187 | phy-connection-type = "xgmii"; | ||
188 | }; | ||
189 | }; | ||
190 | |||
191 | fman@500000 { | ||
192 | ethernet@e0000 { | ||
193 | phy-handle = <&sgmiiphy41>; | ||
194 | phy-connection-type = "sgmii"; | ||
195 | }; | ||
196 | |||
197 | ethernet@e2000 { | ||
198 | phy-handle = <&sgmiiphy42>; | ||
199 | phy-connection-type = "sgmii"; | ||
200 | }; | ||
201 | |||
202 | ethernet@e4000 { | ||
203 | phy-handle = <&sgmiiphy43>; | ||
204 | phy-connection-type = "sgmii"; | ||
205 | }; | ||
206 | |||
207 | ethernet@e6000 { | ||
208 | phy-handle = <&sgmiiphy44>; | ||
209 | phy-connection-type = "sgmii"; | ||
210 | }; | ||
211 | |||
212 | ethernet@e8000 { | ||
213 | status = "disabled"; | ||
214 | }; | ||
215 | |||
216 | ethernet@ea000 { | ||
217 | status = "disabled"; | ||
218 | }; | ||
219 | |||
220 | ethernet@f0000 { | ||
221 | phy-handle = <&xfiphy3>; | ||
222 | phy-connection-type = "xgmii"; | ||
223 | }; | ||
224 | |||
225 | ethernet@f2000 { | ||
226 | phy-handle = <&xfiphy4>; | ||
227 | phy-connection-type = "xgmii"; | ||
228 | }; | ||
229 | |||
230 | mdio@fc000 { | ||
231 | sgmiiphy21: ethernet-phy@0 { | ||
232 | reg = <0x0>; | ||
233 | }; | ||
234 | |||
235 | sgmiiphy22: ethernet-phy@1 { | ||
236 | reg = <0x1>; | ||
237 | }; | ||
238 | |||
239 | sgmiiphy23: ethernet-phy@2 { | ||
240 | reg = <0x2>; | ||
241 | }; | ||
242 | |||
243 | sgmiiphy24: ethernet-phy@3 { | ||
244 | reg = <0x3>; | ||
245 | }; | ||
246 | |||
247 | sgmiiphy41: ethernet-phy@4 { | ||
248 | reg = <0x4>; | ||
249 | }; | ||
250 | |||
251 | sgmiiphy42: ethernet-phy@5 { | ||
252 | reg = <0x5>; | ||
253 | }; | ||
254 | |||
255 | sgmiiphy43: ethernet-phy@6 { | ||
256 | reg = <0x6>; | ||
257 | }; | ||
258 | |||
259 | sgmiiphy44: ethernet-phy@7 { | ||
260 | reg = <0x7>; | ||
261 | }; | ||
262 | }; | ||
263 | |||
264 | mdio@fd000 { | ||
265 | xfiphy1: ethernet-phy@10 { | ||
266 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
267 | reg = <0x10>; | ||
268 | }; | ||
269 | |||
270 | xfiphy2: ethernet-phy@11 { | ||
271 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
272 | reg = <0x11>; | ||
273 | }; | ||
274 | |||
275 | xfiphy3: ethernet-phy@13 { | ||
276 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
277 | reg = <0x13>; | ||
278 | }; | ||
279 | |||
280 | xfiphy4: ethernet-phy@12 { | ||
281 | compatible = "ethernet-phy-ieee802.3-c45"; | ||
282 | reg = <0x12>; | ||
283 | }; | ||
284 | }; | ||
285 | }; | ||
139 | }; | 286 | }; |
140 | 287 | ||
141 | pci0: pcie@ffe240000 { | 288 | pci0: pcie@ffe240000 { |
diff --git a/arch/powerpc/boot/dts/gef_ppc9a.dts b/arch/powerpc/boot/dts/gef_ppc9a.dts deleted file mode 100644 index 83eb0fda2666..000000000000 --- a/arch/powerpc/boot/dts/gef_ppc9a.dts +++ /dev/null | |||
@@ -1,425 +0,0 @@ | |||
1 | /* | ||
2 | * GE PPC9A Device Tree Source | ||
3 | * | ||
4 | * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | * Based on: SBS CM6 Device Tree Source | ||
12 | * Copyright 2007 SBS Technologies GmbH & Co. KG | ||
13 | * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source) | ||
14 | * Copyright 2006 Freescale Semiconductor Inc. | ||
15 | */ | ||
16 | |||
17 | /* | ||
18 | * Compiled with dtc -I dts -O dtb -o gef_ppc9a.dtb gef_ppc9a.dts | ||
19 | */ | ||
20 | |||
21 | /dts-v1/; | ||
22 | |||
23 | / { | ||
24 | model = "GEF_PPC9A"; | ||
25 | compatible = "gef,ppc9a"; | ||
26 | #address-cells = <1>; | ||
27 | #size-cells = <1>; | ||
28 | |||
29 | aliases { | ||
30 | ethernet0 = &enet0; | ||
31 | ethernet1 = &enet1; | ||
32 | serial0 = &serial0; | ||
33 | serial1 = &serial1; | ||
34 | pci0 = &pci0; | ||
35 | }; | ||
36 | |||
37 | cpus { | ||
38 | #address-cells = <1>; | ||
39 | #size-cells = <0>; | ||
40 | |||
41 | PowerPC,8641@0 { | ||
42 | device_type = "cpu"; | ||
43 | reg = <0>; | ||
44 | d-cache-line-size = <32>; // 32 bytes | ||
45 | i-cache-line-size = <32>; // 32 bytes | ||
46 | d-cache-size = <32768>; // L1, 32K | ||
47 | i-cache-size = <32768>; // L1, 32K | ||
48 | timebase-frequency = <0>; // From uboot | ||
49 | bus-frequency = <0>; // From uboot | ||
50 | clock-frequency = <0>; // From uboot | ||
51 | }; | ||
52 | PowerPC,8641@1 { | ||
53 | device_type = "cpu"; | ||
54 | reg = <1>; | ||
55 | d-cache-line-size = <32>; // 32 bytes | ||
56 | i-cache-line-size = <32>; // 32 bytes | ||
57 | d-cache-size = <32768>; // L1, 32K | ||
58 | i-cache-size = <32768>; // L1, 32K | ||
59 | timebase-frequency = <0>; // From uboot | ||
60 | bus-frequency = <0>; // From uboot | ||
61 | clock-frequency = <0>; // From uboot | ||
62 | }; | ||
63 | }; | ||
64 | |||
65 | memory { | ||
66 | device_type = "memory"; | ||
67 | reg = <0x0 0x40000000>; // set by uboot | ||
68 | }; | ||
69 | |||
70 | localbus@fef05000 { | ||
71 | #address-cells = <2>; | ||
72 | #size-cells = <1>; | ||
73 | compatible = "fsl,mpc8641-localbus", "simple-bus"; | ||
74 | reg = <0xfef05000 0x1000>; | ||
75 | interrupts = <19 2>; | ||
76 | interrupt-parent = <&mpic>; | ||
77 | |||
78 | ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash | ||
79 | 1 0 0xe8000000 0x08000000 // Paged Flash 0 | ||
80 | 2 0 0xe0000000 0x08000000 // Paged Flash 1 | ||
81 | 3 0 0xfc100000 0x00020000 // NVRAM | ||
82 | 4 0 0xfc000000 0x00008000 // FPGA | ||
83 | 5 0 0xfc008000 0x00008000 // AFIX FPGA | ||
84 | 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit) | ||
85 | 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit) | ||
86 | |||
87 | /* flash@0,0 is a mirror of part of the memory in flash@1,0 | ||
88 | flash@0,0 { | ||
89 | compatible = "gef,ppc9a-firmware-mirror", "cfi-flash"; | ||
90 | reg = <0x0 0x0 0x1000000>; | ||
91 | bank-width = <4>; | ||
92 | device-width = <2>; | ||
93 | #address-cells = <1>; | ||
94 | #size-cells = <1>; | ||
95 | partition@0 { | ||
96 | label = "firmware"; | ||
97 | reg = <0x0 0x1000000>; | ||
98 | read-only; | ||
99 | }; | ||
100 | }; | ||
101 | */ | ||
102 | |||
103 | flash@1,0 { | ||
104 | compatible = "gef,ppc9a-paged-flash", "cfi-flash"; | ||
105 | reg = <0x1 0x0 0x8000000>; | ||
106 | bank-width = <4>; | ||
107 | device-width = <2>; | ||
108 | #address-cells = <1>; | ||
109 | #size-cells = <1>; | ||
110 | partition@0 { | ||
111 | label = "user"; | ||
112 | reg = <0x0 0x7800000>; | ||
113 | }; | ||
114 | partition@7800000 { | ||
115 | label = "firmware"; | ||
116 | reg = <0x7800000 0x800000>; | ||
117 | read-only; | ||
118 | }; | ||
119 | }; | ||
120 | |||
121 | nvram@3,0 { | ||
122 | device_type = "nvram"; | ||
123 | compatible = "simtek,stk14ca8"; | ||
124 | reg = <0x3 0x0 0x20000>; | ||
125 | }; | ||
126 | |||
127 | fpga@4,0 { | ||
128 | compatible = "gef,ppc9a-fpga-regs"; | ||
129 | reg = <0x4 0x0 0x40>; | ||
130 | }; | ||
131 | |||
132 | wdt@4,2000 { | ||
133 | compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00", | ||
134 | "gef,fpga-wdt"; | ||
135 | reg = <0x4 0x2000 0x8>; | ||
136 | interrupts = <0x1a 0x4>; | ||
137 | interrupt-parent = <&gef_pic>; | ||
138 | }; | ||
139 | /* Second watchdog available, driver currently supports one. | ||
140 | wdt@4,2010 { | ||
141 | compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00", | ||
142 | "gef,fpga-wdt"; | ||
143 | reg = <0x4 0x2010 0x8>; | ||
144 | interrupts = <0x1b 0x4>; | ||
145 | interrupt-parent = <&gef_pic>; | ||
146 | }; | ||
147 | */ | ||
148 | gef_pic: pic@4,4000 { | ||
149 | #interrupt-cells = <1>; | ||
150 | interrupt-controller; | ||
151 | compatible = "gef,ppc9a-fpga-pic", "gef,fpga-pic-1.00"; | ||
152 | reg = <0x4 0x4000 0x20>; | ||
153 | interrupts = <0x8 | ||
154 | 0x9>; | ||
155 | interrupt-parent = <&mpic>; | ||
156 | |||
157 | }; | ||
158 | gef_gpio: gpio@7,14000 { | ||
159 | #gpio-cells = <2>; | ||
160 | compatible = "gef,ppc9a-gpio", "gef,sbc610-gpio"; | ||
161 | reg = <0x7 0x14000 0x24>; | ||
162 | gpio-controller; | ||
163 | }; | ||
164 | }; | ||
165 | |||
166 | soc@fef00000 { | ||
167 | #address-cells = <1>; | ||
168 | #size-cells = <1>; | ||
169 | #interrupt-cells = <2>; | ||
170 | device_type = "soc"; | ||
171 | compatible = "fsl,mpc8641-soc", "simple-bus"; | ||
172 | ranges = <0x0 0xfef00000 0x00100000>; | ||
173 | bus-frequency = <33333333>; | ||
174 | |||
175 | mcm-law@0 { | ||
176 | compatible = "fsl,mcm-law"; | ||
177 | reg = <0x0 0x1000>; | ||
178 | fsl,num-laws = <10>; | ||
179 | }; | ||
180 | |||
181 | mcm@1000 { | ||
182 | compatible = "fsl,mpc8641-mcm", "fsl,mcm"; | ||
183 | reg = <0x1000 0x1000>; | ||
184 | interrupts = <17 2>; | ||
185 | interrupt-parent = <&mpic>; | ||
186 | }; | ||
187 | |||
188 | i2c1: i2c@3000 { | ||
189 | #address-cells = <1>; | ||
190 | #size-cells = <0>; | ||
191 | compatible = "fsl-i2c"; | ||
192 | reg = <0x3000 0x100>; | ||
193 | interrupts = <0x2b 0x2>; | ||
194 | interrupt-parent = <&mpic>; | ||
195 | dfsrr; | ||
196 | |||
197 | hwmon@48 { | ||
198 | compatible = "national,lm92"; | ||
199 | reg = <0x48>; | ||
200 | }; | ||
201 | |||
202 | hwmon@4c { | ||
203 | compatible = "adi,adt7461"; | ||
204 | reg = <0x4c>; | ||
205 | }; | ||
206 | |||
207 | rtc@51 { | ||
208 | compatible = "epson,rx8581"; | ||
209 | reg = <0x00000051>; | ||
210 | }; | ||
211 | |||
212 | eti@6b { | ||
213 | compatible = "dallas,ds1682"; | ||
214 | reg = <0x6b>; | ||
215 | }; | ||
216 | }; | ||
217 | |||
218 | i2c2: i2c@3100 { | ||
219 | #address-cells = <1>; | ||
220 | #size-cells = <0>; | ||
221 | compatible = "fsl-i2c"; | ||
222 | reg = <0x3100 0x100>; | ||
223 | interrupts = <0x2b 0x2>; | ||
224 | interrupt-parent = <&mpic>; | ||
225 | dfsrr; | ||
226 | }; | ||
227 | |||
228 | dma@21300 { | ||
229 | #address-cells = <1>; | ||
230 | #size-cells = <1>; | ||
231 | compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; | ||
232 | reg = <0x21300 0x4>; | ||
233 | ranges = <0x0 0x21100 0x200>; | ||
234 | cell-index = <0>; | ||
235 | dma-channel@0 { | ||
236 | compatible = "fsl,mpc8641-dma-channel", | ||
237 | "fsl,eloplus-dma-channel"; | ||
238 | reg = <0x0 0x80>; | ||
239 | cell-index = <0>; | ||
240 | interrupt-parent = <&mpic>; | ||
241 | interrupts = <20 2>; | ||
242 | }; | ||
243 | dma-channel@80 { | ||
244 | compatible = "fsl,mpc8641-dma-channel", | ||
245 | "fsl,eloplus-dma-channel"; | ||
246 | reg = <0x80 0x80>; | ||
247 | cell-index = <1>; | ||
248 | interrupt-parent = <&mpic>; | ||
249 | interrupts = <21 2>; | ||
250 | }; | ||
251 | dma-channel@100 { | ||
252 | compatible = "fsl,mpc8641-dma-channel", | ||
253 | "fsl,eloplus-dma-channel"; | ||
254 | reg = <0x100 0x80>; | ||
255 | cell-index = <2>; | ||
256 | interrupt-parent = <&mpic>; | ||
257 | interrupts = <22 2>; | ||
258 | }; | ||
259 | dma-channel@180 { | ||
260 | compatible = "fsl,mpc8641-dma-channel", | ||
261 | "fsl,eloplus-dma-channel"; | ||
262 | reg = <0x180 0x80>; | ||
263 | cell-index = <3>; | ||
264 | interrupt-parent = <&mpic>; | ||
265 | interrupts = <23 2>; | ||
266 | }; | ||
267 | }; | ||
268 | |||
269 | enet0: ethernet@24000 { | ||
270 | #address-cells = <1>; | ||
271 | #size-cells = <1>; | ||
272 | cell-index = <0>; | ||
273 | device_type = "network"; | ||
274 | model = "TSEC"; | ||
275 | compatible = "gianfar"; | ||
276 | reg = <0x24000 0x1000>; | ||
277 | ranges = <0x0 0x24000 0x1000>; | ||
278 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
279 | interrupts = <29 2 30 2 34 2>; | ||
280 | interrupt-parent = <&mpic>; | ||
281 | tbi-handle = <&tbi0>; | ||
282 | phy-handle = <&phy0>; | ||
283 | phy-connection-type = "gmii"; | ||
284 | |||
285 | mdio@520 { | ||
286 | #address-cells = <1>; | ||
287 | #size-cells = <0>; | ||
288 | compatible = "fsl,gianfar-mdio"; | ||
289 | reg = <0x520 0x20>; | ||
290 | |||
291 | phy0: ethernet-phy@0 { | ||
292 | interrupt-parent = <&gef_pic>; | ||
293 | interrupts = <0x9 0x4>; | ||
294 | reg = <1>; | ||
295 | }; | ||
296 | phy2: ethernet-phy@2 { | ||
297 | interrupt-parent = <&gef_pic>; | ||
298 | interrupts = <0x8 0x4>; | ||
299 | reg = <3>; | ||
300 | }; | ||
301 | tbi0: tbi-phy@11 { | ||
302 | reg = <0x11>; | ||
303 | device_type = "tbi-phy"; | ||
304 | }; | ||
305 | }; | ||
306 | }; | ||
307 | |||
308 | enet1: ethernet@26000 { | ||
309 | #address-cells = <1>; | ||
310 | #size-cells = <1>; | ||
311 | cell-index = <2>; | ||
312 | device_type = "network"; | ||
313 | model = "TSEC"; | ||
314 | compatible = "gianfar"; | ||
315 | reg = <0x26000 0x1000>; | ||
316 | ranges = <0x0 0x26000 0x1000>; | ||
317 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
318 | interrupts = <31 2 32 2 33 2>; | ||
319 | interrupt-parent = <&mpic>; | ||
320 | tbi-handle = <&tbi2>; | ||
321 | phy-handle = <&phy2>; | ||
322 | phy-connection-type = "gmii"; | ||
323 | |||
324 | mdio@520 { | ||
325 | #address-cells = <1>; | ||
326 | #size-cells = <0>; | ||
327 | compatible = "fsl,gianfar-tbi"; | ||
328 | reg = <0x520 0x20>; | ||
329 | |||
330 | tbi2: tbi-phy@11 { | ||
331 | reg = <0x11>; | ||
332 | device_type = "tbi-phy"; | ||
333 | }; | ||
334 | }; | ||
335 | }; | ||
336 | |||
337 | serial0: serial@4500 { | ||
338 | cell-index = <0>; | ||
339 | device_type = "serial"; | ||
340 | compatible = "fsl,ns16550", "ns16550"; | ||
341 | reg = <0x4500 0x100>; | ||
342 | clock-frequency = <0>; | ||
343 | interrupts = <0x2a 0x2>; | ||
344 | interrupt-parent = <&mpic>; | ||
345 | }; | ||
346 | |||
347 | serial1: serial@4600 { | ||
348 | cell-index = <1>; | ||
349 | device_type = "serial"; | ||
350 | compatible = "fsl,ns16550", "ns16550"; | ||
351 | reg = <0x4600 0x100>; | ||
352 | clock-frequency = <0>; | ||
353 | interrupts = <0x1c 0x2>; | ||
354 | interrupt-parent = <&mpic>; | ||
355 | }; | ||
356 | |||
357 | mpic: pic@40000 { | ||
358 | clock-frequency = <0>; | ||
359 | interrupt-controller; | ||
360 | #address-cells = <0>; | ||
361 | #interrupt-cells = <2>; | ||
362 | reg = <0x40000 0x40000>; | ||
363 | compatible = "chrp,open-pic"; | ||
364 | device_type = "open-pic"; | ||
365 | }; | ||
366 | |||
367 | msi@41600 { | ||
368 | compatible = "fsl,mpc8641-msi", "fsl,mpic-msi"; | ||
369 | reg = <0x41600 0x80>; | ||
370 | msi-available-ranges = <0 0x100>; | ||
371 | interrupts = < | ||
372 | 0xe0 0 | ||
373 | 0xe1 0 | ||
374 | 0xe2 0 | ||
375 | 0xe3 0 | ||
376 | 0xe4 0 | ||
377 | 0xe5 0 | ||
378 | 0xe6 0 | ||
379 | 0xe7 0>; | ||
380 | interrupt-parent = <&mpic>; | ||
381 | }; | ||
382 | |||
383 | global-utilities@e0000 { | ||
384 | compatible = "fsl,mpc8641-guts"; | ||
385 | reg = <0xe0000 0x1000>; | ||
386 | fsl,has-rstcr; | ||
387 | }; | ||
388 | }; | ||
389 | |||
390 | pci0: pcie@fef08000 { | ||
391 | compatible = "fsl,mpc8641-pcie"; | ||
392 | device_type = "pci"; | ||
393 | #interrupt-cells = <1>; | ||
394 | #size-cells = <2>; | ||
395 | #address-cells = <3>; | ||
396 | reg = <0xfef08000 0x1000>; | ||
397 | bus-range = <0x0 0xff>; | ||
398 | ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000 | ||
399 | 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>; | ||
400 | clock-frequency = <33333333>; | ||
401 | interrupt-parent = <&mpic>; | ||
402 | interrupts = <0x18 0x2>; | ||
403 | interrupt-map-mask = <0xf800 0x0 0x0 0x7>; | ||
404 | interrupt-map = < | ||
405 | 0x0000 0x0 0x0 0x1 &mpic 0x0 0x1 | ||
406 | 0x0000 0x0 0x0 0x2 &mpic 0x1 0x1 | ||
407 | 0x0000 0x0 0x0 0x3 &mpic 0x2 0x1 | ||
408 | 0x0000 0x0 0x0 0x4 &mpic 0x3 0x1 | ||
409 | >; | ||
410 | |||
411 | pcie@0 { | ||
412 | reg = <0 0 0 0 0>; | ||
413 | #size-cells = <2>; | ||
414 | #address-cells = <3>; | ||
415 | device_type = "pci"; | ||
416 | ranges = <0x02000000 0x0 0x80000000 | ||
417 | 0x02000000 0x0 0x80000000 | ||
418 | 0x0 0x40000000 | ||
419 | |||
420 | 0x01000000 0x0 0x00000000 | ||
421 | 0x01000000 0x0 0x00000000 | ||
422 | 0x0 0x00400000>; | ||
423 | }; | ||
424 | }; | ||
425 | }; | ||
diff --git a/arch/powerpc/boot/dts/gef_sbc310.dts b/arch/powerpc/boot/dts/gef_sbc310.dts deleted file mode 100644 index d426dd3de9ef..000000000000 --- a/arch/powerpc/boot/dts/gef_sbc310.dts +++ /dev/null | |||
@@ -1,459 +0,0 @@ | |||
1 | /* | ||
2 | * GE SBC310 Device Tree Source | ||
3 | * | ||
4 | * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | * Based on: SBS CM6 Device Tree Source | ||
12 | * Copyright 2007 SBS Technologies GmbH & Co. KG | ||
13 | * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source) | ||
14 | * Copyright 2006 Freescale Semiconductor Inc. | ||
15 | */ | ||
16 | |||
17 | /* | ||
18 | * Compiled with dtc -I dts -O dtb -o gef_sbc310.dtb gef_sbc310.dts | ||
19 | */ | ||
20 | |||
21 | /dts-v1/; | ||
22 | |||
23 | / { | ||
24 | model = "GEF_SBC310"; | ||
25 | compatible = "gef,sbc310"; | ||
26 | #address-cells = <1>; | ||
27 | #size-cells = <1>; | ||
28 | |||
29 | aliases { | ||
30 | ethernet0 = &enet0; | ||
31 | ethernet1 = &enet1; | ||
32 | serial0 = &serial0; | ||
33 | serial1 = &serial1; | ||
34 | pci0 = &pci0; | ||
35 | pci1 = &pci1; | ||
36 | }; | ||
37 | |||
38 | cpus { | ||
39 | #address-cells = <1>; | ||
40 | #size-cells = <0>; | ||
41 | |||
42 | PowerPC,8641@0 { | ||
43 | device_type = "cpu"; | ||
44 | reg = <0>; | ||
45 | d-cache-line-size = <32>; // 32 bytes | ||
46 | i-cache-line-size = <32>; // 32 bytes | ||
47 | d-cache-size = <32768>; // L1, 32K | ||
48 | i-cache-size = <32768>; // L1, 32K | ||
49 | timebase-frequency = <0>; // From uboot | ||
50 | bus-frequency = <0>; // From uboot | ||
51 | clock-frequency = <0>; // From uboot | ||
52 | }; | ||
53 | PowerPC,8641@1 { | ||
54 | device_type = "cpu"; | ||
55 | reg = <1>; | ||
56 | d-cache-line-size = <32>; // 32 bytes | ||
57 | i-cache-line-size = <32>; // 32 bytes | ||
58 | d-cache-size = <32768>; // L1, 32K | ||
59 | i-cache-size = <32768>; // L1, 32K | ||
60 | timebase-frequency = <0>; // From uboot | ||
61 | bus-frequency = <0>; // From uboot | ||
62 | clock-frequency = <0>; // From uboot | ||
63 | }; | ||
64 | }; | ||
65 | |||
66 | memory { | ||
67 | device_type = "memory"; | ||
68 | reg = <0x0 0x40000000>; // set by uboot | ||
69 | }; | ||
70 | |||
71 | localbus@fef05000 { | ||
72 | #address-cells = <2>; | ||
73 | #size-cells = <1>; | ||
74 | compatible = "fsl,mpc8641-localbus", "simple-bus"; | ||
75 | reg = <0xfef05000 0x1000>; | ||
76 | interrupts = <19 2>; | ||
77 | interrupt-parent = <&mpic>; | ||
78 | |||
79 | ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash | ||
80 | 1 0 0xe0000000 0x08000000 // Paged Flash 0 | ||
81 | 2 0 0xe8000000 0x08000000 // Paged Flash 1 | ||
82 | 3 0 0xfc100000 0x00020000 // NVRAM | ||
83 | 4 0 0xfc000000 0x00010000>; // FPGA | ||
84 | |||
85 | /* flash@0,0 is a mirror of part of the memory in flash@1,0 | ||
86 | flash@0,0 { | ||
87 | compatible = "gef,sbc310-firmware-mirror", "cfi-flash"; | ||
88 | reg = <0x0 0x0 0x01000000>; | ||
89 | bank-width = <2>; | ||
90 | device-width = <2>; | ||
91 | #address-cells = <1>; | ||
92 | #size-cells = <1>; | ||
93 | partition@0 { | ||
94 | label = "firmware"; | ||
95 | reg = <0x0 0x01000000>; | ||
96 | read-only; | ||
97 | }; | ||
98 | }; | ||
99 | */ | ||
100 | |||
101 | flash@1,0 { | ||
102 | compatible = "gef,sbc310-paged-flash", "cfi-flash"; | ||
103 | reg = <0x1 0x0 0x8000000>; | ||
104 | bank-width = <2>; | ||
105 | device-width = <2>; | ||
106 | #address-cells = <1>; | ||
107 | #size-cells = <1>; | ||
108 | partition@0 { | ||
109 | label = "user"; | ||
110 | reg = <0x0 0x7800000>; | ||
111 | }; | ||
112 | partition@7800000 { | ||
113 | label = "firmware"; | ||
114 | reg = <0x7800000 0x800000>; | ||
115 | read-only; | ||
116 | }; | ||
117 | }; | ||
118 | |||
119 | nvram@3,0 { | ||
120 | device_type = "nvram"; | ||
121 | compatible = "simtek,stk14ca8"; | ||
122 | reg = <0x3 0x0 0x20000>; | ||
123 | }; | ||
124 | |||
125 | fpga@4,0 { | ||
126 | compatible = "gef,fpga-regs"; | ||
127 | reg = <0x4 0x0 0x40>; | ||
128 | }; | ||
129 | |||
130 | wdt@4,2000 { | ||
131 | compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00", | ||
132 | "gef,fpga-wdt"; | ||
133 | reg = <0x4 0x2000 0x8>; | ||
134 | interrupts = <0x1a 0x4>; | ||
135 | interrupt-parent = <&gef_pic>; | ||
136 | }; | ||
137 | /* | ||
138 | wdt@4,2010 { | ||
139 | compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00", | ||
140 | "gef,fpga-wdt"; | ||
141 | reg = <0x4 0x2010 0x8>; | ||
142 | interrupts = <0x1b 0x4>; | ||
143 | interrupt-parent = <&gef_pic>; | ||
144 | }; | ||
145 | */ | ||
146 | gef_pic: pic@4,4000 { | ||
147 | #interrupt-cells = <1>; | ||
148 | interrupt-controller; | ||
149 | compatible = "gef,sbc310-fpga-pic", "gef,fpga-pic"; | ||
150 | reg = <0x4 0x4000 0x20>; | ||
151 | interrupts = <0x8 | ||
152 | 0x9>; | ||
153 | interrupt-parent = <&mpic>; | ||
154 | |||
155 | }; | ||
156 | gef_gpio: gpio@4,8000 { | ||
157 | #gpio-cells = <2>; | ||
158 | compatible = "gef,sbc310-gpio"; | ||
159 | reg = <0x4 0x8000 0x24>; | ||
160 | gpio-controller; | ||
161 | }; | ||
162 | }; | ||
163 | |||
164 | soc@fef00000 { | ||
165 | #address-cells = <1>; | ||
166 | #size-cells = <1>; | ||
167 | #interrupt-cells = <2>; | ||
168 | device_type = "soc"; | ||
169 | compatible = "fsl,mpc8641-soc", "simple-bus"; | ||
170 | ranges = <0x0 0xfef00000 0x00100000>; | ||
171 | bus-frequency = <33333333>; | ||
172 | |||
173 | mcm-law@0 { | ||
174 | compatible = "fsl,mcm-law"; | ||
175 | reg = <0x0 0x1000>; | ||
176 | fsl,num-laws = <10>; | ||
177 | }; | ||
178 | |||
179 | mcm@1000 { | ||
180 | compatible = "fsl,mpc8641-mcm", "fsl,mcm"; | ||
181 | reg = <0x1000 0x1000>; | ||
182 | interrupts = <17 2>; | ||
183 | interrupt-parent = <&mpic>; | ||
184 | }; | ||
185 | |||
186 | i2c1: i2c@3000 { | ||
187 | #address-cells = <1>; | ||
188 | #size-cells = <0>; | ||
189 | compatible = "fsl-i2c"; | ||
190 | reg = <0x3000 0x100>; | ||
191 | interrupts = <0x2b 0x2>; | ||
192 | interrupt-parent = <&mpic>; | ||
193 | dfsrr; | ||
194 | |||
195 | rtc@51 { | ||
196 | compatible = "epson,rx8581"; | ||
197 | reg = <0x00000051>; | ||
198 | }; | ||
199 | }; | ||
200 | |||
201 | i2c2: i2c@3100 { | ||
202 | #address-cells = <1>; | ||
203 | #size-cells = <0>; | ||
204 | compatible = "fsl-i2c"; | ||
205 | reg = <0x3100 0x100>; | ||
206 | interrupts = <0x2b 0x2>; | ||
207 | interrupt-parent = <&mpic>; | ||
208 | dfsrr; | ||
209 | |||
210 | hwmon@48 { | ||
211 | compatible = "national,lm92"; | ||
212 | reg = <0x48>; | ||
213 | }; | ||
214 | |||
215 | hwmon@4c { | ||
216 | compatible = "adi,adt7461"; | ||
217 | reg = <0x4c>; | ||
218 | }; | ||
219 | |||
220 | eti@6b { | ||
221 | compatible = "dallas,ds1682"; | ||
222 | reg = <0x6b>; | ||
223 | }; | ||
224 | }; | ||
225 | |||
226 | dma@21300 { | ||
227 | #address-cells = <1>; | ||
228 | #size-cells = <1>; | ||
229 | compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; | ||
230 | reg = <0x21300 0x4>; | ||
231 | ranges = <0x0 0x21100 0x200>; | ||
232 | cell-index = <0>; | ||
233 | dma-channel@0 { | ||
234 | compatible = "fsl,mpc8641-dma-channel", | ||
235 | "fsl,eloplus-dma-channel"; | ||
236 | reg = <0x0 0x80>; | ||
237 | cell-index = <0>; | ||
238 | interrupt-parent = <&mpic>; | ||
239 | interrupts = <20 2>; | ||
240 | }; | ||
241 | dma-channel@80 { | ||
242 | compatible = "fsl,mpc8641-dma-channel", | ||
243 | "fsl,eloplus-dma-channel"; | ||
244 | reg = <0x80 0x80>; | ||
245 | cell-index = <1>; | ||
246 | interrupt-parent = <&mpic>; | ||
247 | interrupts = <21 2>; | ||
248 | }; | ||
249 | dma-channel@100 { | ||
250 | compatible = "fsl,mpc8641-dma-channel", | ||
251 | "fsl,eloplus-dma-channel"; | ||
252 | reg = <0x100 0x80>; | ||
253 | cell-index = <2>; | ||
254 | interrupt-parent = <&mpic>; | ||
255 | interrupts = <22 2>; | ||
256 | }; | ||
257 | dma-channel@180 { | ||
258 | compatible = "fsl,mpc8641-dma-channel", | ||
259 | "fsl,eloplus-dma-channel"; | ||
260 | reg = <0x180 0x80>; | ||
261 | cell-index = <3>; | ||
262 | interrupt-parent = <&mpic>; | ||
263 | interrupts = <23 2>; | ||
264 | }; | ||
265 | }; | ||
266 | |||
267 | enet0: ethernet@24000 { | ||
268 | #address-cells = <1>; | ||
269 | #size-cells = <1>; | ||
270 | cell-index = <0>; | ||
271 | device_type = "network"; | ||
272 | model = "TSEC"; | ||
273 | compatible = "gianfar"; | ||
274 | reg = <0x24000 0x1000>; | ||
275 | ranges = <0x0 0x24000 0x1000>; | ||
276 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
277 | interrupts = <29 2 30 2 34 2>; | ||
278 | interrupt-parent = <&mpic>; | ||
279 | tbi-handle = <&tbi0>; | ||
280 | phy-handle = <&phy0>; | ||
281 | phy-connection-type = "gmii"; | ||
282 | |||
283 | mdio@520 { | ||
284 | #address-cells = <1>; | ||
285 | #size-cells = <0>; | ||
286 | compatible = "fsl,gianfar-mdio"; | ||
287 | reg = <0x520 0x20>; | ||
288 | |||
289 | phy0: ethernet-phy@0 { | ||
290 | interrupt-parent = <&gef_pic>; | ||
291 | interrupts = <0x9 0x4>; | ||
292 | reg = <1>; | ||
293 | }; | ||
294 | phy2: ethernet-phy@2 { | ||
295 | interrupt-parent = <&gef_pic>; | ||
296 | interrupts = <0x8 0x4>; | ||
297 | reg = <3>; | ||
298 | }; | ||
299 | tbi0: tbi-phy@11 { | ||
300 | reg = <0x11>; | ||
301 | device_type = "tbi-phy"; | ||
302 | }; | ||
303 | }; | ||
304 | }; | ||
305 | |||
306 | enet1: ethernet@26000 { | ||
307 | #address-cells = <1>; | ||
308 | #size-cells = <1>; | ||
309 | cell-index = <2>; | ||
310 | device_type = "network"; | ||
311 | model = "TSEC"; | ||
312 | compatible = "gianfar"; | ||
313 | reg = <0x26000 0x1000>; | ||
314 | ranges = <0x0 0x26000 0x1000>; | ||
315 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
316 | interrupts = <31 2 32 2 33 2>; | ||
317 | interrupt-parent = <&mpic>; | ||
318 | tbi-handle = <&tbi2>; | ||
319 | phy-handle = <&phy2>; | ||
320 | phy-connection-type = "gmii"; | ||
321 | |||
322 | mdio@520 { | ||
323 | #address-cells = <1>; | ||
324 | #size-cells = <0>; | ||
325 | compatible = "fsl,gianfar-tbi"; | ||
326 | reg = <0x520 0x20>; | ||
327 | |||
328 | tbi2: tbi-phy@11 { | ||
329 | reg = <0x11>; | ||
330 | device_type = "tbi-phy"; | ||
331 | }; | ||
332 | }; | ||
333 | }; | ||
334 | |||
335 | serial0: serial@4500 { | ||
336 | cell-index = <0>; | ||
337 | device_type = "serial"; | ||
338 | compatible = "fsl,ns16550", "ns16550"; | ||
339 | reg = <0x4500 0x100>; | ||
340 | clock-frequency = <0>; | ||
341 | interrupts = <0x2a 0x2>; | ||
342 | interrupt-parent = <&mpic>; | ||
343 | }; | ||
344 | |||
345 | serial1: serial@4600 { | ||
346 | cell-index = <1>; | ||
347 | device_type = "serial"; | ||
348 | compatible = "fsl,ns16550", "ns16550"; | ||
349 | reg = <0x4600 0x100>; | ||
350 | clock-frequency = <0>; | ||
351 | interrupts = <0x1c 0x2>; | ||
352 | interrupt-parent = <&mpic>; | ||
353 | }; | ||
354 | |||
355 | mpic: pic@40000 { | ||
356 | clock-frequency = <0>; | ||
357 | interrupt-controller; | ||
358 | #address-cells = <0>; | ||
359 | #interrupt-cells = <2>; | ||
360 | reg = <0x40000 0x40000>; | ||
361 | compatible = "chrp,open-pic"; | ||
362 | device_type = "open-pic"; | ||
363 | }; | ||
364 | |||
365 | msi@41600 { | ||
366 | compatible = "fsl,mpc8641-msi", "fsl,mpic-msi"; | ||
367 | reg = <0x41600 0x80>; | ||
368 | msi-available-ranges = <0 0x100>; | ||
369 | interrupts = < | ||
370 | 0xe0 0 | ||
371 | 0xe1 0 | ||
372 | 0xe2 0 | ||
373 | 0xe3 0 | ||
374 | 0xe4 0 | ||
375 | 0xe5 0 | ||
376 | 0xe6 0 | ||
377 | 0xe7 0>; | ||
378 | interrupt-parent = <&mpic>; | ||
379 | }; | ||
380 | |||
381 | global-utilities@e0000 { | ||
382 | compatible = "fsl,mpc8641-guts"; | ||
383 | reg = <0xe0000 0x1000>; | ||
384 | fsl,has-rstcr; | ||
385 | }; | ||
386 | }; | ||
387 | |||
388 | pci0: pcie@fef08000 { | ||
389 | compatible = "fsl,mpc8641-pcie"; | ||
390 | device_type = "pci"; | ||
391 | #interrupt-cells = <1>; | ||
392 | #size-cells = <2>; | ||
393 | #address-cells = <3>; | ||
394 | reg = <0xfef08000 0x1000>; | ||
395 | bus-range = <0x0 0xff>; | ||
396 | ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000 | ||
397 | 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>; | ||
398 | clock-frequency = <33333333>; | ||
399 | interrupt-parent = <&mpic>; | ||
400 | interrupts = <0x18 0x2>; | ||
401 | interrupt-map-mask = <0xff00 0x0 0x0 0x7>; | ||
402 | interrupt-map = < | ||
403 | 0x0000 0x0 0x0 0x1 &mpic 0x0 0x2 | ||
404 | 0x0000 0x0 0x0 0x2 &mpic 0x1 0x2 | ||
405 | 0x0000 0x0 0x0 0x3 &mpic 0x2 0x2 | ||
406 | 0x0000 0x0 0x0 0x4 &mpic 0x3 0x2 | ||
407 | >; | ||
408 | |||
409 | pcie@0 { | ||
410 | reg = <0 0 0 0 0>; | ||
411 | #size-cells = <2>; | ||
412 | #address-cells = <3>; | ||
413 | device_type = "pci"; | ||
414 | ranges = <0x02000000 0x0 0x80000000 | ||
415 | 0x02000000 0x0 0x80000000 | ||
416 | 0x0 0x40000000 | ||
417 | |||
418 | 0x01000000 0x0 0x00000000 | ||
419 | 0x01000000 0x0 0x00000000 | ||
420 | 0x0 0x00400000>; | ||
421 | }; | ||
422 | }; | ||
423 | |||
424 | pci1: pcie@fef09000 { | ||
425 | compatible = "fsl,mpc8641-pcie"; | ||
426 | device_type = "pci"; | ||
427 | #interrupt-cells = <1>; | ||
428 | #size-cells = <2>; | ||
429 | #address-cells = <3>; | ||
430 | reg = <0xfef09000 0x1000>; | ||
431 | bus-range = <0x0 0xff>; | ||
432 | ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0x0 0x20000000 | ||
433 | 0x01000000 0x0 0x00000000 0xfe400000 0x0 0x00400000>; | ||
434 | clock-frequency = <33333333>; | ||
435 | interrupt-parent = <&mpic>; | ||
436 | interrupts = <0x19 0x2>; | ||
437 | interrupt-map-mask = <0xf800 0x0 0x0 0x7>; | ||
438 | interrupt-map = < | ||
439 | 0x0000 0x0 0x0 0x1 &mpic 0x4 0x2 | ||
440 | 0x0000 0x0 0x0 0x2 &mpic 0x5 0x2 | ||
441 | 0x0000 0x0 0x0 0x3 &mpic 0x6 0x2 | ||
442 | 0x0000 0x0 0x0 0x4 &mpic 0x7 0x2 | ||
443 | >; | ||
444 | |||
445 | pcie@0 { | ||
446 | reg = <0 0 0 0 0>; | ||
447 | #size-cells = <2>; | ||
448 | #address-cells = <3>; | ||
449 | device_type = "pci"; | ||
450 | ranges = <0x02000000 0x0 0xc0000000 | ||
451 | 0x02000000 0x0 0xc0000000 | ||
452 | 0x0 0x20000000 | ||
453 | |||
454 | 0x01000000 0x0 0x00000000 | ||
455 | 0x01000000 0x0 0x00000000 | ||
456 | 0x0 0x00400000>; | ||
457 | }; | ||
458 | }; | ||
459 | }; | ||
diff --git a/arch/powerpc/boot/dts/gef_sbc610.dts b/arch/powerpc/boot/dts/gef_sbc610.dts deleted file mode 100644 index 5db3399b76b7..000000000000 --- a/arch/powerpc/boot/dts/gef_sbc610.dts +++ /dev/null | |||
@@ -1,423 +0,0 @@ | |||
1 | /* | ||
2 | * GE SBC610 Device Tree Source | ||
3 | * | ||
4 | * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | * Based on: SBS CM6 Device Tree Source | ||
12 | * Copyright 2007 SBS Technologies GmbH & Co. KG | ||
13 | * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source) | ||
14 | * Copyright 2006 Freescale Semiconductor Inc. | ||
15 | */ | ||
16 | |||
17 | /* | ||
18 | * Compiled with dtc -I dts -O dtb -o gef_sbc610.dtb gef_sbc610.dts | ||
19 | */ | ||
20 | |||
21 | /dts-v1/; | ||
22 | |||
23 | / { | ||
24 | model = "GEF_SBC610"; | ||
25 | compatible = "gef,sbc610"; | ||
26 | #address-cells = <1>; | ||
27 | #size-cells = <1>; | ||
28 | |||
29 | aliases { | ||
30 | ethernet0 = &enet0; | ||
31 | ethernet1 = &enet1; | ||
32 | serial0 = &serial0; | ||
33 | serial1 = &serial1; | ||
34 | pci0 = &pci0; | ||
35 | }; | ||
36 | |||
37 | cpus { | ||
38 | #address-cells = <1>; | ||
39 | #size-cells = <0>; | ||
40 | |||
41 | PowerPC,8641@0 { | ||
42 | device_type = "cpu"; | ||
43 | reg = <0>; | ||
44 | d-cache-line-size = <32>; // 32 bytes | ||
45 | i-cache-line-size = <32>; // 32 bytes | ||
46 | d-cache-size = <32768>; // L1, 32K | ||
47 | i-cache-size = <32768>; // L1, 32K | ||
48 | timebase-frequency = <0>; // From uboot | ||
49 | bus-frequency = <0>; // From uboot | ||
50 | clock-frequency = <0>; // From uboot | ||
51 | }; | ||
52 | PowerPC,8641@1 { | ||
53 | device_type = "cpu"; | ||
54 | reg = <1>; | ||
55 | d-cache-line-size = <32>; // 32 bytes | ||
56 | i-cache-line-size = <32>; // 32 bytes | ||
57 | d-cache-size = <32768>; // L1, 32K | ||
58 | i-cache-size = <32768>; // L1, 32K | ||
59 | timebase-frequency = <0>; // From uboot | ||
60 | bus-frequency = <0>; // From uboot | ||
61 | clock-frequency = <0>; // From uboot | ||
62 | }; | ||
63 | }; | ||
64 | |||
65 | memory { | ||
66 | device_type = "memory"; | ||
67 | reg = <0x0 0x40000000>; // set by uboot | ||
68 | }; | ||
69 | |||
70 | localbus@fef05000 { | ||
71 | #address-cells = <2>; | ||
72 | #size-cells = <1>; | ||
73 | compatible = "fsl,mpc8641-localbus", "simple-bus"; | ||
74 | reg = <0xfef05000 0x1000>; | ||
75 | interrupts = <19 2>; | ||
76 | interrupt-parent = <&mpic>; | ||
77 | |||
78 | ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash | ||
79 | 1 0 0xe8000000 0x08000000 // Paged Flash 0 | ||
80 | 2 0 0xe0000000 0x08000000 // Paged Flash 1 | ||
81 | 3 0 0xfc100000 0x00020000 // NVRAM | ||
82 | 4 0 0xfc000000 0x00008000 // FPGA | ||
83 | 5 0 0xfc008000 0x00008000 // AFIX FPGA | ||
84 | 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit) | ||
85 | 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit) | ||
86 | |||
87 | /* flash@0,0 is a mirror of part of the memory in flash@1,0 | ||
88 | flash@0,0 { | ||
89 | compatible = "gef,sbc610-firmware-mirror", "cfi-flash"; | ||
90 | reg = <0x0 0x0 0x1000000>; | ||
91 | bank-width = <4>; | ||
92 | device-width = <2>; | ||
93 | #address-cells = <1>; | ||
94 | #size-cells = <1>; | ||
95 | partition@0 { | ||
96 | label = "firmware"; | ||
97 | reg = <0x0 0x1000000>; | ||
98 | read-only; | ||
99 | }; | ||
100 | }; | ||
101 | */ | ||
102 | |||
103 | flash@1,0 { | ||
104 | compatible = "gef,sbc610-paged-flash", "cfi-flash"; | ||
105 | reg = <0x1 0x0 0x8000000>; | ||
106 | bank-width = <4>; | ||
107 | device-width = <2>; | ||
108 | #address-cells = <1>; | ||
109 | #size-cells = <1>; | ||
110 | partition@0 { | ||
111 | label = "user"; | ||
112 | reg = <0x0 0x7800000>; | ||
113 | }; | ||
114 | partition@7800000 { | ||
115 | label = "firmware"; | ||
116 | reg = <0x7800000 0x800000>; | ||
117 | read-only; | ||
118 | }; | ||
119 | }; | ||
120 | |||
121 | nvram@3,0 { | ||
122 | device_type = "nvram"; | ||
123 | compatible = "simtek,stk14ca8"; | ||
124 | reg = <0x3 0x0 0x20000>; | ||
125 | }; | ||
126 | |||
127 | fpga@4,0 { | ||
128 | compatible = "gef,fpga-regs"; | ||
129 | reg = <0x4 0x0 0x40>; | ||
130 | }; | ||
131 | |||
132 | wdt@4,2000 { | ||
133 | compatible = "gef,fpga-wdt"; | ||
134 | reg = <0x4 0x2000 0x8>; | ||
135 | interrupts = <0x1a 0x4>; | ||
136 | interrupt-parent = <&gef_pic>; | ||
137 | }; | ||
138 | /* Second watchdog available, driver currently supports one. | ||
139 | wdt@4,2010 { | ||
140 | compatible = "gef,fpga-wdt"; | ||
141 | reg = <0x4 0x2010 0x8>; | ||
142 | interrupts = <0x1b 0x4>; | ||
143 | interrupt-parent = <&gef_pic>; | ||
144 | }; | ||
145 | */ | ||
146 | gef_pic: pic@4,4000 { | ||
147 | #interrupt-cells = <1>; | ||
148 | interrupt-controller; | ||
149 | compatible = "gef,fpga-pic"; | ||
150 | reg = <0x4 0x4000 0x20>; | ||
151 | interrupts = <0x8 | ||
152 | 0x9>; | ||
153 | interrupt-parent = <&mpic>; | ||
154 | |||
155 | }; | ||
156 | gef_gpio: gpio@7,14000 { | ||
157 | #gpio-cells = <2>; | ||
158 | compatible = "gef,sbc610-gpio"; | ||
159 | reg = <0x7 0x14000 0x24>; | ||
160 | gpio-controller; | ||
161 | }; | ||
162 | }; | ||
163 | |||
164 | soc@fef00000 { | ||
165 | #address-cells = <1>; | ||
166 | #size-cells = <1>; | ||
167 | #interrupt-cells = <2>; | ||
168 | device_type = "soc"; | ||
169 | compatible = "simple-bus"; | ||
170 | ranges = <0x0 0xfef00000 0x00100000>; | ||
171 | bus-frequency = <33333333>; | ||
172 | |||
173 | mcm-law@0 { | ||
174 | compatible = "fsl,mcm-law"; | ||
175 | reg = <0x0 0x1000>; | ||
176 | fsl,num-laws = <10>; | ||
177 | }; | ||
178 | |||
179 | mcm@1000 { | ||
180 | compatible = "fsl,mpc8641-mcm", "fsl,mcm"; | ||
181 | reg = <0x1000 0x1000>; | ||
182 | interrupts = <17 2>; | ||
183 | interrupt-parent = <&mpic>; | ||
184 | }; | ||
185 | |||
186 | i2c1: i2c@3000 { | ||
187 | #address-cells = <1>; | ||
188 | #size-cells = <0>; | ||
189 | compatible = "fsl-i2c"; | ||
190 | reg = <0x3000 0x100>; | ||
191 | interrupts = <0x2b 0x2>; | ||
192 | interrupt-parent = <&mpic>; | ||
193 | dfsrr; | ||
194 | |||
195 | hwmon@48 { | ||
196 | compatible = "national,lm92"; | ||
197 | reg = <0x48>; | ||
198 | }; | ||
199 | |||
200 | hwmon@4c { | ||
201 | compatible = "adi,adt7461"; | ||
202 | reg = <0x4c>; | ||
203 | }; | ||
204 | |||
205 | rtc@51 { | ||
206 | compatible = "epson,rx8581"; | ||
207 | reg = <0x00000051>; | ||
208 | }; | ||
209 | |||
210 | eti@6b { | ||
211 | compatible = "dallas,ds1682"; | ||
212 | reg = <0x6b>; | ||
213 | }; | ||
214 | }; | ||
215 | |||
216 | i2c2: i2c@3100 { | ||
217 | #address-cells = <1>; | ||
218 | #size-cells = <0>; | ||
219 | compatible = "fsl-i2c"; | ||
220 | reg = <0x3100 0x100>; | ||
221 | interrupts = <0x2b 0x2>; | ||
222 | interrupt-parent = <&mpic>; | ||
223 | dfsrr; | ||
224 | }; | ||
225 | |||
226 | dma@21300 { | ||
227 | #address-cells = <1>; | ||
228 | #size-cells = <1>; | ||
229 | compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; | ||
230 | reg = <0x21300 0x4>; | ||
231 | ranges = <0x0 0x21100 0x200>; | ||
232 | cell-index = <0>; | ||
233 | dma-channel@0 { | ||
234 | compatible = "fsl,mpc8641-dma-channel", | ||
235 | "fsl,eloplus-dma-channel"; | ||
236 | reg = <0x0 0x80>; | ||
237 | cell-index = <0>; | ||
238 | interrupt-parent = <&mpic>; | ||
239 | interrupts = <20 2>; | ||
240 | }; | ||
241 | dma-channel@80 { | ||
242 | compatible = "fsl,mpc8641-dma-channel", | ||
243 | "fsl,eloplus-dma-channel"; | ||
244 | reg = <0x80 0x80>; | ||
245 | cell-index = <1>; | ||
246 | interrupt-parent = <&mpic>; | ||
247 | interrupts = <21 2>; | ||
248 | }; | ||
249 | dma-channel@100 { | ||
250 | compatible = "fsl,mpc8641-dma-channel", | ||
251 | "fsl,eloplus-dma-channel"; | ||
252 | reg = <0x100 0x80>; | ||
253 | cell-index = <2>; | ||
254 | interrupt-parent = <&mpic>; | ||
255 | interrupts = <22 2>; | ||
256 | }; | ||
257 | dma-channel@180 { | ||
258 | compatible = "fsl,mpc8641-dma-channel", | ||
259 | "fsl,eloplus-dma-channel"; | ||
260 | reg = <0x180 0x80>; | ||
261 | cell-index = <3>; | ||
262 | interrupt-parent = <&mpic>; | ||
263 | interrupts = <23 2>; | ||
264 | }; | ||
265 | }; | ||
266 | |||
267 | enet0: ethernet@24000 { | ||
268 | #address-cells = <1>; | ||
269 | #size-cells = <1>; | ||
270 | cell-index = <0>; | ||
271 | device_type = "network"; | ||
272 | model = "TSEC"; | ||
273 | compatible = "gianfar"; | ||
274 | reg = <0x24000 0x1000>; | ||
275 | ranges = <0x0 0x24000 0x1000>; | ||
276 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
277 | interrupts = <29 2 30 2 34 2>; | ||
278 | interrupt-parent = <&mpic>; | ||
279 | tbi-handle = <&tbi0>; | ||
280 | phy-handle = <&phy0>; | ||
281 | phy-connection-type = "gmii"; | ||
282 | |||
283 | mdio@520 { | ||
284 | #address-cells = <1>; | ||
285 | #size-cells = <0>; | ||
286 | compatible = "fsl,gianfar-mdio"; | ||
287 | reg = <0x520 0x20>; | ||
288 | |||
289 | phy0: ethernet-phy@0 { | ||
290 | interrupt-parent = <&gef_pic>; | ||
291 | interrupts = <0x9 0x4>; | ||
292 | reg = <1>; | ||
293 | }; | ||
294 | phy2: ethernet-phy@2 { | ||
295 | interrupt-parent = <&gef_pic>; | ||
296 | interrupts = <0x8 0x4>; | ||
297 | reg = <3>; | ||
298 | }; | ||
299 | tbi0: tbi-phy@11 { | ||
300 | reg = <0x11>; | ||
301 | device_type = "tbi-phy"; | ||
302 | }; | ||
303 | }; | ||
304 | }; | ||
305 | |||
306 | enet1: ethernet@26000 { | ||
307 | #address-cells = <1>; | ||
308 | #size-cells = <1>; | ||
309 | cell-index = <2>; | ||
310 | device_type = "network"; | ||
311 | model = "TSEC"; | ||
312 | compatible = "gianfar"; | ||
313 | reg = <0x26000 0x1000>; | ||
314 | ranges = <0x0 0x26000 0x1000>; | ||
315 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
316 | interrupts = <31 2 32 2 33 2>; | ||
317 | interrupt-parent = <&mpic>; | ||
318 | tbi-handle = <&tbi2>; | ||
319 | phy-handle = <&phy2>; | ||
320 | phy-connection-type = "gmii"; | ||
321 | |||
322 | mdio@520 { | ||
323 | #address-cells = <1>; | ||
324 | #size-cells = <0>; | ||
325 | compatible = "fsl,gianfar-tbi"; | ||
326 | reg = <0x520 0x20>; | ||
327 | |||
328 | tbi2: tbi-phy@11 { | ||
329 | reg = <0x11>; | ||
330 | device_type = "tbi-phy"; | ||
331 | }; | ||
332 | }; | ||
333 | }; | ||
334 | |||
335 | serial0: serial@4500 { | ||
336 | cell-index = <0>; | ||
337 | device_type = "serial"; | ||
338 | compatible = "fsl,ns16550", "ns16550"; | ||
339 | reg = <0x4500 0x100>; | ||
340 | clock-frequency = <0>; | ||
341 | interrupts = <0x2a 0x2>; | ||
342 | interrupt-parent = <&mpic>; | ||
343 | }; | ||
344 | |||
345 | serial1: serial@4600 { | ||
346 | cell-index = <1>; | ||
347 | device_type = "serial"; | ||
348 | compatible = "fsl,ns16550", "ns16550"; | ||
349 | reg = <0x4600 0x100>; | ||
350 | clock-frequency = <0>; | ||
351 | interrupts = <0x1c 0x2>; | ||
352 | interrupt-parent = <&mpic>; | ||
353 | }; | ||
354 | |||
355 | mpic: pic@40000 { | ||
356 | clock-frequency = <0>; | ||
357 | interrupt-controller; | ||
358 | #address-cells = <0>; | ||
359 | #interrupt-cells = <2>; | ||
360 | reg = <0x40000 0x40000>; | ||
361 | compatible = "chrp,open-pic"; | ||
362 | device_type = "open-pic"; | ||
363 | }; | ||
364 | |||
365 | msi@41600 { | ||
366 | compatible = "fsl,mpc8641-msi", "fsl,mpic-msi"; | ||
367 | reg = <0x41600 0x80>; | ||
368 | msi-available-ranges = <0 0x100>; | ||
369 | interrupts = < | ||
370 | 0xe0 0 | ||
371 | 0xe1 0 | ||
372 | 0xe2 0 | ||
373 | 0xe3 0 | ||
374 | 0xe4 0 | ||
375 | 0xe5 0 | ||
376 | 0xe6 0 | ||
377 | 0xe7 0>; | ||
378 | interrupt-parent = <&mpic>; | ||
379 | }; | ||
380 | |||
381 | global-utilities@e0000 { | ||
382 | compatible = "fsl,mpc8641-guts"; | ||
383 | reg = <0xe0000 0x1000>; | ||
384 | fsl,has-rstcr; | ||
385 | }; | ||
386 | }; | ||
387 | |||
388 | pci0: pcie@fef08000 { | ||
389 | compatible = "fsl,mpc8641-pcie"; | ||
390 | device_type = "pci"; | ||
391 | #interrupt-cells = <1>; | ||
392 | #size-cells = <2>; | ||
393 | #address-cells = <3>; | ||
394 | reg = <0xfef08000 0x1000>; | ||
395 | bus-range = <0x0 0xff>; | ||
396 | ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000 | ||
397 | 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>; | ||
398 | clock-frequency = <33333333>; | ||
399 | interrupt-parent = <&mpic>; | ||
400 | interrupts = <0x18 0x2>; | ||
401 | interrupt-map-mask = <0xf800 0x0 0x0 0x7>; | ||
402 | interrupt-map = < | ||
403 | 0x0000 0x0 0x0 0x1 &mpic 0x0 0x1 | ||
404 | 0x0000 0x0 0x0 0x2 &mpic 0x1 0x1 | ||
405 | 0x0000 0x0 0x0 0x3 &mpic 0x2 0x1 | ||
406 | 0x0000 0x0 0x0 0x4 &mpic 0x3 0x1 | ||
407 | >; | ||
408 | |||
409 | pcie@0 { | ||
410 | reg = <0 0 0 0 0>; | ||
411 | #size-cells = <2>; | ||
412 | #address-cells = <3>; | ||
413 | device_type = "pci"; | ||
414 | ranges = <0x02000000 0x0 0x80000000 | ||
415 | 0x02000000 0x0 0x80000000 | ||
416 | 0x0 0x40000000 | ||
417 | |||
418 | 0x01000000 0x0 0x00000000 | ||
419 | 0x01000000 0x0 0x00000000 | ||
420 | 0x0 0x00400000>; | ||
421 | }; | ||
422 | }; | ||
423 | }; | ||
diff --git a/arch/powerpc/boot/dts/sbc8641d.dts b/arch/powerpc/boot/dts/sbc8641d.dts deleted file mode 100644 index 68f0ed7626bd..000000000000 --- a/arch/powerpc/boot/dts/sbc8641d.dts +++ /dev/null | |||
@@ -1,447 +0,0 @@ | |||
1 | /* | ||
2 | * SBC8641D Device Tree Source | ||
3 | * | ||
4 | * Copyright 2008 Wind River Systems Inc. | ||
5 | * | ||
6 | * Paul Gortmaker (see MAINTAINERS for contact information) | ||
7 | * | ||
8 | * Based largely on the mpc8641_hpcn.dts by Freescale Semiconductor Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | */ | ||
15 | |||
16 | /dts-v1/; | ||
17 | |||
18 | / { | ||
19 | model = "SBC8641D"; | ||
20 | compatible = "wind,sbc8641"; | ||
21 | #address-cells = <1>; | ||
22 | #size-cells = <1>; | ||
23 | |||
24 | aliases { | ||
25 | ethernet0 = &enet0; | ||
26 | ethernet1 = &enet1; | ||
27 | ethernet2 = &enet2; | ||
28 | ethernet3 = &enet3; | ||
29 | serial0 = &serial0; | ||
30 | serial1 = &serial1; | ||
31 | pci0 = &pci0; | ||
32 | pci1 = &pci1; | ||
33 | }; | ||
34 | |||
35 | cpus { | ||
36 | #address-cells = <1>; | ||
37 | #size-cells = <0>; | ||
38 | |||
39 | PowerPC,8641@0 { | ||
40 | device_type = "cpu"; | ||
41 | reg = <0>; | ||
42 | d-cache-line-size = <32>; | ||
43 | i-cache-line-size = <32>; | ||
44 | d-cache-size = <32768>; // L1 | ||
45 | i-cache-size = <32768>; // L1 | ||
46 | timebase-frequency = <0>; // From uboot | ||
47 | bus-frequency = <0>; // From uboot | ||
48 | clock-frequency = <0>; // From uboot | ||
49 | }; | ||
50 | PowerPC,8641@1 { | ||
51 | device_type = "cpu"; | ||
52 | reg = <1>; | ||
53 | d-cache-line-size = <32>; | ||
54 | i-cache-line-size = <32>; | ||
55 | d-cache-size = <32768>; | ||
56 | i-cache-size = <32768>; | ||
57 | timebase-frequency = <0>; // From uboot | ||
58 | bus-frequency = <0>; // From uboot | ||
59 | clock-frequency = <0>; // From uboot | ||
60 | }; | ||
61 | }; | ||
62 | |||
63 | memory { | ||
64 | device_type = "memory"; | ||
65 | reg = <0x00000000 0x20000000>; // 512M at 0x0 | ||
66 | }; | ||
67 | |||
68 | localbus@f8005000 { | ||
69 | #address-cells = <2>; | ||
70 | #size-cells = <1>; | ||
71 | compatible = "fsl,mpc8641-localbus", "simple-bus"; | ||
72 | reg = <0xf8005000 0x1000>; | ||
73 | interrupts = <19 2>; | ||
74 | interrupt-parent = <&mpic>; | ||
75 | |||
76 | ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash | ||
77 | 1 0 0xf0000000 0x00010000 // 64KB EEPROM | ||
78 | 2 0 0xf1000000 0x00100000 // EPLD (1MB) | ||
79 | 3 0 0xe0000000 0x04000000 // 64MB LB SDRAM (CS3) | ||
80 | 4 0 0xe4000000 0x04000000 // 64MB LB SDRAM (CS4) | ||
81 | 6 0 0xf4000000 0x00100000 // LCD display (1MB) | ||
82 | 7 0 0xe8000000 0x04000000>; // 64MB OneNAND | ||
83 | |||
84 | flash@0,0 { | ||
85 | compatible = "cfi-flash"; | ||
86 | reg = <0 0 0x01000000>; | ||
87 | bank-width = <2>; | ||
88 | device-width = <2>; | ||
89 | #address-cells = <1>; | ||
90 | #size-cells = <1>; | ||
91 | partition@0 { | ||
92 | label = "dtb"; | ||
93 | reg = <0x00000000 0x00100000>; | ||
94 | read-only; | ||
95 | }; | ||
96 | partition@300000 { | ||
97 | label = "kernel"; | ||
98 | reg = <0x00100000 0x00400000>; | ||
99 | read-only; | ||
100 | }; | ||
101 | partition@400000 { | ||
102 | label = "fs"; | ||
103 | reg = <0x00500000 0x00a00000>; | ||
104 | }; | ||
105 | partition@700000 { | ||
106 | label = "firmware"; | ||
107 | reg = <0x00f00000 0x00100000>; | ||
108 | read-only; | ||
109 | }; | ||
110 | }; | ||
111 | |||
112 | epld@2,0 { | ||
113 | compatible = "wrs,epld-localbus"; | ||
114 | #address-cells = <2>; | ||
115 | #size-cells = <1>; | ||
116 | reg = <2 0 0x100000>; | ||
117 | ranges = <0 0 5 0 1 // User switches | ||
118 | 1 0 5 1 1 // Board ID/Rev | ||
119 | 3 0 5 3 1>; // LEDs | ||
120 | }; | ||
121 | }; | ||
122 | |||
123 | soc@f8000000 { | ||
124 | #address-cells = <1>; | ||
125 | #size-cells = <1>; | ||
126 | device_type = "soc"; | ||
127 | compatible = "simple-bus"; | ||
128 | ranges = <0x00000000 0xf8000000 0x00100000>; | ||
129 | bus-frequency = <0>; | ||
130 | |||
131 | mcm-law@0 { | ||
132 | compatible = "fsl,mcm-law"; | ||
133 | reg = <0x0 0x1000>; | ||
134 | fsl,num-laws = <10>; | ||
135 | }; | ||
136 | |||
137 | mcm@1000 { | ||
138 | compatible = "fsl,mpc8641-mcm", "fsl,mcm"; | ||
139 | reg = <0x1000 0x1000>; | ||
140 | interrupts = <17 2>; | ||
141 | interrupt-parent = <&mpic>; | ||
142 | }; | ||
143 | |||
144 | i2c@3000 { | ||
145 | #address-cells = <1>; | ||
146 | #size-cells = <0>; | ||
147 | cell-index = <0>; | ||
148 | compatible = "fsl-i2c"; | ||
149 | reg = <0x3000 0x100>; | ||
150 | interrupts = <43 2>; | ||
151 | interrupt-parent = <&mpic>; | ||
152 | dfsrr; | ||
153 | }; | ||
154 | |||
155 | i2c@3100 { | ||
156 | #address-cells = <1>; | ||
157 | #size-cells = <0>; | ||
158 | cell-index = <1>; | ||
159 | compatible = "fsl-i2c"; | ||
160 | reg = <0x3100 0x100>; | ||
161 | interrupts = <43 2>; | ||
162 | interrupt-parent = <&mpic>; | ||
163 | dfsrr; | ||
164 | }; | ||
165 | |||
166 | dma@21300 { | ||
167 | #address-cells = <1>; | ||
168 | #size-cells = <1>; | ||
169 | compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; | ||
170 | reg = <0x21300 0x4>; | ||
171 | ranges = <0x0 0x21100 0x200>; | ||
172 | cell-index = <0>; | ||
173 | dma-channel@0 { | ||
174 | compatible = "fsl,mpc8641-dma-channel", | ||
175 | "fsl,eloplus-dma-channel"; | ||
176 | reg = <0x0 0x80>; | ||
177 | cell-index = <0>; | ||
178 | interrupt-parent = <&mpic>; | ||
179 | interrupts = <20 2>; | ||
180 | }; | ||
181 | dma-channel@80 { | ||
182 | compatible = "fsl,mpc8641-dma-channel", | ||
183 | "fsl,eloplus-dma-channel"; | ||
184 | reg = <0x80 0x80>; | ||
185 | cell-index = <1>; | ||
186 | interrupt-parent = <&mpic>; | ||
187 | interrupts = <21 2>; | ||
188 | }; | ||
189 | dma-channel@100 { | ||
190 | compatible = "fsl,mpc8641-dma-channel", | ||
191 | "fsl,eloplus-dma-channel"; | ||
192 | reg = <0x100 0x80>; | ||
193 | cell-index = <2>; | ||
194 | interrupt-parent = <&mpic>; | ||
195 | interrupts = <22 2>; | ||
196 | }; | ||
197 | dma-channel@180 { | ||
198 | compatible = "fsl,mpc8641-dma-channel", | ||
199 | "fsl,eloplus-dma-channel"; | ||
200 | reg = <0x180 0x80>; | ||
201 | cell-index = <3>; | ||
202 | interrupt-parent = <&mpic>; | ||
203 | interrupts = <23 2>; | ||
204 | }; | ||
205 | }; | ||
206 | |||
207 | enet0: ethernet@24000 { | ||
208 | #address-cells = <1>; | ||
209 | #size-cells = <1>; | ||
210 | cell-index = <0>; | ||
211 | device_type = "network"; | ||
212 | model = "TSEC"; | ||
213 | compatible = "gianfar"; | ||
214 | reg = <0x24000 0x1000>; | ||
215 | ranges = <0x0 0x24000 0x1000>; | ||
216 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
217 | interrupts = <29 2 30 2 34 2>; | ||
218 | interrupt-parent = <&mpic>; | ||
219 | tbi-handle = <&tbi0>; | ||
220 | phy-handle = <&phy0>; | ||
221 | phy-connection-type = "rgmii-id"; | ||
222 | |||
223 | mdio@520 { | ||
224 | #address-cells = <1>; | ||
225 | #size-cells = <0>; | ||
226 | compatible = "fsl,gianfar-mdio"; | ||
227 | reg = <0x520 0x20>; | ||
228 | |||
229 | phy0: ethernet-phy@1f { | ||
230 | reg = <0x1f>; | ||
231 | }; | ||
232 | phy1: ethernet-phy@0 { | ||
233 | reg = <0>; | ||
234 | }; | ||
235 | phy2: ethernet-phy@1 { | ||
236 | reg = <1>; | ||
237 | }; | ||
238 | phy3: ethernet-phy@2 { | ||
239 | reg = <2>; | ||
240 | }; | ||
241 | tbi0: tbi-phy@11 { | ||
242 | reg = <0x11>; | ||
243 | device_type = "tbi-phy"; | ||
244 | }; | ||
245 | }; | ||
246 | }; | ||
247 | |||
248 | enet1: ethernet@25000 { | ||
249 | #address-cells = <1>; | ||
250 | #size-cells = <1>; | ||
251 | cell-index = <1>; | ||
252 | device_type = "network"; | ||
253 | model = "TSEC"; | ||
254 | compatible = "gianfar"; | ||
255 | reg = <0x25000 0x1000>; | ||
256 | ranges = <0x0 0x25000 0x1000>; | ||
257 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
258 | interrupts = <35 2 36 2 40 2>; | ||
259 | interrupt-parent = <&mpic>; | ||
260 | tbi-handle = <&tbi1>; | ||
261 | phy-handle = <&phy1>; | ||
262 | phy-connection-type = "rgmii-id"; | ||
263 | |||
264 | mdio@520 { | ||
265 | #address-cells = <1>; | ||
266 | #size-cells = <0>; | ||
267 | compatible = "fsl,gianfar-tbi"; | ||
268 | reg = <0x520 0x20>; | ||
269 | |||
270 | tbi1: tbi-phy@11 { | ||
271 | reg = <0x11>; | ||
272 | device_type = "tbi-phy"; | ||
273 | }; | ||
274 | }; | ||
275 | }; | ||
276 | |||
277 | enet2: ethernet@26000 { | ||
278 | #address-cells = <1>; | ||
279 | #size-cells = <1>; | ||
280 | cell-index = <2>; | ||
281 | device_type = "network"; | ||
282 | model = "TSEC"; | ||
283 | compatible = "gianfar"; | ||
284 | reg = <0x26000 0x1000>; | ||
285 | ranges = <0x0 0x26000 0x1000>; | ||
286 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
287 | interrupts = <31 2 32 2 33 2>; | ||
288 | interrupt-parent = <&mpic>; | ||
289 | tbi-handle = <&tbi2>; | ||
290 | phy-handle = <&phy2>; | ||
291 | phy-connection-type = "rgmii-id"; | ||
292 | |||
293 | mdio@520 { | ||
294 | #address-cells = <1>; | ||
295 | #size-cells = <0>; | ||
296 | compatible = "fsl,gianfar-tbi"; | ||
297 | reg = <0x520 0x20>; | ||
298 | |||
299 | tbi2: tbi-phy@11 { | ||
300 | reg = <0x11>; | ||
301 | device_type = "tbi-phy"; | ||
302 | }; | ||
303 | }; | ||
304 | }; | ||
305 | |||
306 | enet3: ethernet@27000 { | ||
307 | #address-cells = <1>; | ||
308 | #size-cells = <1>; | ||
309 | cell-index = <3>; | ||
310 | device_type = "network"; | ||
311 | model = "TSEC"; | ||
312 | compatible = "gianfar"; | ||
313 | reg = <0x27000 0x1000>; | ||
314 | ranges = <0x0 0x27000 0x1000>; | ||
315 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
316 | interrupts = <37 2 38 2 39 2>; | ||
317 | interrupt-parent = <&mpic>; | ||
318 | tbi-handle = <&tbi3>; | ||
319 | phy-handle = <&phy3>; | ||
320 | phy-connection-type = "rgmii-id"; | ||
321 | |||
322 | mdio@520 { | ||
323 | #address-cells = <1>; | ||
324 | #size-cells = <0>; | ||
325 | compatible = "fsl,gianfar-tbi"; | ||
326 | reg = <0x520 0x20>; | ||
327 | |||
328 | tbi3: tbi-phy@11 { | ||
329 | reg = <0x11>; | ||
330 | device_type = "tbi-phy"; | ||
331 | }; | ||
332 | }; | ||
333 | }; | ||
334 | |||
335 | serial0: serial@4500 { | ||
336 | cell-index = <0>; | ||
337 | device_type = "serial"; | ||
338 | compatible = "fsl,ns16550", "ns16550"; | ||
339 | reg = <0x4500 0x100>; | ||
340 | clock-frequency = <0>; | ||
341 | interrupts = <42 2>; | ||
342 | interrupt-parent = <&mpic>; | ||
343 | }; | ||
344 | |||
345 | serial1: serial@4600 { | ||
346 | cell-index = <1>; | ||
347 | device_type = "serial"; | ||
348 | compatible = "fsl,ns16550", "ns16550"; | ||
349 | reg = <0x4600 0x100>; | ||
350 | clock-frequency = <0>; | ||
351 | interrupts = <28 2>; | ||
352 | interrupt-parent = <&mpic>; | ||
353 | }; | ||
354 | |||
355 | mpic: pic@40000 { | ||
356 | clock-frequency = <0>; | ||
357 | interrupt-controller; | ||
358 | #address-cells = <0>; | ||
359 | #interrupt-cells = <2>; | ||
360 | reg = <0x40000 0x40000>; | ||
361 | compatible = "chrp,open-pic"; | ||
362 | device_type = "open-pic"; | ||
363 | big-endian; | ||
364 | }; | ||
365 | |||
366 | global-utilities@e0000 { | ||
367 | compatible = "fsl,mpc8641-guts"; | ||
368 | reg = <0xe0000 0x1000>; | ||
369 | fsl,has-rstcr; | ||
370 | }; | ||
371 | }; | ||
372 | |||
373 | pci0: pcie@f8008000 { | ||
374 | compatible = "fsl,mpc8641-pcie"; | ||
375 | device_type = "pci"; | ||
376 | #interrupt-cells = <1>; | ||
377 | #size-cells = <2>; | ||
378 | #address-cells = <3>; | ||
379 | reg = <0xf8008000 0x1000>; | ||
380 | bus-range = <0x0 0xff>; | ||
381 | ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000 | ||
382 | 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>; | ||
383 | clock-frequency = <33333333>; | ||
384 | interrupt-parent = <&mpic>; | ||
385 | interrupts = <24 2>; | ||
386 | interrupt-map-mask = <0xff00 0 0 7>; | ||
387 | interrupt-map = < | ||
388 | /* IDSEL 0x0 */ | ||
389 | 0x0000 0 0 1 &mpic 0 1 | ||
390 | 0x0000 0 0 2 &mpic 1 1 | ||
391 | 0x0000 0 0 3 &mpic 2 1 | ||
392 | 0x0000 0 0 4 &mpic 3 1 | ||
393 | >; | ||
394 | |||
395 | pcie@0 { | ||
396 | reg = <0 0 0 0 0>; | ||
397 | #size-cells = <2>; | ||
398 | #address-cells = <3>; | ||
399 | device_type = "pci"; | ||
400 | ranges = <0x02000000 0x0 0x80000000 | ||
401 | 0x02000000 0x0 0x80000000 | ||
402 | 0x0 0x20000000 | ||
403 | |||
404 | 0x01000000 0x0 0x00000000 | ||
405 | 0x01000000 0x0 0x00000000 | ||
406 | 0x0 0x00100000>; | ||
407 | }; | ||
408 | |||
409 | }; | ||
410 | |||
411 | pci1: pcie@f8009000 { | ||
412 | compatible = "fsl,mpc8641-pcie"; | ||
413 | device_type = "pci"; | ||
414 | #interrupt-cells = <1>; | ||
415 | #size-cells = <2>; | ||
416 | #address-cells = <3>; | ||
417 | reg = <0xf8009000 0x1000>; | ||
418 | bus-range = <0 0xff>; | ||
419 | ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000 | ||
420 | 0x01000000 0x0 0x00000000 0xe3000000 0x0 0x00100000>; | ||
421 | clock-frequency = <33333333>; | ||
422 | interrupt-parent = <&mpic>; | ||
423 | interrupts = <25 2>; | ||
424 | interrupt-map-mask = <0xf800 0 0 7>; | ||
425 | interrupt-map = < | ||
426 | /* IDSEL 0x0 */ | ||
427 | 0x0000 0 0 1 &mpic 4 1 | ||
428 | 0x0000 0 0 2 &mpic 5 1 | ||
429 | 0x0000 0 0 3 &mpic 6 1 | ||
430 | 0x0000 0 0 4 &mpic 7 1 | ||
431 | >; | ||
432 | |||
433 | pcie@0 { | ||
434 | reg = <0 0 0 0 0>; | ||
435 | #size-cells = <2>; | ||
436 | #address-cells = <3>; | ||
437 | device_type = "pci"; | ||
438 | ranges = <0x02000000 0x0 0xa0000000 | ||
439 | 0x02000000 0x0 0xa0000000 | ||
440 | 0x0 0x20000000 | ||
441 | |||
442 | 0x01000000 0x0 0x00000000 | ||
443 | 0x01000000 0x0 0x00000000 | ||
444 | 0x0 0x00100000>; | ||
445 | }; | ||
446 | }; | ||
447 | }; | ||
diff --git a/arch/powerpc/boot/rs6000.h b/arch/powerpc/boot/rs6000.h index 433f45084e41..d70517ccc0f7 100644 --- a/arch/powerpc/boot/rs6000.h +++ b/arch/powerpc/boot/rs6000.h | |||
@@ -239,5 +239,5 @@ struct external_reloc { | |||
239 | #define DEFAULT_DATA_SECTION_ALIGNMENT 4 | 239 | #define DEFAULT_DATA_SECTION_ALIGNMENT 4 |
240 | #define DEFAULT_BSS_SECTION_ALIGNMENT 4 | 240 | #define DEFAULT_BSS_SECTION_ALIGNMENT 4 |
241 | #define DEFAULT_TEXT_SECTION_ALIGNMENT 4 | 241 | #define DEFAULT_TEXT_SECTION_ALIGNMENT 4 |
242 | /* For new sections we havn't heard of before */ | 242 | /* For new sections we haven't heard of before */ |
243 | #define DEFAULT_SECTION_ALIGNMENT 4 | 243 | #define DEFAULT_SECTION_ALIGNMENT 4 |
diff --git a/arch/powerpc/boot/treeboot-akebono.c b/arch/powerpc/boot/treeboot-akebono.c index b73174c34fe4..bcc5902f8462 100644 --- a/arch/powerpc/boot/treeboot-akebono.c +++ b/arch/powerpc/boot/treeboot-akebono.c | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | BSS_STACK(4096); | 39 | BSS_STACK(4096); |
40 | 40 | ||
41 | #define SPRN_PIR 0x11E /* Processor Indentification Register */ | 41 | #define SPRN_PIR 0x11E /* Processor Identification Register */ |
42 | #define USERDATA_LEN 256 /* Length of userdata passed in by PIBS */ | 42 | #define USERDATA_LEN 256 /* Length of userdata passed in by PIBS */ |
43 | #define MAX_RANKS 0x4 | 43 | #define MAX_RANKS 0x4 |
44 | #define DDR3_MR0CF 0x80010011U | 44 | #define DDR3_MR0CF 0x80010011U |
diff --git a/arch/powerpc/boot/treeboot-currituck.c b/arch/powerpc/boot/treeboot-currituck.c index 925ae43b7467..303d2074ee56 100644 --- a/arch/powerpc/boot/treeboot-currituck.c +++ b/arch/powerpc/boot/treeboot-currituck.c | |||
@@ -80,7 +80,7 @@ static void ibm_currituck_fixups(void) | |||
80 | } | 80 | } |
81 | } | 81 | } |
82 | 82 | ||
83 | #define SPRN_PIR 0x11E /* Processor Indentification Register */ | 83 | #define SPRN_PIR 0x11E /* Processor Identification Register */ |
84 | void platform_init(void) | 84 | void platform_init(void) |
85 | { | 85 | { |
86 | unsigned long end_of_ram, avail_ram; | 86 | unsigned long end_of_ram, avail_ram; |
diff --git a/arch/powerpc/boot/treeboot-iss4xx.c b/arch/powerpc/boot/treeboot-iss4xx.c index 329e710feda2..733f8bf25184 100644 --- a/arch/powerpc/boot/treeboot-iss4xx.c +++ b/arch/powerpc/boot/treeboot-iss4xx.c | |||
@@ -59,7 +59,7 @@ static void *iss_4xx_vmlinux_alloc(unsigned long size) | |||
59 | return (void *)ibm4xx_memstart; | 59 | return (void *)ibm4xx_memstart; |
60 | } | 60 | } |
61 | 61 | ||
62 | #define SPRN_PIR 0x11E /* Processor Indentification Register */ | 62 | #define SPRN_PIR 0x11E /* Processor Identification Register */ |
63 | void platform_init(void) | 63 | void platform_init(void) |
64 | { | 64 | { |
65 | unsigned long end_of_ram = 0x08000000; | 65 | unsigned long end_of_ram = 0x08000000; |
diff --git a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig index 2a5fdcbabcdd..87fc15bce407 100644 --- a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig +++ b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig | |||
@@ -35,7 +35,6 @@ CONFIG_MTD_PHYSMAP=y | |||
35 | CONFIG_BLK_DEV_LOOP=y | 35 | CONFIG_BLK_DEV_LOOP=y |
36 | CONFIG_BLK_DEV_RAM=y | 36 | CONFIG_BLK_DEV_RAM=y |
37 | CONFIG_BLK_DEV_RAM_SIZE=32768 | 37 | CONFIG_BLK_DEV_RAM_SIZE=32768 |
38 | CONFIG_IDE=y | ||
39 | CONFIG_BLK_DEV_SD=y | 38 | CONFIG_BLK_DEV_SD=y |
40 | CONFIG_CHR_DEV_SG=y | 39 | CONFIG_CHR_DEV_SG=y |
41 | CONFIG_SCSI_SPI_ATTRS=y | 40 | CONFIG_SCSI_SPI_ATTRS=y |
diff --git a/arch/powerpc/configs/85xx/ksi8560_defconfig b/arch/powerpc/configs/85xx/ksi8560_defconfig index 3be85c5f1a2a..6f753a71fe5d 100644 --- a/arch/powerpc/configs/85xx/ksi8560_defconfig +++ b/arch/powerpc/configs/85xx/ksi8560_defconfig | |||
@@ -34,7 +34,6 @@ CONFIG_MTD_PHYSMAP_OF=y | |||
34 | CONFIG_BLK_DEV_LOOP=y | 34 | CONFIG_BLK_DEV_LOOP=y |
35 | CONFIG_BLK_DEV_RAM=y | 35 | CONFIG_BLK_DEV_RAM=y |
36 | CONFIG_BLK_DEV_RAM_SIZE=32768 | 36 | CONFIG_BLK_DEV_RAM_SIZE=32768 |
37 | CONFIG_IDE=y | ||
38 | CONFIG_NETDEVICES=y | 37 | CONFIG_NETDEVICES=y |
39 | CONFIG_FS_ENET=y | 38 | CONFIG_FS_ENET=y |
40 | # CONFIG_FS_ENET_HAS_SCC is not set | 39 | # CONFIG_FS_ENET_HAS_SCC is not set |
diff --git a/arch/powerpc/configs/85xx/stx_gp3_defconfig b/arch/powerpc/configs/85xx/stx_gp3_defconfig index f66d16ba8c58..b45190556c0c 100644 --- a/arch/powerpc/configs/85xx/stx_gp3_defconfig +++ b/arch/powerpc/configs/85xx/stx_gp3_defconfig | |||
@@ -31,8 +31,6 @@ CONFIG_BLK_DEV_LOOP=m | |||
31 | CONFIG_BLK_DEV_NBD=m | 31 | CONFIG_BLK_DEV_NBD=m |
32 | CONFIG_BLK_DEV_RAM=y | 32 | CONFIG_BLK_DEV_RAM=y |
33 | CONFIG_BLK_DEV_RAM_SIZE=32768 | 33 | CONFIG_BLK_DEV_RAM_SIZE=32768 |
34 | CONFIG_IDE=y | ||
35 | CONFIG_BLK_DEV_IDECD=m | ||
36 | CONFIG_SCSI=m | 34 | CONFIG_SCSI=m |
37 | CONFIG_BLK_DEV_SD=m | 35 | CONFIG_BLK_DEV_SD=m |
38 | CONFIG_CHR_DEV_ST=m | 36 | CONFIG_CHR_DEV_ST=m |
diff --git a/arch/powerpc/configs/86xx-hw.config b/arch/powerpc/configs/86xx-hw.config new file mode 100644 index 000000000000..f91f8895fc93 --- /dev/null +++ b/arch/powerpc/configs/86xx-hw.config | |||
@@ -0,0 +1,104 @@ | |||
1 | CONFIG_ATA=y | ||
2 | CONFIG_BLK_DEV_SD=y | ||
3 | CONFIG_BLK_DEV_SR=y | ||
4 | CONFIG_BROADCOM_PHY=y | ||
5 | # CONFIG_CARDBUS is not set | ||
6 | CONFIG_CHR_DEV_SG=y | ||
7 | CONFIG_CHR_DEV_ST=y | ||
8 | CONFIG_CRC_T10DIF=y | ||
9 | CONFIG_CRYPTO_HMAC=y | ||
10 | CONFIG_DS1682=y | ||
11 | CONFIG_EEPROM_LEGACY=y | ||
12 | CONFIG_GEF_WDT=y | ||
13 | CONFIG_GIANFAR=y | ||
14 | CONFIG_GPIO_GE_FPGA=y | ||
15 | CONFIG_GPIO_SYSFS=y | ||
16 | CONFIG_HID_A4TECH=y | ||
17 | CONFIG_HID_APPLE=y | ||
18 | CONFIG_HID_BELKIN=y | ||
19 | CONFIG_HID_CHERRY=y | ||
20 | CONFIG_HID_CHICONY=y | ||
21 | CONFIG_HID_CYPRESS=y | ||
22 | CONFIG_HID_EZKEY=y | ||
23 | CONFIG_HID_GYRATION=y | ||
24 | CONFIG_HID_LOGITECH=y | ||
25 | CONFIG_HID_MICROSOFT=y | ||
26 | CONFIG_HID_MONTEREY=y | ||
27 | CONFIG_HID_PANTHERLORD=y | ||
28 | CONFIG_HID_PETALYNX=y | ||
29 | CONFIG_HID_SAMSUNG=y | ||
30 | CONFIG_HID_SUNPLUS=y | ||
31 | CONFIG_HW_RANDOM=y | ||
32 | CONFIG_HZ_1000=y | ||
33 | CONFIG_I2C_MPC=y | ||
34 | CONFIG_I2C=y | ||
35 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
36 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
37 | CONFIG_INPUT_FF_MEMLESS=m | ||
38 | # CONFIG_INPUT_KEYBOARD is not set | ||
39 | # CONFIG_INPUT_MOUSEDEV is not set | ||
40 | # CONFIG_INPUT_MOUSE is not set | ||
41 | CONFIG_MTD_BLOCK=y | ||
42 | CONFIG_MTD_CFI_ADV_OPTIONS=y | ||
43 | CONFIG_MTD_CFI_AMDSTD=y | ||
44 | CONFIG_MTD_CFI_INTELEXT=y | ||
45 | CONFIG_MTD_CFI_LE_BYTE_SWAP=y | ||
46 | CONFIG_MTD_CFI=y | ||
47 | CONFIG_MTD_CMDLINE_PARTS=y | ||
48 | CONFIG_MTD_JEDECPROBE=y | ||
49 | CONFIG_MTD_NAND_FSL_ELBC=y | ||
50 | CONFIG_MTD_NAND=y | ||
51 | CONFIG_MTD_PHYSMAP_OF=y | ||
52 | CONFIG_NETDEVICES=y | ||
53 | CONFIG_NET_TULIP=y | ||
54 | CONFIG_NVRAM=y | ||
55 | CONFIG_PATA_ALI=y | ||
56 | CONFIG_PCCARD=y | ||
57 | CONFIG_PCI_DEBUG=y | ||
58 | # CONFIG_PCIEASPM is not set | ||
59 | CONFIG_PCIEPORTBUS=y | ||
60 | CONFIG_PCI=y | ||
61 | # CONFIG_PCMCIA_LOAD_CIS is not set | ||
62 | # CONFIG_PPC_CHRP is not set | ||
63 | # CONFIG_PPC_PMAC is not set | ||
64 | CONFIG_RTC_CLASS=y | ||
65 | CONFIG_RTC_DRV_CMOS=y | ||
66 | CONFIG_RTC_DRV_RX8581=y | ||
67 | CONFIG_SATA_AHCI=y | ||
68 | CONFIG_SATA_SIL24=y | ||
69 | CONFIG_SATA_SIL=y | ||
70 | CONFIG_SCSI_LOGGING=y | ||
71 | CONFIG_SENSORS_LM90=y | ||
72 | CONFIG_SENSORS_LM92=y | ||
73 | CONFIG_SERIAL_8250_CONSOLE=y | ||
74 | CONFIG_SERIAL_8250_DETECT_IRQ=y | ||
75 | CONFIG_SERIAL_8250_EXTENDED=y | ||
76 | CONFIG_SERIAL_8250_MANY_PORTS=y | ||
77 | CONFIG_SERIAL_8250_NR_UARTS=2 | ||
78 | CONFIG_SERIAL_8250_RSA=y | ||
79 | CONFIG_SERIAL_8250_RUNTIME_UARTS=2 | ||
80 | CONFIG_SERIAL_8250_SHARE_IRQ=y | ||
81 | CONFIG_SERIAL_8250=y | ||
82 | CONFIG_SERIO_LIBPS2=y | ||
83 | CONFIG_SND_INTEL8X0=y | ||
84 | CONFIG_SND_MIXER_OSS=y | ||
85 | CONFIG_SND_PCM_OSS=y | ||
86 | # CONFIG_SND_SUPPORT_OLD_API is not set | ||
87 | CONFIG_SND=y | ||
88 | CONFIG_SOUND=y | ||
89 | CONFIG_ULI526X=y | ||
90 | CONFIG_USB_EHCI_HCD=y | ||
91 | CONFIG_USB_MON=y | ||
92 | CONFIG_USB_OHCI_HCD_PPC_OF_BE=y | ||
93 | CONFIG_USB_OHCI_HCD_PPC_OF_LE=y | ||
94 | CONFIG_USB_OHCI_HCD=y | ||
95 | CONFIG_USB_STORAGE=y | ||
96 | CONFIG_USB=y | ||
97 | CONFIG_VITESSE_PHY=y | ||
98 | CONFIG_VME_BUS=y | ||
99 | CONFIG_VME_TSI148=y | ||
100 | CONFIG_WATCHDOG=y | ||
101 | # CONFIG_YENTA_O2 is not set | ||
102 | # CONFIG_YENTA_RICOH is not set | ||
103 | # CONFIG_YENTA_TOSHIBA is not set | ||
104 | CONFIG_YENTA=y | ||
diff --git a/arch/powerpc/configs/86xx-smp.config b/arch/powerpc/configs/86xx-smp.config new file mode 100644 index 000000000000..40ac38d3038c --- /dev/null +++ b/arch/powerpc/configs/86xx-smp.config | |||
@@ -0,0 +1,2 @@ | |||
1 | CONFIG_NR_CPUS=2 | ||
2 | CONFIG_SMP=y | ||
diff --git a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig deleted file mode 100644 index 9792a2cb9b20..000000000000 --- a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig +++ /dev/null | |||
@@ -1,216 +0,0 @@ | |||
1 | CONFIG_SMP=y | ||
2 | CONFIG_NR_CPUS=2 | ||
3 | CONFIG_SYSVIPC=y | ||
4 | CONFIG_POSIX_MQUEUE=y | ||
5 | CONFIG_HIGH_RES_TIMERS=y | ||
6 | CONFIG_BSD_PROCESS_ACCT=y | ||
7 | CONFIG_BSD_PROCESS_ACCT_V3=y | ||
8 | CONFIG_IKCONFIG=y | ||
9 | CONFIG_IKCONFIG_PROC=y | ||
10 | CONFIG_LOG_BUF_SHIFT=14 | ||
11 | CONFIG_RELAY=y | ||
12 | CONFIG_BLK_DEV_INITRD=y | ||
13 | CONFIG_EXPERT=y | ||
14 | CONFIG_SLAB=y | ||
15 | CONFIG_MODULES=y | ||
16 | CONFIG_MODULE_UNLOAD=y | ||
17 | # CONFIG_BLK_DEV_BSG is not set | ||
18 | # CONFIG_PPC_CHRP is not set | ||
19 | # CONFIG_PPC_PMAC is not set | ||
20 | CONFIG_PPC_86xx=y | ||
21 | CONFIG_GEF_PPC9A=y | ||
22 | CONFIG_HIGHMEM=y | ||
23 | CONFIG_HZ_1000=y | ||
24 | CONFIG_PREEMPT=y | ||
25 | CONFIG_BINFMT_MISC=m | ||
26 | CONFIG_PCI=y | ||
27 | CONFIG_PCIEPORTBUS=y | ||
28 | # CONFIG_PCIEASPM is not set | ||
29 | CONFIG_PCCARD=y | ||
30 | # CONFIG_PCMCIA_LOAD_CIS is not set | ||
31 | # CONFIG_CARDBUS is not set | ||
32 | CONFIG_YENTA=y | ||
33 | # CONFIG_YENTA_O2 is not set | ||
34 | # CONFIG_YENTA_RICOH is not set | ||
35 | # CONFIG_YENTA_TOSHIBA is not set | ||
36 | CONFIG_NET=y | ||
37 | CONFIG_PACKET=y | ||
38 | CONFIG_UNIX=y | ||
39 | CONFIG_XFRM_USER=m | ||
40 | CONFIG_NET_KEY=m | ||
41 | CONFIG_INET=y | ||
42 | CONFIG_IP_MULTICAST=y | ||
43 | CONFIG_IP_ADVANCED_ROUTER=y | ||
44 | CONFIG_IP_MULTIPLE_TABLES=y | ||
45 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
46 | CONFIG_IP_ROUTE_VERBOSE=y | ||
47 | CONFIG_IP_PNP=y | ||
48 | CONFIG_IP_PNP_DHCP=y | ||
49 | CONFIG_IP_PNP_BOOTP=y | ||
50 | CONFIG_IP_PNP_RARP=y | ||
51 | CONFIG_NET_IPIP=m | ||
52 | CONFIG_IP_MROUTE=y | ||
53 | CONFIG_IP_PIMSM_V1=y | ||
54 | CONFIG_IP_PIMSM_V2=y | ||
55 | CONFIG_SYN_COOKIES=y | ||
56 | CONFIG_INET_AH=m | ||
57 | CONFIG_INET_ESP=m | ||
58 | CONFIG_INET_IPCOMP=m | ||
59 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
60 | CONFIG_INET6_AH=m | ||
61 | CONFIG_INET6_ESP=m | ||
62 | CONFIG_INET6_IPCOMP=m | ||
63 | CONFIG_IPV6_TUNNEL=m | ||
64 | CONFIG_NET_PKTGEN=m | ||
65 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
66 | CONFIG_MTD=y | ||
67 | CONFIG_MTD_BLOCK=y | ||
68 | CONFIG_MTD_CFI=y | ||
69 | CONFIG_MTD_JEDECPROBE=y | ||
70 | CONFIG_MTD_CFI_INTELEXT=y | ||
71 | CONFIG_MTD_CFI_AMDSTD=y | ||
72 | CONFIG_MTD_PHYSMAP_OF=y | ||
73 | CONFIG_BLK_DEV_LOOP=m | ||
74 | CONFIG_BLK_DEV_CRYPTOLOOP=m | ||
75 | CONFIG_BLK_DEV_NBD=m | ||
76 | CONFIG_BLK_DEV_RAM=y | ||
77 | CONFIG_BLK_DEV_RAM_SIZE=131072 | ||
78 | CONFIG_DS1682=y | ||
79 | CONFIG_IDE=y | ||
80 | CONFIG_BLK_DEV_IDECS=y | ||
81 | CONFIG_BLK_DEV_SD=y | ||
82 | CONFIG_CHR_DEV_ST=y | ||
83 | CONFIG_BLK_DEV_SR=y | ||
84 | CONFIG_ATA=y | ||
85 | CONFIG_SATA_SIL=y | ||
86 | CONFIG_NETDEVICES=y | ||
87 | CONFIG_BONDING=m | ||
88 | CONFIG_DUMMY=m | ||
89 | CONFIG_NETCONSOLE=y | ||
90 | CONFIG_TUN=m | ||
91 | CONFIG_GIANFAR=y | ||
92 | CONFIG_PPP=m | ||
93 | CONFIG_PPP_BSDCOMP=m | ||
94 | CONFIG_PPP_DEFLATE=m | ||
95 | CONFIG_PPP_FILTER=y | ||
96 | CONFIG_PPP_MULTILINK=y | ||
97 | CONFIG_PPPOE=m | ||
98 | CONFIG_PPP_ASYNC=m | ||
99 | CONFIG_PPP_SYNC_TTY=m | ||
100 | CONFIG_SLIP=m | ||
101 | CONFIG_SLIP_COMPRESSED=y | ||
102 | CONFIG_SLIP_SMART=y | ||
103 | CONFIG_SLIP_MODE_SLIP6=y | ||
104 | # CONFIG_INPUT_KEYBOARD is not set | ||
105 | # CONFIG_INPUT_MOUSE is not set | ||
106 | # CONFIG_SERIO is not set | ||
107 | # CONFIG_LEGACY_PTYS is not set | ||
108 | CONFIG_SERIAL_8250=y | ||
109 | CONFIG_SERIAL_8250_CONSOLE=y | ||
110 | # CONFIG_SERIAL_8250_PCI is not set | ||
111 | CONFIG_SERIAL_8250_NR_UARTS=2 | ||
112 | CONFIG_SERIAL_8250_RUNTIME_UARTS=2 | ||
113 | CONFIG_HW_RANDOM=y | ||
114 | CONFIG_NVRAM=y | ||
115 | CONFIG_I2C=y | ||
116 | CONFIG_I2C_CHARDEV=y | ||
117 | CONFIG_I2C_MPC=y | ||
118 | CONFIG_GPIO_SYSFS=y | ||
119 | CONFIG_GPIO_GE_FPGA=y | ||
120 | CONFIG_SENSORS_LM90=y | ||
121 | CONFIG_SENSORS_LM92=y | ||
122 | CONFIG_WATCHDOG=y | ||
123 | CONFIG_GEF_WDT=y | ||
124 | CONFIG_HID_A4TECH=y | ||
125 | CONFIG_HID_APPLE=y | ||
126 | CONFIG_HID_BELKIN=y | ||
127 | CONFIG_HID_CHERRY=y | ||
128 | CONFIG_HID_CHICONY=y | ||
129 | CONFIG_HID_CYPRESS=y | ||
130 | CONFIG_HID_EZKEY=y | ||
131 | CONFIG_HID_GYRATION=y | ||
132 | CONFIG_HID_LOGITECH=y | ||
133 | CONFIG_HID_MICROSOFT=y | ||
134 | CONFIG_HID_MONTEREY=y | ||
135 | CONFIG_HID_PANTHERLORD=y | ||
136 | CONFIG_HID_PETALYNX=y | ||
137 | CONFIG_HID_SAMSUNG=y | ||
138 | CONFIG_HID_SUNPLUS=y | ||
139 | CONFIG_USB=y | ||
140 | CONFIG_USB_EHCI_HCD=y | ||
141 | # CONFIG_USB_EHCI_HCD_PPC_OF is not set | ||
142 | CONFIG_USB_OHCI_HCD=y | ||
143 | CONFIG_USB_STORAGE=y | ||
144 | CONFIG_RTC_CLASS=y | ||
145 | # CONFIG_RTC_INTF_PROC is not set | ||
146 | CONFIG_RTC_DRV_RX8581=y | ||
147 | CONFIG_STAGING=y | ||
148 | CONFIG_VME_BUS=y | ||
149 | CONFIG_VME_TSI148=y | ||
150 | CONFIG_EXT2_FS=y | ||
151 | CONFIG_EXT2_FS_XATTR=y | ||
152 | CONFIG_EXT2_FS_POSIX_ACL=y | ||
153 | CONFIG_EXT3_FS=y | ||
154 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
155 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
156 | CONFIG_ISO9660_FS=y | ||
157 | CONFIG_JOLIET=y | ||
158 | CONFIG_ZISOFS=y | ||
159 | CONFIG_UDF_FS=y | ||
160 | CONFIG_MSDOS_FS=y | ||
161 | CONFIG_VFAT_FS=y | ||
162 | CONFIG_FAT_DEFAULT_CODEPAGE=850 | ||
163 | CONFIG_FAT_DEFAULT_IOCHARSET="ascii" | ||
164 | CONFIG_PROC_KCORE=y | ||
165 | CONFIG_TMPFS=y | ||
166 | CONFIG_JFFS2_FS=y | ||
167 | CONFIG_NFS_FS=y | ||
168 | CONFIG_NFS_V4=y | ||
169 | CONFIG_ROOT_NFS=y | ||
170 | CONFIG_CIFS=m | ||
171 | CONFIG_CIFS_XATTR=y | ||
172 | CONFIG_CIFS_POSIX=y | ||
173 | CONFIG_NLS_CODEPAGE_437=m | ||
174 | CONFIG_NLS_CODEPAGE_737=m | ||
175 | CONFIG_NLS_CODEPAGE_775=m | ||
176 | CONFIG_NLS_CODEPAGE_850=m | ||
177 | CONFIG_NLS_CODEPAGE_852=m | ||
178 | CONFIG_NLS_CODEPAGE_855=m | ||
179 | CONFIG_NLS_CODEPAGE_857=m | ||
180 | CONFIG_NLS_CODEPAGE_860=m | ||
181 | CONFIG_NLS_CODEPAGE_861=m | ||
182 | CONFIG_NLS_CODEPAGE_862=m | ||
183 | CONFIG_NLS_CODEPAGE_863=m | ||
184 | CONFIG_NLS_CODEPAGE_864=m | ||
185 | CONFIG_NLS_CODEPAGE_865=m | ||
186 | CONFIG_NLS_CODEPAGE_866=m | ||
187 | CONFIG_NLS_CODEPAGE_869=m | ||
188 | CONFIG_NLS_CODEPAGE_936=m | ||
189 | CONFIG_NLS_CODEPAGE_950=m | ||
190 | CONFIG_NLS_CODEPAGE_932=m | ||
191 | CONFIG_NLS_CODEPAGE_949=m | ||
192 | CONFIG_NLS_CODEPAGE_874=m | ||
193 | CONFIG_NLS_ISO8859_8=m | ||
194 | CONFIG_NLS_CODEPAGE_1250=m | ||
195 | CONFIG_NLS_CODEPAGE_1251=m | ||
196 | CONFIG_NLS_ASCII=m | ||
197 | CONFIG_NLS_ISO8859_1=m | ||
198 | CONFIG_NLS_ISO8859_2=m | ||
199 | CONFIG_NLS_ISO8859_3=m | ||
200 | CONFIG_NLS_ISO8859_4=m | ||
201 | CONFIG_NLS_ISO8859_5=m | ||
202 | CONFIG_NLS_ISO8859_6=m | ||
203 | CONFIG_NLS_ISO8859_7=m | ||
204 | CONFIG_NLS_ISO8859_9=m | ||
205 | CONFIG_NLS_ISO8859_13=m | ||
206 | CONFIG_NLS_ISO8859_14=m | ||
207 | CONFIG_NLS_ISO8859_15=m | ||
208 | CONFIG_NLS_KOI8_R=m | ||
209 | CONFIG_NLS_KOI8_U=m | ||
210 | CONFIG_NLS_UTF8=m | ||
211 | CONFIG_CRC_CCITT=y | ||
212 | CONFIG_CRC_T10DIF=y | ||
213 | CONFIG_LIBCRC32C=y | ||
214 | CONFIG_MAGIC_SYSRQ=y | ||
215 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
216 | # CONFIG_CRYPTO_HW is not set | ||
diff --git a/arch/powerpc/configs/86xx/gef_sbc310_defconfig b/arch/powerpc/configs/86xx/gef_sbc310_defconfig deleted file mode 100644 index cadc36682bb4..000000000000 --- a/arch/powerpc/configs/86xx/gef_sbc310_defconfig +++ /dev/null | |||
@@ -1,214 +0,0 @@ | |||
1 | CONFIG_SMP=y | ||
2 | CONFIG_NR_CPUS=2 | ||
3 | CONFIG_SYSVIPC=y | ||
4 | CONFIG_POSIX_MQUEUE=y | ||
5 | CONFIG_HIGH_RES_TIMERS=y | ||
6 | CONFIG_BSD_PROCESS_ACCT=y | ||
7 | CONFIG_BSD_PROCESS_ACCT_V3=y | ||
8 | CONFIG_IKCONFIG=y | ||
9 | CONFIG_IKCONFIG_PROC=y | ||
10 | CONFIG_LOG_BUF_SHIFT=14 | ||
11 | CONFIG_RELAY=y | ||
12 | CONFIG_BLK_DEV_INITRD=y | ||
13 | CONFIG_EXPERT=y | ||
14 | CONFIG_SLAB=y | ||
15 | CONFIG_MODULES=y | ||
16 | CONFIG_MODULE_UNLOAD=y | ||
17 | # CONFIG_BLK_DEV_BSG is not set | ||
18 | # CONFIG_PPC_CHRP is not set | ||
19 | # CONFIG_PPC_PMAC is not set | ||
20 | CONFIG_PPC_86xx=y | ||
21 | CONFIG_GEF_SBC310=y | ||
22 | CONFIG_HIGHMEM=y | ||
23 | CONFIG_HZ_1000=y | ||
24 | CONFIG_PREEMPT=y | ||
25 | CONFIG_BINFMT_MISC=y | ||
26 | CONFIG_PCI=y | ||
27 | CONFIG_PCIEPORTBUS=y | ||
28 | # CONFIG_PCIEASPM is not set | ||
29 | CONFIG_PCCARD=y | ||
30 | # CONFIG_PCMCIA_LOAD_CIS is not set | ||
31 | # CONFIG_CARDBUS is not set | ||
32 | CONFIG_YENTA=y | ||
33 | # CONFIG_YENTA_O2 is not set | ||
34 | # CONFIG_YENTA_RICOH is not set | ||
35 | # CONFIG_YENTA_TOSHIBA is not set | ||
36 | CONFIG_NET=y | ||
37 | CONFIG_PACKET=y | ||
38 | CONFIG_UNIX=y | ||
39 | CONFIG_XFRM_USER=m | ||
40 | CONFIG_NET_KEY=m | ||
41 | CONFIG_INET=y | ||
42 | CONFIG_IP_MULTICAST=y | ||
43 | CONFIG_IP_ADVANCED_ROUTER=y | ||
44 | CONFIG_IP_MULTIPLE_TABLES=y | ||
45 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
46 | CONFIG_IP_ROUTE_VERBOSE=y | ||
47 | CONFIG_IP_PNP=y | ||
48 | CONFIG_IP_PNP_DHCP=y | ||
49 | CONFIG_IP_PNP_BOOTP=y | ||
50 | CONFIG_IP_PNP_RARP=y | ||
51 | CONFIG_NET_IPIP=m | ||
52 | CONFIG_IP_MROUTE=y | ||
53 | CONFIG_IP_PIMSM_V1=y | ||
54 | CONFIG_IP_PIMSM_V2=y | ||
55 | CONFIG_SYN_COOKIES=y | ||
56 | CONFIG_INET_AH=m | ||
57 | CONFIG_INET_ESP=m | ||
58 | CONFIG_INET_IPCOMP=m | ||
59 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
60 | CONFIG_INET6_AH=m | ||
61 | CONFIG_INET6_ESP=m | ||
62 | CONFIG_INET6_IPCOMP=m | ||
63 | CONFIG_IPV6_TUNNEL=m | ||
64 | CONFIG_NET_PKTGEN=m | ||
65 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
66 | CONFIG_MTD=y | ||
67 | CONFIG_MTD_BLOCK=y | ||
68 | CONFIG_MTD_CFI=y | ||
69 | CONFIG_MTD_JEDECPROBE=y | ||
70 | CONFIG_MTD_CFI_INTELEXT=y | ||
71 | CONFIG_MTD_CFI_AMDSTD=y | ||
72 | CONFIG_MTD_PHYSMAP_OF=y | ||
73 | CONFIG_BLK_DEV_LOOP=m | ||
74 | CONFIG_BLK_DEV_CRYPTOLOOP=m | ||
75 | CONFIG_BLK_DEV_NBD=m | ||
76 | CONFIG_BLK_DEV_RAM=y | ||
77 | CONFIG_BLK_DEV_RAM_SIZE=131072 | ||
78 | CONFIG_DS1682=y | ||
79 | CONFIG_IDE=y | ||
80 | CONFIG_BLK_DEV_IDECS=y | ||
81 | CONFIG_BLK_DEV_SD=y | ||
82 | CONFIG_CHR_DEV_ST=y | ||
83 | CONFIG_BLK_DEV_SR=y | ||
84 | CONFIG_ATA=y | ||
85 | CONFIG_SATA_SIL24=y | ||
86 | # CONFIG_ATA_SFF is not set | ||
87 | CONFIG_NETDEVICES=y | ||
88 | CONFIG_BONDING=m | ||
89 | CONFIG_DUMMY=m | ||
90 | CONFIG_NETCONSOLE=y | ||
91 | CONFIG_TUN=m | ||
92 | CONFIG_GIANFAR=y | ||
93 | CONFIG_PPP=m | ||
94 | CONFIG_PPP_BSDCOMP=m | ||
95 | CONFIG_PPP_DEFLATE=m | ||
96 | CONFIG_PPP_FILTER=y | ||
97 | CONFIG_PPP_MULTILINK=y | ||
98 | CONFIG_PPPOE=m | ||
99 | CONFIG_PPP_ASYNC=m | ||
100 | CONFIG_PPP_SYNC_TTY=m | ||
101 | CONFIG_SLIP=m | ||
102 | CONFIG_SLIP_COMPRESSED=y | ||
103 | CONFIG_SLIP_SMART=y | ||
104 | CONFIG_SLIP_MODE_SLIP6=y | ||
105 | # CONFIG_INPUT_KEYBOARD is not set | ||
106 | # CONFIG_INPUT_MOUSE is not set | ||
107 | # CONFIG_SERIO is not set | ||
108 | # CONFIG_LEGACY_PTYS is not set | ||
109 | CONFIG_SERIAL_8250=y | ||
110 | CONFIG_SERIAL_8250_CONSOLE=y | ||
111 | # CONFIG_SERIAL_8250_PCI is not set | ||
112 | CONFIG_SERIAL_8250_NR_UARTS=2 | ||
113 | CONFIG_SERIAL_8250_RUNTIME_UARTS=2 | ||
114 | CONFIG_HW_RANDOM=y | ||
115 | CONFIG_NVRAM=y | ||
116 | CONFIG_I2C=y | ||
117 | CONFIG_I2C_CHARDEV=y | ||
118 | CONFIG_I2C_MPC=y | ||
119 | CONFIG_GPIO_SYSFS=y | ||
120 | CONFIG_GPIO_GE_FPGA=y | ||
121 | CONFIG_SENSORS_LM90=y | ||
122 | CONFIG_SENSORS_LM92=y | ||
123 | CONFIG_WATCHDOG=y | ||
124 | CONFIG_GEF_WDT=y | ||
125 | CONFIG_HID_A4TECH=y | ||
126 | CONFIG_HID_APPLE=y | ||
127 | CONFIG_HID_BELKIN=y | ||
128 | CONFIG_HID_CHERRY=y | ||
129 | CONFIG_HID_CHICONY=y | ||
130 | CONFIG_HID_CYPRESS=y | ||
131 | CONFIG_HID_EZKEY=y | ||
132 | CONFIG_HID_GYRATION=y | ||
133 | CONFIG_HID_LOGITECH=y | ||
134 | CONFIG_HID_MICROSOFT=y | ||
135 | CONFIG_HID_MONTEREY=y | ||
136 | CONFIG_HID_PANTHERLORD=y | ||
137 | CONFIG_HID_PETALYNX=y | ||
138 | CONFIG_HID_SAMSUNG=y | ||
139 | CONFIG_HID_SUNPLUS=y | ||
140 | CONFIG_USB=y | ||
141 | CONFIG_USB_EHCI_HCD=y | ||
142 | # CONFIG_USB_EHCI_HCD_PPC_OF is not set | ||
143 | CONFIG_USB_OHCI_HCD=y | ||
144 | CONFIG_USB_STORAGE=y | ||
145 | CONFIG_RTC_CLASS=y | ||
146 | # CONFIG_RTC_INTF_PROC is not set | ||
147 | CONFIG_RTC_DRV_RX8581=y | ||
148 | CONFIG_EXT2_FS=y | ||
149 | CONFIG_EXT2_FS_XATTR=y | ||
150 | CONFIG_EXT2_FS_POSIX_ACL=y | ||
151 | CONFIG_EXT3_FS=y | ||
152 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
153 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
154 | CONFIG_ISO9660_FS=y | ||
155 | CONFIG_JOLIET=y | ||
156 | CONFIG_ZISOFS=y | ||
157 | CONFIG_UDF_FS=y | ||
158 | CONFIG_MSDOS_FS=y | ||
159 | CONFIG_VFAT_FS=y | ||
160 | CONFIG_FAT_DEFAULT_CODEPAGE=850 | ||
161 | CONFIG_FAT_DEFAULT_IOCHARSET="ascii" | ||
162 | CONFIG_PROC_KCORE=y | ||
163 | CONFIG_TMPFS=y | ||
164 | CONFIG_JFFS2_FS=y | ||
165 | CONFIG_NFS_FS=y | ||
166 | CONFIG_NFS_V4=y | ||
167 | CONFIG_ROOT_NFS=y | ||
168 | CONFIG_CIFS=m | ||
169 | CONFIG_CIFS_XATTR=y | ||
170 | CONFIG_CIFS_POSIX=y | ||
171 | CONFIG_NLS_CODEPAGE_437=m | ||
172 | CONFIG_NLS_CODEPAGE_737=m | ||
173 | CONFIG_NLS_CODEPAGE_775=m | ||
174 | CONFIG_NLS_CODEPAGE_850=m | ||
175 | CONFIG_NLS_CODEPAGE_852=m | ||
176 | CONFIG_NLS_CODEPAGE_855=m | ||
177 | CONFIG_NLS_CODEPAGE_857=m | ||
178 | CONFIG_NLS_CODEPAGE_860=m | ||
179 | CONFIG_NLS_CODEPAGE_861=m | ||
180 | CONFIG_NLS_CODEPAGE_862=m | ||
181 | CONFIG_NLS_CODEPAGE_863=m | ||
182 | CONFIG_NLS_CODEPAGE_864=m | ||
183 | CONFIG_NLS_CODEPAGE_865=m | ||
184 | CONFIG_NLS_CODEPAGE_866=m | ||
185 | CONFIG_NLS_CODEPAGE_869=m | ||
186 | CONFIG_NLS_CODEPAGE_936=m | ||
187 | CONFIG_NLS_CODEPAGE_950=m | ||
188 | CONFIG_NLS_CODEPAGE_932=m | ||
189 | CONFIG_NLS_CODEPAGE_949=m | ||
190 | CONFIG_NLS_CODEPAGE_874=m | ||
191 | CONFIG_NLS_ISO8859_8=m | ||
192 | CONFIG_NLS_CODEPAGE_1250=m | ||
193 | CONFIG_NLS_CODEPAGE_1251=m | ||
194 | CONFIG_NLS_ASCII=m | ||
195 | CONFIG_NLS_ISO8859_1=m | ||
196 | CONFIG_NLS_ISO8859_2=m | ||
197 | CONFIG_NLS_ISO8859_3=m | ||
198 | CONFIG_NLS_ISO8859_4=m | ||
199 | CONFIG_NLS_ISO8859_5=m | ||
200 | CONFIG_NLS_ISO8859_6=m | ||
201 | CONFIG_NLS_ISO8859_7=m | ||
202 | CONFIG_NLS_ISO8859_9=m | ||
203 | CONFIG_NLS_ISO8859_13=m | ||
204 | CONFIG_NLS_ISO8859_14=m | ||
205 | CONFIG_NLS_ISO8859_15=m | ||
206 | CONFIG_NLS_KOI8_R=m | ||
207 | CONFIG_NLS_KOI8_U=m | ||
208 | CONFIG_NLS_UTF8=m | ||
209 | CONFIG_CRC_CCITT=y | ||
210 | CONFIG_CRC_T10DIF=y | ||
211 | CONFIG_LIBCRC32C=y | ||
212 | CONFIG_MAGIC_SYSRQ=y | ||
213 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
214 | # CONFIG_CRYPTO_HW is not set | ||
diff --git a/arch/powerpc/configs/86xx/gef_sbc610_defconfig b/arch/powerpc/configs/86xx/gef_sbc610_defconfig deleted file mode 100644 index 2aa7d9737e43..000000000000 --- a/arch/powerpc/configs/86xx/gef_sbc610_defconfig +++ /dev/null | |||
@@ -1,273 +0,0 @@ | |||
1 | CONFIG_SMP=y | ||
2 | CONFIG_NR_CPUS=2 | ||
3 | CONFIG_SYSVIPC=y | ||
4 | CONFIG_POSIX_MQUEUE=y | ||
5 | CONFIG_HIGH_RES_TIMERS=y | ||
6 | CONFIG_BSD_PROCESS_ACCT=y | ||
7 | CONFIG_BSD_PROCESS_ACCT_V3=y | ||
8 | CONFIG_IKCONFIG=y | ||
9 | CONFIG_IKCONFIG_PROC=y | ||
10 | CONFIG_LOG_BUF_SHIFT=14 | ||
11 | CONFIG_RELAY=y | ||
12 | CONFIG_BLK_DEV_INITRD=y | ||
13 | CONFIG_EXPERT=y | ||
14 | CONFIG_SLAB=y | ||
15 | CONFIG_MODULES=y | ||
16 | CONFIG_MODULE_UNLOAD=y | ||
17 | # CONFIG_BLK_DEV_BSG is not set | ||
18 | # CONFIG_PPC_CHRP is not set | ||
19 | # CONFIG_PPC_PMAC is not set | ||
20 | CONFIG_PPC_86xx=y | ||
21 | CONFIG_GEF_SBC610=y | ||
22 | CONFIG_HIGHMEM=y | ||
23 | CONFIG_HZ_1000=y | ||
24 | CONFIG_PREEMPT=y | ||
25 | CONFIG_BINFMT_MISC=m | ||
26 | CONFIG_PCI=y | ||
27 | CONFIG_PCIEPORTBUS=y | ||
28 | # CONFIG_PCIEASPM is not set | ||
29 | CONFIG_PCI_DEBUG=y | ||
30 | CONFIG_NET=y | ||
31 | CONFIG_PACKET=y | ||
32 | CONFIG_UNIX=y | ||
33 | CONFIG_XFRM_USER=m | ||
34 | CONFIG_NET_KEY=m | ||
35 | CONFIG_INET=y | ||
36 | CONFIG_IP_MULTICAST=y | ||
37 | CONFIG_IP_ADVANCED_ROUTER=y | ||
38 | CONFIG_IP_MULTIPLE_TABLES=y | ||
39 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
40 | CONFIG_IP_ROUTE_VERBOSE=y | ||
41 | CONFIG_IP_PNP=y | ||
42 | CONFIG_IP_PNP_DHCP=y | ||
43 | CONFIG_IP_PNP_BOOTP=y | ||
44 | CONFIG_IP_PNP_RARP=y | ||
45 | CONFIG_NET_IPIP=m | ||
46 | CONFIG_IP_MROUTE=y | ||
47 | CONFIG_IP_PIMSM_V1=y | ||
48 | CONFIG_IP_PIMSM_V2=y | ||
49 | CONFIG_SYN_COOKIES=y | ||
50 | CONFIG_INET_AH=m | ||
51 | CONFIG_INET_ESP=m | ||
52 | CONFIG_INET_IPCOMP=m | ||
53 | # CONFIG_INET_LRO is not set | ||
54 | CONFIG_INET6_AH=m | ||
55 | CONFIG_INET6_ESP=m | ||
56 | CONFIG_INET6_IPCOMP=m | ||
57 | CONFIG_IPV6_TUNNEL=m | ||
58 | CONFIG_NETFILTER=y | ||
59 | # CONFIG_NETFILTER_XT_MATCH_SCTP is not set | ||
60 | CONFIG_IP_NF_IPTABLES=m | ||
61 | CONFIG_IP_NF_MATCH_ECN=m | ||
62 | CONFIG_IP_NF_MATCH_TTL=m | ||
63 | CONFIG_IP_NF_FILTER=m | ||
64 | CONFIG_IP_NF_TARGET_REJECT=m | ||
65 | CONFIG_IP_NF_MANGLE=m | ||
66 | CONFIG_IP_NF_TARGET_ECN=m | ||
67 | CONFIG_IP_NF_RAW=m | ||
68 | CONFIG_IP_NF_ARPTABLES=m | ||
69 | CONFIG_IP_NF_ARPFILTER=m | ||
70 | CONFIG_IP_NF_ARP_MANGLE=m | ||
71 | CONFIG_IP6_NF_IPTABLES=m | ||
72 | CONFIG_IP6_NF_MATCH_EUI64=m | ||
73 | CONFIG_IP6_NF_MATCH_FRAG=m | ||
74 | CONFIG_IP6_NF_MATCH_OPTS=m | ||
75 | CONFIG_IP6_NF_MATCH_HL=m | ||
76 | CONFIG_IP6_NF_MATCH_IPV6HEADER=m | ||
77 | CONFIG_IP6_NF_MATCH_RT=m | ||
78 | CONFIG_IP6_NF_FILTER=m | ||
79 | CONFIG_IP6_NF_MANGLE=m | ||
80 | CONFIG_IP6_NF_RAW=m | ||
81 | CONFIG_IP_SCTP=m | ||
82 | CONFIG_TIPC=m | ||
83 | CONFIG_ATM=m | ||
84 | CONFIG_ATM_CLIP=m | ||
85 | CONFIG_ATM_LANE=m | ||
86 | CONFIG_ATM_MPOA=m | ||
87 | CONFIG_ATM_BR2684=m | ||
88 | CONFIG_BRIDGE=m | ||
89 | CONFIG_VLAN_8021Q=m | ||
90 | CONFIG_NET_SCHED=y | ||
91 | CONFIG_NET_SCH_CBQ=m | ||
92 | CONFIG_NET_SCH_HTB=m | ||
93 | CONFIG_NET_SCH_HFSC=m | ||
94 | CONFIG_NET_SCH_ATM=m | ||
95 | CONFIG_NET_SCH_PRIO=m | ||
96 | CONFIG_NET_SCH_RED=m | ||
97 | CONFIG_NET_SCH_SFQ=m | ||
98 | CONFIG_NET_SCH_TEQL=m | ||
99 | CONFIG_NET_SCH_TBF=m | ||
100 | CONFIG_NET_SCH_GRED=m | ||
101 | CONFIG_NET_SCH_DSMARK=m | ||
102 | CONFIG_NET_SCH_NETEM=m | ||
103 | CONFIG_NET_CLS_TCINDEX=m | ||
104 | CONFIG_NET_CLS_ROUTE4=m | ||
105 | CONFIG_NET_CLS_FW=m | ||
106 | CONFIG_NET_CLS_U32=m | ||
107 | CONFIG_NET_CLS_RSVP=m | ||
108 | CONFIG_NET_CLS_RSVP6=m | ||
109 | CONFIG_NET_PKTGEN=m | ||
110 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
111 | # CONFIG_FW_LOADER is not set | ||
112 | CONFIG_MTD=y | ||
113 | CONFIG_MTD_BLOCK=y | ||
114 | CONFIG_MTD_CFI=y | ||
115 | CONFIG_MTD_JEDECPROBE=y | ||
116 | CONFIG_MTD_CFI_INTELEXT=y | ||
117 | CONFIG_MTD_CFI_AMDSTD=y | ||
118 | CONFIG_MTD_PHYSMAP_OF=y | ||
119 | CONFIG_BLK_DEV_LOOP=m | ||
120 | CONFIG_BLK_DEV_CRYPTOLOOP=m | ||
121 | CONFIG_BLK_DEV_NBD=m | ||
122 | CONFIG_BLK_DEV_RAM=y | ||
123 | CONFIG_BLK_DEV_RAM_SIZE=131072 | ||
124 | CONFIG_DS1682=y | ||
125 | CONFIG_BLK_DEV_SD=y | ||
126 | CONFIG_CHR_DEV_ST=y | ||
127 | CONFIG_BLK_DEV_SR=y | ||
128 | CONFIG_ATA=y | ||
129 | CONFIG_SATA_SIL=y | ||
130 | CONFIG_NETDEVICES=y | ||
131 | CONFIG_BONDING=m | ||
132 | CONFIG_DUMMY=m | ||
133 | CONFIG_NETCONSOLE=y | ||
134 | CONFIG_TUN=m | ||
135 | CONFIG_GIANFAR=y | ||
136 | CONFIG_PPP=m | ||
137 | CONFIG_PPP_BSDCOMP=m | ||
138 | CONFIG_PPP_DEFLATE=m | ||
139 | CONFIG_PPP_FILTER=y | ||
140 | CONFIG_PPP_MULTILINK=y | ||
141 | CONFIG_PPPOATM=m | ||
142 | CONFIG_PPPOE=m | ||
143 | CONFIG_PPP_ASYNC=m | ||
144 | CONFIG_PPP_SYNC_TTY=m | ||
145 | CONFIG_SLIP=m | ||
146 | CONFIG_SLIP_COMPRESSED=y | ||
147 | CONFIG_SLIP_SMART=y | ||
148 | CONFIG_SLIP_MODE_SLIP6=y | ||
149 | CONFIG_INPUT_FF_MEMLESS=m | ||
150 | # CONFIG_INPUT_KEYBOARD is not set | ||
151 | # CONFIG_INPUT_MOUSE is not set | ||
152 | # CONFIG_SERIO is not set | ||
153 | # CONFIG_LEGACY_PTYS is not set | ||
154 | CONFIG_SERIAL_8250=y | ||
155 | CONFIG_SERIAL_8250_CONSOLE=y | ||
156 | # CONFIG_SERIAL_8250_PCI is not set | ||
157 | CONFIG_SERIAL_8250_NR_UARTS=2 | ||
158 | CONFIG_SERIAL_8250_RUNTIME_UARTS=2 | ||
159 | CONFIG_HW_RANDOM=y | ||
160 | CONFIG_NVRAM=y | ||
161 | CONFIG_I2C=y | ||
162 | CONFIG_I2C_CHARDEV=y | ||
163 | CONFIG_I2C_MPC=y | ||
164 | CONFIG_GPIO_SYSFS=y | ||
165 | CONFIG_GPIO_GE_FPGA=y | ||
166 | CONFIG_SENSORS_LM90=y | ||
167 | CONFIG_SENSORS_LM92=y | ||
168 | CONFIG_WATCHDOG=y | ||
169 | CONFIG_GEF_WDT=y | ||
170 | CONFIG_HID_A4TECH=y | ||
171 | CONFIG_HID_APPLE=y | ||
172 | CONFIG_HID_BELKIN=y | ||
173 | CONFIG_HID_CHERRY=y | ||
174 | CONFIG_HID_CHICONY=y | ||
175 | CONFIG_HID_CYPRESS=y | ||
176 | CONFIG_HID_EZKEY=y | ||
177 | CONFIG_HID_GYRATION=y | ||
178 | CONFIG_HID_LOGITECH=y | ||
179 | CONFIG_HID_MICROSOFT=y | ||
180 | CONFIG_HID_MONTEREY=y | ||
181 | CONFIG_HID_PANTHERLORD=y | ||
182 | CONFIG_HID_PETALYNX=y | ||
183 | CONFIG_HID_SAMSUNG=y | ||
184 | CONFIG_HID_SUNPLUS=y | ||
185 | CONFIG_USB=y | ||
186 | CONFIG_USB_EHCI_HCD=y | ||
187 | # CONFIG_USB_EHCI_HCD_PPC_OF is not set | ||
188 | CONFIG_USB_OHCI_HCD=y | ||
189 | CONFIG_USB_STORAGE=y | ||
190 | CONFIG_RTC_CLASS=y | ||
191 | # CONFIG_RTC_INTF_PROC is not set | ||
192 | CONFIG_RTC_DRV_RX8581=y | ||
193 | CONFIG_STAGING=y | ||
194 | CONFIG_VME_BUS=y | ||
195 | CONFIG_VME_TSI148=y | ||
196 | CONFIG_EXT2_FS=y | ||
197 | CONFIG_EXT2_FS_XATTR=y | ||
198 | CONFIG_EXT2_FS_POSIX_ACL=y | ||
199 | CONFIG_EXT3_FS=y | ||
200 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
201 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
202 | CONFIG_MSDOS_FS=y | ||
203 | CONFIG_VFAT_FS=y | ||
204 | CONFIG_PROC_KCORE=y | ||
205 | CONFIG_TMPFS=y | ||
206 | CONFIG_JFFS2_FS=y | ||
207 | CONFIG_NFS_FS=y | ||
208 | CONFIG_NFS_V4=y | ||
209 | CONFIG_ROOT_NFS=y | ||
210 | CONFIG_CIFS=m | ||
211 | CONFIG_CIFS_XATTR=y | ||
212 | CONFIG_CIFS_POSIX=y | ||
213 | CONFIG_NLS_CODEPAGE_437=m | ||
214 | CONFIG_NLS_CODEPAGE_737=m | ||
215 | CONFIG_NLS_CODEPAGE_775=m | ||
216 | CONFIG_NLS_CODEPAGE_850=m | ||
217 | CONFIG_NLS_CODEPAGE_852=m | ||
218 | CONFIG_NLS_CODEPAGE_855=m | ||
219 | CONFIG_NLS_CODEPAGE_857=m | ||
220 | CONFIG_NLS_CODEPAGE_860=m | ||
221 | CONFIG_NLS_CODEPAGE_861=m | ||
222 | CONFIG_NLS_CODEPAGE_862=m | ||
223 | CONFIG_NLS_CODEPAGE_863=m | ||
224 | CONFIG_NLS_CODEPAGE_864=m | ||
225 | CONFIG_NLS_CODEPAGE_865=m | ||
226 | CONFIG_NLS_CODEPAGE_866=m | ||
227 | CONFIG_NLS_CODEPAGE_869=m | ||
228 | CONFIG_NLS_CODEPAGE_936=m | ||
229 | CONFIG_NLS_CODEPAGE_950=m | ||
230 | CONFIG_NLS_CODEPAGE_932=m | ||
231 | CONFIG_NLS_CODEPAGE_949=m | ||
232 | CONFIG_NLS_CODEPAGE_874=m | ||
233 | CONFIG_NLS_ISO8859_8=m | ||
234 | CONFIG_NLS_CODEPAGE_1250=m | ||
235 | CONFIG_NLS_CODEPAGE_1251=m | ||
236 | CONFIG_NLS_ASCII=m | ||
237 | CONFIG_NLS_ISO8859_1=m | ||
238 | CONFIG_NLS_ISO8859_2=m | ||
239 | CONFIG_NLS_ISO8859_3=m | ||
240 | CONFIG_NLS_ISO8859_4=m | ||
241 | CONFIG_NLS_ISO8859_5=m | ||
242 | CONFIG_NLS_ISO8859_6=m | ||
243 | CONFIG_NLS_ISO8859_7=m | ||
244 | CONFIG_NLS_ISO8859_9=m | ||
245 | CONFIG_NLS_ISO8859_13=m | ||
246 | CONFIG_NLS_ISO8859_14=m | ||
247 | CONFIG_NLS_ISO8859_15=m | ||
248 | CONFIG_NLS_KOI8_R=m | ||
249 | CONFIG_NLS_KOI8_U=m | ||
250 | CONFIG_NLS_UTF8=m | ||
251 | CONFIG_DEBUG_INFO=y | ||
252 | CONFIG_MAGIC_SYSRQ=y | ||
253 | CONFIG_DETECT_HUNG_TASK=y | ||
254 | # CONFIG_DEBUG_BUGVERBOSE is not set | ||
255 | CONFIG_SECURITY=y | ||
256 | CONFIG_SECURITY_NETWORK=y | ||
257 | CONFIG_CRYPTO_NULL=m | ||
258 | CONFIG_CRYPTO_TEST=m | ||
259 | CONFIG_CRYPTO_PCBC=m | ||
260 | CONFIG_CRYPTO_HMAC=y | ||
261 | CONFIG_CRYPTO_MICHAEL_MIC=m | ||
262 | CONFIG_CRYPTO_SHA512=m | ||
263 | CONFIG_CRYPTO_WP512=m | ||
264 | CONFIG_CRYPTO_ANUBIS=m | ||
265 | CONFIG_CRYPTO_BLOWFISH=m | ||
266 | CONFIG_CRYPTO_CAST5=m | ||
267 | CONFIG_CRYPTO_CAST6=m | ||
268 | CONFIG_CRYPTO_KHAZAD=m | ||
269 | CONFIG_CRYPTO_SERPENT=m | ||
270 | CONFIG_CRYPTO_TEA=m | ||
271 | CONFIG_CRYPTO_TWOFISH=m | ||
272 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
273 | # CONFIG_CRYPTO_HW is not set | ||
diff --git a/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig b/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig deleted file mode 100644 index e32207de2b77..000000000000 --- a/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig +++ /dev/null | |||
@@ -1,110 +0,0 @@ | |||
1 | # CONFIG_SWAP is not set | ||
2 | CONFIG_SYSVIPC=y | ||
3 | CONFIG_NO_HZ=y | ||
4 | CONFIG_HIGH_RES_TIMERS=y | ||
5 | CONFIG_IKCONFIG=y | ||
6 | CONFIG_IKCONFIG_PROC=y | ||
7 | CONFIG_LOG_BUF_SHIFT=14 | ||
8 | CONFIG_BLK_DEV_INITRD=y | ||
9 | CONFIG_EXPERT=y | ||
10 | # CONFIG_ELF_CORE is not set | ||
11 | CONFIG_MODULES=y | ||
12 | CONFIG_MODULE_UNLOAD=y | ||
13 | # CONFIG_BLK_DEV_BSG is not set | ||
14 | CONFIG_PARTITION_ADVANCED=y | ||
15 | CONFIG_LDM_PARTITION=y | ||
16 | # CONFIG_IOSCHED_CFQ is not set | ||
17 | # CONFIG_PPC_CHRP is not set | ||
18 | # CONFIG_PPC_PMAC is not set | ||
19 | CONFIG_PPC_86xx=y | ||
20 | CONFIG_MPC8610_HPCD=y | ||
21 | CONFIG_HIGHMEM=y | ||
22 | CONFIG_HZ_1000=y | ||
23 | CONFIG_FORCE_MAX_ZONEORDER=12 | ||
24 | # CONFIG_SECCOMP is not set | ||
25 | CONFIG_PCI=y | ||
26 | CONFIG_PCIEPORTBUS=y | ||
27 | # CONFIG_PCIEASPM is not set | ||
28 | CONFIG_PCI_DEBUG=y | ||
29 | CONFIG_NET=y | ||
30 | CONFIG_PACKET=y | ||
31 | CONFIG_UNIX=y | ||
32 | CONFIG_XFRM_USER=y | ||
33 | CONFIG_INET=y | ||
34 | CONFIG_IP_PNP=y | ||
35 | CONFIG_IP_PNP_DHCP=y | ||
36 | CONFIG_IP_PNP_BOOTP=y | ||
37 | CONFIG_IP_PNP_RARP=y | ||
38 | # CONFIG_INET_LRO is not set | ||
39 | CONFIG_IPV6=y | ||
40 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
41 | CONFIG_MTD=y | ||
42 | CONFIG_MTD_CMDLINE_PARTS=y | ||
43 | CONFIG_MTD_BLOCK=y | ||
44 | CONFIG_MTD_CFI=y | ||
45 | CONFIG_MTD_CFI_AMDSTD=y | ||
46 | CONFIG_MTD_PHYSMAP_OF=y | ||
47 | CONFIG_MTD_NAND=y | ||
48 | CONFIG_MTD_NAND_FSL_ELBC=y | ||
49 | CONFIG_BLK_DEV_LOOP=y | ||
50 | CONFIG_BLK_DEV_RAM=y | ||
51 | CONFIG_BLK_DEV_RAM_SIZE=131072 | ||
52 | CONFIG_IDE=y | ||
53 | CONFIG_BLK_DEV_SD=y | ||
54 | CONFIG_CHR_DEV_SG=y | ||
55 | CONFIG_ATA=y | ||
56 | CONFIG_SATA_AHCI=y | ||
57 | CONFIG_PATA_ALI=y | ||
58 | CONFIG_NETDEVICES=y | ||
59 | CONFIG_DUMMY=y | ||
60 | CONFIG_NET_TULIP=y | ||
61 | CONFIG_ULI526X=y | ||
62 | # CONFIG_INPUT_MOUSEDEV is not set | ||
63 | # CONFIG_INPUT_KEYBOARD is not set | ||
64 | # CONFIG_INPUT_MOUSE is not set | ||
65 | CONFIG_SERIO_LIBPS2=y | ||
66 | # CONFIG_LEGACY_PTYS is not set | ||
67 | CONFIG_SERIAL_8250=y | ||
68 | CONFIG_SERIAL_8250_CONSOLE=y | ||
69 | CONFIG_SERIAL_8250_NR_UARTS=2 | ||
70 | CONFIG_SERIAL_8250_RUNTIME_UARTS=2 | ||
71 | CONFIG_SERIAL_8250_EXTENDED=y | ||
72 | CONFIG_SERIAL_8250_MANY_PORTS=y | ||
73 | CONFIG_SERIAL_8250_SHARE_IRQ=y | ||
74 | CONFIG_SERIAL_8250_DETECT_IRQ=y | ||
75 | CONFIG_SERIAL_8250_RSA=y | ||
76 | # CONFIG_HW_RANDOM is not set | ||
77 | CONFIG_I2C=y | ||
78 | CONFIG_I2C_MPC=y | ||
79 | # CONFIG_HWMON is not set | ||
80 | CONFIG_FB=y | ||
81 | CONFIG_FB_FSL_DIU=y | ||
82 | CONFIG_VGACON_SOFT_SCROLLBACK=y | ||
83 | CONFIG_FRAMEBUFFER_CONSOLE=y | ||
84 | CONFIG_SOUND=y | ||
85 | CONFIG_SND=y | ||
86 | CONFIG_SND_MIXER_OSS=y | ||
87 | CONFIG_SND_PCM_OSS=y | ||
88 | # CONFIG_SND_SUPPORT_OLD_API is not set | ||
89 | CONFIG_SND_SOC=y | ||
90 | CONFIG_SND_POWERPC_SOC=y | ||
91 | CONFIG_RTC_CLASS=y | ||
92 | CONFIG_RTC_DRV_CMOS=y | ||
93 | CONFIG_EXT2_FS=y | ||
94 | CONFIG_EXT3_FS=y | ||
95 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
96 | # CONFIG_DNOTIFY is not set | ||
97 | CONFIG_PROC_KCORE=y | ||
98 | CONFIG_TMPFS=y | ||
99 | CONFIG_NFS_FS=y | ||
100 | CONFIG_ROOT_NFS=y | ||
101 | CONFIG_NFSD=y | ||
102 | CONFIG_NLS=y | ||
103 | CONFIG_CRC_T10DIF=y | ||
104 | CONFIG_FONTS=y | ||
105 | CONFIG_FONT_8x8=y | ||
106 | CONFIG_FONT_8x16=y | ||
107 | CONFIG_DEBUG_INFO=y | ||
108 | CONFIG_DEBUG_SHIRQ=y | ||
109 | CONFIG_DETECT_HUNG_TASK=y | ||
110 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
diff --git a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig b/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig deleted file mode 100644 index a36e11ddaebd..000000000000 --- a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig +++ /dev/null | |||
@@ -1,156 +0,0 @@ | |||
1 | CONFIG_SMP=y | ||
2 | CONFIG_NR_CPUS=2 | ||
3 | CONFIG_SYSVIPC=y | ||
4 | CONFIG_POSIX_MQUEUE=y | ||
5 | CONFIG_AUDIT=y | ||
6 | CONFIG_NO_HZ=y | ||
7 | CONFIG_HIGH_RES_TIMERS=y | ||
8 | CONFIG_BSD_PROCESS_ACCT=y | ||
9 | CONFIG_IKCONFIG=y | ||
10 | CONFIG_IKCONFIG_PROC=y | ||
11 | CONFIG_LOG_BUF_SHIFT=14 | ||
12 | CONFIG_BLK_DEV_INITRD=y | ||
13 | CONFIG_EXPERT=y | ||
14 | CONFIG_KALLSYMS_ALL=y | ||
15 | CONFIG_MODULES=y | ||
16 | CONFIG_MODULE_UNLOAD=y | ||
17 | CONFIG_MODULE_FORCE_UNLOAD=y | ||
18 | CONFIG_MODVERSIONS=y | ||
19 | # CONFIG_BLK_DEV_BSG is not set | ||
20 | CONFIG_PARTITION_ADVANCED=y | ||
21 | CONFIG_MAC_PARTITION=y | ||
22 | # CONFIG_PPC_CHRP is not set | ||
23 | # CONFIG_PPC_PMAC is not set | ||
24 | CONFIG_PPC_86xx=y | ||
25 | CONFIG_MPC8641_HPCN=y | ||
26 | CONFIG_HIGHMEM=y | ||
27 | CONFIG_HZ_1000=y | ||
28 | CONFIG_BINFMT_MISC=m | ||
29 | CONFIG_PCI=y | ||
30 | CONFIG_NET=y | ||
31 | CONFIG_PACKET=y | ||
32 | CONFIG_UNIX=y | ||
33 | CONFIG_XFRM_USER=y | ||
34 | CONFIG_NET_KEY=m | ||
35 | CONFIG_INET=y | ||
36 | CONFIG_IP_MULTICAST=y | ||
37 | CONFIG_IP_ADVANCED_ROUTER=y | ||
38 | CONFIG_IP_MULTIPLE_TABLES=y | ||
39 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
40 | CONFIG_IP_ROUTE_VERBOSE=y | ||
41 | CONFIG_IP_PNP=y | ||
42 | CONFIG_IP_PNP_DHCP=y | ||
43 | CONFIG_IP_PNP_BOOTP=y | ||
44 | CONFIG_IP_PNP_RARP=y | ||
45 | CONFIG_NET_IPIP=y | ||
46 | CONFIG_IP_MROUTE=y | ||
47 | CONFIG_IP_PIMSM_V1=y | ||
48 | CONFIG_IP_PIMSM_V2=y | ||
49 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
50 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
51 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
52 | # CONFIG_INET_LRO is not set | ||
53 | CONFIG_IPV6=y | ||
54 | CONFIG_IP_SCTP=m | ||
55 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
56 | CONFIG_BLK_DEV_LOOP=y | ||
57 | CONFIG_BLK_DEV_NBD=y | ||
58 | CONFIG_BLK_DEV_RAM=y | ||
59 | CONFIG_BLK_DEV_RAM_SIZE=131072 | ||
60 | CONFIG_EEPROM_LEGACY=y | ||
61 | CONFIG_BLK_DEV_SD=y | ||
62 | CONFIG_CHR_DEV_ST=y | ||
63 | CONFIG_BLK_DEV_SR=y | ||
64 | CONFIG_CHR_DEV_SG=y | ||
65 | CONFIG_SCSI_LOGGING=y | ||
66 | CONFIG_ATA=y | ||
67 | CONFIG_SATA_AHCI=y | ||
68 | CONFIG_PATA_ALI=y | ||
69 | CONFIG_NETDEVICES=y | ||
70 | CONFIG_DUMMY=y | ||
71 | CONFIG_GIANFAR=y | ||
72 | CONFIG_VITESSE_PHY=y | ||
73 | CONFIG_INPUT_FF_MEMLESS=m | ||
74 | # CONFIG_INPUT_MOUSEDEV is not set | ||
75 | # CONFIG_INPUT_KEYBOARD is not set | ||
76 | # CONFIG_INPUT_MOUSE is not set | ||
77 | CONFIG_SERIO_LIBPS2=y | ||
78 | CONFIG_SERIAL_8250=y | ||
79 | CONFIG_SERIAL_8250_CONSOLE=y | ||
80 | CONFIG_SERIAL_8250_NR_UARTS=2 | ||
81 | CONFIG_SERIAL_8250_RUNTIME_UARTS=2 | ||
82 | CONFIG_SERIAL_8250_EXTENDED=y | ||
83 | CONFIG_SERIAL_8250_MANY_PORTS=y | ||
84 | CONFIG_SERIAL_8250_SHARE_IRQ=y | ||
85 | CONFIG_SERIAL_8250_DETECT_IRQ=y | ||
86 | CONFIG_SERIAL_8250_RSA=y | ||
87 | # CONFIG_HW_RANDOM is not set | ||
88 | CONFIG_NVRAM=y | ||
89 | CONFIG_I2C=y | ||
90 | CONFIG_I2C_MPC=y | ||
91 | # CONFIG_HWMON is not set | ||
92 | CONFIG_SOUND=y | ||
93 | CONFIG_SND=y | ||
94 | CONFIG_SND_MIXER_OSS=y | ||
95 | CONFIG_SND_PCM_OSS=y | ||
96 | # CONFIG_SND_SUPPORT_OLD_API is not set | ||
97 | CONFIG_SND_INTEL8X0=y | ||
98 | CONFIG_HID_A4TECH=y | ||
99 | CONFIG_HID_APPLE=y | ||
100 | CONFIG_HID_BELKIN=y | ||
101 | CONFIG_HID_CHERRY=y | ||
102 | CONFIG_HID_CHICONY=y | ||
103 | CONFIG_HID_CYPRESS=y | ||
104 | CONFIG_HID_EZKEY=y | ||
105 | CONFIG_HID_GYRATION=y | ||
106 | CONFIG_HID_LOGITECH=y | ||
107 | CONFIG_HID_MICROSOFT=y | ||
108 | CONFIG_HID_MONTEREY=y | ||
109 | CONFIG_HID_PANTHERLORD=y | ||
110 | CONFIG_HID_PETALYNX=y | ||
111 | CONFIG_HID_SAMSUNG=y | ||
112 | CONFIG_HID_SUNPLUS=y | ||
113 | CONFIG_USB=y | ||
114 | CONFIG_USB_MON=y | ||
115 | CONFIG_USB_EHCI_HCD=y | ||
116 | CONFIG_USB_OHCI_HCD=y | ||
117 | CONFIG_USB_OHCI_HCD_PPC_OF_BE=y | ||
118 | CONFIG_USB_OHCI_HCD_PPC_OF_LE=y | ||
119 | CONFIG_USB_STORAGE=y | ||
120 | CONFIG_RTC_CLASS=y | ||
121 | CONFIG_RTC_DRV_CMOS=y | ||
122 | CONFIG_EXT2_FS=y | ||
123 | CONFIG_EXT3_FS=y | ||
124 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
125 | CONFIG_ISO9660_FS=m | ||
126 | CONFIG_JOLIET=y | ||
127 | CONFIG_ZISOFS=y | ||
128 | CONFIG_UDF_FS=m | ||
129 | CONFIG_MSDOS_FS=m | ||
130 | CONFIG_VFAT_FS=y | ||
131 | CONFIG_NTFS_FS=y | ||
132 | CONFIG_PROC_KCORE=y | ||
133 | CONFIG_TMPFS=y | ||
134 | CONFIG_ADFS_FS=m | ||
135 | CONFIG_AFFS_FS=m | ||
136 | CONFIG_HFS_FS=m | ||
137 | CONFIG_HFSPLUS_FS=m | ||
138 | CONFIG_BEFS_FS=m | ||
139 | CONFIG_BFS_FS=m | ||
140 | CONFIG_EFS_FS=m | ||
141 | CONFIG_CRAMFS=y | ||
142 | CONFIG_VXFS_FS=m | ||
143 | CONFIG_HPFS_FS=m | ||
144 | CONFIG_QNX4FS_FS=m | ||
145 | CONFIG_SYSV_FS=m | ||
146 | CONFIG_UFS_FS=m | ||
147 | CONFIG_NFS_FS=y | ||
148 | CONFIG_NFS_V4=y | ||
149 | CONFIG_ROOT_NFS=y | ||
150 | CONFIG_NFSD=y | ||
151 | CONFIG_CRC_T10DIF=y | ||
152 | CONFIG_DEBUG_INFO=y | ||
153 | CONFIG_DETECT_HUNG_TASK=y | ||
154 | CONFIG_CRYPTO_PCBC=m | ||
155 | CONFIG_CRYPTO_HMAC=y | ||
156 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
diff --git a/arch/powerpc/configs/86xx/sbc8641d_defconfig b/arch/powerpc/configs/86xx/sbc8641d_defconfig deleted file mode 100644 index db79bdee844b..000000000000 --- a/arch/powerpc/configs/86xx/sbc8641d_defconfig +++ /dev/null | |||
@@ -1,246 +0,0 @@ | |||
1 | CONFIG_SMP=y | ||
2 | CONFIG_NR_CPUS=2 | ||
3 | CONFIG_SYSVIPC=y | ||
4 | CONFIG_POSIX_MQUEUE=y | ||
5 | CONFIG_HIGH_RES_TIMERS=y | ||
6 | CONFIG_BSD_PROCESS_ACCT=y | ||
7 | CONFIG_BSD_PROCESS_ACCT_V3=y | ||
8 | CONFIG_IKCONFIG=y | ||
9 | CONFIG_IKCONFIG_PROC=y | ||
10 | CONFIG_LOG_BUF_SHIFT=14 | ||
11 | CONFIG_RELAY=y | ||
12 | CONFIG_BLK_DEV_INITRD=y | ||
13 | CONFIG_EXPERT=y | ||
14 | CONFIG_SLAB=y | ||
15 | CONFIG_MODULES=y | ||
16 | CONFIG_MODULE_UNLOAD=y | ||
17 | # CONFIG_BLK_DEV_BSG is not set | ||
18 | # CONFIG_PPC_CHRP is not set | ||
19 | # CONFIG_PPC_PMAC is not set | ||
20 | CONFIG_PPC_86xx=y | ||
21 | CONFIG_SBC8641D=y | ||
22 | CONFIG_PREEMPT=y | ||
23 | CONFIG_BINFMT_MISC=m | ||
24 | CONFIG_PCI=y | ||
25 | CONFIG_PCIEPORTBUS=y | ||
26 | # CONFIG_PCIEASPM is not set | ||
27 | CONFIG_NET=y | ||
28 | CONFIG_PACKET=y | ||
29 | CONFIG_UNIX=y | ||
30 | CONFIG_XFRM_USER=m | ||
31 | CONFIG_NET_KEY=m | ||
32 | CONFIG_INET=y | ||
33 | CONFIG_IP_MULTICAST=y | ||
34 | CONFIG_IP_ADVANCED_ROUTER=y | ||
35 | CONFIG_IP_MULTIPLE_TABLES=y | ||
36 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
37 | CONFIG_IP_ROUTE_VERBOSE=y | ||
38 | CONFIG_IP_PNP=y | ||
39 | CONFIG_IP_PNP_DHCP=y | ||
40 | CONFIG_IP_PNP_BOOTP=y | ||
41 | CONFIG_IP_PNP_RARP=y | ||
42 | CONFIG_NET_IPIP=m | ||
43 | CONFIG_IP_MROUTE=y | ||
44 | CONFIG_IP_PIMSM_V1=y | ||
45 | CONFIG_IP_PIMSM_V2=y | ||
46 | CONFIG_SYN_COOKIES=y | ||
47 | CONFIG_INET_AH=m | ||
48 | CONFIG_INET_ESP=m | ||
49 | CONFIG_INET_IPCOMP=m | ||
50 | # CONFIG_INET_LRO is not set | ||
51 | CONFIG_INET6_AH=m | ||
52 | CONFIG_INET6_ESP=m | ||
53 | CONFIG_INET6_IPCOMP=m | ||
54 | CONFIG_IPV6_TUNNEL=m | ||
55 | CONFIG_NETFILTER=y | ||
56 | # CONFIG_NETFILTER_XT_MATCH_SCTP is not set | ||
57 | CONFIG_IP_NF_IPTABLES=m | ||
58 | CONFIG_IP_NF_MATCH_ECN=m | ||
59 | CONFIG_IP_NF_MATCH_TTL=m | ||
60 | CONFIG_IP_NF_FILTER=m | ||
61 | CONFIG_IP_NF_TARGET_REJECT=m | ||
62 | CONFIG_IP_NF_MANGLE=m | ||
63 | CONFIG_IP_NF_TARGET_ECN=m | ||
64 | CONFIG_IP_NF_RAW=m | ||
65 | CONFIG_IP_NF_ARPTABLES=m | ||
66 | CONFIG_IP_NF_ARPFILTER=m | ||
67 | CONFIG_IP_NF_ARP_MANGLE=m | ||
68 | CONFIG_IP6_NF_IPTABLES=m | ||
69 | CONFIG_IP6_NF_MATCH_EUI64=m | ||
70 | CONFIG_IP6_NF_MATCH_FRAG=m | ||
71 | CONFIG_IP6_NF_MATCH_OPTS=m | ||
72 | CONFIG_IP6_NF_MATCH_HL=m | ||
73 | CONFIG_IP6_NF_MATCH_IPV6HEADER=m | ||
74 | CONFIG_IP6_NF_MATCH_RT=m | ||
75 | CONFIG_IP6_NF_FILTER=m | ||
76 | CONFIG_IP6_NF_MANGLE=m | ||
77 | CONFIG_IP6_NF_RAW=m | ||
78 | CONFIG_IP_SCTP=m | ||
79 | CONFIG_TIPC=m | ||
80 | CONFIG_ATM=m | ||
81 | CONFIG_ATM_CLIP=m | ||
82 | CONFIG_ATM_LANE=m | ||
83 | CONFIG_ATM_MPOA=m | ||
84 | CONFIG_ATM_BR2684=m | ||
85 | CONFIG_BRIDGE=m | ||
86 | CONFIG_VLAN_8021Q=m | ||
87 | CONFIG_NET_SCHED=y | ||
88 | CONFIG_NET_SCH_CBQ=m | ||
89 | CONFIG_NET_SCH_HTB=m | ||
90 | CONFIG_NET_SCH_HFSC=m | ||
91 | CONFIG_NET_SCH_ATM=m | ||
92 | CONFIG_NET_SCH_PRIO=m | ||
93 | CONFIG_NET_SCH_RED=m | ||
94 | CONFIG_NET_SCH_SFQ=m | ||
95 | CONFIG_NET_SCH_TEQL=m | ||
96 | CONFIG_NET_SCH_TBF=m | ||
97 | CONFIG_NET_SCH_GRED=m | ||
98 | CONFIG_NET_SCH_DSMARK=m | ||
99 | CONFIG_NET_SCH_NETEM=m | ||
100 | CONFIG_NET_CLS_TCINDEX=m | ||
101 | CONFIG_NET_CLS_ROUTE4=m | ||
102 | CONFIG_NET_CLS_FW=m | ||
103 | CONFIG_NET_CLS_U32=m | ||
104 | CONFIG_NET_CLS_RSVP=m | ||
105 | CONFIG_NET_CLS_RSVP6=m | ||
106 | CONFIG_NET_PKTGEN=m | ||
107 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
108 | # CONFIG_FW_LOADER is not set | ||
109 | CONFIG_MTD=y | ||
110 | CONFIG_MTD_BLOCK=y | ||
111 | CONFIG_MTD_CFI=y | ||
112 | CONFIG_MTD_CFI_ADV_OPTIONS=y | ||
113 | CONFIG_MTD_CFI_LE_BYTE_SWAP=y | ||
114 | CONFIG_MTD_CFI_INTELEXT=y | ||
115 | CONFIG_MTD_PHYSMAP_OF=y | ||
116 | CONFIG_BLK_DEV_LOOP=m | ||
117 | CONFIG_BLK_DEV_CRYPTOLOOP=m | ||
118 | CONFIG_BLK_DEV_NBD=m | ||
119 | CONFIG_BLK_DEV_RAM=y | ||
120 | CONFIG_MD=y | ||
121 | CONFIG_BLK_DEV_MD=y | ||
122 | CONFIG_MD_LINEAR=y | ||
123 | CONFIG_MD_RAID0=y | ||
124 | CONFIG_MD_RAID1=y | ||
125 | CONFIG_MD_RAID10=y | ||
126 | CONFIG_MD_MULTIPATH=y | ||
127 | CONFIG_MD_FAULTY=y | ||
128 | CONFIG_BLK_DEV_DM=y | ||
129 | CONFIG_DM_CRYPT=y | ||
130 | CONFIG_DM_SNAPSHOT=y | ||
131 | CONFIG_DM_MIRROR=y | ||
132 | CONFIG_DM_ZERO=y | ||
133 | CONFIG_NETDEVICES=y | ||
134 | CONFIG_BONDING=m | ||
135 | CONFIG_DUMMY=m | ||
136 | CONFIG_NETCONSOLE=y | ||
137 | CONFIG_TUN=m | ||
138 | CONFIG_GIANFAR=y | ||
139 | CONFIG_BROADCOM_PHY=y | ||
140 | CONFIG_PPP=m | ||
141 | CONFIG_PPP_BSDCOMP=m | ||
142 | CONFIG_PPP_DEFLATE=m | ||
143 | CONFIG_PPP_FILTER=y | ||
144 | CONFIG_PPP_MULTILINK=y | ||
145 | CONFIG_PPPOATM=m | ||
146 | CONFIG_PPPOE=m | ||
147 | CONFIG_PPP_ASYNC=m | ||
148 | CONFIG_PPP_SYNC_TTY=m | ||
149 | CONFIG_SLIP=m | ||
150 | CONFIG_SLIP_COMPRESSED=y | ||
151 | CONFIG_SLIP_SMART=y | ||
152 | CONFIG_SLIP_MODE_SLIP6=y | ||
153 | # CONFIG_INPUT_KEYBOARD is not set | ||
154 | # CONFIG_INPUT_MOUSE is not set | ||
155 | # CONFIG_SERIO is not set | ||
156 | CONFIG_SERIAL_8250=y | ||
157 | CONFIG_SERIAL_8250_CONSOLE=y | ||
158 | # CONFIG_SERIAL_8250_PCI is not set | ||
159 | CONFIG_SERIAL_8250_NR_UARTS=2 | ||
160 | CONFIG_SERIAL_8250_RUNTIME_UARTS=2 | ||
161 | CONFIG_I2C=y | ||
162 | CONFIG_I2C_CHARDEV=y | ||
163 | CONFIG_I2C_MPC=y | ||
164 | CONFIG_WATCHDOG=y | ||
165 | CONFIG_SOFT_WATCHDOG=m | ||
166 | CONFIG_EXT2_FS=y | ||
167 | CONFIG_EXT2_FS_XATTR=y | ||
168 | CONFIG_EXT2_FS_POSIX_ACL=y | ||
169 | CONFIG_EXT3_FS=y | ||
170 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
171 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
172 | CONFIG_REISERFS_FS=m | ||
173 | CONFIG_REISERFS_FS_XATTR=y | ||
174 | CONFIG_REISERFS_FS_POSIX_ACL=y | ||
175 | CONFIG_AUTOFS4_FS=m | ||
176 | CONFIG_PROC_KCORE=y | ||
177 | CONFIG_TMPFS=y | ||
178 | CONFIG_MINIX_FS=m | ||
179 | CONFIG_ROMFS_FS=m | ||
180 | CONFIG_NFS_FS=y | ||
181 | CONFIG_NFS_V4=y | ||
182 | CONFIG_ROOT_NFS=y | ||
183 | CONFIG_CIFS=m | ||
184 | CONFIG_CIFS_XATTR=y | ||
185 | CONFIG_CIFS_POSIX=y | ||
186 | CONFIG_NLS_CODEPAGE_437=m | ||
187 | CONFIG_NLS_CODEPAGE_737=m | ||
188 | CONFIG_NLS_CODEPAGE_775=m | ||
189 | CONFIG_NLS_CODEPAGE_850=m | ||
190 | CONFIG_NLS_CODEPAGE_852=m | ||
191 | CONFIG_NLS_CODEPAGE_855=m | ||
192 | CONFIG_NLS_CODEPAGE_857=m | ||
193 | CONFIG_NLS_CODEPAGE_860=m | ||
194 | CONFIG_NLS_CODEPAGE_861=m | ||
195 | CONFIG_NLS_CODEPAGE_862=m | ||
196 | CONFIG_NLS_CODEPAGE_863=m | ||
197 | CONFIG_NLS_CODEPAGE_864=m | ||
198 | CONFIG_NLS_CODEPAGE_865=m | ||
199 | CONFIG_NLS_CODEPAGE_866=m | ||
200 | CONFIG_NLS_CODEPAGE_869=m | ||
201 | CONFIG_NLS_CODEPAGE_936=m | ||
202 | CONFIG_NLS_CODEPAGE_950=m | ||
203 | CONFIG_NLS_CODEPAGE_932=m | ||
204 | CONFIG_NLS_CODEPAGE_949=m | ||
205 | CONFIG_NLS_CODEPAGE_874=m | ||
206 | CONFIG_NLS_ISO8859_8=m | ||
207 | CONFIG_NLS_CODEPAGE_1250=m | ||
208 | CONFIG_NLS_CODEPAGE_1251=m | ||
209 | CONFIG_NLS_ASCII=m | ||
210 | CONFIG_NLS_ISO8859_1=m | ||
211 | CONFIG_NLS_ISO8859_2=m | ||
212 | CONFIG_NLS_ISO8859_3=m | ||
213 | CONFIG_NLS_ISO8859_4=m | ||
214 | CONFIG_NLS_ISO8859_5=m | ||
215 | CONFIG_NLS_ISO8859_6=m | ||
216 | CONFIG_NLS_ISO8859_7=m | ||
217 | CONFIG_NLS_ISO8859_9=m | ||
218 | CONFIG_NLS_ISO8859_13=m | ||
219 | CONFIG_NLS_ISO8859_14=m | ||
220 | CONFIG_NLS_ISO8859_15=m | ||
221 | CONFIG_NLS_KOI8_R=m | ||
222 | CONFIG_NLS_KOI8_U=m | ||
223 | CONFIG_NLS_UTF8=m | ||
224 | CONFIG_DEBUG_INFO=y | ||
225 | CONFIG_DEBUG_FS=y | ||
226 | CONFIG_MAGIC_SYSRQ=y | ||
227 | CONFIG_DETECT_HUNG_TASK=y | ||
228 | # CONFIG_DEBUG_BUGVERBOSE is not set | ||
229 | CONFIG_SECURITY=y | ||
230 | CONFIG_SECURITY_NETWORK=y | ||
231 | CONFIG_CRYPTO_NULL=m | ||
232 | CONFIG_CRYPTO_TEST=m | ||
233 | CONFIG_CRYPTO_PCBC=m | ||
234 | CONFIG_CRYPTO_HMAC=y | ||
235 | CONFIG_CRYPTO_MICHAEL_MIC=m | ||
236 | CONFIG_CRYPTO_SHA512=m | ||
237 | CONFIG_CRYPTO_WP512=m | ||
238 | CONFIG_CRYPTO_ANUBIS=m | ||
239 | CONFIG_CRYPTO_BLOWFISH=m | ||
240 | CONFIG_CRYPTO_CAST5=m | ||
241 | CONFIG_CRYPTO_CAST6=m | ||
242 | CONFIG_CRYPTO_KHAZAD=m | ||
243 | CONFIG_CRYPTO_SERPENT=m | ||
244 | CONFIG_CRYPTO_TEA=m | ||
245 | CONFIG_CRYPTO_TWOFISH=m | ||
246 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
diff --git a/arch/powerpc/configs/mpc86xx_basic_defconfig b/arch/powerpc/configs/mpc86xx_basic_defconfig new file mode 100644 index 000000000000..33af5c5de105 --- /dev/null +++ b/arch/powerpc/configs/mpc86xx_basic_defconfig | |||
@@ -0,0 +1,10 @@ | |||
1 | CONFIG_HIGHMEM=y | ||
2 | CONFIG_KEXEC=y | ||
3 | CONFIG_PPC_86xx=y | ||
4 | CONFIG_PROC_KCORE=y | ||
5 | CONFIG_GEF_PPC9A=y | ||
6 | CONFIG_GEF_SBC310=y | ||
7 | CONFIG_GEF_SBC610=y | ||
8 | CONFIG_MPC8610_HPCD=y | ||
9 | CONFIG_MPC8641_HPCN=y | ||
10 | CONFIG_SBC8641D=y | ||
diff --git a/arch/powerpc/configs/mpc86xx_defconfig b/arch/powerpc/configs/mpc86xx_defconfig deleted file mode 100644 index a4572563681c..000000000000 --- a/arch/powerpc/configs/mpc86xx_defconfig +++ /dev/null | |||
@@ -1,162 +0,0 @@ | |||
1 | CONFIG_SMP=y | ||
2 | CONFIG_NR_CPUS=2 | ||
3 | CONFIG_SYSVIPC=y | ||
4 | CONFIG_POSIX_MQUEUE=y | ||
5 | CONFIG_AUDIT=y | ||
6 | CONFIG_NO_HZ=y | ||
7 | CONFIG_HIGH_RES_TIMERS=y | ||
8 | CONFIG_BSD_PROCESS_ACCT=y | ||
9 | CONFIG_IKCONFIG=y | ||
10 | CONFIG_IKCONFIG_PROC=y | ||
11 | CONFIG_LOG_BUF_SHIFT=14 | ||
12 | CONFIG_BLK_DEV_INITRD=y | ||
13 | CONFIG_EXPERT=y | ||
14 | CONFIG_KALLSYMS_ALL=y | ||
15 | CONFIG_MODULES=y | ||
16 | CONFIG_MODULE_UNLOAD=y | ||
17 | CONFIG_MODULE_FORCE_UNLOAD=y | ||
18 | CONFIG_MODVERSIONS=y | ||
19 | # CONFIG_BLK_DEV_BSG is not set | ||
20 | CONFIG_PARTITION_ADVANCED=y | ||
21 | CONFIG_MAC_PARTITION=y | ||
22 | # CONFIG_PPC_CHRP is not set | ||
23 | # CONFIG_PPC_PMAC is not set | ||
24 | CONFIG_PPC_86xx=y | ||
25 | CONFIG_MPC8641_HPCN=y | ||
26 | CONFIG_SBC8641D=y | ||
27 | CONFIG_MPC8610_HPCD=y | ||
28 | CONFIG_GEF_SBC610=y | ||
29 | CONFIG_HIGHMEM=y | ||
30 | CONFIG_HZ_1000=y | ||
31 | CONFIG_BINFMT_MISC=m | ||
32 | CONFIG_PCI=y | ||
33 | CONFIG_NET=y | ||
34 | CONFIG_PACKET=y | ||
35 | CONFIG_UNIX=y | ||
36 | CONFIG_XFRM_USER=y | ||
37 | CONFIG_NET_KEY=m | ||
38 | CONFIG_INET=y | ||
39 | CONFIG_IP_MULTICAST=y | ||
40 | CONFIG_IP_ADVANCED_ROUTER=y | ||
41 | CONFIG_IP_MULTIPLE_TABLES=y | ||
42 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
43 | CONFIG_IP_ROUTE_VERBOSE=y | ||
44 | CONFIG_IP_PNP=y | ||
45 | CONFIG_IP_PNP_DHCP=y | ||
46 | CONFIG_IP_PNP_BOOTP=y | ||
47 | CONFIG_IP_PNP_RARP=y | ||
48 | CONFIG_NET_IPIP=y | ||
49 | CONFIG_IP_MROUTE=y | ||
50 | CONFIG_IP_PIMSM_V1=y | ||
51 | CONFIG_IP_PIMSM_V2=y | ||
52 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
53 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
54 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
55 | # CONFIG_INET_LRO is not set | ||
56 | CONFIG_IPV6=y | ||
57 | CONFIG_IP_SCTP=m | ||
58 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
59 | CONFIG_BLK_DEV_LOOP=y | ||
60 | CONFIG_BLK_DEV_NBD=y | ||
61 | CONFIG_BLK_DEV_RAM=y | ||
62 | CONFIG_BLK_DEV_RAM_SIZE=131072 | ||
63 | CONFIG_EEPROM_LEGACY=y | ||
64 | CONFIG_BLK_DEV_SD=y | ||
65 | CONFIG_CHR_DEV_ST=y | ||
66 | CONFIG_BLK_DEV_SR=y | ||
67 | CONFIG_CHR_DEV_SG=y | ||
68 | CONFIG_SCSI_LOGGING=y | ||
69 | CONFIG_ATA=y | ||
70 | CONFIG_SATA_AHCI=y | ||
71 | CONFIG_PATA_ALI=y | ||
72 | CONFIG_NETDEVICES=y | ||
73 | CONFIG_DUMMY=y | ||
74 | CONFIG_GIANFAR=y | ||
75 | CONFIG_VITESSE_PHY=y | ||
76 | CONFIG_INPUT_FF_MEMLESS=m | ||
77 | # CONFIG_INPUT_MOUSEDEV is not set | ||
78 | # CONFIG_INPUT_KEYBOARD is not set | ||
79 | # CONFIG_INPUT_MOUSE is not set | ||
80 | CONFIG_SERIO_LIBPS2=y | ||
81 | CONFIG_SERIAL_8250=y | ||
82 | CONFIG_SERIAL_8250_CONSOLE=y | ||
83 | CONFIG_SERIAL_8250_NR_UARTS=2 | ||
84 | CONFIG_SERIAL_8250_RUNTIME_UARTS=2 | ||
85 | CONFIG_SERIAL_8250_EXTENDED=y | ||
86 | CONFIG_SERIAL_8250_MANY_PORTS=y | ||
87 | CONFIG_SERIAL_8250_SHARE_IRQ=y | ||
88 | CONFIG_SERIAL_8250_DETECT_IRQ=y | ||
89 | CONFIG_SERIAL_8250_RSA=y | ||
90 | # CONFIG_HW_RANDOM is not set | ||
91 | CONFIG_NVRAM=y | ||
92 | CONFIG_I2C=y | ||
93 | CONFIG_I2C_MPC=y | ||
94 | # CONFIG_HWMON is not set | ||
95 | CONFIG_SOUND=y | ||
96 | CONFIG_SND=y | ||
97 | CONFIG_SND_MIXER_OSS=y | ||
98 | CONFIG_SND_PCM_OSS=y | ||
99 | # CONFIG_SND_SUPPORT_OLD_API is not set | ||
100 | CONFIG_SND_INTEL8X0=y | ||
101 | CONFIG_HID_A4TECH=y | ||
102 | CONFIG_HID_APPLE=y | ||
103 | CONFIG_HID_BELKIN=y | ||
104 | CONFIG_HID_CHERRY=y | ||
105 | CONFIG_HID_CHICONY=y | ||
106 | CONFIG_HID_CYPRESS=y | ||
107 | CONFIG_HID_EZKEY=y | ||
108 | CONFIG_HID_GYRATION=y | ||
109 | CONFIG_HID_LOGITECH=y | ||
110 | CONFIG_HID_MICROSOFT=y | ||
111 | CONFIG_HID_MONTEREY=y | ||
112 | CONFIG_HID_PANTHERLORD=y | ||
113 | CONFIG_HID_PETALYNX=y | ||
114 | CONFIG_HID_SAMSUNG=y | ||
115 | CONFIG_HID_SUNPLUS=y | ||
116 | CONFIG_USB=y | ||
117 | CONFIG_USB_MON=y | ||
118 | CONFIG_USB_EHCI_HCD=y | ||
119 | CONFIG_USB_OHCI_HCD=y | ||
120 | CONFIG_USB_OHCI_HCD_PPC_OF_BE=y | ||
121 | CONFIG_USB_OHCI_HCD_PPC_OF_LE=y | ||
122 | CONFIG_USB_STORAGE=y | ||
123 | CONFIG_RTC_CLASS=y | ||
124 | CONFIG_RTC_DRV_CMOS=y | ||
125 | CONFIG_EXT2_FS=y | ||
126 | CONFIG_EXT3_FS=y | ||
127 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
128 | CONFIG_ISO9660_FS=m | ||
129 | CONFIG_JOLIET=y | ||
130 | CONFIG_ZISOFS=y | ||
131 | CONFIG_UDF_FS=m | ||
132 | CONFIG_MSDOS_FS=m | ||
133 | CONFIG_VFAT_FS=y | ||
134 | CONFIG_NTFS_FS=y | ||
135 | CONFIG_PROC_KCORE=y | ||
136 | CONFIG_TMPFS=y | ||
137 | CONFIG_ADFS_FS=m | ||
138 | CONFIG_AFFS_FS=m | ||
139 | CONFIG_HFS_FS=m | ||
140 | CONFIG_HFSPLUS_FS=m | ||
141 | CONFIG_BEFS_FS=m | ||
142 | CONFIG_BFS_FS=m | ||
143 | CONFIG_EFS_FS=m | ||
144 | CONFIG_CRAMFS=y | ||
145 | CONFIG_VXFS_FS=m | ||
146 | CONFIG_HPFS_FS=m | ||
147 | CONFIG_QNX4FS_FS=m | ||
148 | CONFIG_SYSV_FS=m | ||
149 | CONFIG_UFS_FS=m | ||
150 | CONFIG_NFS_FS=y | ||
151 | CONFIG_NFS_V4=y | ||
152 | CONFIG_ROOT_NFS=y | ||
153 | CONFIG_NFSD=y | ||
154 | CONFIG_NLS_CODEPAGE_437=y | ||
155 | CONFIG_NLS_CODEPAGE_850=y | ||
156 | CONFIG_NLS_ISO8859_1=y | ||
157 | CONFIG_CRC_T10DIF=y | ||
158 | CONFIG_DEBUG_INFO=y | ||
159 | CONFIG_DETECT_HUNG_TASK=y | ||
160 | CONFIG_CRYPTO_PCBC=m | ||
161 | CONFIG_CRYPTO_HMAC=y | ||
162 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig new file mode 100644 index 000000000000..045031048f8d --- /dev/null +++ b/arch/powerpc/configs/powernv_defconfig | |||
@@ -0,0 +1,313 @@ | |||
1 | CONFIG_PPC64=y | ||
2 | CONFIG_SMP=y | ||
3 | CONFIG_NR_CPUS=2048 | ||
4 | CONFIG_CPU_LITTLE_ENDIAN=y | ||
5 | CONFIG_SYSVIPC=y | ||
6 | CONFIG_POSIX_MQUEUE=y | ||
7 | CONFIG_FHANDLE=y | ||
8 | CONFIG_AUDIT=y | ||
9 | CONFIG_IRQ_DOMAIN_DEBUG=y | ||
10 | CONFIG_NO_HZ=y | ||
11 | CONFIG_HIGH_RES_TIMERS=y | ||
12 | CONFIG_TASKSTATS=y | ||
13 | CONFIG_TASK_DELAY_ACCT=y | ||
14 | CONFIG_TASK_XACCT=y | ||
15 | CONFIG_TASK_IO_ACCOUNTING=y | ||
16 | CONFIG_IKCONFIG=y | ||
17 | CONFIG_IKCONFIG_PROC=y | ||
18 | CONFIG_NUMA_BALANCING=y | ||
19 | CONFIG_CGROUPS=y | ||
20 | CONFIG_MEMCG=y | ||
21 | CONFIG_MEMCG_SWAP=y | ||
22 | CONFIG_CGROUP_SCHED=y | ||
23 | CONFIG_CGROUP_FREEZER=y | ||
24 | CONFIG_CPUSETS=y | ||
25 | CONFIG_CGROUP_DEVICE=y | ||
26 | CONFIG_CGROUP_CPUACCT=y | ||
27 | CONFIG_CGROUP_PERF=y | ||
28 | CONFIG_USER_NS=y | ||
29 | CONFIG_BLK_DEV_INITRD=y | ||
30 | # CONFIG_COMPAT_BRK is not set | ||
31 | CONFIG_PROFILING=y | ||
32 | CONFIG_OPROFILE=y | ||
33 | CONFIG_KPROBES=y | ||
34 | CONFIG_JUMP_LABEL=y | ||
35 | CONFIG_MODULES=y | ||
36 | CONFIG_MODULE_UNLOAD=y | ||
37 | CONFIG_MODVERSIONS=y | ||
38 | CONFIG_MODULE_SRCVERSION_ALL=y | ||
39 | CONFIG_PARTITION_ADVANCED=y | ||
40 | CONFIG_OPAL_PRD=y | ||
41 | # CONFIG_PPC_PSERIES is not set | ||
42 | # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set | ||
43 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y | ||
44 | CONFIG_CPU_IDLE=y | ||
45 | CONFIG_HZ_100=y | ||
46 | CONFIG_BINFMT_MISC=m | ||
47 | CONFIG_PPC_TRANSACTIONAL_MEM=y | ||
48 | CONFIG_HOTPLUG_CPU=y | ||
49 | CONFIG_KEXEC=y | ||
50 | CONFIG_IRQ_ALL_CPUS=y | ||
51 | CONFIG_NUMA=y | ||
52 | CONFIG_MEMORY_HOTPLUG=y | ||
53 | CONFIG_MEMORY_HOTREMOVE=y | ||
54 | CONFIG_KSM=y | ||
55 | CONFIG_TRANSPARENT_HUGEPAGE=y | ||
56 | CONFIG_PPC_64K_PAGES=y | ||
57 | CONFIG_PPC_SUBPAGE_PROT=y | ||
58 | CONFIG_SCHED_SMT=y | ||
59 | CONFIG_PM=y | ||
60 | CONFIG_PCI_MSI=y | ||
61 | CONFIG_HOTPLUG_PCI=y | ||
62 | CONFIG_NET=y | ||
63 | CONFIG_PACKET=y | ||
64 | CONFIG_UNIX=y | ||
65 | CONFIG_XFRM_USER=m | ||
66 | CONFIG_NET_KEY=m | ||
67 | CONFIG_INET=y | ||
68 | CONFIG_IP_MULTICAST=y | ||
69 | CONFIG_NET_IPIP=y | ||
70 | CONFIG_SYN_COOKIES=y | ||
71 | CONFIG_INET_AH=m | ||
72 | CONFIG_INET_ESP=m | ||
73 | CONFIG_INET_IPCOMP=m | ||
74 | # CONFIG_IPV6 is not set | ||
75 | CONFIG_NETFILTER=y | ||
76 | # CONFIG_NETFILTER_ADVANCED is not set | ||
77 | CONFIG_BRIDGE=m | ||
78 | CONFIG_VLAN_8021Q=m | ||
79 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
80 | CONFIG_DEVTMPFS=y | ||
81 | CONFIG_DEVTMPFS_MOUNT=y | ||
82 | CONFIG_MTD=y | ||
83 | CONFIG_MTD_POWERNV_FLASH=y | ||
84 | CONFIG_PARPORT=m | ||
85 | CONFIG_PARPORT_PC=m | ||
86 | CONFIG_BLK_DEV_FD=m | ||
87 | CONFIG_BLK_DEV_LOOP=y | ||
88 | CONFIG_BLK_DEV_NBD=m | ||
89 | CONFIG_BLK_DEV_RAM=y | ||
90 | CONFIG_BLK_DEV_RAM_SIZE=65536 | ||
91 | CONFIG_VIRTIO_BLK=m | ||
92 | CONFIG_IDE=y | ||
93 | CONFIG_BLK_DEV_IDECD=y | ||
94 | CONFIG_BLK_DEV_GENERIC=y | ||
95 | CONFIG_BLK_DEV_AMD74XX=y | ||
96 | CONFIG_BLK_DEV_SD=y | ||
97 | CONFIG_CHR_DEV_ST=y | ||
98 | CONFIG_BLK_DEV_SR=y | ||
99 | CONFIG_BLK_DEV_SR_VENDOR=y | ||
100 | CONFIG_CHR_DEV_SG=y | ||
101 | CONFIG_SCSI_CONSTANTS=y | ||
102 | CONFIG_SCSI_FC_ATTRS=y | ||
103 | CONFIG_SCSI_SRP_ATTRS=y | ||
104 | CONFIG_SCSI_CXGB3_ISCSI=m | ||
105 | CONFIG_SCSI_CXGB4_ISCSI=m | ||
106 | CONFIG_SCSI_BNX2_ISCSI=m | ||
107 | CONFIG_BE2ISCSI=m | ||
108 | CONFIG_SCSI_MPT2SAS=m | ||
109 | CONFIG_SCSI_SYM53C8XX_2=y | ||
110 | CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 | ||
111 | CONFIG_SCSI_IPR=y | ||
112 | CONFIG_SCSI_QLA_FC=m | ||
113 | CONFIG_SCSI_QLA_ISCSI=m | ||
114 | CONFIG_SCSI_LPFC=m | ||
115 | CONFIG_SCSI_VIRTIO=m | ||
116 | CONFIG_SCSI_DH=y | ||
117 | CONFIG_SCSI_DH_RDAC=m | ||
118 | CONFIG_SCSI_DH_ALUA=m | ||
119 | CONFIG_ATA=y | ||
120 | CONFIG_SATA_AHCI=y | ||
121 | # CONFIG_ATA_SFF is not set | ||
122 | CONFIG_MD=y | ||
123 | CONFIG_BLK_DEV_MD=y | ||
124 | CONFIG_MD_LINEAR=y | ||
125 | CONFIG_MD_RAID0=y | ||
126 | CONFIG_MD_RAID1=y | ||
127 | CONFIG_MD_RAID10=m | ||
128 | CONFIG_MD_RAID456=m | ||
129 | CONFIG_MD_MULTIPATH=m | ||
130 | CONFIG_MD_FAULTY=m | ||
131 | CONFIG_BLK_DEV_DM=y | ||
132 | CONFIG_DM_CRYPT=m | ||
133 | CONFIG_DM_SNAPSHOT=m | ||
134 | CONFIG_DM_THIN_PROVISIONING=m | ||
135 | CONFIG_DM_MIRROR=m | ||
136 | CONFIG_DM_ZERO=m | ||
137 | CONFIG_DM_MULTIPATH=m | ||
138 | CONFIG_DM_MULTIPATH_QL=m | ||
139 | CONFIG_DM_MULTIPATH_ST=m | ||
140 | CONFIG_DM_UEVENT=y | ||
141 | CONFIG_BONDING=m | ||
142 | CONFIG_DUMMY=m | ||
143 | CONFIG_MACVLAN=m | ||
144 | CONFIG_MACVTAP=m | ||
145 | CONFIG_VXLAN=m | ||
146 | CONFIG_NETCONSOLE=y | ||
147 | CONFIG_TUN=m | ||
148 | CONFIG_VETH=m | ||
149 | CONFIG_VIRTIO_NET=m | ||
150 | CONFIG_VHOST_NET=m | ||
151 | CONFIG_VORTEX=y | ||
152 | CONFIG_ACENIC=m | ||
153 | CONFIG_ACENIC_OMIT_TIGON_I=y | ||
154 | CONFIG_PCNET32=y | ||
155 | CONFIG_TIGON3=y | ||
156 | CONFIG_BNX2X=m | ||
157 | CONFIG_CHELSIO_T1=m | ||
158 | CONFIG_BE2NET=m | ||
159 | CONFIG_S2IO=m | ||
160 | CONFIG_E100=y | ||
161 | CONFIG_E1000=y | ||
162 | CONFIG_E1000E=y | ||
163 | CONFIG_IXGB=m | ||
164 | CONFIG_IXGBE=m | ||
165 | CONFIG_MLX4_EN=m | ||
166 | CONFIG_MYRI10GE=m | ||
167 | CONFIG_QLGE=m | ||
168 | CONFIG_NETXEN_NIC=m | ||
169 | CONFIG_PPP=m | ||
170 | CONFIG_PPP_BSDCOMP=m | ||
171 | CONFIG_PPP_DEFLATE=m | ||
172 | CONFIG_PPPOE=m | ||
173 | CONFIG_PPP_ASYNC=m | ||
174 | CONFIG_PPP_SYNC_TTY=m | ||
175 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | ||
176 | CONFIG_INPUT_EVDEV=m | ||
177 | CONFIG_INPUT_MISC=y | ||
178 | # CONFIG_SERIO_SERPORT is not set | ||
179 | CONFIG_DEVPTS_MULTIPLE_INSTANCES=y | ||
180 | CONFIG_SERIAL_8250=y | ||
181 | CONFIG_SERIAL_8250_CONSOLE=y | ||
182 | CONFIG_SERIAL_JSM=m | ||
183 | CONFIG_VIRTIO_CONSOLE=m | ||
184 | CONFIG_IPMI_HANDLER=y | ||
185 | CONFIG_IPMI_DEVICE_INTERFACE=y | ||
186 | CONFIG_IPMI_POWERNV=y | ||
187 | CONFIG_RAW_DRIVER=y | ||
188 | CONFIG_MAX_RAW_DEVS=1024 | ||
189 | CONFIG_DRM=y | ||
190 | CONFIG_DRM_AST=y | ||
191 | CONFIG_FIRMWARE_EDID=y | ||
192 | CONFIG_FB_OF=y | ||
193 | CONFIG_FB_MATROX=y | ||
194 | CONFIG_FB_MATROX_MILLENIUM=y | ||
195 | CONFIG_FB_MATROX_MYSTIQUE=y | ||
196 | CONFIG_FB_MATROX_G=y | ||
197 | CONFIG_FB_RADEON=y | ||
198 | CONFIG_FB_IBM_GXT4500=y | ||
199 | CONFIG_LCD_PLATFORM=m | ||
200 | # CONFIG_VGA_CONSOLE is not set | ||
201 | CONFIG_LOGO=y | ||
202 | CONFIG_HID_GYRATION=y | ||
203 | CONFIG_HID_PANTHERLORD=y | ||
204 | CONFIG_HID_PETALYNX=y | ||
205 | CONFIG_HID_SAMSUNG=y | ||
206 | CONFIG_HID_SUNPLUS=y | ||
207 | CONFIG_USB_HIDDEV=y | ||
208 | CONFIG_USB=y | ||
209 | CONFIG_USB_MON=m | ||
210 | CONFIG_USB_EHCI_HCD=y | ||
211 | # CONFIG_USB_EHCI_HCD_PPC_OF is not set | ||
212 | CONFIG_USB_OHCI_HCD=y | ||
213 | CONFIG_USB_STORAGE=m | ||
214 | CONFIG_NEW_LEDS=y | ||
215 | CONFIG_LEDS_CLASS=m | ||
216 | CONFIG_LEDS_POWERNV=m | ||
217 | CONFIG_INFINIBAND=m | ||
218 | CONFIG_INFINIBAND_USER_MAD=m | ||
219 | CONFIG_INFINIBAND_USER_ACCESS=m | ||
220 | CONFIG_INFINIBAND_MTHCA=m | ||
221 | CONFIG_INFINIBAND_CXGB3=m | ||
222 | CONFIG_INFINIBAND_CXGB4=m | ||
223 | CONFIG_MLX4_INFINIBAND=m | ||
224 | CONFIG_INFINIBAND_IPOIB=m | ||
225 | CONFIG_INFINIBAND_IPOIB_CM=y | ||
226 | CONFIG_INFINIBAND_SRP=m | ||
227 | CONFIG_INFINIBAND_ISER=m | ||
228 | CONFIG_RTC_CLASS=y | ||
229 | CONFIG_RTC_DRV_GENERIC=y | ||
230 | CONFIG_VIRTIO_PCI=m | ||
231 | CONFIG_VIRTIO_BALLOON=m | ||
232 | CONFIG_EXT2_FS=y | ||
233 | CONFIG_EXT2_FS_XATTR=y | ||
234 | CONFIG_EXT2_FS_POSIX_ACL=y | ||
235 | CONFIG_EXT2_FS_SECURITY=y | ||
236 | CONFIG_EXT3_FS=y | ||
237 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
238 | CONFIG_EXT3_FS_SECURITY=y | ||
239 | CONFIG_REISERFS_FS=y | ||
240 | CONFIG_REISERFS_FS_XATTR=y | ||
241 | CONFIG_REISERFS_FS_POSIX_ACL=y | ||
242 | CONFIG_REISERFS_FS_SECURITY=y | ||
243 | CONFIG_JFS_FS=m | ||
244 | CONFIG_JFS_POSIX_ACL=y | ||
245 | CONFIG_JFS_SECURITY=y | ||
246 | CONFIG_XFS_FS=m | ||
247 | CONFIG_XFS_POSIX_ACL=y | ||
248 | CONFIG_BTRFS_FS=m | ||
249 | CONFIG_BTRFS_FS_POSIX_ACL=y | ||
250 | CONFIG_NILFS2_FS=m | ||
251 | CONFIG_AUTOFS4_FS=m | ||
252 | CONFIG_FUSE_FS=m | ||
253 | CONFIG_OVERLAY_FS=m | ||
254 | CONFIG_ISO9660_FS=y | ||
255 | CONFIG_UDF_FS=m | ||
256 | CONFIG_MSDOS_FS=y | ||
257 | CONFIG_VFAT_FS=y | ||
258 | CONFIG_PROC_KCORE=y | ||
259 | CONFIG_TMPFS=y | ||
260 | CONFIG_TMPFS_POSIX_ACL=y | ||
261 | CONFIG_HUGETLBFS=y | ||
262 | CONFIG_CRAMFS=m | ||
263 | CONFIG_SQUASHFS=m | ||
264 | CONFIG_SQUASHFS_XATTR=y | ||
265 | CONFIG_SQUASHFS_LZO=y | ||
266 | CONFIG_SQUASHFS_XZ=y | ||
267 | CONFIG_PSTORE=y | ||
268 | CONFIG_NFS_FS=y | ||
269 | CONFIG_NFS_V3_ACL=y | ||
270 | CONFIG_NFS_V4=y | ||
271 | CONFIG_NFSD=m | ||
272 | CONFIG_NFSD_V3_ACL=y | ||
273 | CONFIG_NFSD_V4=y | ||
274 | CONFIG_CIFS=m | ||
275 | CONFIG_CIFS_XATTR=y | ||
276 | CONFIG_CIFS_POSIX=y | ||
277 | CONFIG_NLS_DEFAULT="utf8" | ||
278 | CONFIG_NLS_CODEPAGE_437=y | ||
279 | CONFIG_NLS_ASCII=y | ||
280 | CONFIG_NLS_ISO8859_1=y | ||
281 | CONFIG_NLS_UTF8=y | ||
282 | CONFIG_MAGIC_SYSRQ=y | ||
283 | CONFIG_DEBUG_KERNEL=y | ||
284 | CONFIG_DEBUG_STACK_USAGE=y | ||
285 | CONFIG_DEBUG_STACKOVERFLOW=y | ||
286 | CONFIG_LOCKUP_DETECTOR=y | ||
287 | CONFIG_LATENCYTOP=y | ||
288 | CONFIG_SCHED_TRACER=y | ||
289 | CONFIG_BLK_DEV_IO_TRACE=y | ||
290 | CONFIG_CODE_PATCHING_SELFTEST=y | ||
291 | CONFIG_FTR_FIXUP_SELFTEST=y | ||
292 | CONFIG_MSI_BITMAP_SELFTEST=y | ||
293 | CONFIG_XMON=y | ||
294 | CONFIG_CRYPTO_TEST=m | ||
295 | CONFIG_CRYPTO_CCM=m | ||
296 | CONFIG_CRYPTO_PCBC=m | ||
297 | CONFIG_CRYPTO_HMAC=y | ||
298 | CONFIG_CRYPTO_MICHAEL_MIC=m | ||
299 | CONFIG_CRYPTO_TGR192=m | ||
300 | CONFIG_CRYPTO_WP512=m | ||
301 | CONFIG_CRYPTO_ANUBIS=m | ||
302 | CONFIG_CRYPTO_BLOWFISH=m | ||
303 | CONFIG_CRYPTO_CAST6=m | ||
304 | CONFIG_CRYPTO_KHAZAD=m | ||
305 | CONFIG_CRYPTO_SALSA20=m | ||
306 | CONFIG_CRYPTO_SERPENT=m | ||
307 | CONFIG_CRYPTO_TEA=m | ||
308 | CONFIG_CRYPTO_TWOFISH=m | ||
309 | CONFIG_CRYPTO_LZO=m | ||
310 | CONFIG_CRYPTO_DEV_NX=y | ||
311 | CONFIG_VIRTUALIZATION=y | ||
312 | CONFIG_KVM_BOOK3S_64=m | ||
313 | CONFIG_KVM_BOOK3S_64_HV=m | ||
diff --git a/arch/powerpc/crypto/aes-spe-core.S b/arch/powerpc/crypto/aes-spe-core.S index 5dc6bce90a77..bc6ff43a9889 100644 --- a/arch/powerpc/crypto/aes-spe-core.S +++ b/arch/powerpc/crypto/aes-spe-core.S | |||
@@ -61,7 +61,7 @@ | |||
61 | * via bl/blr. It expects that caller has pre-xored input data with first | 61 | * via bl/blr. It expects that caller has pre-xored input data with first |
62 | * 4 words of encryption key into rD0-rD3. Pointer/counter registers must | 62 | * 4 words of encryption key into rD0-rD3. Pointer/counter registers must |
63 | * have also been set up before (rT0, rKP, CTR). Output is stored in rD0-rD3 | 63 | * have also been set up before (rT0, rKP, CTR). Output is stored in rD0-rD3 |
64 | * and rW0-rW3 and caller must execute a final xor on the ouput registers. | 64 | * and rW0-rW3 and caller must execute a final xor on the output registers. |
65 | * All working registers rD0-rD3 & rW0-rW7 are overwritten during processing. | 65 | * All working registers rD0-rD3 & rW0-rW7 are overwritten during processing. |
66 | * | 66 | * |
67 | */ | 67 | */ |
@@ -209,7 +209,7 @@ ppc_encrypt_block_loop: | |||
209 | * via bl/blr. It expects that caller has pre-xored input data with first | 209 | * via bl/blr. It expects that caller has pre-xored input data with first |
210 | * 4 words of encryption key into rD0-rD3. Pointer/counter registers must | 210 | * 4 words of encryption key into rD0-rD3. Pointer/counter registers must |
211 | * have also been set up before (rT0, rKP, CTR). Output is stored in rD0-rD3 | 211 | * have also been set up before (rT0, rKP, CTR). Output is stored in rD0-rD3 |
212 | * and rW0-rW3 and caller must execute a final xor on the ouput registers. | 212 | * and rW0-rW3 and caller must execute a final xor on the output registers. |
213 | * All working registers rD0-rD3 & rW0-rW7 are overwritten during processing. | 213 | * All working registers rD0-rD3 & rW0-rW7 are overwritten during processing. |
214 | * | 214 | * |
215 | */ | 215 | */ |
diff --git a/arch/powerpc/crypto/aes-spe-glue.c b/arch/powerpc/crypto/aes-spe-glue.c index ab113198ed20..748fc00c5e19 100644 --- a/arch/powerpc/crypto/aes-spe-glue.c +++ b/arch/powerpc/crypto/aes-spe-glue.c | |||
@@ -33,7 +33,7 @@ | |||
33 | * 16 byte block block or 25 cycles per byte. Thus 768 bytes of input data | 33 | * 16 byte block block or 25 cycles per byte. Thus 768 bytes of input data |
34 | * will need an estimated maximum of 20,000 cycles. Headroom for cache misses | 34 | * will need an estimated maximum of 20,000 cycles. Headroom for cache misses |
35 | * included. Even with the low end model clocked at 667 MHz this equals to a | 35 | * included. Even with the low end model clocked at 667 MHz this equals to a |
36 | * critical time window of less than 30us. The value has been choosen to | 36 | * critical time window of less than 30us. The value has been chosen to |
37 | * process a 512 byte disk block in one or a large 1400 bytes IPsec network | 37 | * process a 512 byte disk block in one or a large 1400 bytes IPsec network |
38 | * packet in two runs. | 38 | * packet in two runs. |
39 | * | 39 | * |
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h index 55f106ed12bf..ae0751ef8788 100644 --- a/arch/powerpc/include/asm/atomic.h +++ b/arch/powerpc/include/asm/atomic.h | |||
@@ -12,6 +12,24 @@ | |||
12 | 12 | ||
13 | #define ATOMIC_INIT(i) { (i) } | 13 | #define ATOMIC_INIT(i) { (i) } |
14 | 14 | ||
15 | /* | ||
16 | * Since *_return_relaxed and {cmp}xchg_relaxed are implemented with | ||
17 | * a "bne-" instruction at the end, so an isync is enough as a acquire barrier | ||
18 | * on the platform without lwsync. | ||
19 | */ | ||
20 | #define __atomic_op_acquire(op, args...) \ | ||
21 | ({ \ | ||
22 | typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \ | ||
23 | __asm__ __volatile__(PPC_ACQUIRE_BARRIER "" : : : "memory"); \ | ||
24 | __ret; \ | ||
25 | }) | ||
26 | |||
27 | #define __atomic_op_release(op, args...) \ | ||
28 | ({ \ | ||
29 | __asm__ __volatile__(PPC_RELEASE_BARRIER "" : : : "memory"); \ | ||
30 | op##_relaxed(args); \ | ||
31 | }) | ||
32 | |||
15 | static __inline__ int atomic_read(const atomic_t *v) | 33 | static __inline__ int atomic_read(const atomic_t *v) |
16 | { | 34 | { |
17 | int t; | 35 | int t; |
@@ -42,27 +60,27 @@ static __inline__ void atomic_##op(int a, atomic_t *v) \ | |||
42 | : "cc"); \ | 60 | : "cc"); \ |
43 | } \ | 61 | } \ |
44 | 62 | ||
45 | #define ATOMIC_OP_RETURN(op, asm_op) \ | 63 | #define ATOMIC_OP_RETURN_RELAXED(op, asm_op) \ |
46 | static __inline__ int atomic_##op##_return(int a, atomic_t *v) \ | 64 | static inline int atomic_##op##_return_relaxed(int a, atomic_t *v) \ |
47 | { \ | 65 | { \ |
48 | int t; \ | 66 | int t; \ |
49 | \ | 67 | \ |
50 | __asm__ __volatile__( \ | 68 | __asm__ __volatile__( \ |
51 | PPC_ATOMIC_ENTRY_BARRIER \ | 69 | "1: lwarx %0,0,%3 # atomic_" #op "_return_relaxed\n" \ |
52 | "1: lwarx %0,0,%2 # atomic_" #op "_return\n" \ | 70 | #asm_op " %0,%2,%0\n" \ |
53 | #asm_op " %0,%1,%0\n" \ | 71 | PPC405_ERR77(0, %3) \ |
54 | PPC405_ERR77(0,%2) \ | 72 | " stwcx. %0,0,%3\n" \ |
55 | " stwcx. %0,0,%2 \n" \ | ||
56 | " bne- 1b\n" \ | 73 | " bne- 1b\n" \ |
57 | PPC_ATOMIC_EXIT_BARRIER \ | 74 | : "=&r" (t), "+m" (v->counter) \ |
58 | : "=&r" (t) \ | ||
59 | : "r" (a), "r" (&v->counter) \ | 75 | : "r" (a), "r" (&v->counter) \ |
60 | : "cc", "memory"); \ | 76 | : "cc"); \ |
61 | \ | 77 | \ |
62 | return t; \ | 78 | return t; \ |
63 | } | 79 | } |
64 | 80 | ||
65 | #define ATOMIC_OPS(op, asm_op) ATOMIC_OP(op, asm_op) ATOMIC_OP_RETURN(op, asm_op) | 81 | #define ATOMIC_OPS(op, asm_op) \ |
82 | ATOMIC_OP(op, asm_op) \ | ||
83 | ATOMIC_OP_RETURN_RELAXED(op, asm_op) | ||
66 | 84 | ||
67 | ATOMIC_OPS(add, add) | 85 | ATOMIC_OPS(add, add) |
68 | ATOMIC_OPS(sub, subf) | 86 | ATOMIC_OPS(sub, subf) |
@@ -71,8 +89,11 @@ ATOMIC_OP(and, and) | |||
71 | ATOMIC_OP(or, or) | 89 | ATOMIC_OP(or, or) |
72 | ATOMIC_OP(xor, xor) | 90 | ATOMIC_OP(xor, xor) |
73 | 91 | ||
92 | #define atomic_add_return_relaxed atomic_add_return_relaxed | ||
93 | #define atomic_sub_return_relaxed atomic_sub_return_relaxed | ||
94 | |||
74 | #undef ATOMIC_OPS | 95 | #undef ATOMIC_OPS |
75 | #undef ATOMIC_OP_RETURN | 96 | #undef ATOMIC_OP_RETURN_RELAXED |
76 | #undef ATOMIC_OP | 97 | #undef ATOMIC_OP |
77 | 98 | ||
78 | #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) | 99 | #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) |
@@ -92,21 +113,19 @@ static __inline__ void atomic_inc(atomic_t *v) | |||
92 | : "cc", "xer"); | 113 | : "cc", "xer"); |
93 | } | 114 | } |
94 | 115 | ||
95 | static __inline__ int atomic_inc_return(atomic_t *v) | 116 | static __inline__ int atomic_inc_return_relaxed(atomic_t *v) |
96 | { | 117 | { |
97 | int t; | 118 | int t; |
98 | 119 | ||
99 | __asm__ __volatile__( | 120 | __asm__ __volatile__( |
100 | PPC_ATOMIC_ENTRY_BARRIER | 121 | "1: lwarx %0,0,%2 # atomic_inc_return_relaxed\n" |
101 | "1: lwarx %0,0,%1 # atomic_inc_return\n\ | 122 | " addic %0,%0,1\n" |
102 | addic %0,%0,1\n" | 123 | PPC405_ERR77(0, %2) |
103 | PPC405_ERR77(0,%1) | 124 | " stwcx. %0,0,%2\n" |
104 | " stwcx. %0,0,%1 \n\ | 125 | " bne- 1b" |
105 | bne- 1b" | 126 | : "=&r" (t), "+m" (v->counter) |
106 | PPC_ATOMIC_EXIT_BARRIER | ||
107 | : "=&r" (t) | ||
108 | : "r" (&v->counter) | 127 | : "r" (&v->counter) |
109 | : "cc", "xer", "memory"); | 128 | : "cc", "xer"); |
110 | 129 | ||
111 | return t; | 130 | return t; |
112 | } | 131 | } |
@@ -136,27 +155,34 @@ static __inline__ void atomic_dec(atomic_t *v) | |||
136 | : "cc", "xer"); | 155 | : "cc", "xer"); |
137 | } | 156 | } |
138 | 157 | ||
139 | static __inline__ int atomic_dec_return(atomic_t *v) | 158 | static __inline__ int atomic_dec_return_relaxed(atomic_t *v) |
140 | { | 159 | { |
141 | int t; | 160 | int t; |
142 | 161 | ||
143 | __asm__ __volatile__( | 162 | __asm__ __volatile__( |
144 | PPC_ATOMIC_ENTRY_BARRIER | 163 | "1: lwarx %0,0,%2 # atomic_dec_return_relaxed\n" |
145 | "1: lwarx %0,0,%1 # atomic_dec_return\n\ | 164 | " addic %0,%0,-1\n" |
146 | addic %0,%0,-1\n" | 165 | PPC405_ERR77(0, %2) |
147 | PPC405_ERR77(0,%1) | 166 | " stwcx. %0,0,%2\n" |
148 | " stwcx. %0,0,%1\n\ | 167 | " bne- 1b" |
149 | bne- 1b" | 168 | : "=&r" (t), "+m" (v->counter) |
150 | PPC_ATOMIC_EXIT_BARRIER | ||
151 | : "=&r" (t) | ||
152 | : "r" (&v->counter) | 169 | : "r" (&v->counter) |
153 | : "cc", "xer", "memory"); | 170 | : "cc", "xer"); |
154 | 171 | ||
155 | return t; | 172 | return t; |
156 | } | 173 | } |
157 | 174 | ||
175 | #define atomic_inc_return_relaxed atomic_inc_return_relaxed | ||
176 | #define atomic_dec_return_relaxed atomic_dec_return_relaxed | ||
177 | |||
158 | #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) | 178 | #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) |
179 | #define atomic_cmpxchg_relaxed(v, o, n) \ | ||
180 | cmpxchg_relaxed(&((v)->counter), (o), (n)) | ||
181 | #define atomic_cmpxchg_acquire(v, o, n) \ | ||
182 | cmpxchg_acquire(&((v)->counter), (o), (n)) | ||
183 | |||
159 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | 184 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) |
185 | #define atomic_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new)) | ||
160 | 186 | ||
161 | /** | 187 | /** |
162 | * __atomic_add_unless - add unless the number is a given value | 188 | * __atomic_add_unless - add unless the number is a given value |
@@ -285,26 +311,27 @@ static __inline__ void atomic64_##op(long a, atomic64_t *v) \ | |||
285 | : "cc"); \ | 311 | : "cc"); \ |
286 | } | 312 | } |
287 | 313 | ||
288 | #define ATOMIC64_OP_RETURN(op, asm_op) \ | 314 | #define ATOMIC64_OP_RETURN_RELAXED(op, asm_op) \ |
289 | static __inline__ long atomic64_##op##_return(long a, atomic64_t *v) \ | 315 | static inline long \ |
316 | atomic64_##op##_return_relaxed(long a, atomic64_t *v) \ | ||
290 | { \ | 317 | { \ |
291 | long t; \ | 318 | long t; \ |
292 | \ | 319 | \ |
293 | __asm__ __volatile__( \ | 320 | __asm__ __volatile__( \ |
294 | PPC_ATOMIC_ENTRY_BARRIER \ | 321 | "1: ldarx %0,0,%3 # atomic64_" #op "_return_relaxed\n" \ |
295 | "1: ldarx %0,0,%2 # atomic64_" #op "_return\n" \ | 322 | #asm_op " %0,%2,%0\n" \ |
296 | #asm_op " %0,%1,%0\n" \ | 323 | " stdcx. %0,0,%3\n" \ |
297 | " stdcx. %0,0,%2 \n" \ | ||
298 | " bne- 1b\n" \ | 324 | " bne- 1b\n" \ |
299 | PPC_ATOMIC_EXIT_BARRIER \ | 325 | : "=&r" (t), "+m" (v->counter) \ |
300 | : "=&r" (t) \ | ||
301 | : "r" (a), "r" (&v->counter) \ | 326 | : "r" (a), "r" (&v->counter) \ |
302 | : "cc", "memory"); \ | 327 | : "cc"); \ |
303 | \ | 328 | \ |
304 | return t; \ | 329 | return t; \ |
305 | } | 330 | } |
306 | 331 | ||
307 | #define ATOMIC64_OPS(op, asm_op) ATOMIC64_OP(op, asm_op) ATOMIC64_OP_RETURN(op, asm_op) | 332 | #define ATOMIC64_OPS(op, asm_op) \ |
333 | ATOMIC64_OP(op, asm_op) \ | ||
334 | ATOMIC64_OP_RETURN_RELAXED(op, asm_op) | ||
308 | 335 | ||
309 | ATOMIC64_OPS(add, add) | 336 | ATOMIC64_OPS(add, add) |
310 | ATOMIC64_OPS(sub, subf) | 337 | ATOMIC64_OPS(sub, subf) |
@@ -312,8 +339,11 @@ ATOMIC64_OP(and, and) | |||
312 | ATOMIC64_OP(or, or) | 339 | ATOMIC64_OP(or, or) |
313 | ATOMIC64_OP(xor, xor) | 340 | ATOMIC64_OP(xor, xor) |
314 | 341 | ||
315 | #undef ATOMIC64_OPS | 342 | #define atomic64_add_return_relaxed atomic64_add_return_relaxed |
316 | #undef ATOMIC64_OP_RETURN | 343 | #define atomic64_sub_return_relaxed atomic64_sub_return_relaxed |
344 | |||
345 | #undef ATOPIC64_OPS | ||
346 | #undef ATOMIC64_OP_RETURN_RELAXED | ||
317 | #undef ATOMIC64_OP | 347 | #undef ATOMIC64_OP |
318 | 348 | ||
319 | #define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) | 349 | #define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) |
@@ -332,20 +362,18 @@ static __inline__ void atomic64_inc(atomic64_t *v) | |||
332 | : "cc", "xer"); | 362 | : "cc", "xer"); |
333 | } | 363 | } |
334 | 364 | ||
335 | static __inline__ long atomic64_inc_return(atomic64_t *v) | 365 | static __inline__ long atomic64_inc_return_relaxed(atomic64_t *v) |
336 | { | 366 | { |
337 | long t; | 367 | long t; |
338 | 368 | ||
339 | __asm__ __volatile__( | 369 | __asm__ __volatile__( |
340 | PPC_ATOMIC_ENTRY_BARRIER | 370 | "1: ldarx %0,0,%2 # atomic64_inc_return_relaxed\n" |
341 | "1: ldarx %0,0,%1 # atomic64_inc_return\n\ | 371 | " addic %0,%0,1\n" |
342 | addic %0,%0,1\n\ | 372 | " stdcx. %0,0,%2\n" |
343 | stdcx. %0,0,%1 \n\ | 373 | " bne- 1b" |
344 | bne- 1b" | 374 | : "=&r" (t), "+m" (v->counter) |
345 | PPC_ATOMIC_EXIT_BARRIER | ||
346 | : "=&r" (t) | ||
347 | : "r" (&v->counter) | 375 | : "r" (&v->counter) |
348 | : "cc", "xer", "memory"); | 376 | : "cc", "xer"); |
349 | 377 | ||
350 | return t; | 378 | return t; |
351 | } | 379 | } |
@@ -374,24 +402,25 @@ static __inline__ void atomic64_dec(atomic64_t *v) | |||
374 | : "cc", "xer"); | 402 | : "cc", "xer"); |
375 | } | 403 | } |
376 | 404 | ||
377 | static __inline__ long atomic64_dec_return(atomic64_t *v) | 405 | static __inline__ long atomic64_dec_return_relaxed(atomic64_t *v) |
378 | { | 406 | { |
379 | long t; | 407 | long t; |
380 | 408 | ||
381 | __asm__ __volatile__( | 409 | __asm__ __volatile__( |
382 | PPC_ATOMIC_ENTRY_BARRIER | 410 | "1: ldarx %0,0,%2 # atomic64_dec_return_relaxed\n" |
383 | "1: ldarx %0,0,%1 # atomic64_dec_return\n\ | 411 | " addic %0,%0,-1\n" |
384 | addic %0,%0,-1\n\ | 412 | " stdcx. %0,0,%2\n" |
385 | stdcx. %0,0,%1\n\ | 413 | " bne- 1b" |
386 | bne- 1b" | 414 | : "=&r" (t), "+m" (v->counter) |
387 | PPC_ATOMIC_EXIT_BARRIER | ||
388 | : "=&r" (t) | ||
389 | : "r" (&v->counter) | 415 | : "r" (&v->counter) |
390 | : "cc", "xer", "memory"); | 416 | : "cc", "xer"); |
391 | 417 | ||
392 | return t; | 418 | return t; |
393 | } | 419 | } |
394 | 420 | ||
421 | #define atomic64_inc_return_relaxed atomic64_inc_return_relaxed | ||
422 | #define atomic64_dec_return_relaxed atomic64_dec_return_relaxed | ||
423 | |||
395 | #define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0) | 424 | #define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0) |
396 | #define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0) | 425 | #define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0) |
397 | 426 | ||
@@ -420,7 +449,13 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v) | |||
420 | } | 449 | } |
421 | 450 | ||
422 | #define atomic64_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) | 451 | #define atomic64_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) |
452 | #define atomic64_cmpxchg_relaxed(v, o, n) \ | ||
453 | cmpxchg_relaxed(&((v)->counter), (o), (n)) | ||
454 | #define atomic64_cmpxchg_acquire(v, o, n) \ | ||
455 | cmpxchg_acquire(&((v)->counter), (o), (n)) | ||
456 | |||
423 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) | 457 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) |
458 | #define atomic64_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new)) | ||
424 | 459 | ||
425 | /** | 460 | /** |
426 | * atomic64_add_unless - add unless the number is a given value | 461 | * atomic64_add_unless - add unless the number is a given value |
diff --git a/arch/powerpc/include/asm/mmu-hash32.h b/arch/powerpc/include/asm/book3s/32/mmu-hash.h index 16f513e5cbd7..16f513e5cbd7 100644 --- a/arch/powerpc/include/asm/mmu-hash32.h +++ b/arch/powerpc/include/asm/book3s/32/mmu-hash.h | |||
diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h index ea0414d6659e..5f08a0832238 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-4k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h | |||
@@ -52,44 +52,14 @@ | |||
52 | _PAGE_F_SECOND | _PAGE_F_GIX) | 52 | _PAGE_F_SECOND | _PAGE_F_GIX) |
53 | 53 | ||
54 | /* shift to put page number into pte */ | 54 | /* shift to put page number into pte */ |
55 | #define PTE_RPN_SHIFT (18) | 55 | #define PTE_RPN_SHIFT (12) |
56 | #define PTE_RPN_SIZE (45) /* gives 57-bit real addresses */ | ||
56 | 57 | ||
57 | #define _PAGE_4K_PFN 0 | 58 | #define _PAGE_4K_PFN 0 |
58 | #ifndef __ASSEMBLY__ | 59 | #ifndef __ASSEMBLY__ |
59 | /* | 60 | /* |
60 | * 4-level page tables related bits | 61 | * On all 4K setups, remap_4k_pfn() equates to remap_pfn_range() |
61 | */ | 62 | */ |
62 | |||
63 | #define pgd_none(pgd) (!pgd_val(pgd)) | ||
64 | #define pgd_bad(pgd) (pgd_val(pgd) == 0) | ||
65 | #define pgd_present(pgd) (pgd_val(pgd) != 0) | ||
66 | #define pgd_page_vaddr(pgd) (pgd_val(pgd) & ~PGD_MASKED_BITS) | ||
67 | |||
68 | static inline void pgd_clear(pgd_t *pgdp) | ||
69 | { | ||
70 | *pgdp = __pgd(0); | ||
71 | } | ||
72 | |||
73 | static inline pte_t pgd_pte(pgd_t pgd) | ||
74 | { | ||
75 | return __pte(pgd_val(pgd)); | ||
76 | } | ||
77 | |||
78 | static inline pgd_t pte_pgd(pte_t pte) | ||
79 | { | ||
80 | return __pgd(pte_val(pte)); | ||
81 | } | ||
82 | extern struct page *pgd_page(pgd_t pgd); | ||
83 | |||
84 | #define pud_offset(pgdp, addr) \ | ||
85 | (((pud_t *) pgd_page_vaddr(*(pgdp))) + \ | ||
86 | (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))) | ||
87 | |||
88 | #define pud_ERROR(e) \ | ||
89 | pr_err("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e)) | ||
90 | |||
91 | /* | ||
92 | * On all 4K setups, remap_4k_pfn() equates to remap_pfn_range() */ | ||
93 | #define remap_4k_pfn(vma, addr, pfn, prot) \ | 63 | #define remap_4k_pfn(vma, addr, pfn, prot) \ |
94 | remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot)) | 64 | remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot)) |
95 | 65 | ||
diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h index 849bbec80f7b..0a7956a80a08 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h | |||
@@ -1,15 +1,14 @@ | |||
1 | #ifndef _ASM_POWERPC_BOOK3S_64_HASH_64K_H | 1 | #ifndef _ASM_POWERPC_BOOK3S_64_HASH_64K_H |
2 | #define _ASM_POWERPC_BOOK3S_64_HASH_64K_H | 2 | #define _ASM_POWERPC_BOOK3S_64_HASH_64K_H |
3 | 3 | ||
4 | #include <asm-generic/pgtable-nopud.h> | ||
5 | |||
6 | #define PTE_INDEX_SIZE 8 | 4 | #define PTE_INDEX_SIZE 8 |
7 | #define PMD_INDEX_SIZE 10 | 5 | #define PMD_INDEX_SIZE 5 |
8 | #define PUD_INDEX_SIZE 0 | 6 | #define PUD_INDEX_SIZE 5 |
9 | #define PGD_INDEX_SIZE 12 | 7 | #define PGD_INDEX_SIZE 12 |
10 | 8 | ||
11 | #define PTRS_PER_PTE (1 << PTE_INDEX_SIZE) | 9 | #define PTRS_PER_PTE (1 << PTE_INDEX_SIZE) |
12 | #define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) | 10 | #define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) |
11 | #define PTRS_PER_PUD (1 << PUD_INDEX_SIZE) | ||
13 | #define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) | 12 | #define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) |
14 | 13 | ||
15 | /* With 4k base page size, hugepage PTEs go at the PMD level */ | 14 | /* With 4k base page size, hugepage PTEs go at the PMD level */ |
@@ -20,13 +19,18 @@ | |||
20 | #define PMD_SIZE (1UL << PMD_SHIFT) | 19 | #define PMD_SIZE (1UL << PMD_SHIFT) |
21 | #define PMD_MASK (~(PMD_SIZE-1)) | 20 | #define PMD_MASK (~(PMD_SIZE-1)) |
22 | 21 | ||
23 | /* PGDIR_SHIFT determines what a third-level page table entry can map */ | 22 | /* PUD_SHIFT determines what a third-level page table entry can map */ |
24 | #define PGDIR_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE) | 23 | #define PUD_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE) |
24 | #define PUD_SIZE (1UL << PUD_SHIFT) | ||
25 | #define PUD_MASK (~(PUD_SIZE-1)) | ||
26 | |||
27 | /* PGDIR_SHIFT determines what a fourth-level page table entry can map */ | ||
28 | #define PGDIR_SHIFT (PUD_SHIFT + PUD_INDEX_SIZE) | ||
25 | #define PGDIR_SIZE (1UL << PGDIR_SHIFT) | 29 | #define PGDIR_SIZE (1UL << PGDIR_SHIFT) |
26 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) | 30 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) |
27 | 31 | ||
28 | #define _PAGE_COMBO 0x00040000 /* this is a combo 4k page */ | 32 | #define _PAGE_COMBO 0x00001000 /* this is a combo 4k page */ |
29 | #define _PAGE_4K_PFN 0x00080000 /* PFN is for a single 4k page */ | 33 | #define _PAGE_4K_PFN 0x00002000 /* PFN is for a single 4k page */ |
30 | /* | 34 | /* |
31 | * Used to track subpage group valid if _PAGE_COMBO is set | 35 | * Used to track subpage group valid if _PAGE_COMBO is set |
32 | * This overloads _PAGE_F_GIX and _PAGE_F_SECOND | 36 | * This overloads _PAGE_F_GIX and _PAGE_F_SECOND |
@@ -39,10 +43,12 @@ | |||
39 | 43 | ||
40 | /* Shift to put page number into pte. | 44 | /* Shift to put page number into pte. |
41 | * | 45 | * |
42 | * That gives us a max RPN of 34 bits, which means a max of 50 bits | 46 | * That gives us a max RPN of 41 bits, which means a max of 57 bits |
43 | * of addressable physical space, or 46 bits for the special 4k PFNs. | 47 | * of addressable physical space, or 53 bits for the special 4k PFNs. |
44 | */ | 48 | */ |
45 | #define PTE_RPN_SHIFT (30) | 49 | #define PTE_RPN_SHIFT (16) |
50 | #define PTE_RPN_SIZE (41) | ||
51 | |||
46 | /* | 52 | /* |
47 | * we support 16 fragments per PTE page of 64K size. | 53 | * we support 16 fragments per PTE page of 64K size. |
48 | */ | 54 | */ |
@@ -54,13 +60,12 @@ | |||
54 | #define PTE_FRAG_SIZE_SHIFT 12 | 60 | #define PTE_FRAG_SIZE_SHIFT 12 |
55 | #define PTE_FRAG_SIZE (1UL << PTE_FRAG_SIZE_SHIFT) | 61 | #define PTE_FRAG_SIZE (1UL << PTE_FRAG_SIZE_SHIFT) |
56 | 62 | ||
57 | /* | 63 | /* Bits to mask out from a PMD to get to the PTE page */ |
58 | * Bits to mask out from a PMD to get to the PTE page | 64 | #define PMD_MASKED_BITS 0xc0000000000000ffUL |
59 | * PMDs point to PTE table fragments which are PTE_FRAG_SIZE aligned. | 65 | /* Bits to mask out from a PUD to get to the PMD page */ |
60 | */ | 66 | #define PUD_MASKED_BITS 0xc0000000000000ffUL |
61 | #define PMD_MASKED_BITS (PTE_FRAG_SIZE - 1) | 67 | /* Bits to mask out from a PGD to get to the PUD page */ |
62 | /* Bits to mask out from a PGD/PUD to get to the PMD page */ | 68 | #define PGD_MASKED_BITS 0xc0000000000000ffUL |
63 | #define PUD_MASKED_BITS 0x1ff | ||
64 | 69 | ||
65 | #ifndef __ASSEMBLY__ | 70 | #ifndef __ASSEMBLY__ |
66 | 71 | ||
@@ -120,7 +125,7 @@ extern bool __rpte_sub_valid(real_pte_t rpte, unsigned long index); | |||
120 | (((pte) & _PAGE_COMBO)? MMU_PAGE_4K: MMU_PAGE_64K) | 125 | (((pte) & _PAGE_COMBO)? MMU_PAGE_4K: MMU_PAGE_64K) |
121 | 126 | ||
122 | #define remap_4k_pfn(vma, addr, pfn, prot) \ | 127 | #define remap_4k_pfn(vma, addr, pfn, prot) \ |
123 | (WARN_ON(((pfn) >= (1UL << (64 - PTE_RPN_SHIFT)))) ? -EINVAL : \ | 128 | (WARN_ON(((pfn) >= (1UL << PTE_RPN_SIZE))) ? -EINVAL : \ |
124 | remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \ | 129 | remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \ |
125 | __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN))) | 130 | __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN))) |
126 | 131 | ||
@@ -130,11 +135,9 @@ extern bool __rpte_sub_valid(real_pte_t rpte, unsigned long index); | |||
130 | #else | 135 | #else |
131 | #define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE) | 136 | #define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE) |
132 | #endif | 137 | #endif |
138 | #define PUD_TABLE_SIZE (sizeof(pud_t) << PUD_INDEX_SIZE) | ||
133 | #define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE) | 139 | #define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE) |
134 | 140 | ||
135 | #define pgd_pte(pgd) (pud_pte(((pud_t){ pgd }))) | ||
136 | #define pte_pgd(pte) ((pgd_t)pte_pud(pte)) | ||
137 | |||
138 | #ifdef CONFIG_HUGETLB_PAGE | 141 | #ifdef CONFIG_HUGETLB_PAGE |
139 | /* | 142 | /* |
140 | * We have PGD_INDEX_SIZ = 12 and PTE_INDEX_SIZE = 8, so that we can have | 143 | * We have PGD_INDEX_SIZ = 12 and PTE_INDEX_SIZE = 8, so that we can have |
@@ -208,30 +211,30 @@ static inline char *get_hpte_slot_array(pmd_t *pmdp) | |||
208 | /* | 211 | /* |
209 | * The linux hugepage PMD now include the pmd entries followed by the address | 212 | * The linux hugepage PMD now include the pmd entries followed by the address |
210 | * to the stashed pgtable_t. The stashed pgtable_t contains the hpte bits. | 213 | * to the stashed pgtable_t. The stashed pgtable_t contains the hpte bits. |
211 | * [ 1 bit secondary | 3 bit hidx | 1 bit valid | 000]. We use one byte per | 214 | * [ 000 | 1 bit secondary | 3 bit hidx | 1 bit valid]. We use one byte per |
212 | * each HPTE entry. With 16MB hugepage and 64K HPTE we need 256 entries and | 215 | * each HPTE entry. With 16MB hugepage and 64K HPTE we need 256 entries and |
213 | * with 4K HPTE we need 4096 entries. Both will fit in a 4K pgtable_t. | 216 | * with 4K HPTE we need 4096 entries. Both will fit in a 4K pgtable_t. |
214 | * | 217 | * |
215 | * The last three bits are intentionally left to zero. This memory location | 218 | * The top three bits are intentionally left as zero. This memory location |
216 | * are also used as normal page PTE pointers. So if we have any pointers | 219 | * are also used as normal page PTE pointers. So if we have any pointers |
217 | * left around while we collapse a hugepage, we need to make sure | 220 | * left around while we collapse a hugepage, we need to make sure |
218 | * _PAGE_PRESENT bit of that is zero when we look at them | 221 | * _PAGE_PRESENT bit of that is zero when we look at them |
219 | */ | 222 | */ |
220 | static inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index) | 223 | static inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index) |
221 | { | 224 | { |
222 | return (hpte_slot_array[index] >> 3) & 0x1; | 225 | return hpte_slot_array[index] & 0x1; |
223 | } | 226 | } |
224 | 227 | ||
225 | static inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array, | 228 | static inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array, |
226 | int index) | 229 | int index) |
227 | { | 230 | { |
228 | return hpte_slot_array[index] >> 4; | 231 | return hpte_slot_array[index] >> 1; |
229 | } | 232 | } |
230 | 233 | ||
231 | static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array, | 234 | static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array, |
232 | unsigned int index, unsigned int hidx) | 235 | unsigned int index, unsigned int hidx) |
233 | { | 236 | { |
234 | hpte_slot_array[index] = hidx << 4 | 0x1 << 3; | 237 | hpte_slot_array[index] = (hidx << 1) | 0x1; |
235 | } | 238 | } |
236 | 239 | ||
237 | /* | 240 | /* |
diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 8d1c8162f0c1..d0ee6fcef823 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h | |||
@@ -4,8 +4,7 @@ | |||
4 | 4 | ||
5 | /* | 5 | /* |
6 | * Common bits between 4K and 64K pages in a linux-style PTE. | 6 | * Common bits between 4K and 64K pages in a linux-style PTE. |
7 | * These match the bits in the (hardware-defined) PowerPC PTE as closely | 7 | * Additional bits may be defined in pgtable-hash64-*.h |
8 | * as possible. Additional bits may be defined in pgtable-hash64-*.h | ||
9 | * | 8 | * |
10 | * Note: We only support user read/write permissions. Supervisor always | 9 | * Note: We only support user read/write permissions. Supervisor always |
11 | * have full read/write to pages above PAGE_OFFSET (pages below that | 10 | * have full read/write to pages above PAGE_OFFSET (pages below that |
@@ -14,32 +13,35 @@ | |||
14 | * We could create separate kernel read-only if we used the 3 PP bits | 13 | * We could create separate kernel read-only if we used the 3 PP bits |
15 | * combinations that newer processors provide but we currently don't. | 14 | * combinations that newer processors provide but we currently don't. |
16 | */ | 15 | */ |
17 | #define _PAGE_PTE 0x00001 | 16 | #define _PAGE_BIT_SWAP_TYPE 0 |
18 | #define _PAGE_PRESENT 0x00002 /* software: pte contains a translation */ | 17 | |
19 | #define _PAGE_BIT_SWAP_TYPE 2 | 18 | #define _PAGE_EXEC 0x00001 /* execute permission */ |
20 | #define _PAGE_USER 0x00004 /* matches one of the PP bits */ | 19 | #define _PAGE_RW 0x00002 /* read & write access allowed */ |
21 | #define _PAGE_EXEC 0x00008 /* No execute on POWER4 and newer (we invert) */ | 20 | #define _PAGE_READ 0x00004 /* read access allowed */ |
22 | #define _PAGE_GUARDED 0x00010 | 21 | #define _PAGE_USER 0x00008 /* page may be accessed by userspace */ |
23 | /* We can derive Memory coherence from _PAGE_NO_CACHE */ | 22 | #define _PAGE_GUARDED 0x00010 /* G: guarded (side-effect) page */ |
23 | /* M (memory coherence) is always set in the HPTE, so we don't need it here */ | ||
24 | #define _PAGE_COHERENT 0x0 | 24 | #define _PAGE_COHERENT 0x0 |
25 | #define _PAGE_NO_CACHE 0x00020 /* I: cache inhibit */ | 25 | #define _PAGE_NO_CACHE 0x00020 /* I: cache inhibit */ |
26 | #define _PAGE_WRITETHRU 0x00040 /* W: cache write-through */ | 26 | #define _PAGE_WRITETHRU 0x00040 /* W: cache write-through */ |
27 | #define _PAGE_DIRTY 0x00080 /* C: page changed */ | 27 | #define _PAGE_DIRTY 0x00080 /* C: page changed */ |
28 | #define _PAGE_ACCESSED 0x00100 /* R: page referenced */ | 28 | #define _PAGE_ACCESSED 0x00100 /* R: page referenced */ |
29 | #define _PAGE_RW 0x00200 /* software: user write access allowed */ | 29 | #define _PAGE_SPECIAL 0x00400 /* software: special page */ |
30 | #define _PAGE_HASHPTE 0x00400 /* software: pte has an associated HPTE */ | ||
31 | #define _PAGE_BUSY 0x00800 /* software: PTE & hash are busy */ | 30 | #define _PAGE_BUSY 0x00800 /* software: PTE & hash are busy */ |
32 | #define _PAGE_F_GIX 0x07000 /* full page: hidx bits */ | ||
33 | #define _PAGE_F_GIX_SHIFT 12 | ||
34 | #define _PAGE_F_SECOND 0x08000 /* Whether to use secondary hash or not */ | ||
35 | #define _PAGE_SPECIAL 0x10000 /* software: special page */ | ||
36 | 31 | ||
37 | #ifdef CONFIG_MEM_SOFT_DIRTY | 32 | #ifdef CONFIG_MEM_SOFT_DIRTY |
38 | #define _PAGE_SOFT_DIRTY 0x20000 /* software: software dirty tracking */ | 33 | #define _PAGE_SOFT_DIRTY 0x200 /* software: software dirty tracking */ |
39 | #else | 34 | #else |
40 | #define _PAGE_SOFT_DIRTY 0x00000 | 35 | #define _PAGE_SOFT_DIRTY 0x000 |
41 | #endif | 36 | #endif |
42 | 37 | ||
38 | #define _PAGE_F_GIX_SHIFT 57 | ||
39 | #define _PAGE_F_GIX (7ul << 57) /* HPTE index within HPTEG */ | ||
40 | #define _PAGE_F_SECOND (1ul << 60) /* HPTE is in 2ndary HPTEG */ | ||
41 | #define _PAGE_HASHPTE (1ul << 61) /* PTE has associated HPTE */ | ||
42 | #define _PAGE_PTE (1ul << 62) /* distinguishes PTEs from pointers */ | ||
43 | #define _PAGE_PRESENT (1ul << 63) /* pte contains a translation */ | ||
44 | |||
43 | /* | 45 | /* |
44 | * We need to differentiate between explicit huge page and THP huge | 46 | * We need to differentiate between explicit huge page and THP huge |
45 | * page, since THP huge page also need to track real subpage details | 47 | * page, since THP huge page also need to track real subpage details |
@@ -132,7 +134,7 @@ | |||
132 | * The mask convered by the RPN must be a ULL on 32-bit platforms with | 134 | * The mask convered by the RPN must be a ULL on 32-bit platforms with |
133 | * 64-bit PTEs | 135 | * 64-bit PTEs |
134 | */ | 136 | */ |
135 | #define PTE_RPN_MASK (~((1UL << PTE_RPN_SHIFT) - 1)) | 137 | #define PTE_RPN_MASK (((1UL << PTE_RPN_SIZE) - 1) << PTE_RPN_SHIFT) |
136 | /* | 138 | /* |
137 | * _PAGE_CHG_MASK masks of bits that are to be preserved across | 139 | * _PAGE_CHG_MASK masks of bits that are to be preserved across |
138 | * pgprot changes | 140 | * pgprot changes |
@@ -223,15 +225,17 @@ | |||
223 | #define PUD_BAD_BITS (PMD_TABLE_SIZE-1) | 225 | #define PUD_BAD_BITS (PMD_TABLE_SIZE-1) |
224 | 226 | ||
225 | #ifndef __ASSEMBLY__ | 227 | #ifndef __ASSEMBLY__ |
226 | #define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \ | 228 | #define pmd_bad(pmd) (pmd_val(pmd) & PMD_BAD_BITS) |
227 | || (pmd_val(pmd) & PMD_BAD_BITS)) | 229 | #define pmd_page_vaddr(pmd) __va(pmd_val(pmd) & ~PMD_MASKED_BITS) |
228 | #define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS) | 230 | |
231 | #define pud_bad(pud) (pud_val(pud) & PUD_BAD_BITS) | ||
232 | #define pud_page_vaddr(pud) __va(pud_val(pud) & ~PUD_MASKED_BITS) | ||
229 | 233 | ||
230 | #define pud_bad(pud) (!is_kernel_addr(pud_val(pud)) \ | 234 | /* Pointers in the page table tree are physical addresses */ |
231 | || (pud_val(pud) & PUD_BAD_BITS)) | 235 | #define __pgtable_ptr_val(ptr) __pa(ptr) |
232 | #define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS) | ||
233 | 236 | ||
234 | #define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1)) | 237 | #define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1)) |
238 | #define pud_index(address) (((address) >> (PUD_SHIFT)) & (PTRS_PER_PUD - 1)) | ||
235 | #define pmd_index(address) (((address) >> (PMD_SHIFT)) & (PTRS_PER_PMD - 1)) | 239 | #define pmd_index(address) (((address) >> (PMD_SHIFT)) & (PTRS_PER_PMD - 1)) |
236 | #define pte_index(address) (((address) >> (PAGE_SHIFT)) & (PTRS_PER_PTE - 1)) | 240 | #define pte_index(address) (((address) >> (PAGE_SHIFT)) & (PTRS_PER_PTE - 1)) |
237 | 241 | ||
@@ -360,8 +364,18 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) | |||
360 | :"cc"); | 364 | :"cc"); |
361 | } | 365 | } |
362 | 366 | ||
367 | static inline int pgd_bad(pgd_t pgd) | ||
368 | { | ||
369 | return (pgd_val(pgd) == 0); | ||
370 | } | ||
371 | |||
363 | #define __HAVE_ARCH_PTE_SAME | 372 | #define __HAVE_ARCH_PTE_SAME |
364 | #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0) | 373 | #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0) |
374 | static inline unsigned long pgd_page_vaddr(pgd_t pgd) | ||
375 | { | ||
376 | return (unsigned long)__va(pgd_val(pgd) & ~PGD_MASKED_BITS); | ||
377 | } | ||
378 | |||
365 | 379 | ||
366 | /* Generic accessors to PTE bits */ | 380 | /* Generic accessors to PTE bits */ |
367 | static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & _PAGE_RW);} | 381 | static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & _PAGE_RW);} |
@@ -402,7 +416,7 @@ static inline int pte_protnone(pte_t pte) | |||
402 | 416 | ||
403 | static inline int pte_present(pte_t pte) | 417 | static inline int pte_present(pte_t pte) |
404 | { | 418 | { |
405 | return pte_val(pte) & _PAGE_PRESENT; | 419 | return !!(pte_val(pte) & _PAGE_PRESENT); |
406 | } | 420 | } |
407 | 421 | ||
408 | /* Conversion functions: convert a page and protection to a page entry, | 422 | /* Conversion functions: convert a page and protection to a page entry, |
@@ -413,13 +427,13 @@ static inline int pte_present(pte_t pte) | |||
413 | */ | 427 | */ |
414 | static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) | 428 | static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) |
415 | { | 429 | { |
416 | return __pte(((pte_basic_t)(pfn) << PTE_RPN_SHIFT) | | 430 | return __pte((((pte_basic_t)(pfn) << PTE_RPN_SHIFT) & PTE_RPN_MASK) | |
417 | pgprot_val(pgprot)); | 431 | pgprot_val(pgprot)); |
418 | } | 432 | } |
419 | 433 | ||
420 | static inline unsigned long pte_pfn(pte_t pte) | 434 | static inline unsigned long pte_pfn(pte_t pte) |
421 | { | 435 | { |
422 | return pte_val(pte) >> PTE_RPN_SHIFT; | 436 | return (pte_val(pte) & PTE_RPN_MASK) >> PTE_RPN_SHIFT; |
423 | } | 437 | } |
424 | 438 | ||
425 | /* Generic modifiers for PTE bits */ | 439 | /* Generic modifiers for PTE bits */ |
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h index 7352d3f212df..0cea4807e26f 100644 --- a/arch/powerpc/include/asm/mmu-hash64.h +++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h | |||
@@ -114,6 +114,7 @@ | |||
114 | 114 | ||
115 | #define POWER7_TLB_SETS 128 /* # sets in POWER7 TLB */ | 115 | #define POWER7_TLB_SETS 128 /* # sets in POWER7 TLB */ |
116 | #define POWER8_TLB_SETS 512 /* # sets in POWER8 TLB */ | 116 | #define POWER8_TLB_SETS 512 /* # sets in POWER8 TLB */ |
117 | #define POWER9_TLB_SETS_HASH 256 /* # sets in POWER9 TLB Hash mode */ | ||
117 | 118 | ||
118 | #ifndef __ASSEMBLY__ | 119 | #ifndef __ASSEMBLY__ |
119 | 120 | ||
@@ -607,6 +608,9 @@ static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize) | |||
607 | context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1; | 608 | context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1; |
608 | return get_vsid(context, ea, ssize); | 609 | return get_vsid(context, ea, ssize); |
609 | } | 610 | } |
611 | |||
612 | unsigned htab_shift_for_mem_size(unsigned long mem_size); | ||
613 | |||
610 | #endif /* __ASSEMBLY__ */ | 614 | #endif /* __ASSEMBLY__ */ |
611 | 615 | ||
612 | #endif /* _ASM_POWERPC_MMU_HASH64_H_ */ | 616 | #endif /* _ASM_POWERPC_MMU_HASH64_H_ */ |
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index ac07a30a7934..77d3ce05798e 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h | |||
@@ -43,13 +43,8 @@ | |||
43 | */ | 43 | */ |
44 | #ifndef __real_pte | 44 | #ifndef __real_pte |
45 | 45 | ||
46 | #ifdef CONFIG_STRICT_MM_TYPECHECKS | ||
47 | #define __real_pte(e,p) ((real_pte_t){(e)}) | 46 | #define __real_pte(e,p) ((real_pte_t){(e)}) |
48 | #define __rpte_to_pte(r) ((r).pte) | 47 | #define __rpte_to_pte(r) ((r).pte) |
49 | #else | ||
50 | #define __real_pte(e,p) (e) | ||
51 | #define __rpte_to_pte(r) (__pte(r)) | ||
52 | #endif | ||
53 | #define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >>_PAGE_F_GIX_SHIFT) | 48 | #define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >>_PAGE_F_GIX_SHIFT) |
54 | 49 | ||
55 | #define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ | 50 | #define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ |
@@ -111,6 +106,26 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val) | |||
111 | *pgdp = __pgd(val); | 106 | *pgdp = __pgd(val); |
112 | } | 107 | } |
113 | 108 | ||
109 | static inline void pgd_clear(pgd_t *pgdp) | ||
110 | { | ||
111 | *pgdp = __pgd(0); | ||
112 | } | ||
113 | |||
114 | #define pgd_none(pgd) (!pgd_val(pgd)) | ||
115 | #define pgd_present(pgd) (!pgd_none(pgd)) | ||
116 | |||
117 | static inline pte_t pgd_pte(pgd_t pgd) | ||
118 | { | ||
119 | return __pte(pgd_val(pgd)); | ||
120 | } | ||
121 | |||
122 | static inline pgd_t pte_pgd(pte_t pte) | ||
123 | { | ||
124 | return __pgd(pte_val(pte)); | ||
125 | } | ||
126 | |||
127 | extern struct page *pgd_page(pgd_t pgd); | ||
128 | |||
114 | /* | 129 | /* |
115 | * Find an entry in a page-table-directory. We combine the address region | 130 | * Find an entry in a page-table-directory. We combine the address region |
116 | * (the high order N bits) and the pgd portion of the address. | 131 | * (the high order N bits) and the pgd portion of the address. |
@@ -118,9 +133,10 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val) | |||
118 | 133 | ||
119 | #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) | 134 | #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) |
120 | 135 | ||
136 | #define pud_offset(pgdp, addr) \ | ||
137 | (((pud_t *) pgd_page_vaddr(*(pgdp))) + pud_index(addr)) | ||
121 | #define pmd_offset(pudp,addr) \ | 138 | #define pmd_offset(pudp,addr) \ |
122 | (((pmd_t *) pud_page_vaddr(*(pudp))) + pmd_index(addr)) | 139 | (((pmd_t *) pud_page_vaddr(*(pudp))) + pmd_index(addr)) |
123 | |||
124 | #define pte_offset_kernel(dir,addr) \ | 140 | #define pte_offset_kernel(dir,addr) \ |
125 | (((pte_t *) pmd_page_vaddr(*(dir))) + pte_index(addr)) | 141 | (((pte_t *) pmd_page_vaddr(*(dir))) + pte_index(addr)) |
126 | 142 | ||
@@ -135,6 +151,8 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val) | |||
135 | pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) | 151 | pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) |
136 | #define pmd_ERROR(e) \ | 152 | #define pmd_ERROR(e) \ |
137 | pr_err("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) | 153 | pr_err("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) |
154 | #define pud_ERROR(e) \ | ||
155 | pr_err("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e)) | ||
138 | #define pgd_ERROR(e) \ | 156 | #define pgd_ERROR(e) \ |
139 | pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) | 157 | pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) |
140 | 158 | ||
@@ -154,10 +172,10 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val) | |||
154 | #define SWP_TYPE_BITS 5 | 172 | #define SWP_TYPE_BITS 5 |
155 | #define __swp_type(x) (((x).val >> _PAGE_BIT_SWAP_TYPE) \ | 173 | #define __swp_type(x) (((x).val >> _PAGE_BIT_SWAP_TYPE) \ |
156 | & ((1UL << SWP_TYPE_BITS) - 1)) | 174 | & ((1UL << SWP_TYPE_BITS) - 1)) |
157 | #define __swp_offset(x) ((x).val >> PTE_RPN_SHIFT) | 175 | #define __swp_offset(x) (((x).val & PTE_RPN_MASK) >> PTE_RPN_SHIFT) |
158 | #define __swp_entry(type, offset) ((swp_entry_t) { \ | 176 | #define __swp_entry(type, offset) ((swp_entry_t) { \ |
159 | ((type) << _PAGE_BIT_SWAP_TYPE) \ | 177 | ((type) << _PAGE_BIT_SWAP_TYPE) \ |
160 | | ((offset) << PTE_RPN_SHIFT) }) | 178 | | (((offset) << PTE_RPN_SHIFT) & PTE_RPN_MASK)}) |
161 | /* | 179 | /* |
162 | * swp_entry_t must be independent of pte bits. We build a swp_entry_t from | 180 | * swp_entry_t must be independent of pte bits. We build a swp_entry_t from |
163 | * swap type and offset we get from swap and convert that to pte to find a | 181 | * swap type and offset we get from swap and convert that to pte to find a |
diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h new file mode 100644 index 000000000000..1b753f96b374 --- /dev/null +++ b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h | |||
@@ -0,0 +1,94 @@ | |||
1 | #ifndef _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H | ||
2 | #define _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H | ||
3 | |||
4 | #define MMU_NO_CONTEXT 0 | ||
5 | |||
6 | /* | ||
7 | * TLB flushing for 64-bit hash-MMU CPUs | ||
8 | */ | ||
9 | |||
10 | #include <linux/percpu.h> | ||
11 | #include <asm/page.h> | ||
12 | |||
13 | #define PPC64_TLB_BATCH_NR 192 | ||
14 | |||
15 | struct ppc64_tlb_batch { | ||
16 | int active; | ||
17 | unsigned long index; | ||
18 | struct mm_struct *mm; | ||
19 | real_pte_t pte[PPC64_TLB_BATCH_NR]; | ||
20 | unsigned long vpn[PPC64_TLB_BATCH_NR]; | ||
21 | unsigned int psize; | ||
22 | int ssize; | ||
23 | }; | ||
24 | DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); | ||
25 | |||
26 | extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch); | ||
27 | |||
28 | #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE | ||
29 | |||
30 | static inline void arch_enter_lazy_mmu_mode(void) | ||
31 | { | ||
32 | struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch); | ||
33 | |||
34 | batch->active = 1; | ||
35 | } | ||
36 | |||
37 | static inline void arch_leave_lazy_mmu_mode(void) | ||
38 | { | ||
39 | struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch); | ||
40 | |||
41 | if (batch->index) | ||
42 | __flush_tlb_pending(batch); | ||
43 | batch->active = 0; | ||
44 | } | ||
45 | |||
46 | #define arch_flush_lazy_mmu_mode() do {} while (0) | ||
47 | |||
48 | |||
49 | extern void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, | ||
50 | int ssize, unsigned long flags); | ||
51 | extern void flush_hash_range(unsigned long number, int local); | ||
52 | extern void flush_hash_hugepage(unsigned long vsid, unsigned long addr, | ||
53 | pmd_t *pmdp, unsigned int psize, int ssize, | ||
54 | unsigned long flags); | ||
55 | |||
56 | static inline void local_flush_tlb_mm(struct mm_struct *mm) | ||
57 | { | ||
58 | } | ||
59 | |||
60 | static inline void flush_tlb_mm(struct mm_struct *mm) | ||
61 | { | ||
62 | } | ||
63 | |||
64 | static inline void local_flush_tlb_page(struct vm_area_struct *vma, | ||
65 | unsigned long vmaddr) | ||
66 | { | ||
67 | } | ||
68 | |||
69 | static inline void flush_tlb_page(struct vm_area_struct *vma, | ||
70 | unsigned long vmaddr) | ||
71 | { | ||
72 | } | ||
73 | |||
74 | static inline void flush_tlb_page_nohash(struct vm_area_struct *vma, | ||
75 | unsigned long vmaddr) | ||
76 | { | ||
77 | } | ||
78 | |||
79 | static inline void flush_tlb_range(struct vm_area_struct *vma, | ||
80 | unsigned long start, unsigned long end) | ||
81 | { | ||
82 | } | ||
83 | |||
84 | static inline void flush_tlb_kernel_range(unsigned long start, | ||
85 | unsigned long end) | ||
86 | { | ||
87 | } | ||
88 | |||
89 | /* Private function for use by PCI IO mapping code */ | ||
90 | extern void __flush_hash_table_range(struct mm_struct *mm, unsigned long start, | ||
91 | unsigned long end); | ||
92 | extern void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd, | ||
93 | unsigned long addr); | ||
94 | #endif /* _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H */ | ||
diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h index 5f8229e24fe6..ffbafbf76b19 100644 --- a/arch/powerpc/include/asm/cache.h +++ b/arch/powerpc/include/asm/cache.h | |||
@@ -69,6 +69,25 @@ extern void _set_L3CR(unsigned long); | |||
69 | #define _set_L3CR(val) do { } while(0) | 69 | #define _set_L3CR(val) do { } while(0) |
70 | #endif | 70 | #endif |
71 | 71 | ||
72 | static inline void dcbz(void *addr) | ||
73 | { | ||
74 | __asm__ __volatile__ ("dcbz 0, %0" : : "r"(addr) : "memory"); | ||
75 | } | ||
76 | |||
77 | static inline void dcbi(void *addr) | ||
78 | { | ||
79 | __asm__ __volatile__ ("dcbi 0, %0" : : "r"(addr) : "memory"); | ||
80 | } | ||
81 | |||
82 | static inline void dcbf(void *addr) | ||
83 | { | ||
84 | __asm__ __volatile__ ("dcbf 0, %0" : : "r"(addr) : "memory"); | ||
85 | } | ||
86 | |||
87 | static inline void dcbst(void *addr) | ||
88 | { | ||
89 | __asm__ __volatile__ ("dcbst 0, %0" : : "r"(addr) : "memory"); | ||
90 | } | ||
72 | #endif /* !__ASSEMBLY__ */ | 91 | #endif /* !__ASSEMBLY__ */ |
73 | #endif /* __KERNEL__ */ | 92 | #endif /* __KERNEL__ */ |
74 | #endif /* _ASM_POWERPC_CACHE_H */ | 93 | #endif /* _ASM_POWERPC_CACHE_H */ |
diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 6229e6b6037b..69fb16d7a811 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h | |||
@@ -30,8 +30,6 @@ extern void flush_dcache_page(struct page *page); | |||
30 | #define flush_dcache_mmap_lock(mapping) do { } while (0) | 30 | #define flush_dcache_mmap_lock(mapping) do { } while (0) |
31 | #define flush_dcache_mmap_unlock(mapping) do { } while (0) | 31 | #define flush_dcache_mmap_unlock(mapping) do { } while (0) |
32 | 32 | ||
33 | extern void __flush_disable_L1(void); | ||
34 | |||
35 | extern void flush_icache_range(unsigned long, unsigned long); | 33 | extern void flush_icache_range(unsigned long, unsigned long); |
36 | extern void flush_icache_user_range(struct vm_area_struct *vma, | 34 | extern void flush_icache_user_range(struct vm_area_struct *vma, |
37 | struct page *page, unsigned long addr, | 35 | struct page *page, unsigned long addr, |
@@ -47,12 +45,58 @@ static inline void __flush_dcache_icache_phys(unsigned long physaddr) | |||
47 | } | 45 | } |
48 | #endif | 46 | #endif |
49 | 47 | ||
50 | extern void flush_dcache_range(unsigned long start, unsigned long stop); | ||
51 | #ifdef CONFIG_PPC32 | 48 | #ifdef CONFIG_PPC32 |
52 | extern void clean_dcache_range(unsigned long start, unsigned long stop); | 49 | /* |
53 | extern void invalidate_dcache_range(unsigned long start, unsigned long stop); | 50 | * Write any modified data cache blocks out to memory and invalidate them. |
51 | * Does not invalidate the corresponding instruction cache blocks. | ||
52 | */ | ||
53 | static inline void flush_dcache_range(unsigned long start, unsigned long stop) | ||
54 | { | ||
55 | void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1)); | ||
56 | unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1); | ||
57 | unsigned long i; | ||
58 | |||
59 | for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES) | ||
60 | dcbf(addr); | ||
61 | mb(); /* sync */ | ||
62 | } | ||
63 | |||
64 | /* | ||
65 | * Write any modified data cache blocks out to memory. | ||
66 | * Does not invalidate the corresponding cache lines (especially for | ||
67 | * any corresponding instruction cache). | ||
68 | */ | ||
69 | static inline void clean_dcache_range(unsigned long start, unsigned long stop) | ||
70 | { | ||
71 | void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1)); | ||
72 | unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1); | ||
73 | unsigned long i; | ||
74 | |||
75 | for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES) | ||
76 | dcbst(addr); | ||
77 | mb(); /* sync */ | ||
78 | } | ||
79 | |||
80 | /* | ||
81 | * Like above, but invalidate the D-cache. This is used by the 8xx | ||
82 | * to invalidate the cache so the PPC core doesn't get stale data | ||
83 | * from the CPM (no cache snooping here :-). | ||
84 | */ | ||
85 | static inline void invalidate_dcache_range(unsigned long start, | ||
86 | unsigned long stop) | ||
87 | { | ||
88 | void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1)); | ||
89 | unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1); | ||
90 | unsigned long i; | ||
91 | |||
92 | for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES) | ||
93 | dcbi(addr); | ||
94 | mb(); /* sync */ | ||
95 | } | ||
96 | |||
54 | #endif /* CONFIG_PPC32 */ | 97 | #endif /* CONFIG_PPC32 */ |
55 | #ifdef CONFIG_PPC64 | 98 | #ifdef CONFIG_PPC64 |
99 | extern void flush_dcache_range(unsigned long start, unsigned long stop); | ||
56 | extern void flush_inval_dcache_range(unsigned long start, unsigned long stop); | 100 | extern void flush_inval_dcache_range(unsigned long start, unsigned long stop); |
57 | extern void flush_dcache_phys_range(unsigned long start, unsigned long stop); | 101 | extern void flush_dcache_phys_range(unsigned long start, unsigned long stop); |
58 | #endif | 102 | #endif |
diff --git a/arch/powerpc/include/asm/checksum.h b/arch/powerpc/include/asm/checksum.h index e8d9ef4755a4..ee655ed1ff1b 100644 --- a/arch/powerpc/include/asm/checksum.h +++ b/arch/powerpc/include/asm/checksum.h | |||
@@ -9,30 +9,9 @@ | |||
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | /* | ||
13 | * This is a version of ip_compute_csum() optimized for IP headers, | ||
14 | * which always checksum on 4 octet boundaries. ihl is the number | ||
15 | * of 32-bit words and is always >= 5. | ||
16 | */ | ||
17 | #ifdef CONFIG_GENERIC_CSUM | 12 | #ifdef CONFIG_GENERIC_CSUM |
18 | #include <asm-generic/checksum.h> | 13 | #include <asm-generic/checksum.h> |
19 | #else | 14 | #else |
20 | extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl); | ||
21 | |||
22 | /* | ||
23 | * computes the checksum of a memory block at buff, length len, | ||
24 | * and adds in "sum" (32-bit) | ||
25 | * | ||
26 | * returns a 32-bit number suitable for feeding into itself | ||
27 | * or csum_tcpudp_magic | ||
28 | * | ||
29 | * this function must be called with even lengths, except | ||
30 | * for the last fragment, which may be odd | ||
31 | * | ||
32 | * it's best to have buff aligned on a 32-bit boundary | ||
33 | */ | ||
34 | extern __wsum csum_partial(const void *buff, int len, __wsum sum); | ||
35 | |||
36 | /* | 15 | /* |
37 | * Computes the checksum of a memory block at src, length len, | 16 | * Computes the checksum of a memory block at src, length len, |
38 | * and adds in "sum" (32-bit), while copying the block to dst. | 17 | * and adds in "sum" (32-bit), while copying the block to dst. |
@@ -47,21 +26,12 @@ extern __wsum csum_partial_copy_generic(const void *src, void *dst, | |||
47 | int len, __wsum sum, | 26 | int len, __wsum sum, |
48 | int *src_err, int *dst_err); | 27 | int *src_err, int *dst_err); |
49 | 28 | ||
50 | #ifdef __powerpc64__ | ||
51 | #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER | 29 | #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER |
52 | extern __wsum csum_and_copy_from_user(const void __user *src, void *dst, | 30 | extern __wsum csum_and_copy_from_user(const void __user *src, void *dst, |
53 | int len, __wsum sum, int *err_ptr); | 31 | int len, __wsum sum, int *err_ptr); |
54 | #define HAVE_CSUM_COPY_USER | 32 | #define HAVE_CSUM_COPY_USER |
55 | extern __wsum csum_and_copy_to_user(const void *src, void __user *dst, | 33 | extern __wsum csum_and_copy_to_user(const void *src, void __user *dst, |
56 | int len, __wsum sum, int *err_ptr); | 34 | int len, __wsum sum, int *err_ptr); |
57 | #else | ||
58 | /* | ||
59 | * the same as csum_partial, but copies from src to dst while it | ||
60 | * checksums. | ||
61 | */ | ||
62 | #define csum_partial_copy_from_user(src, dst, len, sum, errp) \ | ||
63 | csum_partial_copy_generic((__force const void *)(src), (dst), (len), (sum), (errp), NULL) | ||
64 | #endif | ||
65 | 35 | ||
66 | #define csum_partial_copy_nocheck(src, dst, len, sum) \ | 36 | #define csum_partial_copy_nocheck(src, dst, len, sum) \ |
67 | csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL) | 37 | csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL) |
@@ -83,15 +53,6 @@ static inline __sum16 csum_fold(__wsum sum) | |||
83 | return (__force __sum16)(~((__force u32)sum + tmp) >> 16); | 53 | return (__force __sum16)(~((__force u32)sum + tmp) >> 16); |
84 | } | 54 | } |
85 | 55 | ||
86 | /* | ||
87 | * this routine is used for miscellaneous IP-like checksums, mainly | ||
88 | * in icmp.c | ||
89 | */ | ||
90 | static inline __sum16 ip_compute_csum(const void *buff, int len) | ||
91 | { | ||
92 | return csum_fold(csum_partial(buff, len, 0)); | ||
93 | } | ||
94 | |||
95 | static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, | 56 | static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, |
96 | unsigned short len, | 57 | unsigned short len, |
97 | unsigned short proto, | 58 | unsigned short proto, |
@@ -135,17 +96,117 @@ static inline __wsum csum_add(__wsum csum, __wsum addend) | |||
135 | { | 96 | { |
136 | #ifdef __powerpc64__ | 97 | #ifdef __powerpc64__ |
137 | u64 res = (__force u64)csum; | 98 | u64 res = (__force u64)csum; |
99 | #endif | ||
100 | if (__builtin_constant_p(csum) && csum == 0) | ||
101 | return addend; | ||
102 | if (__builtin_constant_p(addend) && addend == 0) | ||
103 | return csum; | ||
138 | 104 | ||
105 | #ifdef __powerpc64__ | ||
139 | res += (__force u64)addend; | 106 | res += (__force u64)addend; |
140 | return (__force __wsum)((u32)res + (res >> 32)); | 107 | return (__force __wsum)((u32)res + (res >> 32)); |
141 | #else | 108 | #else |
142 | asm("addc %0,%0,%1;" | 109 | asm("addc %0,%0,%1;" |
143 | "addze %0,%0;" | 110 | "addze %0,%0;" |
144 | : "+r" (csum) : "r" (addend)); | 111 | : "+r" (csum) : "r" (addend) : "xer"); |
145 | return csum; | 112 | return csum; |
146 | #endif | 113 | #endif |
147 | } | 114 | } |
148 | 115 | ||
116 | /* | ||
117 | * This is a version of ip_compute_csum() optimized for IP headers, | ||
118 | * which always checksum on 4 octet boundaries. ihl is the number | ||
119 | * of 32-bit words and is always >= 5. | ||
120 | */ | ||
121 | static inline __wsum ip_fast_csum_nofold(const void *iph, unsigned int ihl) | ||
122 | { | ||
123 | const u32 *ptr = (const u32 *)iph + 1; | ||
124 | #ifdef __powerpc64__ | ||
125 | unsigned int i; | ||
126 | u64 s = *(const u32 *)iph; | ||
127 | |||
128 | for (i = 0; i < ihl - 1; i++, ptr++) | ||
129 | s += *ptr; | ||
130 | s += (s >> 32); | ||
131 | return (__force __wsum)s; | ||
132 | #else | ||
133 | __wsum sum, tmp; | ||
134 | |||
135 | asm("mtctr %3;" | ||
136 | "addc %0,%4,%5;" | ||
137 | "1: lwzu %1, 4(%2);" | ||
138 | "adde %0,%0,%1;" | ||
139 | "bdnz 1b;" | ||
140 | "addze %0,%0;" | ||
141 | : "=r" (sum), "=r" (tmp), "+b" (ptr) | ||
142 | : "r" (ihl - 2), "r" (*(const u32 *)iph), "r" (*ptr) | ||
143 | : "ctr", "xer", "memory"); | ||
144 | |||
145 | return sum; | ||
146 | #endif | ||
147 | } | ||
148 | |||
149 | static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) | ||
150 | { | ||
151 | return csum_fold(ip_fast_csum_nofold(iph, ihl)); | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * computes the checksum of a memory block at buff, length len, | ||
156 | * and adds in "sum" (32-bit) | ||
157 | * | ||
158 | * returns a 32-bit number suitable for feeding into itself | ||
159 | * or csum_tcpudp_magic | ||
160 | * | ||
161 | * this function must be called with even lengths, except | ||
162 | * for the last fragment, which may be odd | ||
163 | * | ||
164 | * it's best to have buff aligned on a 32-bit boundary | ||
165 | */ | ||
166 | __wsum __csum_partial(const void *buff, int len, __wsum sum); | ||
167 | |||
168 | static inline __wsum csum_partial(const void *buff, int len, __wsum sum) | ||
169 | { | ||
170 | if (__builtin_constant_p(len) && len <= 16 && (len & 1) == 0) { | ||
171 | if (len == 2) | ||
172 | sum = csum_add(sum, (__force __wsum)*(const u16 *)buff); | ||
173 | if (len >= 4) | ||
174 | sum = csum_add(sum, (__force __wsum)*(const u32 *)buff); | ||
175 | if (len == 6) | ||
176 | sum = csum_add(sum, (__force __wsum) | ||
177 | *(const u16 *)(buff + 4)); | ||
178 | if (len >= 8) | ||
179 | sum = csum_add(sum, (__force __wsum) | ||
180 | *(const u32 *)(buff + 4)); | ||
181 | if (len == 10) | ||
182 | sum = csum_add(sum, (__force __wsum) | ||
183 | *(const u16 *)(buff + 8)); | ||
184 | if (len >= 12) | ||
185 | sum = csum_add(sum, (__force __wsum) | ||
186 | *(const u32 *)(buff + 8)); | ||
187 | if (len == 14) | ||
188 | sum = csum_add(sum, (__force __wsum) | ||
189 | *(const u16 *)(buff + 12)); | ||
190 | if (len >= 16) | ||
191 | sum = csum_add(sum, (__force __wsum) | ||
192 | *(const u32 *)(buff + 12)); | ||
193 | } else if (__builtin_constant_p(len) && (len & 3) == 0) { | ||
194 | sum = csum_add(sum, ip_fast_csum_nofold(buff, len >> 2)); | ||
195 | } else { | ||
196 | sum = __csum_partial(buff, len, sum); | ||
197 | } | ||
198 | return sum; | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | * this routine is used for miscellaneous IP-like checksums, mainly | ||
203 | * in icmp.c | ||
204 | */ | ||
205 | static inline __sum16 ip_compute_csum(const void *buff, int len) | ||
206 | { | ||
207 | return csum_fold(csum_partial(buff, len, 0)); | ||
208 | } | ||
209 | |||
149 | #endif | 210 | #endif |
150 | #endif /* __KERNEL__ */ | 211 | #endif /* __KERNEL__ */ |
151 | #endif | 212 | #endif |
diff --git a/arch/powerpc/include/asm/cmpxchg.h b/arch/powerpc/include/asm/cmpxchg.h index d1a8d93cccfd..44efe739b6b9 100644 --- a/arch/powerpc/include/asm/cmpxchg.h +++ b/arch/powerpc/include/asm/cmpxchg.h | |||
@@ -5,25 +5,25 @@ | |||
5 | #include <linux/compiler.h> | 5 | #include <linux/compiler.h> |
6 | #include <asm/synch.h> | 6 | #include <asm/synch.h> |
7 | #include <asm/asm-compat.h> | 7 | #include <asm/asm-compat.h> |
8 | #include <linux/bug.h> | ||
8 | 9 | ||
9 | /* | 10 | /* |
10 | * Atomic exchange | 11 | * Atomic exchange |
11 | * | 12 | * |
12 | * Changes the memory location '*ptr' to be val and returns | 13 | * Changes the memory location '*p' to be val and returns |
13 | * the previous value stored there. | 14 | * the previous value stored there. |
14 | */ | 15 | */ |
16 | |||
15 | static __always_inline unsigned long | 17 | static __always_inline unsigned long |
16 | __xchg_u32(volatile void *p, unsigned long val) | 18 | __xchg_u32_local(volatile void *p, unsigned long val) |
17 | { | 19 | { |
18 | unsigned long prev; | 20 | unsigned long prev; |
19 | 21 | ||
20 | __asm__ __volatile__( | 22 | __asm__ __volatile__( |
21 | PPC_ATOMIC_ENTRY_BARRIER | ||
22 | "1: lwarx %0,0,%2 \n" | 23 | "1: lwarx %0,0,%2 \n" |
23 | PPC405_ERR77(0,%2) | 24 | PPC405_ERR77(0,%2) |
24 | " stwcx. %3,0,%2 \n\ | 25 | " stwcx. %3,0,%2 \n\ |
25 | bne- 1b" | 26 | bne- 1b" |
26 | PPC_ATOMIC_EXIT_BARRIER | ||
27 | : "=&r" (prev), "+m" (*(volatile unsigned int *)p) | 27 | : "=&r" (prev), "+m" (*(volatile unsigned int *)p) |
28 | : "r" (p), "r" (val) | 28 | : "r" (p), "r" (val) |
29 | : "cc", "memory"); | 29 | : "cc", "memory"); |
@@ -31,42 +31,34 @@ __xchg_u32(volatile void *p, unsigned long val) | |||
31 | return prev; | 31 | return prev; |
32 | } | 32 | } |
33 | 33 | ||
34 | /* | ||
35 | * Atomic exchange | ||
36 | * | ||
37 | * Changes the memory location '*ptr' to be val and returns | ||
38 | * the previous value stored there. | ||
39 | */ | ||
40 | static __always_inline unsigned long | 34 | static __always_inline unsigned long |
41 | __xchg_u32_local(volatile void *p, unsigned long val) | 35 | __xchg_u32_relaxed(u32 *p, unsigned long val) |
42 | { | 36 | { |
43 | unsigned long prev; | 37 | unsigned long prev; |
44 | 38 | ||
45 | __asm__ __volatile__( | 39 | __asm__ __volatile__( |
46 | "1: lwarx %0,0,%2 \n" | 40 | "1: lwarx %0,0,%2\n" |
47 | PPC405_ERR77(0,%2) | 41 | PPC405_ERR77(0, %2) |
48 | " stwcx. %3,0,%2 \n\ | 42 | " stwcx. %3,0,%2\n" |
49 | bne- 1b" | 43 | " bne- 1b" |
50 | : "=&r" (prev), "+m" (*(volatile unsigned int *)p) | 44 | : "=&r" (prev), "+m" (*p) |
51 | : "r" (p), "r" (val) | 45 | : "r" (p), "r" (val) |
52 | : "cc", "memory"); | 46 | : "cc"); |
53 | 47 | ||
54 | return prev; | 48 | return prev; |
55 | } | 49 | } |
56 | 50 | ||
57 | #ifdef CONFIG_PPC64 | 51 | #ifdef CONFIG_PPC64 |
58 | static __always_inline unsigned long | 52 | static __always_inline unsigned long |
59 | __xchg_u64(volatile void *p, unsigned long val) | 53 | __xchg_u64_local(volatile void *p, unsigned long val) |
60 | { | 54 | { |
61 | unsigned long prev; | 55 | unsigned long prev; |
62 | 56 | ||
63 | __asm__ __volatile__( | 57 | __asm__ __volatile__( |
64 | PPC_ATOMIC_ENTRY_BARRIER | ||
65 | "1: ldarx %0,0,%2 \n" | 58 | "1: ldarx %0,0,%2 \n" |
66 | PPC405_ERR77(0,%2) | 59 | PPC405_ERR77(0,%2) |
67 | " stdcx. %3,0,%2 \n\ | 60 | " stdcx. %3,0,%2 \n\ |
68 | bne- 1b" | 61 | bne- 1b" |
69 | PPC_ATOMIC_EXIT_BARRIER | ||
70 | : "=&r" (prev), "+m" (*(volatile unsigned long *)p) | 62 | : "=&r" (prev), "+m" (*(volatile unsigned long *)p) |
71 | : "r" (p), "r" (val) | 63 | : "r" (p), "r" (val) |
72 | : "cc", "memory"); | 64 | : "cc", "memory"); |
@@ -75,64 +67,52 @@ __xchg_u64(volatile void *p, unsigned long val) | |||
75 | } | 67 | } |
76 | 68 | ||
77 | static __always_inline unsigned long | 69 | static __always_inline unsigned long |
78 | __xchg_u64_local(volatile void *p, unsigned long val) | 70 | __xchg_u64_relaxed(u64 *p, unsigned long val) |
79 | { | 71 | { |
80 | unsigned long prev; | 72 | unsigned long prev; |
81 | 73 | ||
82 | __asm__ __volatile__( | 74 | __asm__ __volatile__( |
83 | "1: ldarx %0,0,%2 \n" | 75 | "1: ldarx %0,0,%2\n" |
84 | PPC405_ERR77(0,%2) | 76 | PPC405_ERR77(0, %2) |
85 | " stdcx. %3,0,%2 \n\ | 77 | " stdcx. %3,0,%2\n" |
86 | bne- 1b" | 78 | " bne- 1b" |
87 | : "=&r" (prev), "+m" (*(volatile unsigned long *)p) | 79 | : "=&r" (prev), "+m" (*p) |
88 | : "r" (p), "r" (val) | 80 | : "r" (p), "r" (val) |
89 | : "cc", "memory"); | 81 | : "cc"); |
90 | 82 | ||
91 | return prev; | 83 | return prev; |
92 | } | 84 | } |
93 | #endif | 85 | #endif |
94 | 86 | ||
95 | /* | ||
96 | * This function doesn't exist, so you'll get a linker error | ||
97 | * if something tries to do an invalid xchg(). | ||
98 | */ | ||
99 | extern void __xchg_called_with_bad_pointer(void); | ||
100 | |||
101 | static __always_inline unsigned long | 87 | static __always_inline unsigned long |
102 | __xchg(volatile void *ptr, unsigned long x, unsigned int size) | 88 | __xchg_local(volatile void *ptr, unsigned long x, unsigned int size) |
103 | { | 89 | { |
104 | switch (size) { | 90 | switch (size) { |
105 | case 4: | 91 | case 4: |
106 | return __xchg_u32(ptr, x); | 92 | return __xchg_u32_local(ptr, x); |
107 | #ifdef CONFIG_PPC64 | 93 | #ifdef CONFIG_PPC64 |
108 | case 8: | 94 | case 8: |
109 | return __xchg_u64(ptr, x); | 95 | return __xchg_u64_local(ptr, x); |
110 | #endif | 96 | #endif |
111 | } | 97 | } |
112 | __xchg_called_with_bad_pointer(); | 98 | BUILD_BUG_ON_MSG(1, "Unsupported size for __xchg"); |
113 | return x; | 99 | return x; |
114 | } | 100 | } |
115 | 101 | ||
116 | static __always_inline unsigned long | 102 | static __always_inline unsigned long |
117 | __xchg_local(volatile void *ptr, unsigned long x, unsigned int size) | 103 | __xchg_relaxed(void *ptr, unsigned long x, unsigned int size) |
118 | { | 104 | { |
119 | switch (size) { | 105 | switch (size) { |
120 | case 4: | 106 | case 4: |
121 | return __xchg_u32_local(ptr, x); | 107 | return __xchg_u32_relaxed(ptr, x); |
122 | #ifdef CONFIG_PPC64 | 108 | #ifdef CONFIG_PPC64 |
123 | case 8: | 109 | case 8: |
124 | return __xchg_u64_local(ptr, x); | 110 | return __xchg_u64_relaxed(ptr, x); |
125 | #endif | 111 | #endif |
126 | } | 112 | } |
127 | __xchg_called_with_bad_pointer(); | 113 | BUILD_BUG_ON_MSG(1, "Unsupported size for __xchg_local"); |
128 | return x; | 114 | return x; |
129 | } | 115 | } |
130 | #define xchg(ptr,x) \ | ||
131 | ({ \ | ||
132 | __typeof__(*(ptr)) _x_ = (x); \ | ||
133 | (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \ | ||
134 | }) | ||
135 | |||
136 | #define xchg_local(ptr,x) \ | 116 | #define xchg_local(ptr,x) \ |
137 | ({ \ | 117 | ({ \ |
138 | __typeof__(*(ptr)) _x_ = (x); \ | 118 | __typeof__(*(ptr)) _x_ = (x); \ |
@@ -140,6 +120,12 @@ __xchg_local(volatile void *ptr, unsigned long x, unsigned int size) | |||
140 | (unsigned long)_x_, sizeof(*(ptr))); \ | 120 | (unsigned long)_x_, sizeof(*(ptr))); \ |
141 | }) | 121 | }) |
142 | 122 | ||
123 | #define xchg_relaxed(ptr, x) \ | ||
124 | ({ \ | ||
125 | __typeof__(*(ptr)) _x_ = (x); \ | ||
126 | (__typeof__(*(ptr))) __xchg_relaxed((ptr), \ | ||
127 | (unsigned long)_x_, sizeof(*(ptr))); \ | ||
128 | }) | ||
143 | /* | 129 | /* |
144 | * Compare and exchange - if *p == old, set it to new, | 130 | * Compare and exchange - if *p == old, set it to new, |
145 | * and return the old value of *p. | 131 | * and return the old value of *p. |
@@ -190,6 +176,56 @@ __cmpxchg_u32_local(volatile unsigned int *p, unsigned long old, | |||
190 | return prev; | 176 | return prev; |
191 | } | 177 | } |
192 | 178 | ||
179 | static __always_inline unsigned long | ||
180 | __cmpxchg_u32_relaxed(u32 *p, unsigned long old, unsigned long new) | ||
181 | { | ||
182 | unsigned long prev; | ||
183 | |||
184 | __asm__ __volatile__ ( | ||
185 | "1: lwarx %0,0,%2 # __cmpxchg_u32_relaxed\n" | ||
186 | " cmpw 0,%0,%3\n" | ||
187 | " bne- 2f\n" | ||
188 | PPC405_ERR77(0, %2) | ||
189 | " stwcx. %4,0,%2\n" | ||
190 | " bne- 1b\n" | ||
191 | "2:" | ||
192 | : "=&r" (prev), "+m" (*p) | ||
193 | : "r" (p), "r" (old), "r" (new) | ||
194 | : "cc"); | ||
195 | |||
196 | return prev; | ||
197 | } | ||
198 | |||
199 | /* | ||
200 | * cmpxchg family don't have order guarantee if cmp part fails, therefore we | ||
201 | * can avoid superfluous barriers if we use assembly code to implement | ||
202 | * cmpxchg() and cmpxchg_acquire(), however we don't do the similar for | ||
203 | * cmpxchg_release() because that will result in putting a barrier in the | ||
204 | * middle of a ll/sc loop, which is probably a bad idea. For example, this | ||
205 | * might cause the conditional store more likely to fail. | ||
206 | */ | ||
207 | static __always_inline unsigned long | ||
208 | __cmpxchg_u32_acquire(u32 *p, unsigned long old, unsigned long new) | ||
209 | { | ||
210 | unsigned long prev; | ||
211 | |||
212 | __asm__ __volatile__ ( | ||
213 | "1: lwarx %0,0,%2 # __cmpxchg_u32_acquire\n" | ||
214 | " cmpw 0,%0,%3\n" | ||
215 | " bne- 2f\n" | ||
216 | PPC405_ERR77(0, %2) | ||
217 | " stwcx. %4,0,%2\n" | ||
218 | " bne- 1b\n" | ||
219 | PPC_ACQUIRE_BARRIER | ||
220 | "\n" | ||
221 | "2:" | ||
222 | : "=&r" (prev), "+m" (*p) | ||
223 | : "r" (p), "r" (old), "r" (new) | ||
224 | : "cc", "memory"); | ||
225 | |||
226 | return prev; | ||
227 | } | ||
228 | |||
193 | #ifdef CONFIG_PPC64 | 229 | #ifdef CONFIG_PPC64 |
194 | static __always_inline unsigned long | 230 | static __always_inline unsigned long |
195 | __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new) | 231 | __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new) |
@@ -233,11 +269,47 @@ __cmpxchg_u64_local(volatile unsigned long *p, unsigned long old, | |||
233 | 269 | ||
234 | return prev; | 270 | return prev; |
235 | } | 271 | } |
236 | #endif | ||
237 | 272 | ||
238 | /* This function doesn't exist, so you'll get a linker error | 273 | static __always_inline unsigned long |
239 | if something tries to do an invalid cmpxchg(). */ | 274 | __cmpxchg_u64_relaxed(u64 *p, unsigned long old, unsigned long new) |
240 | extern void __cmpxchg_called_with_bad_pointer(void); | 275 | { |
276 | unsigned long prev; | ||
277 | |||
278 | __asm__ __volatile__ ( | ||
279 | "1: ldarx %0,0,%2 # __cmpxchg_u64_relaxed\n" | ||
280 | " cmpd 0,%0,%3\n" | ||
281 | " bne- 2f\n" | ||
282 | " stdcx. %4,0,%2\n" | ||
283 | " bne- 1b\n" | ||
284 | "2:" | ||
285 | : "=&r" (prev), "+m" (*p) | ||
286 | : "r" (p), "r" (old), "r" (new) | ||
287 | : "cc"); | ||
288 | |||
289 | return prev; | ||
290 | } | ||
291 | |||
292 | static __always_inline unsigned long | ||
293 | __cmpxchg_u64_acquire(u64 *p, unsigned long old, unsigned long new) | ||
294 | { | ||
295 | unsigned long prev; | ||
296 | |||
297 | __asm__ __volatile__ ( | ||
298 | "1: ldarx %0,0,%2 # __cmpxchg_u64_acquire\n" | ||
299 | " cmpd 0,%0,%3\n" | ||
300 | " bne- 2f\n" | ||
301 | " stdcx. %4,0,%2\n" | ||
302 | " bne- 1b\n" | ||
303 | PPC_ACQUIRE_BARRIER | ||
304 | "\n" | ||
305 | "2:" | ||
306 | : "=&r" (prev), "+m" (*p) | ||
307 | : "r" (p), "r" (old), "r" (new) | ||
308 | : "cc", "memory"); | ||
309 | |||
310 | return prev; | ||
311 | } | ||
312 | #endif | ||
241 | 313 | ||
242 | static __always_inline unsigned long | 314 | static __always_inline unsigned long |
243 | __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, | 315 | __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, |
@@ -251,7 +323,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, | |||
251 | return __cmpxchg_u64(ptr, old, new); | 323 | return __cmpxchg_u64(ptr, old, new); |
252 | #endif | 324 | #endif |
253 | } | 325 | } |
254 | __cmpxchg_called_with_bad_pointer(); | 326 | BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg"); |
255 | return old; | 327 | return old; |
256 | } | 328 | } |
257 | 329 | ||
@@ -267,10 +339,41 @@ __cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new, | |||
267 | return __cmpxchg_u64_local(ptr, old, new); | 339 | return __cmpxchg_u64_local(ptr, old, new); |
268 | #endif | 340 | #endif |
269 | } | 341 | } |
270 | __cmpxchg_called_with_bad_pointer(); | 342 | BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_local"); |
343 | return old; | ||
344 | } | ||
345 | |||
346 | static __always_inline unsigned long | ||
347 | __cmpxchg_relaxed(void *ptr, unsigned long old, unsigned long new, | ||
348 | unsigned int size) | ||
349 | { | ||
350 | switch (size) { | ||
351 | case 4: | ||
352 | return __cmpxchg_u32_relaxed(ptr, old, new); | ||
353 | #ifdef CONFIG_PPC64 | ||
354 | case 8: | ||
355 | return __cmpxchg_u64_relaxed(ptr, old, new); | ||
356 | #endif | ||
357 | } | ||
358 | BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_relaxed"); | ||
271 | return old; | 359 | return old; |
272 | } | 360 | } |
273 | 361 | ||
362 | static __always_inline unsigned long | ||
363 | __cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new, | ||
364 | unsigned int size) | ||
365 | { | ||
366 | switch (size) { | ||
367 | case 4: | ||
368 | return __cmpxchg_u32_acquire(ptr, old, new); | ||
369 | #ifdef CONFIG_PPC64 | ||
370 | case 8: | ||
371 | return __cmpxchg_u64_acquire(ptr, old, new); | ||
372 | #endif | ||
373 | } | ||
374 | BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_acquire"); | ||
375 | return old; | ||
376 | } | ||
274 | #define cmpxchg(ptr, o, n) \ | 377 | #define cmpxchg(ptr, o, n) \ |
275 | ({ \ | 378 | ({ \ |
276 | __typeof__(*(ptr)) _o_ = (o); \ | 379 | __typeof__(*(ptr)) _o_ = (o); \ |
@@ -288,6 +391,23 @@ __cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new, | |||
288 | (unsigned long)_n_, sizeof(*(ptr))); \ | 391 | (unsigned long)_n_, sizeof(*(ptr))); \ |
289 | }) | 392 | }) |
290 | 393 | ||
394 | #define cmpxchg_relaxed(ptr, o, n) \ | ||
395 | ({ \ | ||
396 | __typeof__(*(ptr)) _o_ = (o); \ | ||
397 | __typeof__(*(ptr)) _n_ = (n); \ | ||
398 | (__typeof__(*(ptr))) __cmpxchg_relaxed((ptr), \ | ||
399 | (unsigned long)_o_, (unsigned long)_n_, \ | ||
400 | sizeof(*(ptr))); \ | ||
401 | }) | ||
402 | |||
403 | #define cmpxchg_acquire(ptr, o, n) \ | ||
404 | ({ \ | ||
405 | __typeof__(*(ptr)) _o_ = (o); \ | ||
406 | __typeof__(*(ptr)) _n_ = (n); \ | ||
407 | (__typeof__(*(ptr))) __cmpxchg_acquire((ptr), \ | ||
408 | (unsigned long)_o_, (unsigned long)_n_, \ | ||
409 | sizeof(*(ptr))); \ | ||
410 | }) | ||
291 | #ifdef CONFIG_PPC64 | 411 | #ifdef CONFIG_PPC64 |
292 | #define cmpxchg64(ptr, o, n) \ | 412 | #define cmpxchg64(ptr, o, n) \ |
293 | ({ \ | 413 | ({ \ |
@@ -299,7 +419,16 @@ __cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new, | |||
299 | BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ | 419 | BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ |
300 | cmpxchg_local((ptr), (o), (n)); \ | 420 | cmpxchg_local((ptr), (o), (n)); \ |
301 | }) | 421 | }) |
302 | #define cmpxchg64_relaxed cmpxchg64_local | 422 | #define cmpxchg64_relaxed(ptr, o, n) \ |
423 | ({ \ | ||
424 | BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ | ||
425 | cmpxchg_relaxed((ptr), (o), (n)); \ | ||
426 | }) | ||
427 | #define cmpxchg64_acquire(ptr, o, n) \ | ||
428 | ({ \ | ||
429 | BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ | ||
430 | cmpxchg_acquire((ptr), (o), (n)); \ | ||
431 | }) | ||
303 | #else | 432 | #else |
304 | #include <asm-generic/cmpxchg-local.h> | 433 | #include <asm-generic/cmpxchg-local.h> |
305 | #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) | 434 | #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) |
diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h index 840a5509b3f1..994c60a857ce 100644 --- a/arch/powerpc/include/asm/code-patching.h +++ b/arch/powerpc/include/asm/code-patching.h | |||
@@ -99,4 +99,25 @@ static inline unsigned long ppc_global_function_entry(void *func) | |||
99 | #endif | 99 | #endif |
100 | } | 100 | } |
101 | 101 | ||
102 | #ifdef CONFIG_PPC64 | ||
103 | /* | ||
104 | * Some instruction encodings commonly used in dynamic ftracing | ||
105 | * and function live patching. | ||
106 | */ | ||
107 | |||
108 | /* This must match the definition of STK_GOT in <asm/ppc_asm.h> */ | ||
109 | #if defined(_CALL_ELF) && _CALL_ELF == 2 | ||
110 | #define R2_STACK_OFFSET 24 | ||
111 | #else | ||
112 | #define R2_STACK_OFFSET 40 | ||
113 | #endif | ||
114 | |||
115 | #define PPC_INST_LD_TOC (PPC_INST_LD | ___PPC_RT(__REG_R2) | \ | ||
116 | ___PPC_RA(__REG_R1) | R2_STACK_OFFSET) | ||
117 | |||
118 | /* usually preceded by a mflr r0 */ | ||
119 | #define PPC_INST_STD_LR (PPC_INST_STD | ___PPC_RS(__REG_R0) | \ | ||
120 | ___PPC_RA(__REG_R1) | PPC_LR_STKOFF) | ||
121 | #endif /* CONFIG_PPC64 */ | ||
122 | |||
102 | #endif /* _ASM_POWERPC_CODE_PATCHING_H */ | 123 | #endif /* _ASM_POWERPC_CODE_PATCHING_H */ |
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index b118072670fb..df4fb5faba43 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h | |||
@@ -43,6 +43,11 @@ extern int machine_check_e500(struct pt_regs *regs); | |||
43 | extern int machine_check_e200(struct pt_regs *regs); | 43 | extern int machine_check_e200(struct pt_regs *regs); |
44 | extern int machine_check_47x(struct pt_regs *regs); | 44 | extern int machine_check_47x(struct pt_regs *regs); |
45 | 45 | ||
46 | extern void cpu_down_flush_e500v2(void); | ||
47 | extern void cpu_down_flush_e500mc(void); | ||
48 | extern void cpu_down_flush_e5500(void); | ||
49 | extern void cpu_down_flush_e6500(void); | ||
50 | |||
46 | /* NOTE WELL: Update identify_cpu() if fields are added or removed! */ | 51 | /* NOTE WELL: Update identify_cpu() if fields are added or removed! */ |
47 | struct cpu_spec { | 52 | struct cpu_spec { |
48 | /* CPU is matched via (PVR & pvr_mask) == pvr_value */ | 53 | /* CPU is matched via (PVR & pvr_mask) == pvr_value */ |
@@ -59,6 +64,9 @@ struct cpu_spec { | |||
59 | unsigned int icache_bsize; | 64 | unsigned int icache_bsize; |
60 | unsigned int dcache_bsize; | 65 | unsigned int dcache_bsize; |
61 | 66 | ||
67 | /* flush caches inside the current cpu */ | ||
68 | void (*cpu_down_flush)(void); | ||
69 | |||
62 | /* number of performance monitor counters */ | 70 | /* number of performance monitor counters */ |
63 | unsigned int num_pmcs; | 71 | unsigned int num_pmcs; |
64 | enum powerpc_pmc_type pmc_type; | 72 | enum powerpc_pmc_type pmc_type; |
@@ -171,7 +179,7 @@ enum { | |||
171 | #define CPU_FTR_ARCH_201 LONG_ASM_CONST(0x0000000200000000) | 179 | #define CPU_FTR_ARCH_201 LONG_ASM_CONST(0x0000000200000000) |
172 | #define CPU_FTR_ARCH_206 LONG_ASM_CONST(0x0000000400000000) | 180 | #define CPU_FTR_ARCH_206 LONG_ASM_CONST(0x0000000400000000) |
173 | #define CPU_FTR_ARCH_207S LONG_ASM_CONST(0x0000000800000000) | 181 | #define CPU_FTR_ARCH_207S LONG_ASM_CONST(0x0000000800000000) |
174 | /* Free LONG_ASM_CONST(0x0000001000000000) */ | 182 | #define CPU_FTR_ARCH_300 LONG_ASM_CONST(0x0000001000000000) |
175 | #define CPU_FTR_MMCRA LONG_ASM_CONST(0x0000002000000000) | 183 | #define CPU_FTR_MMCRA LONG_ASM_CONST(0x0000002000000000) |
176 | #define CPU_FTR_CTRL LONG_ASM_CONST(0x0000004000000000) | 184 | #define CPU_FTR_CTRL LONG_ASM_CONST(0x0000004000000000) |
177 | #define CPU_FTR_SMT LONG_ASM_CONST(0x0000008000000000) | 185 | #define CPU_FTR_SMT LONG_ASM_CONST(0x0000008000000000) |
@@ -196,6 +204,7 @@ enum { | |||
196 | #define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000) | 204 | #define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000) |
197 | #define CPU_FTR_DABRX LONG_ASM_CONST(0x0800000000000000) | 205 | #define CPU_FTR_DABRX LONG_ASM_CONST(0x0800000000000000) |
198 | #define CPU_FTR_PMAO_BUG LONG_ASM_CONST(0x1000000000000000) | 206 | #define CPU_FTR_PMAO_BUG LONG_ASM_CONST(0x1000000000000000) |
207 | #define CPU_FTR_SUBCORE LONG_ASM_CONST(0x2000000000000000) | ||
199 | 208 | ||
200 | #ifndef __ASSEMBLY__ | 209 | #ifndef __ASSEMBLY__ |
201 | 210 | ||
@@ -443,9 +452,19 @@ enum { | |||
443 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ | 452 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ |
444 | CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ | 453 | CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ |
445 | CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \ | 454 | CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \ |
446 | CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP) | 455 | CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_SUBCORE) |
447 | #define CPU_FTRS_POWER8E (CPU_FTRS_POWER8 | CPU_FTR_PMAO_BUG) | 456 | #define CPU_FTRS_POWER8E (CPU_FTRS_POWER8 | CPU_FTR_PMAO_BUG) |
448 | #define CPU_FTRS_POWER8_DD1 (CPU_FTRS_POWER8 & ~CPU_FTR_DBELL) | 457 | #define CPU_FTRS_POWER8_DD1 (CPU_FTRS_POWER8 & ~CPU_FTR_DBELL) |
458 | #define CPU_FTRS_POWER9 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ | ||
459 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\ | ||
460 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ | ||
461 | CPU_FTR_COHERENT_ICACHE | \ | ||
462 | CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ | ||
463 | CPU_FTR_DSCR | CPU_FTR_SAO | \ | ||
464 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ | ||
465 | CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ | ||
466 | CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \ | ||
467 | CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_ARCH_300) | ||
449 | #define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ | 468 | #define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ |
450 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ | 469 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ |
451 | CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ | 470 | CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
@@ -464,7 +483,7 @@ enum { | |||
464 | (CPU_FTRS_POWER4 | CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \ | 483 | (CPU_FTRS_POWER4 | CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \ |
465 | CPU_FTRS_POWER6 | CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | \ | 484 | CPU_FTRS_POWER6 | CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | \ |
466 | CPU_FTRS_POWER8 | CPU_FTRS_POWER8_DD1 | CPU_FTRS_CELL | \ | 485 | CPU_FTRS_POWER8 | CPU_FTRS_POWER8_DD1 | CPU_FTRS_CELL | \ |
467 | CPU_FTRS_PA6T | CPU_FTR_VSX) | 486 | CPU_FTRS_PA6T | CPU_FTR_VSX | CPU_FTRS_POWER9) |
468 | #endif | 487 | #endif |
469 | #else | 488 | #else |
470 | enum { | 489 | enum { |
@@ -515,7 +534,8 @@ enum { | |||
515 | (CPU_FTRS_POWER4 & CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & \ | 534 | (CPU_FTRS_POWER4 & CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & \ |
516 | CPU_FTRS_POWER6 & CPU_FTRS_POWER7 & CPU_FTRS_CELL & \ | 535 | CPU_FTRS_POWER6 & CPU_FTRS_POWER7 & CPU_FTRS_CELL & \ |
517 | CPU_FTRS_PA6T & CPU_FTRS_POWER8 & CPU_FTRS_POWER8E & \ | 536 | CPU_FTRS_PA6T & CPU_FTRS_POWER8 & CPU_FTRS_POWER8E & \ |
518 | CPU_FTRS_POWER8_DD1 & ~CPU_FTR_HVMODE & CPU_FTRS_POSSIBLE) | 537 | CPU_FTRS_POWER8_DD1 & ~CPU_FTR_HVMODE & CPU_FTRS_POSSIBLE & \ |
538 | CPU_FTRS_POWER9) | ||
519 | #endif | 539 | #endif |
520 | #else | 540 | #else |
521 | enum { | 541 | enum { |
diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h index ba42e46ea58e..666bef4ebfae 100644 --- a/arch/powerpc/include/asm/cputhreads.h +++ b/arch/powerpc/include/asm/cputhreads.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef _ASM_POWERPC_CPUTHREADS_H | 1 | #ifndef _ASM_POWERPC_CPUTHREADS_H |
2 | #define _ASM_POWERPC_CPUTHREADS_H | 2 | #define _ASM_POWERPC_CPUTHREADS_H |
3 | 3 | ||
4 | #ifndef __ASSEMBLY__ | ||
4 | #include <linux/cpumask.h> | 5 | #include <linux/cpumask.h> |
5 | 6 | ||
6 | /* | 7 | /* |
@@ -94,7 +95,21 @@ static inline int cpu_last_thread_sibling(int cpu) | |||
94 | return cpu | (threads_per_core - 1); | 95 | return cpu | (threads_per_core - 1); |
95 | } | 96 | } |
96 | 97 | ||
98 | static inline u32 get_tensr(void) | ||
99 | { | ||
100 | #ifdef CONFIG_BOOKE | ||
101 | if (cpu_has_feature(CPU_FTR_SMT)) | ||
102 | return mfspr(SPRN_TENSR); | ||
103 | #endif | ||
104 | return 1; | ||
105 | } | ||
106 | |||
107 | void book3e_start_thread(int thread, unsigned long addr); | ||
108 | void book3e_stop_thread(int thread); | ||
109 | |||
110 | #endif /* __ASSEMBLY__ */ | ||
97 | 111 | ||
112 | #define INVALID_THREAD_HWID 0x0fff | ||
98 | 113 | ||
99 | #endif /* _ASM_POWERPC_CPUTHREADS_H */ | 114 | #endif /* _ASM_POWERPC_CPUTHREADS_H */ |
100 | 115 | ||
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index 867c39b45df6..fb9f376ae27b 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h | |||
@@ -72,6 +72,7 @@ struct pci_dn; | |||
72 | #define EEH_PE_PHB (1 << 1) /* PHB PE */ | 72 | #define EEH_PE_PHB (1 << 1) /* PHB PE */ |
73 | #define EEH_PE_DEVICE (1 << 2) /* Device PE */ | 73 | #define EEH_PE_DEVICE (1 << 2) /* Device PE */ |
74 | #define EEH_PE_BUS (1 << 3) /* Bus PE */ | 74 | #define EEH_PE_BUS (1 << 3) /* Bus PE */ |
75 | #define EEH_PE_VF (1 << 4) /* VF PE */ | ||
75 | 76 | ||
76 | #define EEH_PE_ISOLATED (1 << 0) /* Isolated PE */ | 77 | #define EEH_PE_ISOLATED (1 << 0) /* Isolated PE */ |
77 | #define EEH_PE_RECOVERING (1 << 1) /* Recovering PE */ | 78 | #define EEH_PE_RECOVERING (1 << 1) /* Recovering PE */ |
@@ -136,11 +137,15 @@ struct eeh_dev { | |||
136 | int pcix_cap; /* Saved PCIx capability */ | 137 | int pcix_cap; /* Saved PCIx capability */ |
137 | int pcie_cap; /* Saved PCIe capability */ | 138 | int pcie_cap; /* Saved PCIe capability */ |
138 | int aer_cap; /* Saved AER capability */ | 139 | int aer_cap; /* Saved AER capability */ |
140 | int af_cap; /* Saved AF capability */ | ||
139 | struct eeh_pe *pe; /* Associated PE */ | 141 | struct eeh_pe *pe; /* Associated PE */ |
140 | struct list_head list; /* Form link list in the PE */ | 142 | struct list_head list; /* Form link list in the PE */ |
143 | struct list_head rmv_list; /* Record the removed edevs */ | ||
141 | struct pci_controller *phb; /* Associated PHB */ | 144 | struct pci_controller *phb; /* Associated PHB */ |
142 | struct pci_dn *pdn; /* Associated PCI device node */ | 145 | struct pci_dn *pdn; /* Associated PCI device node */ |
143 | struct pci_dev *pdev; /* Associated PCI device */ | 146 | struct pci_dev *pdev; /* Associated PCI device */ |
147 | bool in_error; /* Error flag for edev */ | ||
148 | struct pci_dev *physfn; /* Associated SRIOV PF */ | ||
144 | struct pci_bus *bus; /* PCI bus for partial hotplug */ | 149 | struct pci_bus *bus; /* PCI bus for partial hotplug */ |
145 | }; | 150 | }; |
146 | 151 | ||
diff --git a/arch/powerpc/include/asm/fsl_pm.h b/arch/powerpc/include/asm/fsl_pm.h new file mode 100644 index 000000000000..47df55e36d4f --- /dev/null +++ b/arch/powerpc/include/asm/fsl_pm.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | * Support Power Management | ||
3 | * | ||
4 | * Copyright 2014-2015 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | #ifndef __PPC_FSL_PM_H | ||
12 | #define __PPC_FSL_PM_H | ||
13 | |||
14 | #define E500_PM_PH10 1 | ||
15 | #define E500_PM_PH15 2 | ||
16 | #define E500_PM_PH20 3 | ||
17 | #define E500_PM_PH30 4 | ||
18 | #define E500_PM_DOZE E500_PM_PH10 | ||
19 | #define E500_PM_NAP E500_PM_PH15 | ||
20 | |||
21 | #define PLAT_PM_SLEEP 20 | ||
22 | #define PLAT_PM_LPM20 30 | ||
23 | |||
24 | #define FSL_PM_SLEEP (1 << 0) | ||
25 | #define FSL_PM_DEEP_SLEEP (1 << 1) | ||
26 | |||
27 | struct fsl_pm_ops { | ||
28 | /* mask pending interrupts to the RCPM from MPIC */ | ||
29 | void (*irq_mask)(int cpu); | ||
30 | |||
31 | /* unmask pending interrupts to the RCPM from MPIC */ | ||
32 | void (*irq_unmask)(int cpu); | ||
33 | void (*cpu_enter_state)(int cpu, int state); | ||
34 | void (*cpu_exit_state)(int cpu, int state); | ||
35 | void (*cpu_up_prepare)(int cpu); | ||
36 | void (*cpu_die)(int cpu); | ||
37 | int (*plat_enter_sleep)(void); | ||
38 | void (*freeze_time_base)(bool freeze); | ||
39 | |||
40 | /* keep the power of IP blocks during sleep/deep sleep */ | ||
41 | void (*set_ip_power)(bool enable, u32 mask); | ||
42 | |||
43 | /* get platform supported power management modes */ | ||
44 | unsigned int (*get_pm_modes)(void); | ||
45 | }; | ||
46 | |||
47 | extern const struct fsl_pm_ops *qoriq_pm_ops; | ||
48 | |||
49 | int __init fsl_rcpm_init(void); | ||
50 | |||
51 | #endif /* __PPC_FSL_PM_H */ | ||
diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h index ef89b1465573..50ca7585abe2 100644 --- a/arch/powerpc/include/asm/ftrace.h +++ b/arch/powerpc/include/asm/ftrace.h | |||
@@ -46,6 +46,8 @@ | |||
46 | extern void _mcount(void); | 46 | extern void _mcount(void); |
47 | 47 | ||
48 | #ifdef CONFIG_DYNAMIC_FTRACE | 48 | #ifdef CONFIG_DYNAMIC_FTRACE |
49 | # define FTRACE_ADDR ((unsigned long)ftrace_caller) | ||
50 | # define FTRACE_REGS_ADDR FTRACE_ADDR | ||
49 | static inline unsigned long ftrace_call_adjust(unsigned long addr) | 51 | static inline unsigned long ftrace_call_adjust(unsigned long addr) |
50 | { | 52 | { |
51 | /* reloction of mcount call site is the same as the address */ | 53 | /* reloction of mcount call site is the same as the address */ |
@@ -58,6 +60,9 @@ struct dyn_arch_ftrace { | |||
58 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 60 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
59 | #endif /* __ASSEMBLY__ */ | 61 | #endif /* __ASSEMBLY__ */ |
60 | 62 | ||
63 | #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS | ||
64 | #define ARCH_SUPPORTS_FTRACE_OPS 1 | ||
65 | #endif | ||
61 | #endif | 66 | #endif |
62 | 67 | ||
63 | #if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__) | 68 | #if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__) |
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 7eac89b9f02e..42814f0567cc 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h | |||
@@ -19,7 +19,7 @@ static inline pte_t *hugepd_page(hugepd_t hpd) | |||
19 | * We have only four bits to encode, MMU page size | 19 | * We have only four bits to encode, MMU page size |
20 | */ | 20 | */ |
21 | BUILD_BUG_ON((MMU_PAGE_COUNT - 1) > 0xf); | 21 | BUILD_BUG_ON((MMU_PAGE_COUNT - 1) > 0xf); |
22 | return (pte_t *)(hpd.pd & ~HUGEPD_SHIFT_MASK); | 22 | return __va(hpd.pd & HUGEPD_ADDR_MASK); |
23 | } | 23 | } |
24 | 24 | ||
25 | static inline unsigned int hugepd_mmu_psize(hugepd_t hpd) | 25 | static inline unsigned int hugepd_mmu_psize(hugepd_t hpd) |
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index e3b54dd4f730..0bc9c284aa10 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h | |||
@@ -94,6 +94,7 @@ | |||
94 | #define H_SG_LIST -72 | 94 | #define H_SG_LIST -72 |
95 | #define H_OP_MODE -73 | 95 | #define H_OP_MODE -73 |
96 | #define H_COP_HW -74 | 96 | #define H_COP_HW -74 |
97 | #define H_STATE -75 | ||
97 | #define H_UNSUPPORTED_FLAG_START -256 | 98 | #define H_UNSUPPORTED_FLAG_START -256 |
98 | #define H_UNSUPPORTED_FLAG_END -511 | 99 | #define H_UNSUPPORTED_FLAG_END -511 |
99 | #define H_MULTI_THREADS_ACTIVE -9005 | 100 | #define H_MULTI_THREADS_ACTIVE -9005 |
diff --git a/arch/powerpc/include/asm/hydra.h b/arch/powerpc/include/asm/hydra.h index 1cb39c96d155..b3b0f2d020f0 100644 --- a/arch/powerpc/include/asm/hydra.h +++ b/arch/powerpc/include/asm/hydra.h | |||
@@ -89,7 +89,7 @@ extern volatile struct Hydra __iomem *Hydra; | |||
89 | #define HYDRA_INT_EXT2 13 /* PCI IRQX */ | 89 | #define HYDRA_INT_EXT2 13 /* PCI IRQX */ |
90 | #define HYDRA_INT_EXT3 14 /* PCI IRQY */ | 90 | #define HYDRA_INT_EXT3 14 /* PCI IRQY */ |
91 | #define HYDRA_INT_EXT4 15 /* PCI IRQZ */ | 91 | #define HYDRA_INT_EXT4 15 /* PCI IRQZ */ |
92 | #define HYDRA_INT_EXT5 16 /* IDE Primay/Secondary */ | 92 | #define HYDRA_INT_EXT5 16 /* IDE Primary/Secondary */ |
93 | #define HYDRA_INT_EXT6 17 /* IDE Secondary */ | 93 | #define HYDRA_INT_EXT6 17 /* IDE Secondary */ |
94 | #define HYDRA_INT_EXT7 18 /* Power Off Request */ | 94 | #define HYDRA_INT_EXT7 18 /* Power Off Request */ |
95 | #define HYDRA_INT_SPARE 19 | 95 | #define HYDRA_INT_SPARE 19 |
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index 6c1297ec374c..2fd1690b79d2 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h | |||
@@ -300,7 +300,7 @@ extern void _memcpy_toio(volatile void __iomem *dest, const void *src, | |||
300 | * When CONFIG_PPC_INDIRECT_MMIO is set, the platform can provide hooks | 300 | * When CONFIG_PPC_INDIRECT_MMIO is set, the platform can provide hooks |
301 | * on all MMIOs. (Note that this is all 64 bits only for now) | 301 | * on all MMIOs. (Note that this is all 64 bits only for now) |
302 | * | 302 | * |
303 | * To help platforms who may need to differenciate MMIO addresses in | 303 | * To help platforms who may need to differentiate MMIO addresses in |
304 | * their hooks, a bitfield is reserved for use by the platform near the | 304 | * their hooks, a bitfield is reserved for use by the platform near the |
305 | * top of MMIO addresses (not PIO, those have to cope the hard way). | 305 | * top of MMIO addresses (not PIO, those have to cope the hard way). |
306 | * | 306 | * |
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 3f191f573d4f..fd22442d30a9 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h | |||
@@ -54,7 +54,7 @@ struct machdep_calls { | |||
54 | int psize, int apsize, | 54 | int psize, int apsize, |
55 | int ssize); | 55 | int ssize); |
56 | long (*hpte_remove)(unsigned long hpte_group); | 56 | long (*hpte_remove)(unsigned long hpte_group); |
57 | void (*hpte_removebolted)(unsigned long ea, | 57 | int (*hpte_removebolted)(unsigned long ea, |
58 | int psize, int ssize); | 58 | int psize, int ssize); |
59 | void (*flush_hash_range)(unsigned long number, int local); | 59 | void (*flush_hash_range)(unsigned long number, int local); |
60 | void (*hugepage_invalidate)(unsigned long vsid, | 60 | void (*hugepage_invalidate)(unsigned long vsid, |
@@ -174,11 +174,11 @@ struct machdep_calls { | |||
174 | platform, called once per cpu. */ | 174 | platform, called once per cpu. */ |
175 | void (*enable_pmcs)(void); | 175 | void (*enable_pmcs)(void); |
176 | 176 | ||
177 | /* Set DABR for this platform, leave empty for default implemenation */ | 177 | /* Set DABR for this platform, leave empty for default implementation */ |
178 | int (*set_dabr)(unsigned long dabr, | 178 | int (*set_dabr)(unsigned long dabr, |
179 | unsigned long dabrx); | 179 | unsigned long dabrx); |
180 | 180 | ||
181 | /* Set DAWR for this platform, leave empty for default implemenation */ | 181 | /* Set DAWR for this platform, leave empty for default implementation */ |
182 | int (*set_dawr)(unsigned long dawr, | 182 | int (*set_dawr)(unsigned long dawr, |
183 | unsigned long dawrx); | 183 | unsigned long dawrx); |
184 | 184 | ||
diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/mmu-8xx.h index f05500a29a60..0a566f15f985 100644 --- a/arch/powerpc/include/asm/mmu-8xx.h +++ b/arch/powerpc/include/asm/mmu-8xx.h | |||
@@ -171,9 +171,9 @@ typedef struct { | |||
171 | } mm_context_t; | 171 | } mm_context_t; |
172 | #endif /* !__ASSEMBLY__ */ | 172 | #endif /* !__ASSEMBLY__ */ |
173 | 173 | ||
174 | #if (PAGE_SHIFT == 12) | 174 | #if defined(CONFIG_PPC_4K_PAGES) |
175 | #define mmu_virtual_psize MMU_PAGE_4K | 175 | #define mmu_virtual_psize MMU_PAGE_4K |
176 | #elif (PAGE_SHIFT == 14) | 176 | #elif defined(CONFIG_PPC_16K_PAGES) |
177 | #define mmu_virtual_psize MMU_PAGE_16K | 177 | #define mmu_virtual_psize MMU_PAGE_16K |
178 | #else | 178 | #else |
179 | #error "Unsupported PAGE_SIZE" | 179 | #error "Unsupported PAGE_SIZE" |
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index 3d5abfe6ba67..8ca1c983bf6c 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h | |||
@@ -97,6 +97,7 @@ | |||
97 | #define MMU_FTRS_POWER6 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | 97 | #define MMU_FTRS_POWER6 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE |
98 | #define MMU_FTRS_POWER7 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | 98 | #define MMU_FTRS_POWER7 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE |
99 | #define MMU_FTRS_POWER8 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | 99 | #define MMU_FTRS_POWER8 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE |
100 | #define MMU_FTRS_POWER9 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | ||
100 | #define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ | 101 | #define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ |
101 | MMU_FTR_CI_LARGE_PAGE | 102 | MMU_FTR_CI_LARGE_PAGE |
102 | #define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ | 103 | #define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ |
@@ -182,10 +183,10 @@ static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr) | |||
182 | 183 | ||
183 | #if defined(CONFIG_PPC_STD_MMU_64) | 184 | #if defined(CONFIG_PPC_STD_MMU_64) |
184 | /* 64-bit classic hash table MMU */ | 185 | /* 64-bit classic hash table MMU */ |
185 | # include <asm/mmu-hash64.h> | 186 | #include <asm/book3s/64/mmu-hash.h> |
186 | #elif defined(CONFIG_PPC_STD_MMU_32) | 187 | #elif defined(CONFIG_PPC_STD_MMU_32) |
187 | /* 32-bit classic hash table MMU */ | 188 | /* 32-bit classic hash table MMU */ |
188 | # include <asm/mmu-hash32.h> | 189 | #include <asm/book3s/32/mmu-hash.h> |
189 | #elif defined(CONFIG_40x) | 190 | #elif defined(CONFIG_40x) |
190 | /* 40x-style software loaded TLB */ | 191 | /* 40x-style software loaded TLB */ |
191 | # include <asm/mmu-40x.h> | 192 | # include <asm/mmu-40x.h> |
diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h index dcfcad139bcc..cd4ffd86765f 100644 --- a/arch/powerpc/include/asm/module.h +++ b/arch/powerpc/include/asm/module.h | |||
@@ -19,7 +19,7 @@ | |||
19 | * Thanks to Paul M for explaining this. | 19 | * Thanks to Paul M for explaining this. |
20 | * | 20 | * |
21 | * PPC can only do rel jumps += 32MB, and often the kernel and other | 21 | * PPC can only do rel jumps += 32MB, and often the kernel and other |
22 | * modules are furthur away than this. So, we jump to a table of | 22 | * modules are further away than this. So, we jump to a table of |
23 | * trampolines attached to the module (the Procedure Linkage Table) | 23 | * trampolines attached to the module (the Procedure Linkage Table) |
24 | * whenever that happens. | 24 | * whenever that happens. |
25 | */ | 25 | */ |
@@ -78,10 +78,18 @@ struct mod_arch_specific { | |||
78 | # endif /* MODULE */ | 78 | # endif /* MODULE */ |
79 | #endif | 79 | #endif |
80 | 80 | ||
81 | bool is_module_trampoline(u32 *insns); | 81 | int module_trampoline_target(struct module *mod, unsigned long trampoline, |
82 | int module_trampoline_target(struct module *mod, u32 *trampoline, | ||
83 | unsigned long *target); | 82 | unsigned long *target); |
84 | 83 | ||
84 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
85 | int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs); | ||
86 | #else | ||
87 | static inline int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs) | ||
88 | { | ||
89 | return 0; | ||
90 | } | ||
91 | #endif | ||
92 | |||
85 | struct exception_table_entry; | 93 | struct exception_table_entry; |
86 | void sort_ex_table(struct exception_table_entry *start, | 94 | void sort_ex_table(struct exception_table_entry *start, |
87 | struct exception_table_entry *finish); | 95 | struct exception_table_entry *finish); |
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h index c82cbf52d19e..780847597514 100644 --- a/arch/powerpc/include/asm/nohash/32/pgtable.h +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h | |||
@@ -86,7 +86,7 @@ extern int icache_44x_need_flush; | |||
86 | * We no longer map larger than phys RAM with the BATs so we don't have | 86 | * We no longer map larger than phys RAM with the BATs so we don't have |
87 | * to worry about the VMALLOC_OFFSET causing problems. We do have to worry | 87 | * to worry about the VMALLOC_OFFSET causing problems. We do have to worry |
88 | * about clashes between our early calls to ioremap() that start growing down | 88 | * about clashes between our early calls to ioremap() that start growing down |
89 | * from ioremap_base being run into the VM area allocations (growing upwards | 89 | * from IOREMAP_TOP being run into the VM area allocations (growing upwards |
90 | * from VMALLOC_START). For this reason we have ioremap_bot to check when | 90 | * from VMALLOC_START). For this reason we have ioremap_bot to check when |
91 | * we actually run into our mappings setup in the early boot with the VM | 91 | * we actually run into our mappings setup in the early boot with the VM |
92 | * system. This really does become a problem for machines with good amounts | 92 | * system. This really does become a problem for machines with good amounts |
@@ -309,7 +309,8 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) | |||
309 | #define pte_index(address) \ | 309 | #define pte_index(address) \ |
310 | (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) | 310 | (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) |
311 | #define pte_offset_kernel(dir, addr) \ | 311 | #define pte_offset_kernel(dir, addr) \ |
312 | ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(addr)) | 312 | (pmd_bad(*(dir)) ? NULL : (pte_t *)pmd_page_vaddr(*(dir)) + \ |
313 | pte_index(addr)) | ||
313 | #define pte_offset_map(dir, addr) \ | 314 | #define pte_offset_map(dir, addr) \ |
314 | ((pte_t *) kmap_atomic(pmd_page(*(dir))) + pte_index(addr)) | 315 | ((pte_t *) kmap_atomic(pmd_page(*(dir))) + pte_index(addr)) |
315 | #define pte_unmap(pte) kunmap_atomic(pte) | 316 | #define pte_unmap(pte) kunmap_atomic(pte) |
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h index b9f734dd5b81..10debb93c4a4 100644 --- a/arch/powerpc/include/asm/nohash/64/pgtable.h +++ b/arch/powerpc/include/asm/nohash/64/pgtable.h | |||
@@ -108,6 +108,9 @@ | |||
108 | #ifndef __ASSEMBLY__ | 108 | #ifndef __ASSEMBLY__ |
109 | /* pte_clear moved to later in this file */ | 109 | /* pte_clear moved to later in this file */ |
110 | 110 | ||
111 | /* Pointers in the page table tree are virtual addresses */ | ||
112 | #define __pgtable_ptr_val(ptr) ((unsigned long)(ptr)) | ||
113 | |||
111 | #define PMD_BAD_BITS (PTE_TABLE_SIZE-1) | 114 | #define PMD_BAD_BITS (PTE_TABLE_SIZE-1) |
112 | #define PUD_BAD_BITS (PMD_TABLE_SIZE-1) | 115 | #define PUD_BAD_BITS (PMD_TABLE_SIZE-1) |
113 | 116 | ||
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 07a99e638449..9d86c6651716 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h | |||
@@ -248,6 +248,7 @@ extern int opal_elog_init(void); | |||
248 | extern void opal_platform_dump_init(void); | 248 | extern void opal_platform_dump_init(void); |
249 | extern void opal_sys_param_init(void); | 249 | extern void opal_sys_param_init(void); |
250 | extern void opal_msglog_init(void); | 250 | extern void opal_msglog_init(void); |
251 | extern void opal_msglog_sysfs_init(void); | ||
251 | extern int opal_async_comp_init(void); | 252 | extern int opal_async_comp_init(void); |
252 | extern int opal_sensor_init(void); | 253 | extern int opal_sensor_init(void); |
253 | extern int opal_hmi_handler_init(void); | 254 | extern int opal_hmi_handler_init(void); |
@@ -273,6 +274,8 @@ void opal_free_sg_list(struct opal_sg_list *sg); | |||
273 | 274 | ||
274 | extern int opal_error_code(int rc); | 275 | extern int opal_error_code(int rc); |
275 | 276 | ||
277 | ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count); | ||
278 | |||
276 | #endif /* __ASSEMBLY__ */ | 279 | #endif /* __ASSEMBLY__ */ |
277 | 280 | ||
278 | #endif /* _ASM_POWERPC_OPAL_H */ | 281 | #endif /* _ASM_POWERPC_OPAL_H */ |
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index e34124f6fbf2..ab3d8977bacd 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h | |||
@@ -271,6 +271,13 @@ extern long long virt_phys_offset; | |||
271 | #else | 271 | #else |
272 | #define PD_HUGE 0x80000000 | 272 | #define PD_HUGE 0x80000000 |
273 | #endif | 273 | #endif |
274 | |||
275 | #else /* CONFIG_PPC_BOOK3S_64 */ | ||
276 | /* | ||
277 | * Book3S 64 stores real addresses in the hugepd entries to | ||
278 | * avoid overlaps with _PAGE_PRESENT and _PAGE_PTE. | ||
279 | */ | ||
280 | #define HUGEPD_ADDR_MASK (0x0ffffffffffffffful & ~HUGEPD_SHIFT_MASK) | ||
274 | #endif /* CONFIG_PPC_BOOK3S_64 */ | 281 | #endif /* CONFIG_PPC_BOOK3S_64 */ |
275 | 282 | ||
276 | /* | 283 | /* |
@@ -281,109 +288,7 @@ extern long long virt_phys_offset; | |||
281 | 288 | ||
282 | #ifndef __ASSEMBLY__ | 289 | #ifndef __ASSEMBLY__ |
283 | 290 | ||
284 | #ifdef CONFIG_STRICT_MM_TYPECHECKS | 291 | #include <asm/pgtable-types.h> |
285 | /* These are used to make use of C type-checking. */ | ||
286 | |||
287 | /* PTE level */ | ||
288 | typedef struct { pte_basic_t pte; } pte_t; | ||
289 | #define __pte(x) ((pte_t) { (x) }) | ||
290 | static inline pte_basic_t pte_val(pte_t x) | ||
291 | { | ||
292 | return x.pte; | ||
293 | } | ||
294 | |||
295 | /* 64k pages additionally define a bigger "real PTE" type that gathers | ||
296 | * the "second half" part of the PTE for pseudo 64k pages | ||
297 | */ | ||
298 | #if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64) | ||
299 | typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; | ||
300 | #else | ||
301 | typedef struct { pte_t pte; } real_pte_t; | ||
302 | #endif | ||
303 | |||
304 | /* PMD level */ | ||
305 | #ifdef CONFIG_PPC64 | ||
306 | typedef struct { unsigned long pmd; } pmd_t; | ||
307 | #define __pmd(x) ((pmd_t) { (x) }) | ||
308 | static inline unsigned long pmd_val(pmd_t x) | ||
309 | { | ||
310 | return x.pmd; | ||
311 | } | ||
312 | |||
313 | /* PUD level exusts only on 4k pages */ | ||
314 | #ifndef CONFIG_PPC_64K_PAGES | ||
315 | typedef struct { unsigned long pud; } pud_t; | ||
316 | #define __pud(x) ((pud_t) { (x) }) | ||
317 | static inline unsigned long pud_val(pud_t x) | ||
318 | { | ||
319 | return x.pud; | ||
320 | } | ||
321 | #endif /* !CONFIG_PPC_64K_PAGES */ | ||
322 | #endif /* CONFIG_PPC64 */ | ||
323 | |||
324 | /* PGD level */ | ||
325 | typedef struct { unsigned long pgd; } pgd_t; | ||
326 | #define __pgd(x) ((pgd_t) { (x) }) | ||
327 | static inline unsigned long pgd_val(pgd_t x) | ||
328 | { | ||
329 | return x.pgd; | ||
330 | } | ||
331 | |||
332 | /* Page protection bits */ | ||
333 | typedef struct { unsigned long pgprot; } pgprot_t; | ||
334 | #define pgprot_val(x) ((x).pgprot) | ||
335 | #define __pgprot(x) ((pgprot_t) { (x) }) | ||
336 | |||
337 | #else | ||
338 | |||
339 | /* | ||
340 | * .. while these make it easier on the compiler | ||
341 | */ | ||
342 | |||
343 | typedef pte_basic_t pte_t; | ||
344 | #define __pte(x) (x) | ||
345 | static inline pte_basic_t pte_val(pte_t pte) | ||
346 | { | ||
347 | return pte; | ||
348 | } | ||
349 | |||
350 | #if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64) | ||
351 | typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; | ||
352 | #else | ||
353 | typedef pte_t real_pte_t; | ||
354 | #endif | ||
355 | |||
356 | |||
357 | #ifdef CONFIG_PPC64 | ||
358 | typedef unsigned long pmd_t; | ||
359 | #define __pmd(x) (x) | ||
360 | static inline unsigned long pmd_val(pmd_t pmd) | ||
361 | { | ||
362 | return pmd; | ||
363 | } | ||
364 | |||
365 | #ifndef CONFIG_PPC_64K_PAGES | ||
366 | typedef unsigned long pud_t; | ||
367 | #define __pud(x) (x) | ||
368 | static inline unsigned long pud_val(pud_t pud) | ||
369 | { | ||
370 | return pud; | ||
371 | } | ||
372 | #endif /* !CONFIG_PPC_64K_PAGES */ | ||
373 | #endif /* CONFIG_PPC64 */ | ||
374 | |||
375 | typedef unsigned long pgd_t; | ||
376 | #define __pgd(x) (x) | ||
377 | static inline unsigned long pgd_val(pgd_t pgd) | ||
378 | { | ||
379 | return pgd; | ||
380 | } | ||
381 | |||
382 | typedef unsigned long pgprot_t; | ||
383 | #define pgprot_val(x) (x) | ||
384 | #define __pgprot(x) (x) | ||
385 | |||
386 | #endif | ||
387 | 292 | ||
388 | typedef struct { signed long pd; } hugepd_t; | 293 | typedef struct { signed long pd; } hugepd_t; |
389 | 294 | ||
diff --git a/arch/powerpc/include/asm/page_32.h b/arch/powerpc/include/asm/page_32.h index 68d73b2a7bfc..6a8e1797f223 100644 --- a/arch/powerpc/include/asm/page_32.h +++ b/arch/powerpc/include/asm/page_32.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _ASM_POWERPC_PAGE_32_H | 1 | #ifndef _ASM_POWERPC_PAGE_32_H |
2 | #define _ASM_POWERPC_PAGE_32_H | 2 | #define _ASM_POWERPC_PAGE_32_H |
3 | 3 | ||
4 | #include <asm/cache.h> | ||
5 | |||
4 | #if defined(CONFIG_PHYSICAL_ALIGN) && (CONFIG_PHYSICAL_START != 0) | 6 | #if defined(CONFIG_PHYSICAL_ALIGN) && (CONFIG_PHYSICAL_START != 0) |
5 | #if (CONFIG_PHYSICAL_START % CONFIG_PHYSICAL_ALIGN) != 0 | 7 | #if (CONFIG_PHYSICAL_START % CONFIG_PHYSICAL_ALIGN) != 0 |
6 | #error "CONFIG_PHYSICAL_START must be a multiple of CONFIG_PHYSICAL_ALIGN" | 8 | #error "CONFIG_PHYSICAL_START must be a multiple of CONFIG_PHYSICAL_ALIGN" |
@@ -36,9 +38,18 @@ typedef unsigned long long pte_basic_t; | |||
36 | typedef unsigned long pte_basic_t; | 38 | typedef unsigned long pte_basic_t; |
37 | #endif | 39 | #endif |
38 | 40 | ||
39 | struct page; | 41 | /* |
40 | extern void clear_pages(void *page, int order); | 42 | * Clear page using the dcbz instruction, which doesn't cause any |
41 | static inline void clear_page(void *page) { clear_pages(page, 0); } | 43 | * memory traffic (except to write out any cache lines which get |
44 | * displaced). This only works on cacheable memory. | ||
45 | */ | ||
46 | static inline void clear_page(void *addr) | ||
47 | { | ||
48 | unsigned int i; | ||
49 | |||
50 | for (i = 0; i < PAGE_SIZE / L1_CACHE_BYTES; i++, addr += L1_CACHE_BYTES) | ||
51 | dcbz(addr); | ||
52 | } | ||
42 | extern void copy_page(void *to, void *from); | 53 | extern void copy_page(void *to, void *from); |
43 | 54 | ||
44 | #include <asm-generic/getorder.h> | 55 | #include <asm-generic/getorder.h> |
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 78968c1ff931..f5056e3394b4 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h | |||
@@ -211,15 +211,16 @@ struct pci_dn { | |||
211 | #define IODA_INVALID_PE (-1) | 211 | #define IODA_INVALID_PE (-1) |
212 | #ifdef CONFIG_PPC_POWERNV | 212 | #ifdef CONFIG_PPC_POWERNV |
213 | int pe_number; | 213 | int pe_number; |
214 | int vf_index; /* VF index in the PF */ | ||
214 | #ifdef CONFIG_PCI_IOV | 215 | #ifdef CONFIG_PCI_IOV |
215 | u16 vfs_expanded; /* number of VFs IOV BAR expanded */ | 216 | u16 vfs_expanded; /* number of VFs IOV BAR expanded */ |
216 | u16 num_vfs; /* number of VFs enabled*/ | 217 | u16 num_vfs; /* number of VFs enabled*/ |
217 | int offset; /* PE# for the first VF PE */ | 218 | int *pe_num_map; /* PE# for the first VF PE or array */ |
218 | #define M64_PER_IOV 4 | 219 | bool m64_single_mode; /* Use M64 BAR in Single Mode */ |
219 | int m64_per_iov; | ||
220 | #define IODA_INVALID_M64 (-1) | 220 | #define IODA_INVALID_M64 (-1) |
221 | int m64_wins[PCI_SRIOV_NUM_BARS][M64_PER_IOV]; | 221 | int (*m64_map)[PCI_SRIOV_NUM_BARS]; |
222 | #endif /* CONFIG_PCI_IOV */ | 222 | #endif /* CONFIG_PCI_IOV */ |
223 | int mps; /* Maximum Payload Size */ | ||
223 | #endif | 224 | #endif |
224 | struct list_head child_list; | 225 | struct list_head child_list; |
225 | struct list_head list; | 226 | struct list_head list; |
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h index 814622146d5a..e157489ee7a1 100644 --- a/arch/powerpc/include/asm/perf_event_server.h +++ b/arch/powerpc/include/asm/perf_event_server.h | |||
@@ -136,16 +136,24 @@ extern ssize_t power_events_sysfs_show(struct device *dev, | |||
136 | * event 'cpu-cycles' can have two entries in sysfs: 'cpu-cycles' and | 136 | * event 'cpu-cycles' can have two entries in sysfs: 'cpu-cycles' and |
137 | * 'PM_CYC' where the latter is the name by which the event is known in | 137 | * 'PM_CYC' where the latter is the name by which the event is known in |
138 | * POWER CPU specification. | 138 | * POWER CPU specification. |
139 | * | ||
140 | * Similarly, some hardware and cache events use the same event code. Eg. | ||
141 | * on POWER8, both "cache-references" and "L1-dcache-loads" events refer | ||
142 | * to the same event, PM_LD_REF_L1. The suffix, allows us to have two | ||
143 | * sysfs objects for the same event and thus two entries/aliases in sysfs. | ||
139 | */ | 144 | */ |
140 | #define EVENT_VAR(_id, _suffix) event_attr_##_id##_suffix | 145 | #define EVENT_VAR(_id, _suffix) event_attr_##_id##_suffix |
141 | #define EVENT_PTR(_id, _suffix) &EVENT_VAR(_id, _suffix).attr.attr | 146 | #define EVENT_PTR(_id, _suffix) &EVENT_VAR(_id, _suffix).attr.attr |
142 | 147 | ||
143 | #define EVENT_ATTR(_name, _id, _suffix) \ | 148 | #define EVENT_ATTR(_name, _id, _suffix) \ |
144 | PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), PME_##_id, \ | 149 | PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), _id, \ |
145 | power_events_sysfs_show) | 150 | power_events_sysfs_show) |
146 | 151 | ||
147 | #define GENERIC_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _g) | 152 | #define GENERIC_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _g) |
148 | #define GENERIC_EVENT_PTR(_id) EVENT_PTR(_id, _g) | 153 | #define GENERIC_EVENT_PTR(_id) EVENT_PTR(_id, _g) |
149 | 154 | ||
155 | #define CACHE_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _c) | ||
156 | #define CACHE_EVENT_PTR(_id) EVENT_PTR(_id, _c) | ||
157 | |||
150 | #define POWER_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _p) | 158 | #define POWER_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _p) |
151 | #define POWER_EVENT_PTR(_id) EVENT_PTR(_id, _p) | 159 | #define POWER_EVENT_PTR(_id) EVENT_PTR(_id, _p) |
diff --git a/arch/powerpc/include/asm/pgalloc-64.h b/arch/powerpc/include/asm/pgalloc-64.h index 69ef28a81733..8d5fc3ac43da 100644 --- a/arch/powerpc/include/asm/pgalloc-64.h +++ b/arch/powerpc/include/asm/pgalloc-64.h | |||
@@ -53,7 +53,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) | |||
53 | 53 | ||
54 | #ifndef CONFIG_PPC_64K_PAGES | 54 | #ifndef CONFIG_PPC_64K_PAGES |
55 | 55 | ||
56 | #define pgd_populate(MM, PGD, PUD) pgd_set(PGD, (unsigned long)PUD) | 56 | #define pgd_populate(MM, PGD, PUD) pgd_set(PGD, __pgtable_ptr_val(PUD)) |
57 | 57 | ||
58 | static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) | 58 | static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) |
59 | { | 59 | { |
@@ -68,19 +68,19 @@ static inline void pud_free(struct mm_struct *mm, pud_t *pud) | |||
68 | 68 | ||
69 | static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) | 69 | static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) |
70 | { | 70 | { |
71 | pud_set(pud, (unsigned long)pmd); | 71 | pud_set(pud, __pgtable_ptr_val(pmd)); |
72 | } | 72 | } |
73 | 73 | ||
74 | static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, | 74 | static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, |
75 | pte_t *pte) | 75 | pte_t *pte) |
76 | { | 76 | { |
77 | pmd_set(pmd, (unsigned long)pte); | 77 | pmd_set(pmd, __pgtable_ptr_val(pte)); |
78 | } | 78 | } |
79 | 79 | ||
80 | static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, | 80 | static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, |
81 | pgtable_t pte_page) | 81 | pgtable_t pte_page) |
82 | { | 82 | { |
83 | pmd_set(pmd, (unsigned long)page_address(pte_page)); | 83 | pmd_set(pmd, __pgtable_ptr_val(page_address(pte_page))); |
84 | } | 84 | } |
85 | 85 | ||
86 | #define pmd_pgtable(pmd) pmd_page(pmd) | 86 | #define pmd_pgtable(pmd) pmd_page(pmd) |
@@ -171,23 +171,45 @@ extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift); | |||
171 | extern void __tlb_remove_table(void *_table); | 171 | extern void __tlb_remove_table(void *_table); |
172 | #endif | 172 | #endif |
173 | 173 | ||
174 | #define pud_populate(mm, pud, pmd) pud_set(pud, (unsigned long)pmd) | 174 | #ifndef __PAGETABLE_PUD_FOLDED |
175 | /* book3s 64 is 4 level page table */ | ||
176 | static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) | ||
177 | { | ||
178 | pgd_set(pgd, __pgtable_ptr_val(pud)); | ||
179 | } | ||
180 | |||
181 | static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) | ||
182 | { | ||
183 | return kmem_cache_alloc(PGT_CACHE(PUD_INDEX_SIZE), | ||
184 | GFP_KERNEL|__GFP_REPEAT); | ||
185 | } | ||
186 | |||
187 | static inline void pud_free(struct mm_struct *mm, pud_t *pud) | ||
188 | { | ||
189 | kmem_cache_free(PGT_CACHE(PUD_INDEX_SIZE), pud); | ||
190 | } | ||
191 | #endif | ||
192 | |||
193 | static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) | ||
194 | { | ||
195 | pud_set(pud, __pgtable_ptr_val(pmd)); | ||
196 | } | ||
175 | 197 | ||
176 | static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, | 198 | static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, |
177 | pte_t *pte) | 199 | pte_t *pte) |
178 | { | 200 | { |
179 | pmd_set(pmd, (unsigned long)pte); | 201 | pmd_set(pmd, __pgtable_ptr_val(pte)); |
180 | } | 202 | } |
181 | 203 | ||
182 | static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, | 204 | static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, |
183 | pgtable_t pte_page) | 205 | pgtable_t pte_page) |
184 | { | 206 | { |
185 | pmd_set(pmd, (unsigned long)pte_page); | 207 | pmd_set(pmd, __pgtable_ptr_val(pte_page)); |
186 | } | 208 | } |
187 | 209 | ||
188 | static inline pgtable_t pmd_pgtable(pmd_t pmd) | 210 | static inline pgtable_t pmd_pgtable(pmd_t pmd) |
189 | { | 211 | { |
190 | return (pgtable_t)(pmd_val(pmd) & ~PMD_MASKED_BITS); | 212 | return (pgtable_t)pmd_page_vaddr(pmd); |
191 | } | 213 | } |
192 | 214 | ||
193 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | 215 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, |
@@ -233,11 +255,11 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) | |||
233 | 255 | ||
234 | #define __pmd_free_tlb(tlb, pmd, addr) \ | 256 | #define __pmd_free_tlb(tlb, pmd, addr) \ |
235 | pgtable_free_tlb(tlb, pmd, PMD_CACHE_INDEX) | 257 | pgtable_free_tlb(tlb, pmd, PMD_CACHE_INDEX) |
236 | #ifndef CONFIG_PPC_64K_PAGES | 258 | #ifndef __PAGETABLE_PUD_FOLDED |
237 | #define __pud_free_tlb(tlb, pud, addr) \ | 259 | #define __pud_free_tlb(tlb, pud, addr) \ |
238 | pgtable_free_tlb(tlb, pud, PUD_INDEX_SIZE) | 260 | pgtable_free_tlb(tlb, pud, PUD_INDEX_SIZE) |
239 | 261 | ||
240 | #endif /* CONFIG_PPC_64K_PAGES */ | 262 | #endif /* __PAGETABLE_PUD_FOLDED */ |
241 | 263 | ||
242 | #define check_pgt_cache() do { } while (0) | 264 | #define check_pgt_cache() do { } while (0) |
243 | 265 | ||
diff --git a/arch/powerpc/include/asm/pgtable-types.h b/arch/powerpc/include/asm/pgtable-types.h new file mode 100644 index 000000000000..43140f8b0592 --- /dev/null +++ b/arch/powerpc/include/asm/pgtable-types.h | |||
@@ -0,0 +1,103 @@ | |||
1 | #ifndef _ASM_POWERPC_PGTABLE_TYPES_H | ||
2 | #define _ASM_POWERPC_PGTABLE_TYPES_H | ||
3 | |||
4 | #ifdef CONFIG_STRICT_MM_TYPECHECKS | ||
5 | /* These are used to make use of C type-checking. */ | ||
6 | |||
7 | /* PTE level */ | ||
8 | typedef struct { pte_basic_t pte; } pte_t; | ||
9 | #define __pte(x) ((pte_t) { (x) }) | ||
10 | static inline pte_basic_t pte_val(pte_t x) | ||
11 | { | ||
12 | return x.pte; | ||
13 | } | ||
14 | |||
15 | /* PMD level */ | ||
16 | #ifdef CONFIG_PPC64 | ||
17 | typedef struct { unsigned long pmd; } pmd_t; | ||
18 | #define __pmd(x) ((pmd_t) { (x) }) | ||
19 | static inline unsigned long pmd_val(pmd_t x) | ||
20 | { | ||
21 | return x.pmd; | ||
22 | } | ||
23 | |||
24 | /* | ||
25 | * 64 bit hash always use 4 level table. Everybody else use 4 level | ||
26 | * only for 4K page size. | ||
27 | */ | ||
28 | #if defined(CONFIG_PPC_BOOK3S_64) || !defined(CONFIG_PPC_64K_PAGES) | ||
29 | typedef struct { unsigned long pud; } pud_t; | ||
30 | #define __pud(x) ((pud_t) { (x) }) | ||
31 | static inline unsigned long pud_val(pud_t x) | ||
32 | { | ||
33 | return x.pud; | ||
34 | } | ||
35 | #endif /* CONFIG_PPC_BOOK3S_64 || !CONFIG_PPC_64K_PAGES */ | ||
36 | #endif /* CONFIG_PPC64 */ | ||
37 | |||
38 | /* PGD level */ | ||
39 | typedef struct { unsigned long pgd; } pgd_t; | ||
40 | #define __pgd(x) ((pgd_t) { (x) }) | ||
41 | static inline unsigned long pgd_val(pgd_t x) | ||
42 | { | ||
43 | return x.pgd; | ||
44 | } | ||
45 | |||
46 | /* Page protection bits */ | ||
47 | typedef struct { unsigned long pgprot; } pgprot_t; | ||
48 | #define pgprot_val(x) ((x).pgprot) | ||
49 | #define __pgprot(x) ((pgprot_t) { (x) }) | ||
50 | |||
51 | #else | ||
52 | |||
53 | /* | ||
54 | * .. while these make it easier on the compiler | ||
55 | */ | ||
56 | |||
57 | typedef pte_basic_t pte_t; | ||
58 | #define __pte(x) (x) | ||
59 | static inline pte_basic_t pte_val(pte_t pte) | ||
60 | { | ||
61 | return pte; | ||
62 | } | ||
63 | |||
64 | #ifdef CONFIG_PPC64 | ||
65 | typedef unsigned long pmd_t; | ||
66 | #define __pmd(x) (x) | ||
67 | static inline unsigned long pmd_val(pmd_t pmd) | ||
68 | { | ||
69 | return pmd; | ||
70 | } | ||
71 | |||
72 | #if defined(CONFIG_PPC_BOOK3S_64) || !defined(CONFIG_PPC_64K_PAGES) | ||
73 | typedef unsigned long pud_t; | ||
74 | #define __pud(x) (x) | ||
75 | static inline unsigned long pud_val(pud_t pud) | ||
76 | { | ||
77 | return pud; | ||
78 | } | ||
79 | #endif /* CONFIG_PPC_BOOK3S_64 || !CONFIG_PPC_64K_PAGES */ | ||
80 | #endif /* CONFIG_PPC64 */ | ||
81 | |||
82 | typedef unsigned long pgd_t; | ||
83 | #define __pgd(x) (x) | ||
84 | static inline unsigned long pgd_val(pgd_t pgd) | ||
85 | { | ||
86 | return pgd; | ||
87 | } | ||
88 | |||
89 | typedef unsigned long pgprot_t; | ||
90 | #define pgprot_val(x) (x) | ||
91 | #define __pgprot(x) (x) | ||
92 | |||
93 | #endif /* CONFIG_STRICT_MM_TYPECHECKS */ | ||
94 | /* | ||
95 | * With hash config 64k pages additionally define a bigger "real PTE" type that | ||
96 | * gathers the "second half" part of the PTE for pseudo 64k pages | ||
97 | */ | ||
98 | #if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64) | ||
99 | typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; | ||
100 | #else | ||
101 | typedef struct { pte_t pte; } real_pte_t; | ||
102 | #endif | ||
103 | #endif /* _ASM_POWERPC_PGTABLE_TYPES_H */ | ||
diff --git a/arch/powerpc/include/asm/pmac_feature.h b/arch/powerpc/include/asm/pmac_feature.h index 10902c9375d0..925697968946 100644 --- a/arch/powerpc/include/asm/pmac_feature.h +++ b/arch/powerpc/include/asm/pmac_feature.h | |||
@@ -46,7 +46,7 @@ | |||
46 | 46 | ||
47 | /* PowerSurge are the first generation of PCI Pmacs. This include | 47 | /* PowerSurge are the first generation of PCI Pmacs. This include |
48 | * all of the Grand-Central based machines. We currently don't | 48 | * all of the Grand-Central based machines. We currently don't |
49 | * differenciate most of them. | 49 | * differentiate most of them. |
50 | */ | 50 | */ |
51 | #define PMAC_TYPE_PSURGE 0x10 /* PowerSurge */ | 51 | #define PMAC_TYPE_PSURGE 0x10 /* PowerSurge */ |
52 | #define PMAC_TYPE_ANS 0x11 /* Apple Network Server */ | 52 | #define PMAC_TYPE_ANS 0x11 /* Apple Network Server */ |
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index ac2330820b9a..8ab8a1a9610a 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h | |||
@@ -236,7 +236,9 @@ struct thread_struct { | |||
236 | #endif | 236 | #endif |
237 | struct arch_hw_breakpoint hw_brk; /* info on the hardware breakpoint */ | 237 | struct arch_hw_breakpoint hw_brk; /* info on the hardware breakpoint */ |
238 | unsigned long trap_nr; /* last trap # on this thread */ | 238 | unsigned long trap_nr; /* last trap # on this thread */ |
239 | u8 load_fp; | ||
239 | #ifdef CONFIG_ALTIVEC | 240 | #ifdef CONFIG_ALTIVEC |
241 | u8 load_vec; | ||
240 | struct thread_vr_state vr_state; | 242 | struct thread_vr_state vr_state; |
241 | struct thread_vr_state *vr_save_area; | 243 | struct thread_vr_state *vr_save_area; |
242 | unsigned long vrsave; | 244 | unsigned long vrsave; |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index c4cb2ffc624e..f5f4c66bbbc9 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -75,6 +75,14 @@ | |||
75 | #define MSR_HV 0 | 75 | #define MSR_HV 0 |
76 | #endif | 76 | #endif |
77 | 77 | ||
78 | /* | ||
79 | * To be used in shared book E/book S, this avoids needing to worry about | ||
80 | * book S/book E in shared code | ||
81 | */ | ||
82 | #ifndef MSR_SPE | ||
83 | #define MSR_SPE 0 | ||
84 | #endif | ||
85 | |||
78 | #define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */ | 86 | #define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */ |
79 | #define MSR_VSX __MASK(MSR_VSX_LG) /* Enable VSX */ | 87 | #define MSR_VSX __MASK(MSR_VSX_LG) /* Enable VSX */ |
80 | #define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */ | 88 | #define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */ |
@@ -376,7 +384,7 @@ | |||
376 | #define SPRN_TSCR 0x399 /* Thread Switch Control Register */ | 384 | #define SPRN_TSCR 0x399 /* Thread Switch Control Register */ |
377 | 385 | ||
378 | #define SPRN_DEC 0x016 /* Decrement Register */ | 386 | #define SPRN_DEC 0x016 /* Decrement Register */ |
379 | #define SPRN_DER 0x095 /* Debug Enable Regsiter */ | 387 | #define SPRN_DER 0x095 /* Debug Enable Register */ |
380 | #define DER_RSTE 0x40000000 /* Reset Interrupt */ | 388 | #define DER_RSTE 0x40000000 /* Reset Interrupt */ |
381 | #define DER_CHSTPE 0x20000000 /* Check Stop */ | 389 | #define DER_CHSTPE 0x20000000 /* Check Stop */ |
382 | #define DER_MCIE 0x10000000 /* Machine Check Interrupt */ | 390 | #define DER_MCIE 0x10000000 /* Machine Check Interrupt */ |
@@ -401,7 +409,7 @@ | |||
401 | #define SPRN_DPDES 0x0B0 /* Directed Priv. Doorbell Exc. State */ | 409 | #define SPRN_DPDES 0x0B0 /* Directed Priv. Doorbell Exc. State */ |
402 | #define SPRN_EAR 0x11A /* External Address Register */ | 410 | #define SPRN_EAR 0x11A /* External Address Register */ |
403 | #define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */ | 411 | #define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */ |
404 | #define SPRN_HASH2 0x3D3 /* Secondary Hash Address Resgister */ | 412 | #define SPRN_HASH2 0x3D3 /* Secondary Hash Address Register */ |
405 | #define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */ | 413 | #define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */ |
406 | #define HID0_HDICE_SH (63 - 23) /* 970 HDEC interrupt enable */ | 414 | #define HID0_HDICE_SH (63 - 23) /* 970 HDEC interrupt enable */ |
407 | #define HID0_EMCP (1<<31) /* Enable Machine Check pin */ | 415 | #define HID0_EMCP (1<<31) /* Enable Machine Check pin */ |
@@ -514,7 +522,7 @@ | |||
514 | #define ICTRL_EICP 0x00000100 /* enable icache par. check */ | 522 | #define ICTRL_EICP 0x00000100 /* enable icache par. check */ |
515 | #define SPRN_IMISS 0x3D4 /* Instruction TLB Miss Register */ | 523 | #define SPRN_IMISS 0x3D4 /* Instruction TLB Miss Register */ |
516 | #define SPRN_IMMR 0x27E /* Internal Memory Map Register */ | 524 | #define SPRN_IMMR 0x27E /* Internal Memory Map Register */ |
517 | #define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ | 525 | #define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Register */ |
518 | #define SPRN_L2CR2 0x3f8 | 526 | #define SPRN_L2CR2 0x3f8 |
519 | #define L2CR_L2E 0x80000000 /* L2 enable */ | 527 | #define L2CR_L2E 0x80000000 /* L2 enable */ |
520 | #define L2CR_L2PE 0x40000000 /* L2 parity enable */ | 528 | #define L2CR_L2PE 0x40000000 /* L2 parity enable */ |
@@ -549,7 +557,7 @@ | |||
549 | #define L2CR_L2DO_745x 0x00010000 /* L2 data only (745x) */ | 557 | #define L2CR_L2DO_745x 0x00010000 /* L2 data only (745x) */ |
550 | #define L2CR_L2REP_745x 0x00001000 /* L2 repl. algorithm (745x) */ | 558 | #define L2CR_L2REP_745x 0x00001000 /* L2 repl. algorithm (745x) */ |
551 | #define L2CR_L2HWF_745x 0x00000800 /* L2 hardware flush (745x) */ | 559 | #define L2CR_L2HWF_745x 0x00000800 /* L2 hardware flush (745x) */ |
552 | #define SPRN_L3CR 0x3FA /* Level 3 Cache Control Regsiter */ | 560 | #define SPRN_L3CR 0x3FA /* Level 3 Cache Control Register */ |
553 | #define L3CR_L3E 0x80000000 /* L3 enable */ | 561 | #define L3CR_L3E 0x80000000 /* L3 enable */ |
554 | #define L3CR_L3PE 0x40000000 /* L3 data parity enable */ | 562 | #define L3CR_L3PE 0x40000000 /* L3 data parity enable */ |
555 | #define L3CR_L3APE 0x20000000 /* L3 addr parity enable */ | 563 | #define L3CR_L3APE 0x20000000 /* L3 addr parity enable */ |
@@ -1211,9 +1219,11 @@ static inline void mtmsr_isync(unsigned long val) | |||
1211 | #define mfspr(rn) ({unsigned long rval; \ | 1219 | #define mfspr(rn) ({unsigned long rval; \ |
1212 | asm volatile("mfspr %0," __stringify(rn) \ | 1220 | asm volatile("mfspr %0," __stringify(rn) \ |
1213 | : "=r" (rval)); rval;}) | 1221 | : "=r" (rval)); rval;}) |
1222 | #ifndef mtspr | ||
1214 | #define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \ | 1223 | #define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \ |
1215 | : "r" ((unsigned long)(v)) \ | 1224 | : "r" ((unsigned long)(v)) \ |
1216 | : "memory") | 1225 | : "memory") |
1226 | #endif | ||
1217 | 1227 | ||
1218 | extern void msr_check_and_set(unsigned long bits); | 1228 | extern void msr_check_and_set(unsigned long bits); |
1219 | extern bool strict_msr_control; | 1229 | extern bool strict_msr_control; |
diff --git a/arch/powerpc/include/asm/reg_8xx.h b/arch/powerpc/include/asm/reg_8xx.h index e8ea346b21d3..94d01f81e668 100644 --- a/arch/powerpc/include/asm/reg_8xx.h +++ b/arch/powerpc/include/asm/reg_8xx.h | |||
@@ -4,6 +4,8 @@ | |||
4 | #ifndef _ASM_POWERPC_REG_8xx_H | 4 | #ifndef _ASM_POWERPC_REG_8xx_H |
5 | #define _ASM_POWERPC_REG_8xx_H | 5 | #define _ASM_POWERPC_REG_8xx_H |
6 | 6 | ||
7 | #include <asm/mmu-8xx.h> | ||
8 | |||
7 | /* Cache control on the MPC8xx is provided through some additional | 9 | /* Cache control on the MPC8xx is provided through some additional |
8 | * special purpose registers. | 10 | * special purpose registers. |
9 | */ | 11 | */ |
@@ -14,6 +16,15 @@ | |||
14 | #define SPRN_DC_ADR 569 /* Address needed for some commands */ | 16 | #define SPRN_DC_ADR 569 /* Address needed for some commands */ |
15 | #define SPRN_DC_DAT 570 /* Read-only data register */ | 17 | #define SPRN_DC_DAT 570 /* Read-only data register */ |
16 | 18 | ||
19 | /* Misc Debug */ | ||
20 | #define SPRN_DPDR 630 | ||
21 | #define SPRN_MI_CAM 816 | ||
22 | #define SPRN_MI_RAM0 817 | ||
23 | #define SPRN_MI_RAM1 818 | ||
24 | #define SPRN_MD_CAM 824 | ||
25 | #define SPRN_MD_RAM0 825 | ||
26 | #define SPRN_MD_RAM1 826 | ||
27 | |||
17 | /* Commands. Only the first few are available to the instruction cache. | 28 | /* Commands. Only the first few are available to the instruction cache. |
18 | */ | 29 | */ |
19 | #define IDC_ENABLE 0x02000000 /* Cache enable */ | 30 | #define IDC_ENABLE 0x02000000 /* Cache enable */ |
@@ -39,4 +50,86 @@ | |||
39 | #define DC_DFWT 0x40000000 /* Data cache is forced write through */ | 50 | #define DC_DFWT 0x40000000 /* Data cache is forced write through */ |
40 | #define DC_LES 0x20000000 /* Caches are little endian mode */ | 51 | #define DC_LES 0x20000000 /* Caches are little endian mode */ |
41 | 52 | ||
53 | #ifdef CONFIG_8xx_CPU6 | ||
54 | #define do_mtspr_cpu6(rn, rn_addr, v) \ | ||
55 | do { \ | ||
56 | int _reg_cpu6 = rn_addr, _tmp_cpu6; \ | ||
57 | asm volatile("stw %0, %1;" \ | ||
58 | "lwz %0, %1;" \ | ||
59 | "mtspr " __stringify(rn) ",%2" : \ | ||
60 | : "r" (_reg_cpu6), "m"(_tmp_cpu6), \ | ||
61 | "r" ((unsigned long)(v)) \ | ||
62 | : "memory"); \ | ||
63 | } while (0) | ||
64 | |||
65 | #define do_mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \ | ||
66 | : "r" ((unsigned long)(v)) \ | ||
67 | : "memory") | ||
68 | #define mtspr(rn, v) \ | ||
69 | do { \ | ||
70 | if (rn == SPRN_IMMR) \ | ||
71 | do_mtspr_cpu6(rn, 0x3d30, v); \ | ||
72 | else if (rn == SPRN_IC_CST) \ | ||
73 | do_mtspr_cpu6(rn, 0x2110, v); \ | ||
74 | else if (rn == SPRN_IC_ADR) \ | ||
75 | do_mtspr_cpu6(rn, 0x2310, v); \ | ||
76 | else if (rn == SPRN_IC_DAT) \ | ||
77 | do_mtspr_cpu6(rn, 0x2510, v); \ | ||
78 | else if (rn == SPRN_DC_CST) \ | ||
79 | do_mtspr_cpu6(rn, 0x3110, v); \ | ||
80 | else if (rn == SPRN_DC_ADR) \ | ||
81 | do_mtspr_cpu6(rn, 0x3310, v); \ | ||
82 | else if (rn == SPRN_DC_DAT) \ | ||
83 | do_mtspr_cpu6(rn, 0x3510, v); \ | ||
84 | else if (rn == SPRN_MI_CTR) \ | ||
85 | do_mtspr_cpu6(rn, 0x2180, v); \ | ||
86 | else if (rn == SPRN_MI_AP) \ | ||
87 | do_mtspr_cpu6(rn, 0x2580, v); \ | ||
88 | else if (rn == SPRN_MI_EPN) \ | ||
89 | do_mtspr_cpu6(rn, 0x2780, v); \ | ||
90 | else if (rn == SPRN_MI_TWC) \ | ||
91 | do_mtspr_cpu6(rn, 0x2b80, v); \ | ||
92 | else if (rn == SPRN_MI_RPN) \ | ||
93 | do_mtspr_cpu6(rn, 0x2d80, v); \ | ||
94 | else if (rn == SPRN_MI_CAM) \ | ||
95 | do_mtspr_cpu6(rn, 0x2190, v); \ | ||
96 | else if (rn == SPRN_MI_RAM0) \ | ||
97 | do_mtspr_cpu6(rn, 0x2390, v); \ | ||
98 | else if (rn == SPRN_MI_RAM1) \ | ||
99 | do_mtspr_cpu6(rn, 0x2590, v); \ | ||
100 | else if (rn == SPRN_MD_CTR) \ | ||
101 | do_mtspr_cpu6(rn, 0x3180, v); \ | ||
102 | else if (rn == SPRN_M_CASID) \ | ||
103 | do_mtspr_cpu6(rn, 0x3380, v); \ | ||
104 | else if (rn == SPRN_MD_AP) \ | ||
105 | do_mtspr_cpu6(rn, 0x3580, v); \ | ||
106 | else if (rn == SPRN_MD_EPN) \ | ||
107 | do_mtspr_cpu6(rn, 0x3780, v); \ | ||
108 | else if (rn == SPRN_M_TWB) \ | ||
109 | do_mtspr_cpu6(rn, 0x3980, v); \ | ||
110 | else if (rn == SPRN_MD_TWC) \ | ||
111 | do_mtspr_cpu6(rn, 0x3b80, v); \ | ||
112 | else if (rn == SPRN_MD_RPN) \ | ||
113 | do_mtspr_cpu6(rn, 0x3d80, v); \ | ||
114 | else if (rn == SPRN_M_TW) \ | ||
115 | do_mtspr_cpu6(rn, 0x3f80, v); \ | ||
116 | else if (rn == SPRN_MD_CAM) \ | ||
117 | do_mtspr_cpu6(rn, 0x3190, v); \ | ||
118 | else if (rn == SPRN_MD_RAM0) \ | ||
119 | do_mtspr_cpu6(rn, 0x3390, v); \ | ||
120 | else if (rn == SPRN_MD_RAM1) \ | ||
121 | do_mtspr_cpu6(rn, 0x3590, v); \ | ||
122 | else if (rn == SPRN_DEC) \ | ||
123 | do_mtspr_cpu6(rn, 0x2c00, v); \ | ||
124 | else if (rn == SPRN_TBWL) \ | ||
125 | do_mtspr_cpu6(rn, 0x3880, v); \ | ||
126 | else if (rn == SPRN_TBWU) \ | ||
127 | do_mtspr_cpu6(rn, 0x3a80, v); \ | ||
128 | else if (rn == SPRN_DPDR) \ | ||
129 | do_mtspr_cpu6(rn, 0x2d30, v); \ | ||
130 | else \ | ||
131 | do_mtspr(rn, v); \ | ||
132 | } while (0) | ||
133 | #endif | ||
134 | |||
42 | #endif /* _ASM_POWERPC_REG_8xx_H */ | 135 | #endif /* _ASM_POWERPC_REG_8xx_H */ |
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index 2fef74b474f0..737e012ef56e 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h | |||
@@ -681,7 +681,7 @@ | |||
681 | #define SPRN_CDBCR 0x3D7 /* Cache Debug Control Register */ | 681 | #define SPRN_CDBCR 0x3D7 /* Cache Debug Control Register */ |
682 | #define SPRN_TBHI 0x3DC /* Time Base High */ | 682 | #define SPRN_TBHI 0x3DC /* Time Base High */ |
683 | #define SPRN_TBLO 0x3DD /* Time Base Low */ | 683 | #define SPRN_TBLO 0x3DD /* Time Base Low */ |
684 | #define SPRN_DBCR 0x3F2 /* Debug Control Regsiter */ | 684 | #define SPRN_DBCR 0x3F2 /* Debug Control Register */ |
685 | #define SPRN_PBL1 0x3FC /* Protection Bound Lower 1 */ | 685 | #define SPRN_PBL1 0x3FC /* Protection Bound Lower 1 */ |
686 | #define SPRN_PBL2 0x3FE /* Protection Bound Lower 2 */ | 686 | #define SPRN_PBL2 0x3FE /* Protection Bound Lower 2 */ |
687 | #define SPRN_PBU1 0x3FD /* Protection Bound Upper 1 */ | 687 | #define SPRN_PBU1 0x3FD /* Protection Bound Upper 1 */ |
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h index a5e930aca804..abf5866e08c6 100644 --- a/arch/powerpc/include/asm/sections.h +++ b/arch/powerpc/include/asm/sections.h | |||
@@ -22,6 +22,18 @@ static inline int in_kernel_text(unsigned long addr) | |||
22 | return 0; | 22 | return 0; |
23 | } | 23 | } |
24 | 24 | ||
25 | static inline unsigned long kernel_toc_addr(void) | ||
26 | { | ||
27 | /* Defined by the linker, see vmlinux.lds.S */ | ||
28 | extern unsigned long __toc_start; | ||
29 | |||
30 | /* | ||
31 | * The TOC register (r2) points 32kB into the TOC, so that 64kB of | ||
32 | * the TOC can be addressed using a single machine instruction. | ||
33 | */ | ||
34 | return (unsigned long)(&__toc_start) + 0x8000UL; | ||
35 | } | ||
36 | |||
25 | static inline int overlaps_interrupt_vector_text(unsigned long start, | 37 | static inline int overlaps_interrupt_vector_text(unsigned long start, |
26 | unsigned long end) | 38 | unsigned long end) |
27 | { | 39 | { |
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 78083ed20792..e1afd4c4f695 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h | |||
@@ -67,6 +67,9 @@ void generic_cpu_die(unsigned int cpu); | |||
67 | void generic_set_cpu_dead(unsigned int cpu); | 67 | void generic_set_cpu_dead(unsigned int cpu); |
68 | void generic_set_cpu_up(unsigned int cpu); | 68 | void generic_set_cpu_up(unsigned int cpu); |
69 | int generic_check_cpu_restart(unsigned int cpu); | 69 | int generic_check_cpu_restart(unsigned int cpu); |
70 | int is_cpu_dead(unsigned int cpu); | ||
71 | #else | ||
72 | #define generic_set_cpu_up(i) do { } while (0) | ||
70 | #endif | 73 | #endif |
71 | 74 | ||
72 | #ifdef CONFIG_PPC64 | 75 | #ifdef CONFIG_PPC64 |
@@ -201,6 +204,7 @@ extern void generic_secondary_thread_init(void); | |||
201 | extern unsigned long __secondary_hold_spinloop; | 204 | extern unsigned long __secondary_hold_spinloop; |
202 | extern unsigned long __secondary_hold_acknowledge; | 205 | extern unsigned long __secondary_hold_acknowledge; |
203 | extern char __secondary_hold; | 206 | extern char __secondary_hold; |
207 | extern unsigned int booting_thread_hwid; | ||
204 | 208 | ||
205 | extern void __early_start(void); | 209 | extern void __early_start(void); |
206 | #endif /* __ASSEMBLY__ */ | 210 | #endif /* __ASSEMBLY__ */ |
diff --git a/arch/powerpc/include/asm/smu.h b/arch/powerpc/include/asm/smu.h index 37d2da6feabf..f280dd11243f 100644 --- a/arch/powerpc/include/asm/smu.h +++ b/arch/powerpc/include/asm/smu.h | |||
@@ -154,7 +154,7 @@ | |||
154 | * | 154 | * |
155 | * The Darwin I2C driver is less subtle though. On any non-success status | 155 | * The Darwin I2C driver is less subtle though. On any non-success status |
156 | * from the response command, it waits 5ms and tries again up to 20 times, | 156 | * from the response command, it waits 5ms and tries again up to 20 times, |
157 | * it doesn't differenciate between fatal errors or "busy" status. | 157 | * it doesn't differentiate between fatal errors or "busy" status. |
158 | * | 158 | * |
159 | * This driver provides an asynchronous paramblock based i2c command | 159 | * This driver provides an asynchronous paramblock based i2c command |
160 | * interface to be used either directly by low level code or by a higher | 160 | * interface to be used either directly by low level code or by a higher |
diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 5b268b6be74c..17c8380673a6 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h | |||
@@ -28,12 +28,14 @@ extern void giveup_all(struct task_struct *); | |||
28 | extern void enable_kernel_fp(void); | 28 | extern void enable_kernel_fp(void); |
29 | extern void flush_fp_to_thread(struct task_struct *); | 29 | extern void flush_fp_to_thread(struct task_struct *); |
30 | extern void giveup_fpu(struct task_struct *); | 30 | extern void giveup_fpu(struct task_struct *); |
31 | extern void __giveup_fpu(struct task_struct *); | 31 | extern void save_fpu(struct task_struct *); |
32 | static inline void disable_kernel_fp(void) | 32 | static inline void disable_kernel_fp(void) |
33 | { | 33 | { |
34 | msr_check_and_clear(MSR_FP); | 34 | msr_check_and_clear(MSR_FP); |
35 | } | 35 | } |
36 | #else | 36 | #else |
37 | static inline void __giveup_fpu(struct task_struct *t) { } | ||
38 | static inline void save_fpu(struct task_struct *t) { } | ||
37 | static inline void flush_fp_to_thread(struct task_struct *t) { } | 39 | static inline void flush_fp_to_thread(struct task_struct *t) { } |
38 | #endif | 40 | #endif |
39 | 41 | ||
@@ -41,18 +43,19 @@ static inline void flush_fp_to_thread(struct task_struct *t) { } | |||
41 | extern void enable_kernel_altivec(void); | 43 | extern void enable_kernel_altivec(void); |
42 | extern void flush_altivec_to_thread(struct task_struct *); | 44 | extern void flush_altivec_to_thread(struct task_struct *); |
43 | extern void giveup_altivec(struct task_struct *); | 45 | extern void giveup_altivec(struct task_struct *); |
44 | extern void __giveup_altivec(struct task_struct *); | 46 | extern void save_altivec(struct task_struct *); |
45 | static inline void disable_kernel_altivec(void) | 47 | static inline void disable_kernel_altivec(void) |
46 | { | 48 | { |
47 | msr_check_and_clear(MSR_VEC); | 49 | msr_check_and_clear(MSR_VEC); |
48 | } | 50 | } |
51 | #else | ||
52 | static inline void save_altivec(struct task_struct *t) { } | ||
53 | static inline void __giveup_altivec(struct task_struct *t) { } | ||
49 | #endif | 54 | #endif |
50 | 55 | ||
51 | #ifdef CONFIG_VSX | 56 | #ifdef CONFIG_VSX |
52 | extern void enable_kernel_vsx(void); | 57 | extern void enable_kernel_vsx(void); |
53 | extern void flush_vsx_to_thread(struct task_struct *); | 58 | extern void flush_vsx_to_thread(struct task_struct *); |
54 | extern void giveup_vsx(struct task_struct *); | ||
55 | extern void __giveup_vsx(struct task_struct *); | ||
56 | static inline void disable_kernel_vsx(void) | 59 | static inline void disable_kernel_vsx(void) |
57 | { | 60 | { |
58 | msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); | 61 | msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); |
@@ -68,6 +71,8 @@ static inline void disable_kernel_spe(void) | |||
68 | { | 71 | { |
69 | msr_check_and_clear(MSR_SPE); | 72 | msr_check_and_clear(MSR_SPE); |
70 | } | 73 | } |
74 | #else | ||
75 | static inline void __giveup_spe(struct task_struct *t) { } | ||
71 | #endif | 76 | #endif |
72 | 77 | ||
73 | static inline void clear_task_ebb(struct task_struct *t) | 78 | static inline void clear_task_ebb(struct task_struct *t) |
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index 2d7109a8d296..1092fdd7e737 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h | |||
@@ -31,8 +31,6 @@ extern void tick_broadcast_ipi_handler(void); | |||
31 | 31 | ||
32 | extern void generic_calibrate_decr(void); | 32 | extern void generic_calibrate_decr(void); |
33 | 33 | ||
34 | extern void set_dec_cpu6(unsigned int val); | ||
35 | |||
36 | /* Some sane defaults: 125 MHz timebase, 1GHz processor */ | 34 | /* Some sane defaults: 125 MHz timebase, 1GHz processor */ |
37 | extern unsigned long ppc_proc_freq; | 35 | extern unsigned long ppc_proc_freq; |
38 | #define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8) | 36 | #define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8) |
@@ -166,14 +164,12 @@ static inline void set_dec(int val) | |||
166 | { | 164 | { |
167 | #if defined(CONFIG_40x) | 165 | #if defined(CONFIG_40x) |
168 | mtspr(SPRN_PIT, val); | 166 | mtspr(SPRN_PIT, val); |
169 | #elif defined(CONFIG_8xx_CPU6) | ||
170 | set_dec_cpu6(val - 1); | ||
171 | #else | 167 | #else |
172 | #ifndef CONFIG_BOOKE | 168 | #ifndef CONFIG_BOOKE |
173 | --val; | 169 | --val; |
174 | #endif | 170 | #endif |
175 | mtspr(SPRN_DEC, val); | 171 | mtspr(SPRN_DEC, val); |
176 | #endif /* not 40x or 8xx_CPU6 */ | 172 | #endif /* not 40x */ |
177 | } | 173 | } |
178 | 174 | ||
179 | static inline unsigned long tb_ticks_since(unsigned long tstamp) | 175 | static inline unsigned long tb_ticks_since(unsigned long tstamp) |
diff --git a/arch/powerpc/include/asm/tlbflush.h b/arch/powerpc/include/asm/tlbflush.h index 23d351ca0303..9f77f85e3e99 100644 --- a/arch/powerpc/include/asm/tlbflush.h +++ b/arch/powerpc/include/asm/tlbflush.h | |||
@@ -78,97 +78,7 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) | |||
78 | } | 78 | } |
79 | 79 | ||
80 | #elif defined(CONFIG_PPC_STD_MMU_64) | 80 | #elif defined(CONFIG_PPC_STD_MMU_64) |
81 | 81 | #include <asm/book3s/64/tlbflush-hash.h> | |
82 | #define MMU_NO_CONTEXT 0 | ||
83 | |||
84 | /* | ||
85 | * TLB flushing for 64-bit hash-MMU CPUs | ||
86 | */ | ||
87 | |||
88 | #include <linux/percpu.h> | ||
89 | #include <asm/page.h> | ||
90 | |||
91 | #define PPC64_TLB_BATCH_NR 192 | ||
92 | |||
93 | struct ppc64_tlb_batch { | ||
94 | int active; | ||
95 | unsigned long index; | ||
96 | struct mm_struct *mm; | ||
97 | real_pte_t pte[PPC64_TLB_BATCH_NR]; | ||
98 | unsigned long vpn[PPC64_TLB_BATCH_NR]; | ||
99 | unsigned int psize; | ||
100 | int ssize; | ||
101 | }; | ||
102 | DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); | ||
103 | |||
104 | extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch); | ||
105 | |||
106 | #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE | ||
107 | |||
108 | static inline void arch_enter_lazy_mmu_mode(void) | ||
109 | { | ||
110 | struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch); | ||
111 | |||
112 | batch->active = 1; | ||
113 | } | ||
114 | |||
115 | static inline void arch_leave_lazy_mmu_mode(void) | ||
116 | { | ||
117 | struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch); | ||
118 | |||
119 | if (batch->index) | ||
120 | __flush_tlb_pending(batch); | ||
121 | batch->active = 0; | ||
122 | } | ||
123 | |||
124 | #define arch_flush_lazy_mmu_mode() do {} while (0) | ||
125 | |||
126 | |||
127 | extern void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, | ||
128 | int ssize, unsigned long flags); | ||
129 | extern void flush_hash_range(unsigned long number, int local); | ||
130 | extern void flush_hash_hugepage(unsigned long vsid, unsigned long addr, | ||
131 | pmd_t *pmdp, unsigned int psize, int ssize, | ||
132 | unsigned long flags); | ||
133 | |||
134 | static inline void local_flush_tlb_mm(struct mm_struct *mm) | ||
135 | { | ||
136 | } | ||
137 | |||
138 | static inline void flush_tlb_mm(struct mm_struct *mm) | ||
139 | { | ||
140 | } | ||
141 | |||
142 | static inline void local_flush_tlb_page(struct vm_area_struct *vma, | ||
143 | unsigned long vmaddr) | ||
144 | { | ||
145 | } | ||
146 | |||
147 | static inline void flush_tlb_page(struct vm_area_struct *vma, | ||
148 | unsigned long vmaddr) | ||
149 | { | ||
150 | } | ||
151 | |||
152 | static inline void flush_tlb_page_nohash(struct vm_area_struct *vma, | ||
153 | unsigned long vmaddr) | ||
154 | { | ||
155 | } | ||
156 | |||
157 | static inline void flush_tlb_range(struct vm_area_struct *vma, | ||
158 | unsigned long start, unsigned long end) | ||
159 | { | ||
160 | } | ||
161 | |||
162 | static inline void flush_tlb_kernel_range(unsigned long start, | ||
163 | unsigned long end) | ||
164 | { | ||
165 | } | ||
166 | |||
167 | /* Private function for use by PCI IO mapping code */ | ||
168 | extern void __flush_hash_table_range(struct mm_struct *mm, unsigned long start, | ||
169 | unsigned long end); | ||
170 | extern void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd, | ||
171 | unsigned long addr); | ||
172 | #else | 82 | #else |
173 | #error Unsupported MMU type | 83 | #error Unsupported MMU type |
174 | #endif | 84 | #endif |
diff --git a/arch/powerpc/include/asm/uninorth.h b/arch/powerpc/include/asm/uninorth.h index d12b11d7641e..a1d112979fd2 100644 --- a/arch/powerpc/include/asm/uninorth.h +++ b/arch/powerpc/include/asm/uninorth.h | |||
@@ -132,7 +132,7 @@ | |||
132 | 132 | ||
133 | /* This one _might_ return the CPU number of the CPU reading it; | 133 | /* This one _might_ return the CPU number of the CPU reading it; |
134 | * the bootROM decides whether to boot or to sleep/spinloop depending | 134 | * the bootROM decides whether to boot or to sleep/spinloop depending |
135 | * on this register beeing 0 or not | 135 | * on this register being 0 or not |
136 | */ | 136 | */ |
137 | #define UNI_N_CPU_NUMBER 0x0050 | 137 | #define UNI_N_CPU_NUMBER 0x0050 |
138 | 138 | ||
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h index 254604856e69..04ef3ae511da 100644 --- a/arch/powerpc/include/asm/xics.h +++ b/arch/powerpc/include/asm/xics.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Common definitions accross all variants of ICP and ICS interrupt | 2 | * Common definitions across all variants of ICP and ICS interrupt |
3 | * controllers. | 3 | * controllers. |
4 | */ | 4 | */ |
5 | 5 | ||
diff --git a/arch/powerpc/include/uapi/asm/epapr_hcalls.h b/arch/powerpc/include/uapi/asm/epapr_hcalls.h index 7f9c74b46704..b4504f394427 100644 --- a/arch/powerpc/include/uapi/asm/epapr_hcalls.h +++ b/arch/powerpc/include/uapi/asm/epapr_hcalls.h | |||
@@ -78,7 +78,7 @@ | |||
78 | #define EV_SUCCESS 0 | 78 | #define EV_SUCCESS 0 |
79 | #define EV_EPERM 1 /* Operation not permitted */ | 79 | #define EV_EPERM 1 /* Operation not permitted */ |
80 | #define EV_ENOENT 2 /* Entry Not Found */ | 80 | #define EV_ENOENT 2 /* Entry Not Found */ |
81 | #define EV_EIO 3 /* I/O error occured */ | 81 | #define EV_EIO 3 /* I/O error occurred */ |
82 | #define EV_EAGAIN 4 /* The operation had insufficient | 82 | #define EV_EAGAIN 4 /* The operation had insufficient |
83 | * resources to complete and should be | 83 | * resources to complete and should be |
84 | * retried | 84 | * retried |
@@ -89,7 +89,7 @@ | |||
89 | #define EV_ENODEV 7 /* No such device */ | 89 | #define EV_ENODEV 7 /* No such device */ |
90 | #define EV_EINVAL 8 /* An argument supplied to the hcall | 90 | #define EV_EINVAL 8 /* An argument supplied to the hcall |
91 | was out of range or invalid */ | 91 | was out of range or invalid */ |
92 | #define EV_INTERNAL 9 /* An internal error occured */ | 92 | #define EV_INTERNAL 9 /* An internal error occurred */ |
93 | #define EV_CONFIG 10 /* A configuration error was detected */ | 93 | #define EV_CONFIG 10 /* A configuration error was detected */ |
94 | #define EV_INVALID_STATE 11 /* The object is in an invalid state */ | 94 | #define EV_INVALID_STATE 11 /* The object is in an invalid state */ |
95 | #define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */ | 95 | #define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */ |
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 794f22adf99d..2da380fcc34c 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -16,14 +16,14 @@ endif | |||
16 | 16 | ||
17 | ifdef CONFIG_FUNCTION_TRACER | 17 | ifdef CONFIG_FUNCTION_TRACER |
18 | # Do not trace early boot code | 18 | # Do not trace early boot code |
19 | CFLAGS_REMOVE_cputable.o = -pg -mno-sched-epilog | 19 | CFLAGS_REMOVE_cputable.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) |
20 | CFLAGS_REMOVE_prom_init.o = -pg -mno-sched-epilog | 20 | CFLAGS_REMOVE_prom_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) |
21 | CFLAGS_REMOVE_btext.o = -pg -mno-sched-epilog | 21 | CFLAGS_REMOVE_btext.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) |
22 | CFLAGS_REMOVE_prom.o = -pg -mno-sched-epilog | 22 | CFLAGS_REMOVE_prom.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) |
23 | # do not trace tracer code | 23 | # do not trace tracer code |
24 | CFLAGS_REMOVE_ftrace.o = -pg -mno-sched-epilog | 24 | CFLAGS_REMOVE_ftrace.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) |
25 | # timers used by tracing | 25 | # timers used by tracing |
26 | CFLAGS_REMOVE_time.o = -pg -mno-sched-epilog | 26 | CFLAGS_REMOVE_time.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) |
27 | endif | 27 | endif |
28 | 28 | ||
29 | obj-y := cputable.o ptrace.o syscalls.o \ | 29 | obj-y := cputable.o ptrace.o syscalls.o \ |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 07cebc3514f3..0d0183d3180a 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -95,12 +95,14 @@ int main(void) | |||
95 | DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fp_state)); | 95 | DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fp_state)); |
96 | DEFINE(THREAD_FPSAVEAREA, offsetof(struct thread_struct, fp_save_area)); | 96 | DEFINE(THREAD_FPSAVEAREA, offsetof(struct thread_struct, fp_save_area)); |
97 | DEFINE(FPSTATE_FPSCR, offsetof(struct thread_fp_state, fpscr)); | 97 | DEFINE(FPSTATE_FPSCR, offsetof(struct thread_fp_state, fpscr)); |
98 | DEFINE(THREAD_LOAD_FP, offsetof(struct thread_struct, load_fp)); | ||
98 | #ifdef CONFIG_ALTIVEC | 99 | #ifdef CONFIG_ALTIVEC |
99 | DEFINE(THREAD_VRSTATE, offsetof(struct thread_struct, vr_state)); | 100 | DEFINE(THREAD_VRSTATE, offsetof(struct thread_struct, vr_state)); |
100 | DEFINE(THREAD_VRSAVEAREA, offsetof(struct thread_struct, vr_save_area)); | 101 | DEFINE(THREAD_VRSAVEAREA, offsetof(struct thread_struct, vr_save_area)); |
101 | DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave)); | 102 | DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave)); |
102 | DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr)); | 103 | DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr)); |
103 | DEFINE(VRSTATE_VSCR, offsetof(struct thread_vr_state, vscr)); | 104 | DEFINE(VRSTATE_VSCR, offsetof(struct thread_vr_state, vscr)); |
105 | DEFINE(THREAD_LOAD_VEC, offsetof(struct thread_struct, load_vec)); | ||
104 | #endif /* CONFIG_ALTIVEC */ | 106 | #endif /* CONFIG_ALTIVEC */ |
105 | #ifdef CONFIG_VSX | 107 | #ifdef CONFIG_VSX |
106 | DEFINE(THREAD_USED_VSR, offsetof(struct thread_struct, used_vsr)); | 108 | DEFINE(THREAD_USED_VSR, offsetof(struct thread_struct, used_vsr)); |
@@ -374,6 +376,7 @@ int main(void) | |||
374 | DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); | 376 | DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); |
375 | DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); | 377 | DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); |
376 | DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore)); | 378 | DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore)); |
379 | DEFINE(CPU_DOWN_FLUSH, offsetof(struct cpu_spec, cpu_down_flush)); | ||
377 | 380 | ||
378 | DEFINE(pbe_address, offsetof(struct pbe, address)); | 381 | DEFINE(pbe_address, offsetof(struct pbe, address)); |
379 | DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); | 382 | DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); |
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S index dddba3e94260..462aed9bcf51 100644 --- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S | |||
@@ -13,11 +13,13 @@ | |||
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <asm/page.h> | ||
16 | #include <asm/processor.h> | 17 | #include <asm/processor.h> |
17 | #include <asm/cputable.h> | 18 | #include <asm/cputable.h> |
18 | #include <asm/ppc_asm.h> | 19 | #include <asm/ppc_asm.h> |
19 | #include <asm/mmu-book3e.h> | 20 | #include <asm/mmu-book3e.h> |
20 | #include <asm/asm-offsets.h> | 21 | #include <asm/asm-offsets.h> |
22 | #include <asm/mpc85xx.h> | ||
21 | 23 | ||
22 | _GLOBAL(__e500_icache_setup) | 24 | _GLOBAL(__e500_icache_setup) |
23 | mfspr r0, SPRN_L1CSR1 | 25 | mfspr r0, SPRN_L1CSR1 |
@@ -233,3 +235,113 @@ _GLOBAL(__setup_cpu_e5500) | |||
233 | mtlr r5 | 235 | mtlr r5 |
234 | blr | 236 | blr |
235 | #endif | 237 | #endif |
238 | |||
239 | /* flush L1 date cache, it can apply to e500v2, e500mc and e5500 */ | ||
240 | _GLOBAL(flush_dcache_L1) | ||
241 | mfmsr r10 | ||
242 | wrteei 0 | ||
243 | |||
244 | mfspr r3,SPRN_L1CFG0 | ||
245 | rlwinm r5,r3,9,3 /* Extract cache block size */ | ||
246 | twlgti r5,1 /* Only 32 and 64 byte cache blocks | ||
247 | * are currently defined. | ||
248 | */ | ||
249 | li r4,32 | ||
250 | subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) - | ||
251 | * log2(number of ways) | ||
252 | */ | ||
253 | slw r5,r4,r5 /* r5 = cache block size */ | ||
254 | |||
255 | rlwinm r7,r3,0,0xff /* Extract number of KiB in the cache */ | ||
256 | mulli r7,r7,13 /* An 8-way cache will require 13 | ||
257 | * loads per set. | ||
258 | */ | ||
259 | slw r7,r7,r6 | ||
260 | |||
261 | /* save off HID0 and set DCFA */ | ||
262 | mfspr r8,SPRN_HID0 | ||
263 | ori r9,r8,HID0_DCFA@l | ||
264 | mtspr SPRN_HID0,r9 | ||
265 | isync | ||
266 | |||
267 | LOAD_REG_IMMEDIATE(r6, KERNELBASE) | ||
268 | mr r4, r6 | ||
269 | mtctr r7 | ||
270 | |||
271 | 1: lwz r3,0(r4) /* Load... */ | ||
272 | add r4,r4,r5 | ||
273 | bdnz 1b | ||
274 | |||
275 | msync | ||
276 | mr r4, r6 | ||
277 | mtctr r7 | ||
278 | |||
279 | 1: dcbf 0,r4 /* ...and flush. */ | ||
280 | add r4,r4,r5 | ||
281 | bdnz 1b | ||
282 | |||
283 | /* restore HID0 */ | ||
284 | mtspr SPRN_HID0,r8 | ||
285 | isync | ||
286 | |||
287 | wrtee r10 | ||
288 | |||
289 | blr | ||
290 | |||
291 | has_L2_cache: | ||
292 | /* skip L2 cache on P2040/P2040E as they have no L2 cache */ | ||
293 | mfspr r3, SPRN_SVR | ||
294 | /* shift right by 8 bits and clear E bit of SVR */ | ||
295 | rlwinm r4, r3, 24, ~0x800 | ||
296 | |||
297 | lis r3, SVR_P2040@h | ||
298 | ori r3, r3, SVR_P2040@l | ||
299 | cmpw r4, r3 | ||
300 | beq 1f | ||
301 | |||
302 | li r3, 1 | ||
303 | blr | ||
304 | 1: | ||
305 | li r3, 0 | ||
306 | blr | ||
307 | |||
308 | /* flush backside L2 cache */ | ||
309 | flush_backside_L2_cache: | ||
310 | mflr r10 | ||
311 | bl has_L2_cache | ||
312 | mtlr r10 | ||
313 | cmpwi r3, 0 | ||
314 | beq 2f | ||
315 | |||
316 | /* Flush the L2 cache */ | ||
317 | mfspr r3, SPRN_L2CSR0 | ||
318 | ori r3, r3, L2CSR0_L2FL@l | ||
319 | msync | ||
320 | isync | ||
321 | mtspr SPRN_L2CSR0,r3 | ||
322 | isync | ||
323 | |||
324 | /* check if it is complete */ | ||
325 | 1: mfspr r3,SPRN_L2CSR0 | ||
326 | andi. r3, r3, L2CSR0_L2FL@l | ||
327 | bne 1b | ||
328 | 2: | ||
329 | blr | ||
330 | |||
331 | _GLOBAL(cpu_down_flush_e500v2) | ||
332 | mflr r0 | ||
333 | bl flush_dcache_L1 | ||
334 | mtlr r0 | ||
335 | blr | ||
336 | |||
337 | _GLOBAL(cpu_down_flush_e500mc) | ||
338 | _GLOBAL(cpu_down_flush_e5500) | ||
339 | mflr r0 | ||
340 | bl flush_dcache_L1 | ||
341 | bl flush_backside_L2_cache | ||
342 | mtlr r0 | ||
343 | blr | ||
344 | |||
345 | /* L1 Data Cache of e6500 contains no modified data, no flush is required */ | ||
346 | _GLOBAL(cpu_down_flush_e6500) | ||
347 | blr | ||
diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S index 9c9b7411b28b..584e119fa8b0 100644 --- a/arch/powerpc/kernel/cpu_setup_power.S +++ b/arch/powerpc/kernel/cpu_setup_power.S | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <asm/ppc_asm.h> | 15 | #include <asm/ppc_asm.h> |
16 | #include <asm/asm-offsets.h> | 16 | #include <asm/asm-offsets.h> |
17 | #include <asm/cache.h> | 17 | #include <asm/cache.h> |
18 | #include <asm/book3s/64/mmu-hash.h> | ||
18 | 19 | ||
19 | /* Entry: r3 = crap, r4 = ptr to cputable entry | 20 | /* Entry: r3 = crap, r4 = ptr to cputable entry |
20 | * | 21 | * |
@@ -83,6 +84,39 @@ _GLOBAL(__restore_cpu_power8) | |||
83 | mtlr r11 | 84 | mtlr r11 |
84 | blr | 85 | blr |
85 | 86 | ||
87 | _GLOBAL(__setup_cpu_power9) | ||
88 | mflr r11 | ||
89 | bl __init_FSCR | ||
90 | bl __init_hvmode_206 | ||
91 | mtlr r11 | ||
92 | beqlr | ||
93 | li r0,0 | ||
94 | mtspr SPRN_LPID,r0 | ||
95 | mfspr r3,SPRN_LPCR | ||
96 | ori r3, r3, LPCR_PECEDH | ||
97 | bl __init_LPCR | ||
98 | bl __init_HFSCR | ||
99 | bl __init_tlb_power9 | ||
100 | mtlr r11 | ||
101 | blr | ||
102 | |||
103 | _GLOBAL(__restore_cpu_power9) | ||
104 | mflr r11 | ||
105 | bl __init_FSCR | ||
106 | mfmsr r3 | ||
107 | rldicl. r0,r3,4,63 | ||
108 | mtlr r11 | ||
109 | beqlr | ||
110 | li r0,0 | ||
111 | mtspr SPRN_LPID,r0 | ||
112 | mfspr r3,SPRN_LPCR | ||
113 | ori r3, r3, LPCR_PECEDH | ||
114 | bl __init_LPCR | ||
115 | bl __init_HFSCR | ||
116 | bl __init_tlb_power9 | ||
117 | mtlr r11 | ||
118 | blr | ||
119 | |||
86 | __init_hvmode_206: | 120 | __init_hvmode_206: |
87 | /* Disable CPU_FTR_HVMODE and exit if MSR:HV is not set */ | 121 | /* Disable CPU_FTR_HVMODE and exit if MSR:HV is not set */ |
88 | mfmsr r3 | 122 | mfmsr r3 |
@@ -139,7 +173,7 @@ __init_HFSCR: | |||
139 | * (invalidate by congruence class). P7 has 128 CCs., P8 has 512. | 173 | * (invalidate by congruence class). P7 has 128 CCs., P8 has 512. |
140 | */ | 174 | */ |
141 | __init_tlb_power7: | 175 | __init_tlb_power7: |
142 | li r6,128 | 176 | li r6,POWER7_TLB_SETS |
143 | mtctr r6 | 177 | mtctr r6 |
144 | li r7,0xc00 /* IS field = 0b11 */ | 178 | li r7,0xc00 /* IS field = 0b11 */ |
145 | ptesync | 179 | ptesync |
@@ -150,7 +184,18 @@ __init_tlb_power7: | |||
150 | 1: blr | 184 | 1: blr |
151 | 185 | ||
152 | __init_tlb_power8: | 186 | __init_tlb_power8: |
153 | li r6,512 | 187 | li r6,POWER8_TLB_SETS |
188 | mtctr r6 | ||
189 | li r7,0xc00 /* IS field = 0b11 */ | ||
190 | ptesync | ||
191 | 2: tlbiel r7 | ||
192 | addi r7,r7,0x1000 | ||
193 | bdnz 2b | ||
194 | ptesync | ||
195 | 1: blr | ||
196 | |||
197 | __init_tlb_power9: | ||
198 | li r6,POWER9_TLB_SETS_HASH | ||
154 | mtctr r6 | 199 | mtctr r6 |
155 | li r7,0xc00 /* IS field = 0b11 */ | 200 | li r7,0xc00 /* IS field = 0b11 */ |
156 | ptesync | 201 | ptesync |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 7d80bfdfb15e..6c662b8de90d 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -70,9 +70,12 @@ extern void __setup_cpu_power7(unsigned long offset, struct cpu_spec* spec); | |||
70 | extern void __restore_cpu_power7(void); | 70 | extern void __restore_cpu_power7(void); |
71 | extern void __setup_cpu_power8(unsigned long offset, struct cpu_spec* spec); | 71 | extern void __setup_cpu_power8(unsigned long offset, struct cpu_spec* spec); |
72 | extern void __restore_cpu_power8(void); | 72 | extern void __restore_cpu_power8(void); |
73 | extern void __setup_cpu_power9(unsigned long offset, struct cpu_spec* spec); | ||
74 | extern void __restore_cpu_power9(void); | ||
73 | extern void __restore_cpu_a2(void); | 75 | extern void __restore_cpu_a2(void); |
74 | extern void __flush_tlb_power7(unsigned int action); | 76 | extern void __flush_tlb_power7(unsigned int action); |
75 | extern void __flush_tlb_power8(unsigned int action); | 77 | extern void __flush_tlb_power8(unsigned int action); |
78 | extern void __flush_tlb_power9(unsigned int action); | ||
76 | extern long __machine_check_early_realmode_p7(struct pt_regs *regs); | 79 | extern long __machine_check_early_realmode_p7(struct pt_regs *regs); |
77 | extern long __machine_check_early_realmode_p8(struct pt_regs *regs); | 80 | extern long __machine_check_early_realmode_p8(struct pt_regs *regs); |
78 | #endif /* CONFIG_PPC64 */ | 81 | #endif /* CONFIG_PPC64 */ |
@@ -116,6 +119,11 @@ extern void __restore_cpu_e6500(void); | |||
116 | #define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\ | 119 | #define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\ |
117 | PPC_FEATURE_TRUE_LE | \ | 120 | PPC_FEATURE_TRUE_LE | \ |
118 | PPC_FEATURE_HAS_ALTIVEC_COMP) | 121 | PPC_FEATURE_HAS_ALTIVEC_COMP) |
122 | #define COMMON_USER_POWER9 COMMON_USER_POWER8 | ||
123 | #define COMMON_USER2_POWER9 (COMMON_USER2_POWER8 | \ | ||
124 | PPC_FEATURE2_ARCH_3_00 | \ | ||
125 | PPC_FEATURE2_HAS_IEEE128) | ||
126 | |||
119 | #ifdef CONFIG_PPC_BOOK3E_64 | 127 | #ifdef CONFIG_PPC_BOOK3E_64 |
120 | #define COMMON_USER_BOOKE (COMMON_USER_PPC64 | PPC_FEATURE_BOOKE) | 128 | #define COMMON_USER_BOOKE (COMMON_USER_PPC64 | PPC_FEATURE_BOOKE) |
121 | #else | 129 | #else |
@@ -499,6 +507,25 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
499 | .machine_check_early = __machine_check_early_realmode_p8, | 507 | .machine_check_early = __machine_check_early_realmode_p8, |
500 | .platform = "power8", | 508 | .platform = "power8", |
501 | }, | 509 | }, |
510 | { /* Power9 */ | ||
511 | .pvr_mask = 0xffff0000, | ||
512 | .pvr_value = 0x004e0000, | ||
513 | .cpu_name = "POWER9 (raw)", | ||
514 | .cpu_features = CPU_FTRS_POWER9, | ||
515 | .cpu_user_features = COMMON_USER_POWER9, | ||
516 | .cpu_user_features2 = COMMON_USER2_POWER9, | ||
517 | .mmu_features = MMU_FTRS_POWER9, | ||
518 | .icache_bsize = 128, | ||
519 | .dcache_bsize = 128, | ||
520 | .num_pmcs = 6, | ||
521 | .pmc_type = PPC_PMC_IBM, | ||
522 | .oprofile_cpu_type = "ppc64/power9", | ||
523 | .oprofile_type = PPC_OPROFILE_INVALID, | ||
524 | .cpu_setup = __setup_cpu_power9, | ||
525 | .cpu_restore = __restore_cpu_power9, | ||
526 | .flush_tlb = __flush_tlb_power9, | ||
527 | .platform = "power9", | ||
528 | }, | ||
502 | { /* Cell Broadband Engine */ | 529 | { /* Cell Broadband Engine */ |
503 | .pvr_mask = 0xffff0000, | 530 | .pvr_mask = 0xffff0000, |
504 | .pvr_value = 0x00700000, | 531 | .pvr_value = 0x00700000, |
@@ -2023,6 +2050,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
2023 | .cpu_setup = __setup_cpu_e500v2, | 2050 | .cpu_setup = __setup_cpu_e500v2, |
2024 | .machine_check = machine_check_e500, | 2051 | .machine_check = machine_check_e500, |
2025 | .platform = "ppc8548", | 2052 | .platform = "ppc8548", |
2053 | .cpu_down_flush = cpu_down_flush_e500v2, | ||
2026 | }, | 2054 | }, |
2027 | #else | 2055 | #else |
2028 | { /* e500mc */ | 2056 | { /* e500mc */ |
@@ -2042,6 +2070,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
2042 | .cpu_setup = __setup_cpu_e500mc, | 2070 | .cpu_setup = __setup_cpu_e500mc, |
2043 | .machine_check = machine_check_e500mc, | 2071 | .machine_check = machine_check_e500mc, |
2044 | .platform = "ppce500mc", | 2072 | .platform = "ppce500mc", |
2073 | .cpu_down_flush = cpu_down_flush_e500mc, | ||
2045 | }, | 2074 | }, |
2046 | #endif /* CONFIG_PPC_E500MC */ | 2075 | #endif /* CONFIG_PPC_E500MC */ |
2047 | #endif /* CONFIG_PPC32 */ | 2076 | #endif /* CONFIG_PPC32 */ |
@@ -2066,6 +2095,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
2066 | #endif | 2095 | #endif |
2067 | .machine_check = machine_check_e500mc, | 2096 | .machine_check = machine_check_e500mc, |
2068 | .platform = "ppce5500", | 2097 | .platform = "ppce5500", |
2098 | .cpu_down_flush = cpu_down_flush_e5500, | ||
2069 | }, | 2099 | }, |
2070 | { /* e6500 */ | 2100 | { /* e6500 */ |
2071 | .pvr_mask = 0xffff0000, | 2101 | .pvr_mask = 0xffff0000, |
@@ -2088,6 +2118,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
2088 | #endif | 2118 | #endif |
2089 | .machine_check = machine_check_e500mc, | 2119 | .machine_check = machine_check_e500mc, |
2090 | .platform = "ppce6500", | 2120 | .platform = "ppce6500", |
2121 | .cpu_down_flush = cpu_down_flush_e6500, | ||
2091 | }, | 2122 | }, |
2092 | #endif /* CONFIG_PPC_E500MC */ | 2123 | #endif /* CONFIG_PPC_E500MC */ |
2093 | #ifdef CONFIG_PPC32 | 2124 | #ifdef CONFIG_PPC32 |
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 40e4d4a27663..6544017eb90b 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c | |||
@@ -268,13 +268,6 @@ static void *eeh_dump_pe_log(void *data, void *flag) | |||
268 | struct eeh_dev *edev, *tmp; | 268 | struct eeh_dev *edev, *tmp; |
269 | size_t *plen = flag; | 269 | size_t *plen = flag; |
270 | 270 | ||
271 | /* If the PE's config space is blocked, 0xFF's will be | ||
272 | * returned. It's pointless to collect the log in this | ||
273 | * case. | ||
274 | */ | ||
275 | if (pe->state & EEH_PE_CFG_BLOCKED) | ||
276 | return NULL; | ||
277 | |||
278 | eeh_pe_for_each_dev(pe, edev, tmp) | 271 | eeh_pe_for_each_dev(pe, edev, tmp) |
279 | *plen += eeh_dump_dev_log(edev, pci_regs_buf + *plen, | 272 | *plen += eeh_dump_dev_log(edev, pci_regs_buf + *plen, |
280 | EEH_PCI_REGS_LOG_LEN - *plen); | 273 | EEH_PCI_REGS_LOG_LEN - *plen); |
@@ -677,7 +670,7 @@ int eeh_pci_enable(struct eeh_pe *pe, int function) | |||
677 | /* Check if the request is finished successfully */ | 670 | /* Check if the request is finished successfully */ |
678 | if (active_flag) { | 671 | if (active_flag) { |
679 | rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC); | 672 | rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC); |
680 | if (rc <= 0) | 673 | if (rc < 0) |
681 | return rc; | 674 | return rc; |
682 | 675 | ||
683 | if (rc & active_flag) | 676 | if (rc & active_flag) |
@@ -739,7 +732,7 @@ static void *eeh_restore_dev_state(void *data, void *userdata) | |||
739 | } | 732 | } |
740 | 733 | ||
741 | /** | 734 | /** |
742 | * pcibios_set_pcie_slot_reset - Set PCI-E reset state | 735 | * pcibios_set_pcie_reset_state - Set PCI-E reset state |
743 | * @dev: pci device struct | 736 | * @dev: pci device struct |
744 | * @state: reset state to enter | 737 | * @state: reset state to enter |
745 | * | 738 | * |
@@ -761,7 +754,8 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat | |||
761 | case pcie_deassert_reset: | 754 | case pcie_deassert_reset: |
762 | eeh_ops->reset(pe, EEH_RESET_DEACTIVATE); | 755 | eeh_ops->reset(pe, EEH_RESET_DEACTIVATE); |
763 | eeh_unfreeze_pe(pe, false); | 756 | eeh_unfreeze_pe(pe, false); |
764 | eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED); | 757 | if (!(pe->type & EEH_PE_VF)) |
758 | eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED); | ||
765 | eeh_pe_dev_traverse(pe, eeh_restore_dev_state, dev); | 759 | eeh_pe_dev_traverse(pe, eeh_restore_dev_state, dev); |
766 | eeh_pe_state_clear(pe, EEH_PE_ISOLATED); | 760 | eeh_pe_state_clear(pe, EEH_PE_ISOLATED); |
767 | break; | 761 | break; |
@@ -769,14 +763,16 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat | |||
769 | eeh_pe_state_mark_with_cfg(pe, EEH_PE_ISOLATED); | 763 | eeh_pe_state_mark_with_cfg(pe, EEH_PE_ISOLATED); |
770 | eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE); | 764 | eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE); |
771 | eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev); | 765 | eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev); |
772 | eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED); | 766 | if (!(pe->type & EEH_PE_VF)) |
767 | eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED); | ||
773 | eeh_ops->reset(pe, EEH_RESET_HOT); | 768 | eeh_ops->reset(pe, EEH_RESET_HOT); |
774 | break; | 769 | break; |
775 | case pcie_warm_reset: | 770 | case pcie_warm_reset: |
776 | eeh_pe_state_mark_with_cfg(pe, EEH_PE_ISOLATED); | 771 | eeh_pe_state_mark_with_cfg(pe, EEH_PE_ISOLATED); |
777 | eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE); | 772 | eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE); |
778 | eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev); | 773 | eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev); |
779 | eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED); | 774 | if (!(pe->type & EEH_PE_VF)) |
775 | eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED); | ||
780 | eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL); | 776 | eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL); |
781 | break; | 777 | break; |
782 | default: | 778 | default: |
@@ -1243,6 +1239,14 @@ void eeh_remove_device(struct pci_dev *dev) | |||
1243 | * from the parent PE during the BAR resotre. | 1239 | * from the parent PE during the BAR resotre. |
1244 | */ | 1240 | */ |
1245 | edev->pdev = NULL; | 1241 | edev->pdev = NULL; |
1242 | |||
1243 | /* | ||
1244 | * The flag "in_error" is used to trace EEH devices for VFs | ||
1245 | * in error state or not. It's set in eeh_report_error(). If | ||
1246 | * it's not set, eeh_report_{reset,resume}() won't be called | ||
1247 | * for the VF EEH device. | ||
1248 | */ | ||
1249 | edev->in_error = false; | ||
1246 | dev->dev.archdata.edev = NULL; | 1250 | dev->dev.archdata.edev = NULL; |
1247 | if (!(edev->pe->state & EEH_PE_KEEP)) | 1251 | if (!(edev->pe->state & EEH_PE_KEEP)) |
1248 | eeh_rmv_from_parent_pe(edev); | 1252 | eeh_rmv_from_parent_pe(edev); |
@@ -1537,6 +1541,17 @@ int eeh_pe_get_state(struct eeh_pe *pe) | |||
1537 | if (!eeh_ops || !eeh_ops->get_state) | 1541 | if (!eeh_ops || !eeh_ops->get_state) |
1538 | return -ENOENT; | 1542 | return -ENOENT; |
1539 | 1543 | ||
1544 | /* | ||
1545 | * If the parent PE is owned by the host kernel and is undergoing | ||
1546 | * error recovery, we should return the PE state as temporarily | ||
1547 | * unavailable so that the error recovery on the guest is suspended | ||
1548 | * until the recovery completes on the host. | ||
1549 | */ | ||
1550 | if (pe->parent && | ||
1551 | !(pe->state & EEH_PE_REMOVED) && | ||
1552 | (pe->parent->state & (EEH_PE_ISOLATED | EEH_PE_RECOVERING))) | ||
1553 | return EEH_PE_STATE_UNAVAIL; | ||
1554 | |||
1540 | result = eeh_ops->get_state(pe, NULL); | 1555 | result = eeh_ops->get_state(pe, NULL); |
1541 | rst_active = !!(result & EEH_STATE_RESET_ACTIVE); | 1556 | rst_active = !!(result & EEH_STATE_RESET_ACTIVE); |
1542 | dma_en = !!(result & EEH_STATE_DMA_ENABLED); | 1557 | dma_en = !!(result & EEH_STATE_DMA_ENABLED); |
diff --git a/arch/powerpc/kernel/eeh_cache.c b/arch/powerpc/kernel/eeh_cache.c index a1e86e172e3c..ddbcfab7efdf 100644 --- a/arch/powerpc/kernel/eeh_cache.c +++ b/arch/powerpc/kernel/eeh_cache.c | |||
@@ -195,8 +195,11 @@ static void __eeh_addr_cache_insert_dev(struct pci_dev *dev) | |||
195 | return; | 195 | return; |
196 | } | 196 | } |
197 | 197 | ||
198 | /* Walk resources on this device, poke them into the tree */ | 198 | /* |
199 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 199 | * Walk resources on this device, poke the first 7 (6 normal BAR and 1 |
200 | * ROM BAR) into the tree. | ||
201 | */ | ||
202 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
200 | resource_size_t start = pci_resource_start(dev,i); | 203 | resource_size_t start = pci_resource_start(dev,i); |
201 | resource_size_t end = pci_resource_end(dev,i); | 204 | resource_size_t end = pci_resource_end(dev,i); |
202 | unsigned long flags = pci_resource_flags(dev,i); | 205 | unsigned long flags = pci_resource_flags(dev,i); |
@@ -222,10 +225,6 @@ void eeh_addr_cache_insert_dev(struct pci_dev *dev) | |||
222 | { | 225 | { |
223 | unsigned long flags; | 226 | unsigned long flags; |
224 | 227 | ||
225 | /* Ignore PCI bridges */ | ||
226 | if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) | ||
227 | return; | ||
228 | |||
229 | spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags); | 228 | spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags); |
230 | __eeh_addr_cache_insert_dev(dev); | 229 | __eeh_addr_cache_insert_dev(dev); |
231 | spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags); | 230 | spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags); |
diff --git a/arch/powerpc/kernel/eeh_dev.c b/arch/powerpc/kernel/eeh_dev.c index aabba94ff9cb..7815095fe3d8 100644 --- a/arch/powerpc/kernel/eeh_dev.c +++ b/arch/powerpc/kernel/eeh_dev.c | |||
@@ -67,6 +67,7 @@ void *eeh_dev_init(struct pci_dn *pdn, void *data) | |||
67 | edev->pdn = pdn; | 67 | edev->pdn = pdn; |
68 | edev->phb = phb; | 68 | edev->phb = phb; |
69 | INIT_LIST_HEAD(&edev->list); | 69 | INIT_LIST_HEAD(&edev->list); |
70 | INIT_LIST_HEAD(&edev->rmv_list); | ||
70 | 71 | ||
71 | return NULL; | 72 | return NULL; |
72 | } | 73 | } |
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index 650cfb31ea3d..fb6207d2c604 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c | |||
@@ -34,6 +34,11 @@ | |||
34 | #include <asm/prom.h> | 34 | #include <asm/prom.h> |
35 | #include <asm/rtas.h> | 35 | #include <asm/rtas.h> |
36 | 36 | ||
37 | struct eeh_rmv_data { | ||
38 | struct list_head edev_list; | ||
39 | int removed; | ||
40 | }; | ||
41 | |||
37 | /** | 42 | /** |
38 | * eeh_pcid_name - Retrieve name of PCI device driver | 43 | * eeh_pcid_name - Retrieve name of PCI device driver |
39 | * @pdev: PCI device | 44 | * @pdev: PCI device |
@@ -190,7 +195,7 @@ static void *eeh_report_error(void *data, void *userdata) | |||
190 | enum pci_ers_result rc, *res = userdata; | 195 | enum pci_ers_result rc, *res = userdata; |
191 | struct pci_driver *driver; | 196 | struct pci_driver *driver; |
192 | 197 | ||
193 | if (!dev || eeh_dev_removed(edev)) | 198 | if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) |
194 | return NULL; | 199 | return NULL; |
195 | dev->error_state = pci_channel_io_frozen; | 200 | dev->error_state = pci_channel_io_frozen; |
196 | 201 | ||
@@ -211,6 +216,7 @@ static void *eeh_report_error(void *data, void *userdata) | |||
211 | if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; | 216 | if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; |
212 | if (*res == PCI_ERS_RESULT_NONE) *res = rc; | 217 | if (*res == PCI_ERS_RESULT_NONE) *res = rc; |
213 | 218 | ||
219 | edev->in_error = true; | ||
214 | eeh_pcid_put(dev); | 220 | eeh_pcid_put(dev); |
215 | return NULL; | 221 | return NULL; |
216 | } | 222 | } |
@@ -231,7 +237,7 @@ static void *eeh_report_mmio_enabled(void *data, void *userdata) | |||
231 | enum pci_ers_result rc, *res = userdata; | 237 | enum pci_ers_result rc, *res = userdata; |
232 | struct pci_driver *driver; | 238 | struct pci_driver *driver; |
233 | 239 | ||
234 | if (!dev || eeh_dev_removed(edev)) | 240 | if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) |
235 | return NULL; | 241 | return NULL; |
236 | 242 | ||
237 | driver = eeh_pcid_get(dev); | 243 | driver = eeh_pcid_get(dev); |
@@ -271,7 +277,7 @@ static void *eeh_report_reset(void *data, void *userdata) | |||
271 | enum pci_ers_result rc, *res = userdata; | 277 | enum pci_ers_result rc, *res = userdata; |
272 | struct pci_driver *driver; | 278 | struct pci_driver *driver; |
273 | 279 | ||
274 | if (!dev || eeh_dev_removed(edev)) | 280 | if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) |
275 | return NULL; | 281 | return NULL; |
276 | dev->error_state = pci_channel_io_normal; | 282 | dev->error_state = pci_channel_io_normal; |
277 | 283 | ||
@@ -282,7 +288,8 @@ static void *eeh_report_reset(void *data, void *userdata) | |||
282 | 288 | ||
283 | if (!driver->err_handler || | 289 | if (!driver->err_handler || |
284 | !driver->err_handler->slot_reset || | 290 | !driver->err_handler->slot_reset || |
285 | (edev->mode & EEH_DEV_NO_HANDLER)) { | 291 | (edev->mode & EEH_DEV_NO_HANDLER) || |
292 | (!edev->in_error)) { | ||
286 | eeh_pcid_put(dev); | 293 | eeh_pcid_put(dev); |
287 | return NULL; | 294 | return NULL; |
288 | } | 295 | } |
@@ -326,20 +333,23 @@ static void *eeh_report_resume(void *data, void *userdata) | |||
326 | { | 333 | { |
327 | struct eeh_dev *edev = (struct eeh_dev *)data; | 334 | struct eeh_dev *edev = (struct eeh_dev *)data; |
328 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); | 335 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); |
336 | bool was_in_error; | ||
329 | struct pci_driver *driver; | 337 | struct pci_driver *driver; |
330 | 338 | ||
331 | if (!dev || eeh_dev_removed(edev)) | 339 | if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) |
332 | return NULL; | 340 | return NULL; |
333 | dev->error_state = pci_channel_io_normal; | 341 | dev->error_state = pci_channel_io_normal; |
334 | 342 | ||
335 | driver = eeh_pcid_get(dev); | 343 | driver = eeh_pcid_get(dev); |
336 | if (!driver) return NULL; | 344 | if (!driver) return NULL; |
337 | 345 | ||
346 | was_in_error = edev->in_error; | ||
347 | edev->in_error = false; | ||
338 | eeh_enable_irq(dev); | 348 | eeh_enable_irq(dev); |
339 | 349 | ||
340 | if (!driver->err_handler || | 350 | if (!driver->err_handler || |
341 | !driver->err_handler->resume || | 351 | !driver->err_handler->resume || |
342 | (edev->mode & EEH_DEV_NO_HANDLER)) { | 352 | (edev->mode & EEH_DEV_NO_HANDLER) || !was_in_error) { |
343 | edev->mode &= ~EEH_DEV_NO_HANDLER; | 353 | edev->mode &= ~EEH_DEV_NO_HANDLER; |
344 | eeh_pcid_put(dev); | 354 | eeh_pcid_put(dev); |
345 | return NULL; | 355 | return NULL; |
@@ -365,7 +375,7 @@ static void *eeh_report_failure(void *data, void *userdata) | |||
365 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); | 375 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); |
366 | struct pci_driver *driver; | 376 | struct pci_driver *driver; |
367 | 377 | ||
368 | if (!dev || eeh_dev_removed(edev)) | 378 | if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) |
369 | return NULL; | 379 | return NULL; |
370 | dev->error_state = pci_channel_io_perm_failure; | 380 | dev->error_state = pci_channel_io_perm_failure; |
371 | 381 | ||
@@ -386,12 +396,40 @@ static void *eeh_report_failure(void *data, void *userdata) | |||
386 | return NULL; | 396 | return NULL; |
387 | } | 397 | } |
388 | 398 | ||
399 | static void *eeh_add_virt_device(void *data, void *userdata) | ||
400 | { | ||
401 | struct pci_driver *driver; | ||
402 | struct eeh_dev *edev = (struct eeh_dev *)data; | ||
403 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); | ||
404 | struct pci_dn *pdn = eeh_dev_to_pdn(edev); | ||
405 | |||
406 | if (!(edev->physfn)) { | ||
407 | pr_warn("%s: EEH dev %04x:%02x:%02x.%01x not for VF\n", | ||
408 | __func__, edev->phb->global_number, pdn->busno, | ||
409 | PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn)); | ||
410 | return NULL; | ||
411 | } | ||
412 | |||
413 | driver = eeh_pcid_get(dev); | ||
414 | if (driver) { | ||
415 | eeh_pcid_put(dev); | ||
416 | if (driver->err_handler) | ||
417 | return NULL; | ||
418 | } | ||
419 | |||
420 | #ifdef CONFIG_PPC_POWERNV | ||
421 | pci_iov_add_virtfn(edev->physfn, pdn->vf_index, 0); | ||
422 | #endif | ||
423 | return NULL; | ||
424 | } | ||
425 | |||
389 | static void *eeh_rmv_device(void *data, void *userdata) | 426 | static void *eeh_rmv_device(void *data, void *userdata) |
390 | { | 427 | { |
391 | struct pci_driver *driver; | 428 | struct pci_driver *driver; |
392 | struct eeh_dev *edev = (struct eeh_dev *)data; | 429 | struct eeh_dev *edev = (struct eeh_dev *)data; |
393 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); | 430 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); |
394 | int *removed = (int *)userdata; | 431 | struct eeh_rmv_data *rmv_data = (struct eeh_rmv_data *)userdata; |
432 | int *removed = rmv_data ? &rmv_data->removed : NULL; | ||
395 | 433 | ||
396 | /* | 434 | /* |
397 | * Actually, we should remove the PCI bridges as well. | 435 | * Actually, we should remove the PCI bridges as well. |
@@ -416,7 +454,11 @@ static void *eeh_rmv_device(void *data, void *userdata) | |||
416 | driver = eeh_pcid_get(dev); | 454 | driver = eeh_pcid_get(dev); |
417 | if (driver) { | 455 | if (driver) { |
418 | eeh_pcid_put(dev); | 456 | eeh_pcid_put(dev); |
419 | if (driver->err_handler && | 457 | if (removed && |
458 | eeh_pe_passed(edev->pe)) | ||
459 | return NULL; | ||
460 | if (removed && | ||
461 | driver->err_handler && | ||
420 | driver->err_handler->error_detected && | 462 | driver->err_handler->error_detected && |
421 | driver->err_handler->slot_reset) | 463 | driver->err_handler->slot_reset) |
422 | return NULL; | 464 | return NULL; |
@@ -427,11 +469,29 @@ static void *eeh_rmv_device(void *data, void *userdata) | |||
427 | pci_name(dev)); | 469 | pci_name(dev)); |
428 | edev->bus = dev->bus; | 470 | edev->bus = dev->bus; |
429 | edev->mode |= EEH_DEV_DISCONNECTED; | 471 | edev->mode |= EEH_DEV_DISCONNECTED; |
430 | (*removed)++; | 472 | if (removed) |
473 | (*removed)++; | ||
431 | 474 | ||
432 | pci_lock_rescan_remove(); | 475 | if (edev->physfn) { |
433 | pci_stop_and_remove_bus_device(dev); | 476 | #ifdef CONFIG_PPC_POWERNV |
434 | pci_unlock_rescan_remove(); | 477 | struct pci_dn *pdn = eeh_dev_to_pdn(edev); |
478 | |||
479 | pci_iov_remove_virtfn(edev->physfn, pdn->vf_index, 0); | ||
480 | edev->pdev = NULL; | ||
481 | |||
482 | /* | ||
483 | * We have to set the VF PE number to invalid one, which is | ||
484 | * required to plug the VF successfully. | ||
485 | */ | ||
486 | pdn->pe_number = IODA_INVALID_PE; | ||
487 | #endif | ||
488 | if (rmv_data) | ||
489 | list_add(&edev->rmv_list, &rmv_data->edev_list); | ||
490 | } else { | ||
491 | pci_lock_rescan_remove(); | ||
492 | pci_stop_and_remove_bus_device(dev); | ||
493 | pci_unlock_rescan_remove(); | ||
494 | } | ||
435 | 495 | ||
436 | return NULL; | 496 | return NULL; |
437 | } | 497 | } |
@@ -545,11 +605,13 @@ int eeh_pe_reset_and_recover(struct eeh_pe *pe) | |||
545 | * During the reset, udev might be invoked because those affected | 605 | * During the reset, udev might be invoked because those affected |
546 | * PCI devices will be removed and then added. | 606 | * PCI devices will be removed and then added. |
547 | */ | 607 | */ |
548 | static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) | 608 | static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus, |
609 | struct eeh_rmv_data *rmv_data) | ||
549 | { | 610 | { |
550 | struct pci_bus *frozen_bus = eeh_pe_bus_get(pe); | 611 | struct pci_bus *frozen_bus = eeh_pe_bus_get(pe); |
551 | struct timeval tstamp; | 612 | struct timeval tstamp; |
552 | int cnt, rc, removed = 0; | 613 | int cnt, rc; |
614 | struct eeh_dev *edev; | ||
553 | 615 | ||
554 | /* pcibios will clear the counter; save the value */ | 616 | /* pcibios will clear the counter; save the value */ |
555 | cnt = pe->freeze_count; | 617 | cnt = pe->freeze_count; |
@@ -563,12 +625,16 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) | |||
563 | */ | 625 | */ |
564 | eeh_pe_state_mark(pe, EEH_PE_KEEP); | 626 | eeh_pe_state_mark(pe, EEH_PE_KEEP); |
565 | if (bus) { | 627 | if (bus) { |
566 | eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); | 628 | if (pe->type & EEH_PE_VF) { |
567 | pci_lock_rescan_remove(); | 629 | eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL); |
568 | pcibios_remove_pci_devices(bus); | 630 | } else { |
569 | pci_unlock_rescan_remove(); | 631 | eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); |
632 | pci_lock_rescan_remove(); | ||
633 | pcibios_remove_pci_devices(bus); | ||
634 | pci_unlock_rescan_remove(); | ||
635 | } | ||
570 | } else if (frozen_bus) { | 636 | } else if (frozen_bus) { |
571 | eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed); | 637 | eeh_pe_dev_traverse(pe, eeh_rmv_device, &rmv_data); |
572 | } | 638 | } |
573 | 639 | ||
574 | /* | 640 | /* |
@@ -610,14 +676,22 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) | |||
610 | * PE. We should disconnect it so the binding can be | 676 | * PE. We should disconnect it so the binding can be |
611 | * rebuilt when adding PCI devices. | 677 | * rebuilt when adding PCI devices. |
612 | */ | 678 | */ |
679 | edev = list_first_entry(&pe->edevs, struct eeh_dev, list); | ||
613 | eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL); | 680 | eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL); |
614 | pcibios_add_pci_devices(bus); | 681 | if (pe->type & EEH_PE_VF) |
615 | } else if (frozen_bus && removed) { | 682 | eeh_add_virt_device(edev, NULL); |
683 | else | ||
684 | pcibios_add_pci_devices(bus); | ||
685 | } else if (frozen_bus && rmv_data->removed) { | ||
616 | pr_info("EEH: Sleep 5s ahead of partial hotplug\n"); | 686 | pr_info("EEH: Sleep 5s ahead of partial hotplug\n"); |
617 | ssleep(5); | 687 | ssleep(5); |
618 | 688 | ||
689 | edev = list_first_entry(&pe->edevs, struct eeh_dev, list); | ||
619 | eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL); | 690 | eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL); |
620 | pcibios_add_pci_devices(frozen_bus); | 691 | if (pe->type & EEH_PE_VF) |
692 | eeh_add_virt_device(edev, NULL); | ||
693 | else | ||
694 | pcibios_add_pci_devices(frozen_bus); | ||
621 | } | 695 | } |
622 | eeh_pe_state_clear(pe, EEH_PE_KEEP); | 696 | eeh_pe_state_clear(pe, EEH_PE_KEEP); |
623 | 697 | ||
@@ -636,8 +710,10 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) | |||
636 | static void eeh_handle_normal_event(struct eeh_pe *pe) | 710 | static void eeh_handle_normal_event(struct eeh_pe *pe) |
637 | { | 711 | { |
638 | struct pci_bus *frozen_bus; | 712 | struct pci_bus *frozen_bus; |
713 | struct eeh_dev *edev, *tmp; | ||
639 | int rc = 0; | 714 | int rc = 0; |
640 | enum pci_ers_result result = PCI_ERS_RESULT_NONE; | 715 | enum pci_ers_result result = PCI_ERS_RESULT_NONE; |
716 | struct eeh_rmv_data rmv_data = {LIST_HEAD_INIT(rmv_data.edev_list), 0}; | ||
641 | 717 | ||
642 | frozen_bus = eeh_pe_bus_get(pe); | 718 | frozen_bus = eeh_pe_bus_get(pe); |
643 | if (!frozen_bus) { | 719 | if (!frozen_bus) { |
@@ -692,7 +768,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe) | |||
692 | */ | 768 | */ |
693 | if (result == PCI_ERS_RESULT_NONE) { | 769 | if (result == PCI_ERS_RESULT_NONE) { |
694 | pr_info("EEH: Reset with hotplug activity\n"); | 770 | pr_info("EEH: Reset with hotplug activity\n"); |
695 | rc = eeh_reset_device(pe, frozen_bus); | 771 | rc = eeh_reset_device(pe, frozen_bus, NULL); |
696 | if (rc) { | 772 | if (rc) { |
697 | pr_warn("%s: Unable to reset, err=%d\n", | 773 | pr_warn("%s: Unable to reset, err=%d\n", |
698 | __func__, rc); | 774 | __func__, rc); |
@@ -744,7 +820,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe) | |||
744 | /* If any device called out for a reset, then reset the slot */ | 820 | /* If any device called out for a reset, then reset the slot */ |
745 | if (result == PCI_ERS_RESULT_NEED_RESET) { | 821 | if (result == PCI_ERS_RESULT_NEED_RESET) { |
746 | pr_info("EEH: Reset without hotplug activity\n"); | 822 | pr_info("EEH: Reset without hotplug activity\n"); |
747 | rc = eeh_reset_device(pe, NULL); | 823 | rc = eeh_reset_device(pe, NULL, &rmv_data); |
748 | if (rc) { | 824 | if (rc) { |
749 | pr_warn("%s: Cannot reset, err=%d\n", | 825 | pr_warn("%s: Cannot reset, err=%d\n", |
750 | __func__, rc); | 826 | __func__, rc); |
@@ -764,6 +840,15 @@ static void eeh_handle_normal_event(struct eeh_pe *pe) | |||
764 | goto hard_fail; | 840 | goto hard_fail; |
765 | } | 841 | } |
766 | 842 | ||
843 | /* | ||
844 | * For those hot removed VFs, we should add back them after PF get | ||
845 | * recovered properly. | ||
846 | */ | ||
847 | list_for_each_entry_safe(edev, tmp, &rmv_data.edev_list, rmv_list) { | ||
848 | eeh_add_virt_device(edev, NULL); | ||
849 | list_del(&edev->rmv_list); | ||
850 | } | ||
851 | |||
767 | /* Tell all device drivers that they can resume operations */ | 852 | /* Tell all device drivers that they can resume operations */ |
768 | pr_info("EEH: Notify device driver to resume\n"); | 853 | pr_info("EEH: Notify device driver to resume\n"); |
769 | eeh_pe_dev_traverse(pe, eeh_report_resume, NULL); | 854 | eeh_pe_dev_traverse(pe, eeh_report_resume, NULL); |
@@ -803,12 +888,17 @@ perm_error: | |||
803 | * the their PCI config any more. | 888 | * the their PCI config any more. |
804 | */ | 889 | */ |
805 | if (frozen_bus) { | 890 | if (frozen_bus) { |
806 | eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); | 891 | if (pe->type & EEH_PE_VF) { |
807 | eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); | 892 | eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL); |
893 | eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); | ||
894 | } else { | ||
895 | eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); | ||
896 | eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); | ||
808 | 897 | ||
809 | pci_lock_rescan_remove(); | 898 | pci_lock_rescan_remove(); |
810 | pcibios_remove_pci_devices(frozen_bus); | 899 | pcibios_remove_pci_devices(frozen_bus); |
811 | pci_unlock_rescan_remove(); | 900 | pci_unlock_rescan_remove(); |
901 | } | ||
812 | } | 902 | } |
813 | } | 903 | } |
814 | 904 | ||
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index 98f81800e00c..eea48d8baf49 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c | |||
@@ -299,7 +299,10 @@ static struct eeh_pe *eeh_pe_get_parent(struct eeh_dev *edev) | |||
299 | * EEH device already having associated PE, but | 299 | * EEH device already having associated PE, but |
300 | * the direct parent EEH device doesn't have yet. | 300 | * the direct parent EEH device doesn't have yet. |
301 | */ | 301 | */ |
302 | pdn = pdn ? pdn->parent : NULL; | 302 | if (edev->physfn) |
303 | pdn = pci_get_pdn(edev->physfn); | ||
304 | else | ||
305 | pdn = pdn ? pdn->parent : NULL; | ||
303 | while (pdn) { | 306 | while (pdn) { |
304 | /* We're poking out of PCI territory */ | 307 | /* We're poking out of PCI territory */ |
305 | parent = pdn_to_eeh_dev(pdn); | 308 | parent = pdn_to_eeh_dev(pdn); |
@@ -382,7 +385,10 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev) | |||
382 | } | 385 | } |
383 | 386 | ||
384 | /* Create a new EEH PE */ | 387 | /* Create a new EEH PE */ |
385 | pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE); | 388 | if (edev->physfn) |
389 | pe = eeh_pe_alloc(edev->phb, EEH_PE_VF); | ||
390 | else | ||
391 | pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE); | ||
386 | if (!pe) { | 392 | if (!pe) { |
387 | pr_err("%s: out of memory!\n", __func__); | 393 | pr_err("%s: out of memory!\n", __func__); |
388 | return -ENOMEM; | 394 | return -ENOMEM; |
@@ -920,25 +926,21 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe) | |||
920 | */ | 926 | */ |
921 | struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe) | 927 | struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe) |
922 | { | 928 | { |
923 | struct pci_bus *bus = NULL; | ||
924 | struct eeh_dev *edev; | 929 | struct eeh_dev *edev; |
925 | struct pci_dev *pdev; | 930 | struct pci_dev *pdev; |
926 | 931 | ||
927 | if (pe->type & EEH_PE_PHB) { | 932 | if (pe->type & EEH_PE_PHB) |
928 | bus = pe->phb->bus; | 933 | return pe->phb->bus; |
929 | } else if (pe->type & EEH_PE_BUS || | ||
930 | pe->type & EEH_PE_DEVICE) { | ||
931 | if (pe->state & EEH_PE_PRI_BUS) { | ||
932 | bus = pe->bus; | ||
933 | goto out; | ||
934 | } | ||
935 | 934 | ||
936 | edev = list_first_entry(&pe->edevs, struct eeh_dev, list); | 935 | /* The primary bus might be cached during probe time */ |
937 | pdev = eeh_dev_to_pci_dev(edev); | 936 | if (pe->state & EEH_PE_PRI_BUS) |
938 | if (pdev) | 937 | return pe->bus; |
939 | bus = pdev->bus; | ||
940 | } | ||
941 | 938 | ||
942 | out: | 939 | /* Retrieve the parent PCI bus of first (top) PCI device */ |
943 | return bus; | 940 | edev = list_first_entry_or_null(&pe->edevs, struct eeh_dev, list); |
941 | pdev = eeh_dev_to_pci_dev(edev); | ||
942 | if (pdev) | ||
943 | return pdev->bus; | ||
944 | |||
945 | return NULL; | ||
944 | } | 946 | } |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 0d525ce3717f..9916d150b28c 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -210,7 +210,29 @@ system_call: /* label this so stack traces look sane */ | |||
210 | li r11,-MAX_ERRNO | 210 | li r11,-MAX_ERRNO |
211 | andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK) | 211 | andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK) |
212 | bne- syscall_exit_work | 212 | bne- syscall_exit_work |
213 | cmpld r3,r11 | 213 | |
214 | andi. r0,r8,MSR_FP | ||
215 | beq 2f | ||
216 | #ifdef CONFIG_ALTIVEC | ||
217 | andis. r0,r8,MSR_VEC@h | ||
218 | bne 3f | ||
219 | #endif | ||
220 | 2: addi r3,r1,STACK_FRAME_OVERHEAD | ||
221 | #ifdef CONFIG_PPC_BOOK3S | ||
222 | mtmsrd r10,1 /* Restore RI */ | ||
223 | #endif | ||
224 | bl restore_math | ||
225 | #ifdef CONFIG_PPC_BOOK3S | ||
226 | ld r10,PACAKMSR(r13) | ||
227 | li r9,MSR_RI | ||
228 | andc r11,r10,r9 /* Re-clear RI */ | ||
229 | mtmsrd r11,1 | ||
230 | #endif | ||
231 | ld r8,_MSR(r1) | ||
232 | ld r3,RESULT(r1) | ||
233 | li r11,-MAX_ERRNO | ||
234 | |||
235 | 3: cmpld r3,r11 | ||
214 | ld r5,_CCR(r1) | 236 | ld r5,_CCR(r1) |
215 | bge- syscall_error | 237 | bge- syscall_error |
216 | .Lsyscall_error_cont: | 238 | .Lsyscall_error_cont: |
@@ -602,8 +624,8 @@ _GLOBAL(ret_from_except_lite) | |||
602 | 624 | ||
603 | /* Check current_thread_info()->flags */ | 625 | /* Check current_thread_info()->flags */ |
604 | andi. r0,r4,_TIF_USER_WORK_MASK | 626 | andi. r0,r4,_TIF_USER_WORK_MASK |
605 | #ifdef CONFIG_PPC_BOOK3E | ||
606 | bne 1f | 627 | bne 1f |
628 | #ifdef CONFIG_PPC_BOOK3E | ||
607 | /* | 629 | /* |
608 | * Check to see if the dbcr0 register is set up to debug. | 630 | * Check to see if the dbcr0 register is set up to debug. |
609 | * Use the internal debug mode bit to do this. | 631 | * Use the internal debug mode bit to do this. |
@@ -618,7 +640,9 @@ _GLOBAL(ret_from_except_lite) | |||
618 | mtspr SPRN_DBSR,r10 | 640 | mtspr SPRN_DBSR,r10 |
619 | b restore | 641 | b restore |
620 | #else | 642 | #else |
621 | beq restore | 643 | addi r3,r1,STACK_FRAME_OVERHEAD |
644 | bl restore_math | ||
645 | b restore | ||
622 | #endif | 646 | #endif |
623 | 1: andi. r0,r4,_TIF_NEED_RESCHED | 647 | 1: andi. r0,r4,_TIF_NEED_RESCHED |
624 | beq 2f | 648 | beq 2f |
@@ -1143,8 +1167,12 @@ _GLOBAL(enter_prom) | |||
1143 | #ifdef CONFIG_DYNAMIC_FTRACE | 1167 | #ifdef CONFIG_DYNAMIC_FTRACE |
1144 | _GLOBAL(mcount) | 1168 | _GLOBAL(mcount) |
1145 | _GLOBAL(_mcount) | 1169 | _GLOBAL(_mcount) |
1146 | blr | 1170 | mflr r12 |
1171 | mtctr r12 | ||
1172 | mtlr r0 | ||
1173 | bctr | ||
1147 | 1174 | ||
1175 | #ifndef CC_USING_MPROFILE_KERNEL | ||
1148 | _GLOBAL_TOC(ftrace_caller) | 1176 | _GLOBAL_TOC(ftrace_caller) |
1149 | /* Taken from output of objdump from lib64/glibc */ | 1177 | /* Taken from output of objdump from lib64/glibc */ |
1150 | mflr r3 | 1178 | mflr r3 |
@@ -1166,6 +1194,115 @@ _GLOBAL(ftrace_graph_stub) | |||
1166 | ld r0, 128(r1) | 1194 | ld r0, 128(r1) |
1167 | mtlr r0 | 1195 | mtlr r0 |
1168 | addi r1, r1, 112 | 1196 | addi r1, r1, 112 |
1197 | |||
1198 | #else /* CC_USING_MPROFILE_KERNEL */ | ||
1199 | /* | ||
1200 | * | ||
1201 | * ftrace_caller() is the function that replaces _mcount() when ftrace is | ||
1202 | * active. | ||
1203 | * | ||
1204 | * We arrive here after a function A calls function B, and we are the trace | ||
1205 | * function for B. When we enter r1 points to A's stack frame, B has not yet | ||
1206 | * had a chance to allocate one yet. | ||
1207 | * | ||
1208 | * Additionally r2 may point either to the TOC for A, or B, depending on | ||
1209 | * whether B did a TOC setup sequence before calling us. | ||
1210 | * | ||
1211 | * On entry the LR points back to the _mcount() call site, and r0 holds the | ||
1212 | * saved LR as it was on entry to B, ie. the original return address at the | ||
1213 | * call site in A. | ||
1214 | * | ||
1215 | * Our job is to save the register state into a struct pt_regs (on the stack) | ||
1216 | * and then arrange for the ftrace function to be called. | ||
1217 | */ | ||
1218 | _GLOBAL(ftrace_caller) | ||
1219 | /* Save the original return address in A's stack frame */ | ||
1220 | std r0,LRSAVE(r1) | ||
1221 | |||
1222 | /* Create our stack frame + pt_regs */ | ||
1223 | stdu r1,-SWITCH_FRAME_SIZE(r1) | ||
1224 | |||
1225 | /* Save all gprs to pt_regs */ | ||
1226 | SAVE_8GPRS(0,r1) | ||
1227 | SAVE_8GPRS(8,r1) | ||
1228 | SAVE_8GPRS(16,r1) | ||
1229 | SAVE_8GPRS(24,r1) | ||
1230 | |||
1231 | /* Load special regs for save below */ | ||
1232 | mfmsr r8 | ||
1233 | mfctr r9 | ||
1234 | mfxer r10 | ||
1235 | mfcr r11 | ||
1236 | |||
1237 | /* Get the _mcount() call site out of LR */ | ||
1238 | mflr r7 | ||
1239 | /* Save it as pt_regs->nip & pt_regs->link */ | ||
1240 | std r7, _NIP(r1) | ||
1241 | std r7, _LINK(r1) | ||
1242 | |||
1243 | /* Save callee's TOC in the ABI compliant location */ | ||
1244 | std r2, 24(r1) | ||
1245 | ld r2,PACATOC(r13) /* get kernel TOC in r2 */ | ||
1246 | |||
1247 | addis r3,r2,function_trace_op@toc@ha | ||
1248 | addi r3,r3,function_trace_op@toc@l | ||
1249 | ld r5,0(r3) | ||
1250 | |||
1251 | /* Calculate ip from nip-4 into r3 for call below */ | ||
1252 | subi r3, r7, MCOUNT_INSN_SIZE | ||
1253 | |||
1254 | /* Put the original return address in r4 as parent_ip */ | ||
1255 | mr r4, r0 | ||
1256 | |||
1257 | /* Save special regs */ | ||
1258 | std r8, _MSR(r1) | ||
1259 | std r9, _CTR(r1) | ||
1260 | std r10, _XER(r1) | ||
1261 | std r11, _CCR(r1) | ||
1262 | |||
1263 | /* Load &pt_regs in r6 for call below */ | ||
1264 | addi r6, r1 ,STACK_FRAME_OVERHEAD | ||
1265 | |||
1266 | /* ftrace_call(r3, r4, r5, r6) */ | ||
1267 | .globl ftrace_call | ||
1268 | ftrace_call: | ||
1269 | bl ftrace_stub | ||
1270 | nop | ||
1271 | |||
1272 | /* Load ctr with the possibly modified NIP */ | ||
1273 | ld r3, _NIP(r1) | ||
1274 | mtctr r3 | ||
1275 | |||
1276 | /* Restore gprs */ | ||
1277 | REST_8GPRS(0,r1) | ||
1278 | REST_8GPRS(8,r1) | ||
1279 | REST_8GPRS(16,r1) | ||
1280 | REST_8GPRS(24,r1) | ||
1281 | |||
1282 | /* Restore callee's TOC */ | ||
1283 | ld r2, 24(r1) | ||
1284 | |||
1285 | /* Pop our stack frame */ | ||
1286 | addi r1, r1, SWITCH_FRAME_SIZE | ||
1287 | |||
1288 | /* Restore original LR for return to B */ | ||
1289 | ld r0, LRSAVE(r1) | ||
1290 | mtlr r0 | ||
1291 | |||
1292 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
1293 | stdu r1, -112(r1) | ||
1294 | .globl ftrace_graph_call | ||
1295 | ftrace_graph_call: | ||
1296 | b ftrace_graph_stub | ||
1297 | _GLOBAL(ftrace_graph_stub) | ||
1298 | addi r1, r1, 112 | ||
1299 | #endif | ||
1300 | |||
1301 | ld r0,LRSAVE(r1) /* restore callee's lr at _mcount site */ | ||
1302 | mtlr r0 | ||
1303 | bctr /* jump after _mcount site */ | ||
1304 | #endif /* CC_USING_MPROFILE_KERNEL */ | ||
1305 | |||
1169 | _GLOBAL(ftrace_stub) | 1306 | _GLOBAL(ftrace_stub) |
1170 | blr | 1307 | blr |
1171 | #else | 1308 | #else |
@@ -1198,6 +1335,7 @@ _GLOBAL(ftrace_stub) | |||
1198 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 1335 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
1199 | 1336 | ||
1200 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 1337 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
1338 | #ifndef CC_USING_MPROFILE_KERNEL | ||
1201 | _GLOBAL(ftrace_graph_caller) | 1339 | _GLOBAL(ftrace_graph_caller) |
1202 | /* load r4 with local address */ | 1340 | /* load r4 with local address */ |
1203 | ld r4, 128(r1) | 1341 | ld r4, 128(r1) |
@@ -1222,6 +1360,56 @@ _GLOBAL(ftrace_graph_caller) | |||
1222 | addi r1, r1, 112 | 1360 | addi r1, r1, 112 |
1223 | blr | 1361 | blr |
1224 | 1362 | ||
1363 | #else /* CC_USING_MPROFILE_KERNEL */ | ||
1364 | _GLOBAL(ftrace_graph_caller) | ||
1365 | /* with -mprofile-kernel, parameter regs are still alive at _mcount */ | ||
1366 | std r10, 104(r1) | ||
1367 | std r9, 96(r1) | ||
1368 | std r8, 88(r1) | ||
1369 | std r7, 80(r1) | ||
1370 | std r6, 72(r1) | ||
1371 | std r5, 64(r1) | ||
1372 | std r4, 56(r1) | ||
1373 | std r3, 48(r1) | ||
1374 | |||
1375 | /* Save callee's TOC in the ABI compliant location */ | ||
1376 | std r2, 24(r1) | ||
1377 | ld r2, PACATOC(r13) /* get kernel TOC in r2 */ | ||
1378 | |||
1379 | mfctr r4 /* ftrace_caller has moved local addr here */ | ||
1380 | std r4, 40(r1) | ||
1381 | mflr r3 /* ftrace_caller has restored LR from stack */ | ||
1382 | subi r4, r4, MCOUNT_INSN_SIZE | ||
1383 | |||
1384 | bl prepare_ftrace_return | ||
1385 | nop | ||
1386 | |||
1387 | /* | ||
1388 | * prepare_ftrace_return gives us the address we divert to. | ||
1389 | * Change the LR to this. | ||
1390 | */ | ||
1391 | mtlr r3 | ||
1392 | |||
1393 | ld r0, 40(r1) | ||
1394 | mtctr r0 | ||
1395 | ld r10, 104(r1) | ||
1396 | ld r9, 96(r1) | ||
1397 | ld r8, 88(r1) | ||
1398 | ld r7, 80(r1) | ||
1399 | ld r6, 72(r1) | ||
1400 | ld r5, 64(r1) | ||
1401 | ld r4, 56(r1) | ||
1402 | ld r3, 48(r1) | ||
1403 | |||
1404 | /* Restore callee's TOC */ | ||
1405 | ld r2, 24(r1) | ||
1406 | |||
1407 | addi r1, r1, 112 | ||
1408 | mflr r0 | ||
1409 | std r0, LRSAVE(r1) | ||
1410 | bctr | ||
1411 | #endif /* CC_USING_MPROFILE_KERNEL */ | ||
1412 | |||
1225 | _GLOBAL(return_to_handler) | 1413 | _GLOBAL(return_to_handler) |
1226 | /* need to save return values */ | 1414 | /* need to save return values */ |
1227 | std r4, -32(r1) | 1415 | std r4, -32(r1) |
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 2117eaca3d28..15da2b5df85e 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S | |||
@@ -130,6 +130,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) | |||
130 | or r12,r12,r4 | 130 | or r12,r12,r4 |
131 | std r12,_MSR(r1) | 131 | std r12,_MSR(r1) |
132 | #endif | 132 | #endif |
133 | /* Don't care if r4 overflows, this is desired behaviour */ | ||
134 | lbz r4,THREAD_LOAD_FP(r5) | ||
135 | addi r4,r4,1 | ||
136 | stb r4,THREAD_LOAD_FP(r5) | ||
133 | addi r10,r5,THREAD_FPSTATE | 137 | addi r10,r5,THREAD_FPSTATE |
134 | lfd fr0,FPSTATE_FPSCR(r10) | 138 | lfd fr0,FPSTATE_FPSCR(r10) |
135 | MTFSF_L(fr0) | 139 | MTFSF_L(fr0) |
@@ -139,33 +143,20 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) | |||
139 | blr | 143 | blr |
140 | 144 | ||
141 | /* | 145 | /* |
142 | * __giveup_fpu(tsk) | 146 | * save_fpu(tsk) |
143 | * Disable FP for the task given as the argument, | 147 | * Save the floating-point registers in its thread_struct. |
144 | * and save the floating-point registers in its thread_struct. | ||
145 | * Enables the FPU for use in the kernel on return. | 148 | * Enables the FPU for use in the kernel on return. |
146 | */ | 149 | */ |
147 | _GLOBAL(__giveup_fpu) | 150 | _GLOBAL(save_fpu) |
148 | addi r3,r3,THREAD /* want THREAD of task */ | 151 | addi r3,r3,THREAD /* want THREAD of task */ |
149 | PPC_LL r6,THREAD_FPSAVEAREA(r3) | 152 | PPC_LL r6,THREAD_FPSAVEAREA(r3) |
150 | PPC_LL r5,PT_REGS(r3) | 153 | PPC_LL r5,PT_REGS(r3) |
151 | PPC_LCMPI 0,r6,0 | 154 | PPC_LCMPI 0,r6,0 |
152 | bne 2f | 155 | bne 2f |
153 | addi r6,r3,THREAD_FPSTATE | 156 | addi r6,r3,THREAD_FPSTATE |
154 | 2: PPC_LCMPI 0,r5,0 | 157 | 2: SAVE_32FPVSRS(0, R4, R6) |
155 | SAVE_32FPVSRS(0, R4, R6) | ||
156 | mffs fr0 | 158 | mffs fr0 |
157 | stfd fr0,FPSTATE_FPSCR(r6) | 159 | stfd fr0,FPSTATE_FPSCR(r6) |
158 | beq 1f | ||
159 | PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
160 | li r3,MSR_FP|MSR_FE0|MSR_FE1 | ||
161 | #ifdef CONFIG_VSX | ||
162 | BEGIN_FTR_SECTION | ||
163 | oris r3,r3,MSR_VSX@h | ||
164 | END_FTR_SECTION_IFSET(CPU_FTR_VSX) | ||
165 | #endif | ||
166 | andc r4,r4,r3 /* disable FP for previous task */ | ||
167 | PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
168 | 1: | ||
169 | blr | 160 | blr |
170 | 161 | ||
171 | /* | 162 | /* |
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index 44d4d8eb3c85..9dac18dabd03 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c | |||
@@ -61,8 +61,11 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new) | |||
61 | return -EFAULT; | 61 | return -EFAULT; |
62 | 62 | ||
63 | /* Make sure it is what we expect it to be */ | 63 | /* Make sure it is what we expect it to be */ |
64 | if (replaced != old) | 64 | if (replaced != old) { |
65 | pr_err("%p: replaced (%#x) != old (%#x)", | ||
66 | (void *)ip, replaced, old); | ||
65 | return -EINVAL; | 67 | return -EINVAL; |
68 | } | ||
66 | 69 | ||
67 | /* replace the text with the new text */ | 70 | /* replace the text with the new text */ |
68 | if (patch_instruction((unsigned int *)ip, new)) | 71 | if (patch_instruction((unsigned int *)ip, new)) |
@@ -106,14 +109,15 @@ static int | |||
106 | __ftrace_make_nop(struct module *mod, | 109 | __ftrace_make_nop(struct module *mod, |
107 | struct dyn_ftrace *rec, unsigned long addr) | 110 | struct dyn_ftrace *rec, unsigned long addr) |
108 | { | 111 | { |
109 | unsigned int op; | 112 | unsigned long entry, ptr, tramp; |
110 | unsigned long entry, ptr; | ||
111 | unsigned long ip = rec->ip; | 113 | unsigned long ip = rec->ip; |
112 | void *tramp; | 114 | unsigned int op, pop; |
113 | 115 | ||
114 | /* read where this goes */ | 116 | /* read where this goes */ |
115 | if (probe_kernel_read(&op, (void *)ip, sizeof(int))) | 117 | if (probe_kernel_read(&op, (void *)ip, sizeof(int))) { |
118 | pr_err("Fetching opcode failed.\n"); | ||
116 | return -EFAULT; | 119 | return -EFAULT; |
120 | } | ||
117 | 121 | ||
118 | /* Make sure that that this is still a 24bit jump */ | 122 | /* Make sure that that this is still a 24bit jump */ |
119 | if (!is_bl_op(op)) { | 123 | if (!is_bl_op(op)) { |
@@ -122,14 +126,9 @@ __ftrace_make_nop(struct module *mod, | |||
122 | } | 126 | } |
123 | 127 | ||
124 | /* lets find where the pointer goes */ | 128 | /* lets find where the pointer goes */ |
125 | tramp = (void *)find_bl_target(ip, op); | 129 | tramp = find_bl_target(ip, op); |
126 | |||
127 | pr_devel("ip:%lx jumps to %p", ip, tramp); | ||
128 | 130 | ||
129 | if (!is_module_trampoline(tramp)) { | 131 | pr_devel("ip:%lx jumps to %lx", ip, tramp); |
130 | pr_err("Not a trampoline\n"); | ||
131 | return -EINVAL; | ||
132 | } | ||
133 | 132 | ||
134 | if (module_trampoline_target(mod, tramp, &ptr)) { | 133 | if (module_trampoline_target(mod, tramp, &ptr)) { |
135 | pr_err("Failed to get trampoline target\n"); | 134 | pr_err("Failed to get trampoline target\n"); |
@@ -158,10 +157,42 @@ __ftrace_make_nop(struct module *mod, | |||
158 | * | 157 | * |
159 | * Use a b +8 to jump over the load. | 158 | * Use a b +8 to jump over the load. |
160 | */ | 159 | */ |
161 | op = 0x48000008; /* b +8 */ | ||
162 | 160 | ||
163 | if (patch_instruction((unsigned int *)ip, op)) | 161 | pop = PPC_INST_BRANCH | 8; /* b +8 */ |
162 | |||
163 | /* | ||
164 | * Check what is in the next instruction. We can see ld r2,40(r1), but | ||
165 | * on first pass after boot we will see mflr r0. | ||
166 | */ | ||
167 | if (probe_kernel_read(&op, (void *)(ip+4), MCOUNT_INSN_SIZE)) { | ||
168 | pr_err("Fetching op failed.\n"); | ||
169 | return -EFAULT; | ||
170 | } | ||
171 | |||
172 | if (op != PPC_INST_LD_TOC) { | ||
173 | unsigned int inst; | ||
174 | |||
175 | if (probe_kernel_read(&inst, (void *)(ip - 4), 4)) { | ||
176 | pr_err("Fetching instruction at %lx failed.\n", ip - 4); | ||
177 | return -EFAULT; | ||
178 | } | ||
179 | |||
180 | /* We expect either a mlfr r0, or a std r0, LRSAVE(r1) */ | ||
181 | if (inst != PPC_INST_MFLR && inst != PPC_INST_STD_LR) { | ||
182 | pr_err("Unexpected instructions around bl _mcount\n" | ||
183 | "when enabling dynamic ftrace!\t" | ||
184 | "(%08x,bl,%08x)\n", inst, op); | ||
185 | return -EINVAL; | ||
186 | } | ||
187 | |||
188 | /* When using -mkernel_profile there is no load to jump over */ | ||
189 | pop = PPC_INST_NOP; | ||
190 | } | ||
191 | |||
192 | if (patch_instruction((unsigned int *)ip, pop)) { | ||
193 | pr_err("Patching NOP failed.\n"); | ||
164 | return -EPERM; | 194 | return -EPERM; |
195 | } | ||
165 | 196 | ||
166 | return 0; | 197 | return 0; |
167 | } | 198 | } |
@@ -287,16 +318,15 @@ int ftrace_make_nop(struct module *mod, | |||
287 | 318 | ||
288 | #ifdef CONFIG_MODULES | 319 | #ifdef CONFIG_MODULES |
289 | #ifdef CONFIG_PPC64 | 320 | #ifdef CONFIG_PPC64 |
321 | /* | ||
322 | * Examine the existing instructions for __ftrace_make_call. | ||
323 | * They should effectively be a NOP, and follow formal constraints, | ||
324 | * depending on the ABI. Return false if they don't. | ||
325 | */ | ||
326 | #ifndef CC_USING_MPROFILE_KERNEL | ||
290 | static int | 327 | static int |
291 | __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | 328 | expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1) |
292 | { | 329 | { |
293 | unsigned int op[2]; | ||
294 | void *ip = (void *)rec->ip; | ||
295 | |||
296 | /* read where this goes */ | ||
297 | if (probe_kernel_read(op, ip, sizeof(op))) | ||
298 | return -EFAULT; | ||
299 | |||
300 | /* | 330 | /* |
301 | * We expect to see: | 331 | * We expect to see: |
302 | * | 332 | * |
@@ -306,8 +336,34 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | |||
306 | * The load offset is different depending on the ABI. For simplicity | 336 | * The load offset is different depending on the ABI. For simplicity |
307 | * just mask it out when doing the compare. | 337 | * just mask it out when doing the compare. |
308 | */ | 338 | */ |
309 | if ((op[0] != 0x48000008) || ((op[1] & 0xffff0000) != 0xe8410000)) { | 339 | if ((op0 != 0x48000008) || ((op1 & 0xffff0000) != 0xe8410000)) |
310 | pr_err("Unexpected call sequence: %x %x\n", op[0], op[1]); | 340 | return 0; |
341 | return 1; | ||
342 | } | ||
343 | #else | ||
344 | static int | ||
345 | expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1) | ||
346 | { | ||
347 | /* look for patched "NOP" on ppc64 with -mprofile-kernel */ | ||
348 | if (op0 != PPC_INST_NOP) | ||
349 | return 0; | ||
350 | return 1; | ||
351 | } | ||
352 | #endif | ||
353 | |||
354 | static int | ||
355 | __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | ||
356 | { | ||
357 | unsigned int op[2]; | ||
358 | void *ip = (void *)rec->ip; | ||
359 | |||
360 | /* read where this goes */ | ||
361 | if (probe_kernel_read(op, ip, sizeof(op))) | ||
362 | return -EFAULT; | ||
363 | |||
364 | if (!expected_nop_sequence(ip, op[0], op[1])) { | ||
365 | pr_err("Unexpected call sequence at %p: %x %x\n", | ||
366 | ip, op[0], op[1]); | ||
311 | return -EINVAL; | 367 | return -EINVAL; |
312 | } | 368 | } |
313 | 369 | ||
@@ -330,7 +386,16 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | |||
330 | 386 | ||
331 | return 0; | 387 | return 0; |
332 | } | 388 | } |
333 | #else | 389 | |
390 | #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS | ||
391 | int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, | ||
392 | unsigned long addr) | ||
393 | { | ||
394 | return ftrace_make_call(rec, addr); | ||
395 | } | ||
396 | #endif | ||
397 | |||
398 | #else /* !CONFIG_PPC64: */ | ||
334 | static int | 399 | static int |
335 | __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | 400 | __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) |
336 | { | 401 | { |
@@ -455,20 +520,13 @@ void ftrace_replace_code(int enable) | |||
455 | } | 520 | } |
456 | } | 521 | } |
457 | 522 | ||
523 | /* | ||
524 | * Use the default ftrace_modify_all_code, but without | ||
525 | * stop_machine(). | ||
526 | */ | ||
458 | void arch_ftrace_update_code(int command) | 527 | void arch_ftrace_update_code(int command) |
459 | { | 528 | { |
460 | if (command & FTRACE_UPDATE_CALLS) | 529 | ftrace_modify_all_code(command); |
461 | ftrace_replace_code(1); | ||
462 | else if (command & FTRACE_DISABLE_CALLS) | ||
463 | ftrace_replace_code(0); | ||
464 | |||
465 | if (command & FTRACE_UPDATE_TRACE_FUNC) | ||
466 | ftrace_update_ftrace_func(ftrace_trace_function); | ||
467 | |||
468 | if (command & FTRACE_START_FUNC_RET) | ||
469 | ftrace_enable_ftrace_graph_caller(); | ||
470 | else if (command & FTRACE_STOP_FUNC_RET) | ||
471 | ftrace_disable_ftrace_graph_caller(); | ||
472 | } | 530 | } |
473 | 531 | ||
474 | int __init ftrace_dyn_arch_init(void) | 532 | int __init ftrace_dyn_arch_init(void) |
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index b5061abbd2e0..9cdf5c71e426 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S | |||
@@ -806,7 +806,7 @@ _GLOBAL(set_context) | |||
806 | _GLOBAL(init_cpu_state) | 806 | _GLOBAL(init_cpu_state) |
807 | mflr r22 | 807 | mflr r22 |
808 | #ifdef CONFIG_PPC_47x | 808 | #ifdef CONFIG_PPC_47x |
809 | /* We use the PVR to differenciate 44x cores from 476 */ | 809 | /* We use the PVR to differentiate 44x cores from 476 */ |
810 | mfspr r3,SPRN_PVR | 810 | mfspr r3,SPRN_PVR |
811 | srwi r3,r3,16 | 811 | srwi r3,r3,16 |
812 | cmplwi cr0,r3,PVR_476FPE@h | 812 | cmplwi cr0,r3,PVR_476FPE@h |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 1b779560728f..4286775cbde9 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <asm/kvm_book3s_asm.h> | 40 | #include <asm/kvm_book3s_asm.h> |
41 | #include <asm/ptrace.h> | 41 | #include <asm/ptrace.h> |
42 | #include <asm/hw_irq.h> | 42 | #include <asm/hw_irq.h> |
43 | #include <asm/cputhreads.h> | ||
44 | #include <asm/ppc-opcode.h> | ||
43 | 45 | ||
44 | /* The physical memory is laid out such that the secondary processor | 46 | /* The physical memory is laid out such that the secondary processor |
45 | * spin code sits at 0x0000...0x00ff. On server, the vectors follow | 47 | * spin code sits at 0x0000...0x00ff. On server, the vectors follow |
@@ -181,6 +183,64 @@ exception_marker: | |||
181 | #endif | 183 | #endif |
182 | 184 | ||
183 | #ifdef CONFIG_PPC_BOOK3E | 185 | #ifdef CONFIG_PPC_BOOK3E |
186 | /* | ||
187 | * The booting_thread_hwid holds the thread id we want to boot in cpu | ||
188 | * hotplug case. It is set by cpu hotplug code, and is invalid by default. | ||
189 | * The thread id is the same as the initial value of SPRN_PIR[THREAD_ID] | ||
190 | * bit field. | ||
191 | */ | ||
192 | .globl booting_thread_hwid | ||
193 | booting_thread_hwid: | ||
194 | .long INVALID_THREAD_HWID | ||
195 | .align 3 | ||
196 | /* | ||
197 | * start a thread in the same core | ||
198 | * input parameters: | ||
199 | * r3 = the thread physical id | ||
200 | * r4 = the entry point where thread starts | ||
201 | */ | ||
202 | _GLOBAL(book3e_start_thread) | ||
203 | LOAD_REG_IMMEDIATE(r5, MSR_KERNEL) | ||
204 | cmpi 0, r3, 0 | ||
205 | beq 10f | ||
206 | cmpi 0, r3, 1 | ||
207 | beq 11f | ||
208 | /* If the thread id is invalid, just exit. */ | ||
209 | b 13f | ||
210 | 10: | ||
211 | MTTMR(TMRN_IMSR0, 5) | ||
212 | MTTMR(TMRN_INIA0, 4) | ||
213 | b 12f | ||
214 | 11: | ||
215 | MTTMR(TMRN_IMSR1, 5) | ||
216 | MTTMR(TMRN_INIA1, 4) | ||
217 | 12: | ||
218 | isync | ||
219 | li r6, 1 | ||
220 | sld r6, r6, r3 | ||
221 | mtspr SPRN_TENS, r6 | ||
222 | 13: | ||
223 | blr | ||
224 | |||
225 | /* | ||
226 | * stop a thread in the same core | ||
227 | * input parameter: | ||
228 | * r3 = the thread physical id | ||
229 | */ | ||
230 | _GLOBAL(book3e_stop_thread) | ||
231 | cmpi 0, r3, 0 | ||
232 | beq 10f | ||
233 | cmpi 0, r3, 1 | ||
234 | beq 10f | ||
235 | /* If the thread id is invalid, just exit. */ | ||
236 | b 13f | ||
237 | 10: | ||
238 | li r4, 1 | ||
239 | sld r4, r4, r3 | ||
240 | mtspr SPRN_TENC, r4 | ||
241 | 13: | ||
242 | blr | ||
243 | |||
184 | _GLOBAL(fsl_secondary_thread_init) | 244 | _GLOBAL(fsl_secondary_thread_init) |
185 | mfspr r4,SPRN_BUCSR | 245 | mfspr r4,SPRN_BUCSR |
186 | 246 | ||
@@ -261,6 +321,44 @@ _GLOBAL(generic_secondary_smp_init) | |||
261 | mr r3,r24 | 321 | mr r3,r24 |
262 | mr r4,r25 | 322 | mr r4,r25 |
263 | bl book3e_secondary_core_init | 323 | bl book3e_secondary_core_init |
324 | |||
325 | /* | ||
326 | * After common core init has finished, check if the current thread is the | ||
327 | * one we wanted to boot. If not, start the specified thread and stop the | ||
328 | * current thread. | ||
329 | */ | ||
330 | LOAD_REG_ADDR(r4, booting_thread_hwid) | ||
331 | lwz r3, 0(r4) | ||
332 | li r5, INVALID_THREAD_HWID | ||
333 | cmpw r3, r5 | ||
334 | beq 20f | ||
335 | |||
336 | /* | ||
337 | * The value of booting_thread_hwid has been stored in r3, | ||
338 | * so make it invalid. | ||
339 | */ | ||
340 | stw r5, 0(r4) | ||
341 | |||
342 | /* | ||
343 | * Get the current thread id and check if it is the one we wanted. | ||
344 | * If not, start the one specified in booting_thread_hwid and stop | ||
345 | * the current thread. | ||
346 | */ | ||
347 | mfspr r8, SPRN_TIR | ||
348 | cmpw r3, r8 | ||
349 | beq 20f | ||
350 | |||
351 | /* start the specified thread */ | ||
352 | LOAD_REG_ADDR(r5, fsl_secondary_thread_init) | ||
353 | ld r4, 0(r5) | ||
354 | bl book3e_start_thread | ||
355 | |||
356 | /* stop the current thread */ | ||
357 | mr r3, r8 | ||
358 | bl book3e_stop_thread | ||
359 | 10: | ||
360 | b 10b | ||
361 | 20: | ||
264 | #endif | 362 | #endif |
265 | 363 | ||
266 | generic_secondary_common_init: | 364 | generic_secondary_common_init: |
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 78c1eba4c04a..80c69472314e 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S | |||
@@ -329,7 +329,7 @@ InstructionTLBMiss: | |||
329 | /* If we are faulting a kernel address, we have to use the | 329 | /* If we are faulting a kernel address, we have to use the |
330 | * kernel page tables. | 330 | * kernel page tables. |
331 | */ | 331 | */ |
332 | #ifdef CONFIG_MODULES | 332 | #if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) |
333 | /* Only modules will cause ITLB Misses as we always | 333 | /* Only modules will cause ITLB Misses as we always |
334 | * pin the first 8MB of kernel memory */ | 334 | * pin the first 8MB of kernel memory */ |
335 | mfspr r11, SPRN_SRR0 /* Get effective address of fault */ | 335 | mfspr r11, SPRN_SRR0 /* Get effective address of fault */ |
@@ -385,27 +385,26 @@ InstructionTLBMiss: | |||
385 | 385 | ||
386 | . = 0x1200 | 386 | . = 0x1200 |
387 | DataStoreTLBMiss: | 387 | DataStoreTLBMiss: |
388 | #ifdef CONFIG_8xx_CPU6 | ||
389 | mtspr SPRN_SPRG_SCRATCH2, r3 | 388 | mtspr SPRN_SPRG_SCRATCH2, r3 |
390 | #endif | ||
391 | EXCEPTION_PROLOG_0 | 389 | EXCEPTION_PROLOG_0 |
392 | mfcr r10 | 390 | mfcr r3 |
393 | 391 | ||
394 | /* If we are faulting a kernel address, we have to use the | 392 | /* If we are faulting a kernel address, we have to use the |
395 | * kernel page tables. | 393 | * kernel page tables. |
396 | */ | 394 | */ |
397 | mfspr r11, SPRN_MD_EPN | 395 | mfspr r10, SPRN_MD_EPN |
398 | IS_KERNEL(r11, r11) | 396 | IS_KERNEL(r11, r10) |
399 | mfspr r11, SPRN_M_TW /* Get level 1 table */ | 397 | mfspr r11, SPRN_M_TW /* Get level 1 table */ |
400 | BRANCH_UNLESS_KERNEL(3f) | 398 | BRANCH_UNLESS_KERNEL(3f) |
401 | lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha | 399 | lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha |
402 | 3: | 400 | 3: |
403 | mtcr r10 | ||
404 | mfspr r10, SPRN_MD_EPN | ||
405 | 401 | ||
406 | /* Insert level 1 index */ | 402 | /* Insert level 1 index */ |
407 | rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 | 403 | rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 |
408 | lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */ | 404 | lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */ |
405 | mtcr r11 | ||
406 | bt- 28,DTLBMiss8M /* bit 28 = Large page (8M) */ | ||
407 | mtcr r3 | ||
409 | 408 | ||
410 | /* We have a pte table, so load fetch the pte from the table. | 409 | /* We have a pte table, so load fetch the pte from the table. |
411 | */ | 410 | */ |
@@ -453,13 +452,34 @@ DataStoreTLBMiss: | |||
453 | MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */ | 452 | MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */ |
454 | 453 | ||
455 | /* Restore registers */ | 454 | /* Restore registers */ |
456 | #ifdef CONFIG_8xx_CPU6 | ||
457 | mfspr r3, SPRN_SPRG_SCRATCH2 | 455 | mfspr r3, SPRN_SPRG_SCRATCH2 |
456 | mtspr SPRN_DAR, r11 /* Tag DAR */ | ||
457 | EXCEPTION_EPILOG_0 | ||
458 | rfi | ||
459 | |||
460 | DTLBMiss8M: | ||
461 | mtcr r3 | ||
462 | ori r11, r11, MD_SVALID | ||
463 | MTSPR_CPU6(SPRN_MD_TWC, r11, r3) | ||
464 | #ifdef CONFIG_PPC_16K_PAGES | ||
465 | /* | ||
466 | * In 16k pages mode, each PGD entry defines a 64M block. | ||
467 | * Here we select the 8M page within the block. | ||
468 | */ | ||
469 | rlwimi r11, r10, 0, 0x03800000 | ||
458 | #endif | 470 | #endif |
471 | rlwinm r10, r11, 0, 0xff800000 | ||
472 | ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \ | ||
473 | _PAGE_PRESENT | ||
474 | MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */ | ||
475 | |||
476 | li r11, RPN_PATTERN | ||
477 | mfspr r3, SPRN_SPRG_SCRATCH2 | ||
459 | mtspr SPRN_DAR, r11 /* Tag DAR */ | 478 | mtspr SPRN_DAR, r11 /* Tag DAR */ |
460 | EXCEPTION_EPILOG_0 | 479 | EXCEPTION_EPILOG_0 |
461 | rfi | 480 | rfi |
462 | 481 | ||
482 | |||
463 | /* This is an instruction TLB error on the MPC8xx. This could be due | 483 | /* This is an instruction TLB error on the MPC8xx. This could be due |
464 | * to many reasons, such as executing guarded memory or illegal instruction | 484 | * to many reasons, such as executing guarded memory or illegal instruction |
465 | * addresses. There is nothing to do but handle a big time error fault. | 485 | * addresses. There is nothing to do but handle a big time error fault. |
@@ -537,13 +557,15 @@ FixupDAR:/* Entry point for dcbx workaround. */ | |||
537 | /* Insert level 1 index */ | 557 | /* Insert level 1 index */ |
538 | 3: rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 | 558 | 3: rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 |
539 | lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */ | 559 | lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */ |
560 | mtcr r11 | ||
561 | bt 28,200f /* bit 28 = Large page (8M) */ | ||
540 | rlwinm r11, r11,0,0,19 /* Extract page descriptor page address */ | 562 | rlwinm r11, r11,0,0,19 /* Extract page descriptor page address */ |
541 | /* Insert level 2 index */ | 563 | /* Insert level 2 index */ |
542 | rlwimi r11, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29 | 564 | rlwimi r11, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29 |
543 | lwz r11, 0(r11) /* Get the pte */ | 565 | lwz r11, 0(r11) /* Get the pte */ |
544 | /* concat physical page address(r11) and page offset(r10) */ | 566 | /* concat physical page address(r11) and page offset(r10) */ |
545 | rlwimi r11, r10, 0, 32 - PAGE_SHIFT, 31 | 567 | rlwimi r11, r10, 0, 32 - PAGE_SHIFT, 31 |
546 | lwz r11,0(r11) | 568 | 201: lwz r11,0(r11) |
547 | /* Check if it really is a dcbx instruction. */ | 569 | /* Check if it really is a dcbx instruction. */ |
548 | /* dcbt and dcbtst does not generate DTLB Misses/Errors, | 570 | /* dcbt and dcbtst does not generate DTLB Misses/Errors, |
549 | * no need to include them here */ | 571 | * no need to include them here */ |
@@ -562,6 +584,10 @@ FixupDAR:/* Entry point for dcbx workaround. */ | |||
562 | 141: mfspr r10,SPRN_SPRG_SCRATCH2 | 584 | 141: mfspr r10,SPRN_SPRG_SCRATCH2 |
563 | b DARFixed /* Nope, go back to normal TLB processing */ | 585 | b DARFixed /* Nope, go back to normal TLB processing */ |
564 | 586 | ||
587 | /* concat physical page address(r11) and page offset(r10) */ | ||
588 | 200: rlwimi r11, r10, 0, 32 - (PAGE_SHIFT << 1), 31 | ||
589 | b 201b | ||
590 | |||
565 | 144: mfspr r10, SPRN_DSISR | 591 | 144: mfspr r10, SPRN_DSISR |
566 | rlwinm r10, r10,0,7,5 /* Clear store bit for buggy dcbst insn */ | 592 | rlwinm r10, r10,0,7,5 /* Clear store bit for buggy dcbst insn */ |
567 | mtspr SPRN_DSISR, r10 | 593 | mtspr SPRN_DSISR, r10 |
@@ -857,68 +883,6 @@ initial_mmu: | |||
857 | 883 | ||
858 | 884 | ||
859 | /* | 885 | /* |
860 | * Set up to use a given MMU context. | ||
861 | * r3 is context number, r4 is PGD pointer. | ||
862 | * | ||
863 | * We place the physical address of the new task page directory loaded | ||
864 | * into the MMU base register, and set the ASID compare register with | ||
865 | * the new "context." | ||
866 | */ | ||
867 | _GLOBAL(set_context) | ||
868 | |||
869 | #ifdef CONFIG_BDI_SWITCH | ||
870 | /* Context switch the PTE pointer for the Abatron BDI2000. | ||
871 | * The PGDIR is passed as second argument. | ||
872 | */ | ||
873 | lis r5, KERNELBASE@h | ||
874 | lwz r5, 0xf0(r5) | ||
875 | stw r4, 0x4(r5) | ||
876 | #endif | ||
877 | |||
878 | /* Register M_TW will contain base address of level 1 table minus the | ||
879 | * lower part of the kernel PGDIR base address, so that all accesses to | ||
880 | * level 1 table are done relative to lower part of kernel PGDIR base | ||
881 | * address. | ||
882 | */ | ||
883 | li r5, (swapper_pg_dir-PAGE_OFFSET)@l | ||
884 | sub r4, r4, r5 | ||
885 | tophys (r4, r4) | ||
886 | #ifdef CONFIG_8xx_CPU6 | ||
887 | lis r6, cpu6_errata_word@h | ||
888 | ori r6, r6, cpu6_errata_word@l | ||
889 | li r7, 0x3f80 | ||
890 | stw r7, 12(r6) | ||
891 | lwz r7, 12(r6) | ||
892 | #endif | ||
893 | mtspr SPRN_M_TW, r4 /* Update pointeur to level 1 table */ | ||
894 | #ifdef CONFIG_8xx_CPU6 | ||
895 | li r7, 0x3380 | ||
896 | stw r7, 12(r6) | ||
897 | lwz r7, 12(r6) | ||
898 | #endif | ||
899 | mtspr SPRN_M_CASID, r3 /* Update context */ | ||
900 | SYNC | ||
901 | blr | ||
902 | |||
903 | #ifdef CONFIG_8xx_CPU6 | ||
904 | /* It's here because it is unique to the 8xx. | ||
905 | * It is important we get called with interrupts disabled. I used to | ||
906 | * do that, but it appears that all code that calls this already had | ||
907 | * interrupt disabled. | ||
908 | */ | ||
909 | .globl set_dec_cpu6 | ||
910 | set_dec_cpu6: | ||
911 | lis r7, cpu6_errata_word@h | ||
912 | ori r7, r7, cpu6_errata_word@l | ||
913 | li r4, 0x2c00 | ||
914 | stw r4, 8(r7) | ||
915 | lwz r4, 8(r7) | ||
916 | mtspr 22, r3 /* Update Decrementer */ | ||
917 | SYNC | ||
918 | blr | ||
919 | #endif | ||
920 | |||
921 | /* | ||
922 | * We put a few things here that have to be page-aligned. | 886 | * We put a few things here that have to be page-aligned. |
923 | * This stuff goes at the beginning of the data segment, | 887 | * This stuff goes at the beginning of the data segment, |
924 | * which is page-aligned. | 888 | * which is page-aligned. |
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index f705171b924b..3bfa3150911f 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S | |||
@@ -1037,80 +1037,6 @@ _GLOBAL(set_context) | |||
1037 | isync /* Force context change */ | 1037 | isync /* Force context change */ |
1038 | blr | 1038 | blr |
1039 | 1039 | ||
1040 | _GLOBAL(flush_dcache_L1) | ||
1041 | mfspr r3,SPRN_L1CFG0 | ||
1042 | |||
1043 | rlwinm r5,r3,9,3 /* Extract cache block size */ | ||
1044 | twlgti r5,1 /* Only 32 and 64 byte cache blocks | ||
1045 | * are currently defined. | ||
1046 | */ | ||
1047 | li r4,32 | ||
1048 | subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) - | ||
1049 | * log2(number of ways) | ||
1050 | */ | ||
1051 | slw r5,r4,r5 /* r5 = cache block size */ | ||
1052 | |||
1053 | rlwinm r7,r3,0,0xff /* Extract number of KiB in the cache */ | ||
1054 | mulli r7,r7,13 /* An 8-way cache will require 13 | ||
1055 | * loads per set. | ||
1056 | */ | ||
1057 | slw r7,r7,r6 | ||
1058 | |||
1059 | /* save off HID0 and set DCFA */ | ||
1060 | mfspr r8,SPRN_HID0 | ||
1061 | ori r9,r8,HID0_DCFA@l | ||
1062 | mtspr SPRN_HID0,r9 | ||
1063 | isync | ||
1064 | |||
1065 | lis r4,KERNELBASE@h | ||
1066 | mtctr r7 | ||
1067 | |||
1068 | 1: lwz r3,0(r4) /* Load... */ | ||
1069 | add r4,r4,r5 | ||
1070 | bdnz 1b | ||
1071 | |||
1072 | msync | ||
1073 | lis r4,KERNELBASE@h | ||
1074 | mtctr r7 | ||
1075 | |||
1076 | 1: dcbf 0,r4 /* ...and flush. */ | ||
1077 | add r4,r4,r5 | ||
1078 | bdnz 1b | ||
1079 | |||
1080 | /* restore HID0 */ | ||
1081 | mtspr SPRN_HID0,r8 | ||
1082 | isync | ||
1083 | |||
1084 | blr | ||
1085 | |||
1086 | /* Flush L1 d-cache, invalidate and disable d-cache and i-cache */ | ||
1087 | _GLOBAL(__flush_disable_L1) | ||
1088 | mflr r10 | ||
1089 | bl flush_dcache_L1 /* Flush L1 d-cache */ | ||
1090 | mtlr r10 | ||
1091 | |||
1092 | mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */ | ||
1093 | li r5, 2 | ||
1094 | rlwimi r4, r5, 0, 3 | ||
1095 | |||
1096 | msync | ||
1097 | isync | ||
1098 | mtspr SPRN_L1CSR0, r4 | ||
1099 | isync | ||
1100 | |||
1101 | 1: mfspr r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */ | ||
1102 | andi. r4, r4, 2 | ||
1103 | bne 1b | ||
1104 | |||
1105 | mfspr r4, SPRN_L1CSR1 /* Invalidate and disable i-cache */ | ||
1106 | li r5, 2 | ||
1107 | rlwimi r4, r5, 0, 3 | ||
1108 | |||
1109 | mtspr SPRN_L1CSR1, r4 | ||
1110 | isync | ||
1111 | |||
1112 | blr | ||
1113 | |||
1114 | #ifdef CONFIG_SMP | 1040 | #ifdef CONFIG_SMP |
1115 | /* When we get here, r24 needs to hold the CPU # */ | 1041 | /* When we get here, r24 needs to hold the CPU # */ |
1116 | .globl __secondary_start | 1042 | .globl __secondary_start |
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S index cf4fb5429cf1..470ceebd2d23 100644 --- a/arch/powerpc/kernel/idle_power7.S +++ b/arch/powerpc/kernel/idle_power7.S | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <asm/kvm_book3s_asm.h> | 19 | #include <asm/kvm_book3s_asm.h> |
20 | #include <asm/opal.h> | 20 | #include <asm/opal.h> |
21 | #include <asm/cpuidle.h> | 21 | #include <asm/cpuidle.h> |
22 | #include <asm/mmu-hash64.h> | 22 | #include <asm/book3s/64/mmu-hash.h> |
23 | 23 | ||
24 | #undef DEBUG | 24 | #undef DEBUG |
25 | 25 | ||
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index e77c3ccf8dcf..dbf098121ce6 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c | |||
@@ -445,7 +445,11 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code, | |||
445 | * Global data | 445 | * Global data |
446 | */ | 446 | */ |
447 | struct kgdb_arch arch_kgdb_ops = { | 447 | struct kgdb_arch arch_kgdb_ops = { |
448 | #ifdef __LITTLE_ENDIAN__ | ||
449 | .gdb_bpt_instr = {0x08, 0x10, 0x82, 0x7d}, | ||
450 | #else | ||
448 | .gdb_bpt_instr = {0x7d, 0x82, 0x10, 0x08}, | 451 | .gdb_bpt_instr = {0x7d, 0x82, 0x10, 0x08}, |
452 | #endif | ||
449 | }; | 453 | }; |
450 | 454 | ||
451 | static int kgdb_not_implemented(struct pt_regs *regs) | 455 | static int kgdb_not_implemented(struct pt_regs *regs) |
diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c index 2c647b1e62e4..ee62b197502d 100644 --- a/arch/powerpc/kernel/mce_power.c +++ b/arch/powerpc/kernel/mce_power.c | |||
@@ -54,8 +54,8 @@ static void flush_tlb_206(unsigned int num_sets, unsigned int action) | |||
54 | } | 54 | } |
55 | 55 | ||
56 | /* | 56 | /* |
57 | * Generic routine to flush TLB on power7. This routine is used as | 57 | * Generic routines to flush TLB on POWER processors. These routines |
58 | * flush_tlb hook in cpu_spec for Power7 processor. | 58 | * are used as flush_tlb hook in the cpu_spec. |
59 | * | 59 | * |
60 | * action => TLB_INVAL_SCOPE_GLOBAL: Invalidate all TLBs. | 60 | * action => TLB_INVAL_SCOPE_GLOBAL: Invalidate all TLBs. |
61 | * TLB_INVAL_SCOPE_LPID: Invalidate TLB for current LPID. | 61 | * TLB_INVAL_SCOPE_LPID: Invalidate TLB for current LPID. |
@@ -65,18 +65,17 @@ void __flush_tlb_power7(unsigned int action) | |||
65 | flush_tlb_206(POWER7_TLB_SETS, action); | 65 | flush_tlb_206(POWER7_TLB_SETS, action); |
66 | } | 66 | } |
67 | 67 | ||
68 | /* | ||
69 | * Generic routine to flush TLB on power8. This routine is used as | ||
70 | * flush_tlb hook in cpu_spec for power8 processor. | ||
71 | * | ||
72 | * action => TLB_INVAL_SCOPE_GLOBAL: Invalidate all TLBs. | ||
73 | * TLB_INVAL_SCOPE_LPID: Invalidate TLB for current LPID. | ||
74 | */ | ||
75 | void __flush_tlb_power8(unsigned int action) | 68 | void __flush_tlb_power8(unsigned int action) |
76 | { | 69 | { |
77 | flush_tlb_206(POWER8_TLB_SETS, action); | 70 | flush_tlb_206(POWER8_TLB_SETS, action); |
78 | } | 71 | } |
79 | 72 | ||
73 | void __flush_tlb_power9(unsigned int action) | ||
74 | { | ||
75 | flush_tlb_206(POWER9_TLB_SETS_HASH, action); | ||
76 | } | ||
77 | |||
78 | |||
80 | /* flush SLBs and reload */ | 79 | /* flush SLBs and reload */ |
81 | static void flush_and_reload_slb(void) | 80 | static void flush_and_reload_slb(void) |
82 | { | 81 | { |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index be8edd67f05b..bf5160fbf9d8 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -91,17 +91,16 @@ _GLOBAL(mulhdu) | |||
91 | addc r7,r0,r7 | 91 | addc r7,r0,r7 |
92 | addze r4,r4 | 92 | addze r4,r4 |
93 | 1: beqlr cr1 /* all done if high part of A is 0 */ | 93 | 1: beqlr cr1 /* all done if high part of A is 0 */ |
94 | mr r10,r3 | ||
95 | mullw r9,r3,r5 | 94 | mullw r9,r3,r5 |
96 | mulhwu r3,r3,r5 | 95 | mulhwu r10,r3,r5 |
97 | beq 2f | 96 | beq 2f |
98 | mullw r0,r10,r6 | 97 | mullw r0,r3,r6 |
99 | mulhwu r8,r10,r6 | 98 | mulhwu r8,r3,r6 |
100 | addc r7,r0,r7 | 99 | addc r7,r0,r7 |
101 | adde r4,r4,r8 | 100 | adde r4,r4,r8 |
102 | addze r3,r3 | 101 | addze r10,r10 |
103 | 2: addc r4,r4,r9 | 102 | 2: addc r4,r4,r9 |
104 | addze r3,r3 | 103 | addze r3,r10 |
105 | blr | 104 | blr |
106 | 105 | ||
107 | /* | 106 | /* |
@@ -296,12 +295,9 @@ _GLOBAL(real_writeb) | |||
296 | * Flush instruction cache. | 295 | * Flush instruction cache. |
297 | * This is a no-op on the 601. | 296 | * This is a no-op on the 601. |
298 | */ | 297 | */ |
298 | #ifndef CONFIG_PPC_8xx | ||
299 | _GLOBAL(flush_instruction_cache) | 299 | _GLOBAL(flush_instruction_cache) |
300 | #if defined(CONFIG_8xx) | 300 | #if defined(CONFIG_4xx) |
301 | isync | ||
302 | lis r5, IDC_INVALL@h | ||
303 | mtspr SPRN_IC_CST, r5 | ||
304 | #elif defined(CONFIG_4xx) | ||
305 | #ifdef CONFIG_403GCX | 301 | #ifdef CONFIG_403GCX |
306 | li r3, 512 | 302 | li r3, 512 |
307 | mtctr r3 | 303 | mtctr r3 |
@@ -334,9 +330,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE) | |||
334 | mfspr r3,SPRN_HID0 | 330 | mfspr r3,SPRN_HID0 |
335 | ori r3,r3,HID0_ICFI | 331 | ori r3,r3,HID0_ICFI |
336 | mtspr SPRN_HID0,r3 | 332 | mtspr SPRN_HID0,r3 |
337 | #endif /* CONFIG_8xx/4xx */ | 333 | #endif /* CONFIG_4xx */ |
338 | isync | 334 | isync |
339 | blr | 335 | blr |
336 | #endif /* CONFIG_PPC_8xx */ | ||
340 | 337 | ||
341 | /* | 338 | /* |
342 | * Write any modified data cache blocks out to memory | 339 | * Write any modified data cache blocks out to memory |
@@ -350,10 +347,9 @@ BEGIN_FTR_SECTION | |||
350 | PURGE_PREFETCHED_INS | 347 | PURGE_PREFETCHED_INS |
351 | blr /* for 601, do nothing */ | 348 | blr /* for 601, do nothing */ |
352 | END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) | 349 | END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) |
353 | li r5,L1_CACHE_BYTES-1 | 350 | rlwinm r3,r3,0,0,31 - L1_CACHE_SHIFT |
354 | andc r3,r3,r5 | ||
355 | subf r4,r3,r4 | 351 | subf r4,r3,r4 |
356 | add r4,r4,r5 | 352 | addi r4,r4,L1_CACHE_BYTES - 1 |
357 | srwi. r4,r4,L1_CACHE_SHIFT | 353 | srwi. r4,r4,L1_CACHE_SHIFT |
358 | beqlr | 354 | beqlr |
359 | mtctr r4 | 355 | mtctr r4 |
@@ -377,71 +373,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) | |||
377 | isync | 373 | isync |
378 | blr | 374 | blr |
379 | /* | 375 | /* |
380 | * Write any modified data cache blocks out to memory. | ||
381 | * Does not invalidate the corresponding cache lines (especially for | ||
382 | * any corresponding instruction cache). | ||
383 | * | ||
384 | * clean_dcache_range(unsigned long start, unsigned long stop) | ||
385 | */ | ||
386 | _GLOBAL(clean_dcache_range) | ||
387 | li r5,L1_CACHE_BYTES-1 | ||
388 | andc r3,r3,r5 | ||
389 | subf r4,r3,r4 | ||
390 | add r4,r4,r5 | ||
391 | srwi. r4,r4,L1_CACHE_SHIFT | ||
392 | beqlr | ||
393 | mtctr r4 | ||
394 | |||
395 | 1: dcbst 0,r3 | ||
396 | addi r3,r3,L1_CACHE_BYTES | ||
397 | bdnz 1b | ||
398 | sync /* wait for dcbst's to get to ram */ | ||
399 | blr | ||
400 | |||
401 | /* | ||
402 | * Write any modified data cache blocks out to memory and invalidate them. | ||
403 | * Does not invalidate the corresponding instruction cache blocks. | ||
404 | * | ||
405 | * flush_dcache_range(unsigned long start, unsigned long stop) | ||
406 | */ | ||
407 | _GLOBAL(flush_dcache_range) | ||
408 | li r5,L1_CACHE_BYTES-1 | ||
409 | andc r3,r3,r5 | ||
410 | subf r4,r3,r4 | ||
411 | add r4,r4,r5 | ||
412 | srwi. r4,r4,L1_CACHE_SHIFT | ||
413 | beqlr | ||
414 | mtctr r4 | ||
415 | |||
416 | 1: dcbf 0,r3 | ||
417 | addi r3,r3,L1_CACHE_BYTES | ||
418 | bdnz 1b | ||
419 | sync /* wait for dcbst's to get to ram */ | ||
420 | blr | ||
421 | |||
422 | /* | ||
423 | * Like above, but invalidate the D-cache. This is used by the 8xx | ||
424 | * to invalidate the cache so the PPC core doesn't get stale data | ||
425 | * from the CPM (no cache snooping here :-). | ||
426 | * | ||
427 | * invalidate_dcache_range(unsigned long start, unsigned long stop) | ||
428 | */ | ||
429 | _GLOBAL(invalidate_dcache_range) | ||
430 | li r5,L1_CACHE_BYTES-1 | ||
431 | andc r3,r3,r5 | ||
432 | subf r4,r3,r4 | ||
433 | add r4,r4,r5 | ||
434 | srwi. r4,r4,L1_CACHE_SHIFT | ||
435 | beqlr | ||
436 | mtctr r4 | ||
437 | |||
438 | 1: dcbi 0,r3 | ||
439 | addi r3,r3,L1_CACHE_BYTES | ||
440 | bdnz 1b | ||
441 | sync /* wait for dcbi's to get to ram */ | ||
442 | blr | ||
443 | |||
444 | /* | ||
445 | * Flush a particular page from the data cache to RAM. | 376 | * Flush a particular page from the data cache to RAM. |
446 | * Note: this is necessary because the instruction cache does *not* | 377 | * Note: this is necessary because the instruction cache does *not* |
447 | * snoop from the data cache. | 378 | * snoop from the data cache. |
@@ -519,22 +450,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) | |||
519 | #endif /* CONFIG_BOOKE */ | 450 | #endif /* CONFIG_BOOKE */ |
520 | 451 | ||
521 | /* | 452 | /* |
522 | * Clear pages using the dcbz instruction, which doesn't cause any | ||
523 | * memory traffic (except to write out any cache lines which get | ||
524 | * displaced). This only works on cacheable memory. | ||
525 | * | ||
526 | * void clear_pages(void *page, int order) ; | ||
527 | */ | ||
528 | _GLOBAL(clear_pages) | ||
529 | li r0,PAGE_SIZE/L1_CACHE_BYTES | ||
530 | slw r0,r0,r4 | ||
531 | mtctr r0 | ||
532 | 1: dcbz 0,r3 | ||
533 | addi r3,r3,L1_CACHE_BYTES | ||
534 | bdnz 1b | ||
535 | blr | ||
536 | |||
537 | /* | ||
538 | * Copy a whole page. We use the dcbz instruction on the destination | 453 | * Copy a whole page. We use the dcbz instruction on the destination |
539 | * to reduce memory traffic (it eliminates the unnecessary reads of | 454 | * to reduce memory traffic (it eliminates the unnecessary reads of |
540 | * the destination into cache). This requires that the destination | 455 | * the destination into cache). This requires that the destination |
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c index 9547381b631a..d1f1b35bf0c7 100644 --- a/arch/powerpc/kernel/module.c +++ b/arch/powerpc/kernel/module.c | |||
@@ -47,6 +47,11 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
47 | const Elf_Shdr *sechdrs, struct module *me) | 47 | const Elf_Shdr *sechdrs, struct module *me) |
48 | { | 48 | { |
49 | const Elf_Shdr *sect; | 49 | const Elf_Shdr *sect; |
50 | int rc; | ||
51 | |||
52 | rc = module_finalize_ftrace(me, sechdrs); | ||
53 | if (rc) | ||
54 | return rc; | ||
50 | 55 | ||
51 | /* Apply feature fixups */ | 56 | /* Apply feature fixups */ |
52 | sect = find_section(hdr, sechdrs, "__ftr_fixup"); | 57 | sect = find_section(hdr, sechdrs, "__ftr_fixup"); |
diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c index 2c01665eb410..5a7a78f12562 100644 --- a/arch/powerpc/kernel/module_32.c +++ b/arch/powerpc/kernel/module_32.c | |||
@@ -181,7 +181,7 @@ static inline int entry_matches(struct ppc_plt_entry *entry, Elf32_Addr val) | |||
181 | /* Set up a trampoline in the PLT to bounce us to the distant function */ | 181 | /* Set up a trampoline in the PLT to bounce us to the distant function */ |
182 | static uint32_t do_plt_call(void *location, | 182 | static uint32_t do_plt_call(void *location, |
183 | Elf32_Addr val, | 183 | Elf32_Addr val, |
184 | Elf32_Shdr *sechdrs, | 184 | const Elf32_Shdr *sechdrs, |
185 | struct module *mod) | 185 | struct module *mod) |
186 | { | 186 | { |
187 | struct ppc_plt_entry *entry; | 187 | struct ppc_plt_entry *entry; |
@@ -294,11 +294,19 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
294 | return -ENOEXEC; | 294 | return -ENOEXEC; |
295 | } | 295 | } |
296 | } | 296 | } |
297 | |||
298 | return 0; | ||
299 | } | ||
300 | |||
297 | #ifdef CONFIG_DYNAMIC_FTRACE | 301 | #ifdef CONFIG_DYNAMIC_FTRACE |
298 | module->arch.tramp = | 302 | int module_finalize_ftrace(struct module *module, const Elf_Shdr *sechdrs) |
299 | do_plt_call(module->core_layout.base, | 303 | { |
300 | (unsigned long)ftrace_caller, | 304 | module->arch.tramp = do_plt_call(module->core_layout.base, |
301 | sechdrs, module); | 305 | (unsigned long)ftrace_caller, |
302 | #endif | 306 | sechdrs, module); |
307 | if (!module->arch.tramp) | ||
308 | return -ENOENT; | ||
309 | |||
303 | return 0; | 310 | return 0; |
304 | } | 311 | } |
312 | #endif | ||
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 08b7a40de5f8..9ce9a25f58b5 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <asm/code-patching.h> | 31 | #include <asm/code-patching.h> |
32 | #include <linux/sort.h> | 32 | #include <linux/sort.h> |
33 | #include <asm/setup.h> | 33 | #include <asm/setup.h> |
34 | #include <asm/sections.h> | ||
34 | 35 | ||
35 | /* FIXME: We don't do .init separately. To do this, we'd need to have | 36 | /* FIXME: We don't do .init separately. To do this, we'd need to have |
36 | a separate r2 value in the init and core section, and stub between | 37 | a separate r2 value in the init and core section, and stub between |
@@ -41,7 +42,6 @@ | |||
41 | --RR. */ | 42 | --RR. */ |
42 | 43 | ||
43 | #if defined(_CALL_ELF) && _CALL_ELF == 2 | 44 | #if defined(_CALL_ELF) && _CALL_ELF == 2 |
44 | #define R2_STACK_OFFSET 24 | ||
45 | 45 | ||
46 | /* An address is simply the address of the function. */ | 46 | /* An address is simply the address of the function. */ |
47 | typedef unsigned long func_desc_t; | 47 | typedef unsigned long func_desc_t; |
@@ -73,7 +73,6 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym) | |||
73 | return PPC64_LOCAL_ENTRY_OFFSET(sym->st_other); | 73 | return PPC64_LOCAL_ENTRY_OFFSET(sym->st_other); |
74 | } | 74 | } |
75 | #else | 75 | #else |
76 | #define R2_STACK_OFFSET 40 | ||
77 | 76 | ||
78 | /* An address is address of the OPD entry, which contains address of fn. */ | 77 | /* An address is address of the OPD entry, which contains address of fn. */ |
79 | typedef struct ppc64_opd_entry func_desc_t; | 78 | typedef struct ppc64_opd_entry func_desc_t; |
@@ -96,6 +95,8 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym) | |||
96 | } | 95 | } |
97 | #endif | 96 | #endif |
98 | 97 | ||
98 | #define STUB_MAGIC 0x73747562 /* stub */ | ||
99 | |||
99 | /* Like PPC32, we need little trampolines to do > 24-bit jumps (into | 100 | /* Like PPC32, we need little trampolines to do > 24-bit jumps (into |
100 | the kernel itself). But on PPC64, these need to be used for every | 101 | the kernel itself). But on PPC64, these need to be used for every |
101 | jump, actually, to reset r2 (TOC+0x8000). */ | 102 | jump, actually, to reset r2 (TOC+0x8000). */ |
@@ -105,7 +106,8 @@ struct ppc64_stub_entry | |||
105 | * need 6 instructions on ABIv2 but we always allocate 7 so | 106 | * need 6 instructions on ABIv2 but we always allocate 7 so |
106 | * so we don't have to modify the trampoline load instruction. */ | 107 | * so we don't have to modify the trampoline load instruction. */ |
107 | u32 jump[7]; | 108 | u32 jump[7]; |
108 | u32 unused; | 109 | /* Used by ftrace to identify stubs */ |
110 | u32 magic; | ||
109 | /* Data for the above code */ | 111 | /* Data for the above code */ |
110 | func_desc_t funcdata; | 112 | func_desc_t funcdata; |
111 | }; | 113 | }; |
@@ -139,70 +141,39 @@ static u32 ppc64_stub_insns[] = { | |||
139 | }; | 141 | }; |
140 | 142 | ||
141 | #ifdef CONFIG_DYNAMIC_FTRACE | 143 | #ifdef CONFIG_DYNAMIC_FTRACE |
142 | 144 | int module_trampoline_target(struct module *mod, unsigned long addr, | |
143 | static u32 ppc64_stub_mask[] = { | 145 | unsigned long *target) |
144 | 0xffff0000, | ||
145 | 0xffff0000, | ||
146 | 0xffffffff, | ||
147 | 0xffffffff, | ||
148 | #if !defined(_CALL_ELF) || _CALL_ELF != 2 | ||
149 | 0xffffffff, | ||
150 | #endif | ||
151 | 0xffffffff, | ||
152 | 0xffffffff | ||
153 | }; | ||
154 | |||
155 | bool is_module_trampoline(u32 *p) | ||
156 | { | 146 | { |
157 | unsigned int i; | 147 | struct ppc64_stub_entry *stub; |
158 | u32 insns[ARRAY_SIZE(ppc64_stub_insns)]; | 148 | func_desc_t funcdata; |
159 | 149 | u32 magic; | |
160 | BUILD_BUG_ON(sizeof(ppc64_stub_insns) != sizeof(ppc64_stub_mask)); | ||
161 | 150 | ||
162 | if (probe_kernel_read(insns, p, sizeof(insns))) | 151 | if (!within_module_core(addr, mod)) { |
152 | pr_err("%s: stub %lx not in module %s\n", __func__, addr, mod->name); | ||
163 | return -EFAULT; | 153 | return -EFAULT; |
164 | |||
165 | for (i = 0; i < ARRAY_SIZE(ppc64_stub_insns); i++) { | ||
166 | u32 insna = insns[i]; | ||
167 | u32 insnb = ppc64_stub_insns[i]; | ||
168 | u32 mask = ppc64_stub_mask[i]; | ||
169 | |||
170 | if ((insna & mask) != (insnb & mask)) | ||
171 | return false; | ||
172 | } | 154 | } |
173 | 155 | ||
174 | return true; | 156 | stub = (struct ppc64_stub_entry *)addr; |
175 | } | ||
176 | |||
177 | int module_trampoline_target(struct module *mod, u32 *trampoline, | ||
178 | unsigned long *target) | ||
179 | { | ||
180 | u32 buf[2]; | ||
181 | u16 upper, lower; | ||
182 | long offset; | ||
183 | void *toc_entry; | ||
184 | 157 | ||
185 | if (probe_kernel_read(buf, trampoline, sizeof(buf))) | 158 | if (probe_kernel_read(&magic, &stub->magic, sizeof(magic))) { |
159 | pr_err("%s: fault reading magic for stub %lx for %s\n", __func__, addr, mod->name); | ||
186 | return -EFAULT; | 160 | return -EFAULT; |
161 | } | ||
187 | 162 | ||
188 | upper = buf[0] & 0xffff; | 163 | if (magic != STUB_MAGIC) { |
189 | lower = buf[1] & 0xffff; | 164 | pr_err("%s: bad magic for stub %lx for %s\n", __func__, addr, mod->name); |
190 | 165 | return -EFAULT; | |
191 | /* perform the addis/addi, both signed */ | 166 | } |
192 | offset = ((short)upper << 16) + (short)lower; | ||
193 | 167 | ||
194 | /* | 168 | if (probe_kernel_read(&funcdata, &stub->funcdata, sizeof(funcdata))) { |
195 | * Now get the address this trampoline jumps to. This | 169 | pr_err("%s: fault reading funcdata for stub %lx for %s\n", __func__, addr, mod->name); |
196 | * is always 32 bytes into our trampoline stub. | 170 | return -EFAULT; |
197 | */ | 171 | } |
198 | toc_entry = (void *)mod->arch.toc + offset + 32; | ||
199 | 172 | ||
200 | if (probe_kernel_read(target, toc_entry, sizeof(*target))) | 173 | *target = stub_func_addr(funcdata); |
201 | return -EFAULT; | ||
202 | 174 | ||
203 | return 0; | 175 | return 0; |
204 | } | 176 | } |
205 | |||
206 | #endif | 177 | #endif |
207 | 178 | ||
208 | /* Count how many different 24-bit relocations (different symbol, | 179 | /* Count how many different 24-bit relocations (different symbol, |
@@ -413,7 +384,7 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr, | |||
413 | /* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this | 384 | /* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this |
414 | gives the value maximum span in an instruction which uses a signed | 385 | gives the value maximum span in an instruction which uses a signed |
415 | offset) */ | 386 | offset) */ |
416 | static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me) | 387 | static inline unsigned long my_r2(const Elf64_Shdr *sechdrs, struct module *me) |
417 | { | 388 | { |
418 | return sechdrs[me->arch.toc_section].sh_addr + 0x8000; | 389 | return sechdrs[me->arch.toc_section].sh_addr + 0x8000; |
419 | } | 390 | } |
@@ -426,7 +397,7 @@ static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me) | |||
426 | #define PPC_HA(v) PPC_HI ((v) + 0x8000) | 397 | #define PPC_HA(v) PPC_HI ((v) + 0x8000) |
427 | 398 | ||
428 | /* Patch stub to reference function and correct r2 value. */ | 399 | /* Patch stub to reference function and correct r2 value. */ |
429 | static inline int create_stub(Elf64_Shdr *sechdrs, | 400 | static inline int create_stub(const Elf64_Shdr *sechdrs, |
430 | struct ppc64_stub_entry *entry, | 401 | struct ppc64_stub_entry *entry, |
431 | unsigned long addr, | 402 | unsigned long addr, |
432 | struct module *me) | 403 | struct module *me) |
@@ -447,12 +418,14 @@ static inline int create_stub(Elf64_Shdr *sechdrs, | |||
447 | entry->jump[0] |= PPC_HA(reladdr); | 418 | entry->jump[0] |= PPC_HA(reladdr); |
448 | entry->jump[1] |= PPC_LO(reladdr); | 419 | entry->jump[1] |= PPC_LO(reladdr); |
449 | entry->funcdata = func_desc(addr); | 420 | entry->funcdata = func_desc(addr); |
421 | entry->magic = STUB_MAGIC; | ||
422 | |||
450 | return 1; | 423 | return 1; |
451 | } | 424 | } |
452 | 425 | ||
453 | /* Create stub to jump to function described in this OPD/ptr: we need the | 426 | /* Create stub to jump to function described in this OPD/ptr: we need the |
454 | stub to set up the TOC ptr (r2) for the function. */ | 427 | stub to set up the TOC ptr (r2) for the function. */ |
455 | static unsigned long stub_for_addr(Elf64_Shdr *sechdrs, | 428 | static unsigned long stub_for_addr(const Elf64_Shdr *sechdrs, |
456 | unsigned long addr, | 429 | unsigned long addr, |
457 | struct module *me) | 430 | struct module *me) |
458 | { | 431 | { |
@@ -476,17 +449,60 @@ static unsigned long stub_for_addr(Elf64_Shdr *sechdrs, | |||
476 | return (unsigned long)&stubs[i]; | 449 | return (unsigned long)&stubs[i]; |
477 | } | 450 | } |
478 | 451 | ||
452 | #ifdef CC_USING_MPROFILE_KERNEL | ||
453 | static bool is_early_mcount_callsite(u32 *instruction) | ||
454 | { | ||
455 | /* | ||
456 | * Check if this is one of the -mprofile-kernel sequences. | ||
457 | */ | ||
458 | if (instruction[-1] == PPC_INST_STD_LR && | ||
459 | instruction[-2] == PPC_INST_MFLR) | ||
460 | return true; | ||
461 | |||
462 | if (instruction[-1] == PPC_INST_MFLR) | ||
463 | return true; | ||
464 | |||
465 | return false; | ||
466 | } | ||
467 | |||
468 | /* | ||
469 | * In case of _mcount calls, do not save the current callee's TOC (in r2) into | ||
470 | * the original caller's stack frame. If we did we would clobber the saved TOC | ||
471 | * value of the original caller. | ||
472 | */ | ||
473 | static void squash_toc_save_inst(const char *name, unsigned long addr) | ||
474 | { | ||
475 | struct ppc64_stub_entry *stub = (struct ppc64_stub_entry *)addr; | ||
476 | |||
477 | /* Only for calls to _mcount */ | ||
478 | if (strcmp("_mcount", name) != 0) | ||
479 | return; | ||
480 | |||
481 | stub->jump[2] = PPC_INST_NOP; | ||
482 | } | ||
483 | #else | ||
484 | static void squash_toc_save_inst(const char *name, unsigned long addr) { } | ||
485 | |||
486 | /* without -mprofile-kernel, mcount calls are never early */ | ||
487 | static bool is_early_mcount_callsite(u32 *instruction) | ||
488 | { | ||
489 | return false; | ||
490 | } | ||
491 | #endif | ||
492 | |||
479 | /* We expect a noop next: if it is, replace it with instruction to | 493 | /* We expect a noop next: if it is, replace it with instruction to |
480 | restore r2. */ | 494 | restore r2. */ |
481 | static int restore_r2(u32 *instruction, struct module *me) | 495 | static int restore_r2(u32 *instruction, struct module *me) |
482 | { | 496 | { |
483 | if (*instruction != PPC_INST_NOP) { | 497 | if (*instruction != PPC_INST_NOP) { |
498 | if (is_early_mcount_callsite(instruction - 1)) | ||
499 | return 1; | ||
484 | pr_err("%s: Expect noop after relocate, got %08x\n", | 500 | pr_err("%s: Expect noop after relocate, got %08x\n", |
485 | me->name, *instruction); | 501 | me->name, *instruction); |
486 | return 0; | 502 | return 0; |
487 | } | 503 | } |
488 | /* ld r2,R2_STACK_OFFSET(r1) */ | 504 | /* ld r2,R2_STACK_OFFSET(r1) */ |
489 | *instruction = 0xe8410000 | R2_STACK_OFFSET; | 505 | *instruction = PPC_INST_LD_TOC; |
490 | return 1; | 506 | return 1; |
491 | } | 507 | } |
492 | 508 | ||
@@ -611,6 +627,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
611 | return -ENOENT; | 627 | return -ENOENT; |
612 | if (!restore_r2((u32 *)location + 1, me)) | 628 | if (!restore_r2((u32 *)location + 1, me)) |
613 | return -ENOEXEC; | 629 | return -ENOEXEC; |
630 | |||
631 | squash_toc_save_inst(strtab + sym->st_name, value); | ||
614 | } else | 632 | } else |
615 | value += local_entry_offset(sym); | 633 | value += local_entry_offset(sym); |
616 | 634 | ||
@@ -693,12 +711,84 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
693 | } | 711 | } |
694 | } | 712 | } |
695 | 713 | ||
714 | return 0; | ||
715 | } | ||
716 | |||
696 | #ifdef CONFIG_DYNAMIC_FTRACE | 717 | #ifdef CONFIG_DYNAMIC_FTRACE |
697 | me->arch.toc = my_r2(sechdrs, me); | 718 | |
698 | me->arch.tramp = stub_for_addr(sechdrs, | 719 | #ifdef CC_USING_MPROFILE_KERNEL |
699 | (unsigned long)ftrace_caller, | 720 | |
700 | me); | 721 | #define PACATOC offsetof(struct paca_struct, kernel_toc) |
722 | |||
723 | /* | ||
724 | * For mprofile-kernel we use a special stub for ftrace_caller() because we | ||
725 | * can't rely on r2 containing this module's TOC when we enter the stub. | ||
726 | * | ||
727 | * That can happen if the function calling us didn't need to use the toc. In | ||
728 | * that case it won't have setup r2, and the r2 value will be either the | ||
729 | * kernel's toc, or possibly another modules toc. | ||
730 | * | ||
731 | * To deal with that this stub uses the kernel toc, which is always accessible | ||
732 | * via the paca (in r13). The target (ftrace_caller()) is responsible for | ||
733 | * saving and restoring the toc before returning. | ||
734 | */ | ||
735 | static unsigned long create_ftrace_stub(const Elf64_Shdr *sechdrs, struct module *me) | ||
736 | { | ||
737 | struct ppc64_stub_entry *entry; | ||
738 | unsigned int i, num_stubs; | ||
739 | static u32 stub_insns[] = { | ||
740 | 0xe98d0000 | PACATOC, /* ld r12,PACATOC(r13) */ | ||
741 | 0x3d8c0000, /* addis r12,r12,<high> */ | ||
742 | 0x398c0000, /* addi r12,r12,<low> */ | ||
743 | 0x7d8903a6, /* mtctr r12 */ | ||
744 | 0x4e800420, /* bctr */ | ||
745 | }; | ||
746 | long reladdr; | ||
747 | |||
748 | num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*entry); | ||
749 | |||
750 | /* Find the next available stub entry */ | ||
751 | entry = (void *)sechdrs[me->arch.stubs_section].sh_addr; | ||
752 | for (i = 0; i < num_stubs && stub_func_addr(entry->funcdata); i++, entry++); | ||
753 | |||
754 | if (i >= num_stubs) { | ||
755 | pr_err("%s: Unable to find a free slot for ftrace stub.\n", me->name); | ||
756 | return 0; | ||
757 | } | ||
758 | |||
759 | memcpy(entry->jump, stub_insns, sizeof(stub_insns)); | ||
760 | |||
761 | /* Stub uses address relative to kernel toc (from the paca) */ | ||
762 | reladdr = (unsigned long)ftrace_caller - kernel_toc_addr(); | ||
763 | if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) { | ||
764 | pr_err("%s: Address of ftrace_caller out of range of kernel_toc.\n", me->name); | ||
765 | return 0; | ||
766 | } | ||
767 | |||
768 | entry->jump[1] |= PPC_HA(reladdr); | ||
769 | entry->jump[2] |= PPC_LO(reladdr); | ||
770 | |||
771 | /* Eventhough we don't use funcdata in the stub, it's needed elsewhere. */ | ||
772 | entry->funcdata = func_desc((unsigned long)ftrace_caller); | ||
773 | entry->magic = STUB_MAGIC; | ||
774 | |||
775 | return (unsigned long)entry; | ||
776 | } | ||
777 | #else | ||
778 | static unsigned long create_ftrace_stub(const Elf64_Shdr *sechdrs, struct module *me) | ||
779 | { | ||
780 | return stub_for_addr(sechdrs, (unsigned long)ftrace_caller, me); | ||
781 | } | ||
701 | #endif | 782 | #endif |
702 | 783 | ||
784 | int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs) | ||
785 | { | ||
786 | mod->arch.toc = my_r2(sechdrs, mod); | ||
787 | mod->arch.tramp = create_ftrace_stub(sechdrs, mod); | ||
788 | |||
789 | if (!mod->arch.tramp) | ||
790 | return -ENOENT; | ||
791 | |||
703 | return 0; | 792 | return 0; |
704 | } | 793 | } |
794 | #endif | ||
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 01ea0edf0579..93dae296b6be 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c | |||
@@ -17,10 +17,6 @@ | |||
17 | #include <asm/pgtable.h> | 17 | #include <asm/pgtable.h> |
18 | #include <asm/kexec.h> | 18 | #include <asm/kexec.h> |
19 | 19 | ||
20 | /* This symbol is provided by the linker - let it fill in the paca | ||
21 | * field correctly */ | ||
22 | extern unsigned long __toc_start; | ||
23 | |||
24 | #ifdef CONFIG_PPC_BOOK3S | 20 | #ifdef CONFIG_PPC_BOOK3S |
25 | 21 | ||
26 | /* | 22 | /* |
@@ -149,11 +145,6 @@ EXPORT_SYMBOL(paca); | |||
149 | 145 | ||
150 | void __init initialise_paca(struct paca_struct *new_paca, int cpu) | 146 | void __init initialise_paca(struct paca_struct *new_paca, int cpu) |
151 | { | 147 | { |
152 | /* The TOC register (GPR2) points 32kB into the TOC, so that 64kB | ||
153 | * of the TOC can be addressed using a single machine instruction. | ||
154 | */ | ||
155 | unsigned long kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL; | ||
156 | |||
157 | #ifdef CONFIG_PPC_BOOK3S | 148 | #ifdef CONFIG_PPC_BOOK3S |
158 | new_paca->lppaca_ptr = new_lppaca(cpu); | 149 | new_paca->lppaca_ptr = new_lppaca(cpu); |
159 | #else | 150 | #else |
@@ -161,7 +152,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu) | |||
161 | #endif | 152 | #endif |
162 | new_paca->lock_token = 0x8000; | 153 | new_paca->lock_token = 0x8000; |
163 | new_paca->paca_index = cpu; | 154 | new_paca->paca_index = cpu; |
164 | new_paca->kernel_toc = kernel_toc; | 155 | new_paca->kernel_toc = kernel_toc_addr(); |
165 | new_paca->kernelbase = (unsigned long) _stext; | 156 | new_paca->kernelbase = (unsigned long) _stext; |
166 | /* Only set MSR:IR/DR when MMU is initialized */ | 157 | /* Only set MSR:IR/DR when MMU is initialized */ |
167 | new_paca->kernel_msr = MSR_KERNEL & ~(MSR_IR | MSR_DR); | 158 | new_paca->kernel_msr = MSR_KERNEL & ~(MSR_IR | MSR_DR); |
diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c index 7f9ed0c1f6b9..59c436189f46 100644 --- a/arch/powerpc/kernel/pci-hotplug.c +++ b/arch/powerpc/kernel/pci-hotplug.c | |||
@@ -55,7 +55,7 @@ void pcibios_remove_pci_devices(struct pci_bus *bus) | |||
55 | 55 | ||
56 | pr_debug("PCI: Removing devices on bus %04x:%02x\n", | 56 | pr_debug("PCI: Removing devices on bus %04x:%02x\n", |
57 | pci_domain_nr(bus), bus->number); | 57 | pci_domain_nr(bus), bus->number); |
58 | list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { | 58 | list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) { |
59 | pr_debug(" Removing %s...\n", pci_name(dev)); | 59 | pr_debug(" Removing %s...\n", pci_name(dev)); |
60 | pci_stop_and_remove_bus_device(dev); | 60 | pci_stop_and_remove_bus_device(dev); |
61 | } | 61 | } |
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index b3b4df91b792..38102cb9baa9 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c | |||
@@ -139,6 +139,7 @@ struct pci_dn *pci_get_pdn(struct pci_dev *pdev) | |||
139 | #ifdef CONFIG_PCI_IOV | 139 | #ifdef CONFIG_PCI_IOV |
140 | static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent, | 140 | static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent, |
141 | struct pci_dev *pdev, | 141 | struct pci_dev *pdev, |
142 | int vf_index, | ||
142 | int busno, int devfn) | 143 | int busno, int devfn) |
143 | { | 144 | { |
144 | struct pci_dn *pdn; | 145 | struct pci_dn *pdn; |
@@ -158,6 +159,7 @@ static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent, | |||
158 | pdn->busno = busno; | 159 | pdn->busno = busno; |
159 | pdn->devfn = devfn; | 160 | pdn->devfn = devfn; |
160 | #ifdef CONFIG_PPC_POWERNV | 161 | #ifdef CONFIG_PPC_POWERNV |
162 | pdn->vf_index = vf_index; | ||
161 | pdn->pe_number = IODA_INVALID_PE; | 163 | pdn->pe_number = IODA_INVALID_PE; |
162 | #endif | 164 | #endif |
163 | INIT_LIST_HEAD(&pdn->child_list); | 165 | INIT_LIST_HEAD(&pdn->child_list); |
@@ -179,6 +181,7 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev) | |||
179 | { | 181 | { |
180 | #ifdef CONFIG_PCI_IOV | 182 | #ifdef CONFIG_PCI_IOV |
181 | struct pci_dn *parent, *pdn; | 183 | struct pci_dn *parent, *pdn; |
184 | struct eeh_dev *edev; | ||
182 | int i; | 185 | int i; |
183 | 186 | ||
184 | /* Only support IOV for now */ | 187 | /* Only support IOV for now */ |
@@ -196,7 +199,7 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev) | |||
196 | return NULL; | 199 | return NULL; |
197 | 200 | ||
198 | for (i = 0; i < pci_sriov_get_totalvfs(pdev); i++) { | 201 | for (i = 0; i < pci_sriov_get_totalvfs(pdev); i++) { |
199 | pdn = add_one_dev_pci_data(parent, NULL, | 202 | pdn = add_one_dev_pci_data(parent, NULL, i, |
200 | pci_iov_virtfn_bus(pdev, i), | 203 | pci_iov_virtfn_bus(pdev, i), |
201 | pci_iov_virtfn_devfn(pdev, i)); | 204 | pci_iov_virtfn_devfn(pdev, i)); |
202 | if (!pdn) { | 205 | if (!pdn) { |
@@ -204,6 +207,12 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev) | |||
204 | __func__, i); | 207 | __func__, i); |
205 | return NULL; | 208 | return NULL; |
206 | } | 209 | } |
210 | |||
211 | /* Create the EEH device for the VF */ | ||
212 | eeh_dev_init(pdn, pci_bus_to_host(pdev->bus)); | ||
213 | edev = pdn_to_eeh_dev(pdn); | ||
214 | BUG_ON(!edev); | ||
215 | edev->physfn = pdev; | ||
207 | } | 216 | } |
208 | #endif /* CONFIG_PCI_IOV */ | 217 | #endif /* CONFIG_PCI_IOV */ |
209 | 218 | ||
@@ -215,6 +224,7 @@ void remove_dev_pci_data(struct pci_dev *pdev) | |||
215 | #ifdef CONFIG_PCI_IOV | 224 | #ifdef CONFIG_PCI_IOV |
216 | struct pci_dn *parent; | 225 | struct pci_dn *parent; |
217 | struct pci_dn *pdn, *tmp; | 226 | struct pci_dn *pdn, *tmp; |
227 | struct eeh_dev *edev; | ||
218 | int i; | 228 | int i; |
219 | 229 | ||
220 | /* | 230 | /* |
@@ -256,6 +266,13 @@ void remove_dev_pci_data(struct pci_dev *pdev) | |||
256 | pdn->devfn != pci_iov_virtfn_devfn(pdev, i)) | 266 | pdn->devfn != pci_iov_virtfn_devfn(pdev, i)) |
257 | continue; | 267 | continue; |
258 | 268 | ||
269 | /* Release EEH device for the VF */ | ||
270 | edev = pdn_to_eeh_dev(pdn); | ||
271 | if (edev) { | ||
272 | pdn->edev = NULL; | ||
273 | kfree(edev); | ||
274 | } | ||
275 | |||
259 | if (!list_empty(&pdn->list)) | 276 | if (!list_empty(&pdn->list)) |
260 | list_del(&pdn->list); | 277 | list_del(&pdn->list); |
261 | 278 | ||
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 41e1607e800c..9f01e28ecef3 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -6,7 +6,9 @@ | |||
6 | #include <asm/cacheflush.h> | 6 | #include <asm/cacheflush.h> |
7 | #include <asm/epapr_hcalls.h> | 7 | #include <asm/epapr_hcalls.h> |
8 | 8 | ||
9 | #ifdef CONFIG_PPC64 | ||
9 | EXPORT_SYMBOL(flush_dcache_range); | 10 | EXPORT_SYMBOL(flush_dcache_range); |
11 | #endif | ||
10 | EXPORT_SYMBOL(flush_icache_range); | 12 | EXPORT_SYMBOL(flush_icache_range); |
11 | 13 | ||
12 | EXPORT_SYMBOL(empty_zero_page); | 14 | EXPORT_SYMBOL(empty_zero_page); |
@@ -28,10 +30,6 @@ EXPORT_SYMBOL(load_vr_state); | |||
28 | EXPORT_SYMBOL(store_vr_state); | 30 | EXPORT_SYMBOL(store_vr_state); |
29 | #endif | 31 | #endif |
30 | 32 | ||
31 | #ifdef CONFIG_VSX | ||
32 | EXPORT_SYMBOL_GPL(__giveup_vsx); | ||
33 | #endif | ||
34 | |||
35 | #ifdef CONFIG_EPAPR_PARAVIRT | 33 | #ifdef CONFIG_EPAPR_PARAVIRT |
36 | EXPORT_SYMBOL(epapr_hypercall_start); | 34 | EXPORT_SYMBOL(epapr_hypercall_start); |
37 | #endif | 35 | #endif |
diff --git a/arch/powerpc/kernel/ppc_ksyms_32.c b/arch/powerpc/kernel/ppc_ksyms_32.c index 30ddd8a24eee..2bfaafe5be99 100644 --- a/arch/powerpc/kernel/ppc_ksyms_32.c +++ b/arch/powerpc/kernel/ppc_ksyms_32.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <asm/pgtable.h> | 10 | #include <asm/pgtable.h> |
11 | #include <asm/dcr.h> | 11 | #include <asm/dcr.h> |
12 | 12 | ||
13 | EXPORT_SYMBOL(clear_pages); | ||
14 | EXPORT_SYMBOL(ISA_DMA_THRESHOLD); | 13 | EXPORT_SYMBOL(ISA_DMA_THRESHOLD); |
15 | EXPORT_SYMBOL(DMA_MODE_READ); | 14 | EXPORT_SYMBOL(DMA_MODE_READ); |
16 | EXPORT_SYMBOL(DMA_MODE_WRITE); | 15 | EXPORT_SYMBOL(DMA_MODE_WRITE); |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 3c5736e52a14..612df305886b 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -133,6 +133,16 @@ void __msr_check_and_clear(unsigned long bits) | |||
133 | EXPORT_SYMBOL(__msr_check_and_clear); | 133 | EXPORT_SYMBOL(__msr_check_and_clear); |
134 | 134 | ||
135 | #ifdef CONFIG_PPC_FPU | 135 | #ifdef CONFIG_PPC_FPU |
136 | void __giveup_fpu(struct task_struct *tsk) | ||
137 | { | ||
138 | save_fpu(tsk); | ||
139 | tsk->thread.regs->msr &= ~MSR_FP; | ||
140 | #ifdef CONFIG_VSX | ||
141 | if (cpu_has_feature(CPU_FTR_VSX)) | ||
142 | tsk->thread.regs->msr &= ~MSR_VSX; | ||
143 | #endif | ||
144 | } | ||
145 | |||
136 | void giveup_fpu(struct task_struct *tsk) | 146 | void giveup_fpu(struct task_struct *tsk) |
137 | { | 147 | { |
138 | check_if_tm_restore_required(tsk); | 148 | check_if_tm_restore_required(tsk); |
@@ -187,9 +197,32 @@ void enable_kernel_fp(void) | |||
187 | } | 197 | } |
188 | } | 198 | } |
189 | EXPORT_SYMBOL(enable_kernel_fp); | 199 | EXPORT_SYMBOL(enable_kernel_fp); |
200 | |||
201 | static int restore_fp(struct task_struct *tsk) { | ||
202 | if (tsk->thread.load_fp) { | ||
203 | load_fp_state(¤t->thread.fp_state); | ||
204 | current->thread.load_fp++; | ||
205 | return 1; | ||
206 | } | ||
207 | return 0; | ||
208 | } | ||
209 | #else | ||
210 | static int restore_fp(struct task_struct *tsk) { return 0; } | ||
190 | #endif /* CONFIG_PPC_FPU */ | 211 | #endif /* CONFIG_PPC_FPU */ |
191 | 212 | ||
192 | #ifdef CONFIG_ALTIVEC | 213 | #ifdef CONFIG_ALTIVEC |
214 | #define loadvec(thr) ((thr).load_vec) | ||
215 | |||
216 | static void __giveup_altivec(struct task_struct *tsk) | ||
217 | { | ||
218 | save_altivec(tsk); | ||
219 | tsk->thread.regs->msr &= ~MSR_VEC; | ||
220 | #ifdef CONFIG_VSX | ||
221 | if (cpu_has_feature(CPU_FTR_VSX)) | ||
222 | tsk->thread.regs->msr &= ~MSR_VSX; | ||
223 | #endif | ||
224 | } | ||
225 | |||
193 | void giveup_altivec(struct task_struct *tsk) | 226 | void giveup_altivec(struct task_struct *tsk) |
194 | { | 227 | { |
195 | check_if_tm_restore_required(tsk); | 228 | check_if_tm_restore_required(tsk); |
@@ -229,22 +262,49 @@ void flush_altivec_to_thread(struct task_struct *tsk) | |||
229 | } | 262 | } |
230 | } | 263 | } |
231 | EXPORT_SYMBOL_GPL(flush_altivec_to_thread); | 264 | EXPORT_SYMBOL_GPL(flush_altivec_to_thread); |
265 | |||
266 | static int restore_altivec(struct task_struct *tsk) | ||
267 | { | ||
268 | if (cpu_has_feature(CPU_FTR_ALTIVEC) && tsk->thread.load_vec) { | ||
269 | load_vr_state(&tsk->thread.vr_state); | ||
270 | tsk->thread.used_vr = 1; | ||
271 | tsk->thread.load_vec++; | ||
272 | |||
273 | return 1; | ||
274 | } | ||
275 | return 0; | ||
276 | } | ||
277 | #else | ||
278 | #define loadvec(thr) 0 | ||
279 | static inline int restore_altivec(struct task_struct *tsk) { return 0; } | ||
232 | #endif /* CONFIG_ALTIVEC */ | 280 | #endif /* CONFIG_ALTIVEC */ |
233 | 281 | ||
234 | #ifdef CONFIG_VSX | 282 | #ifdef CONFIG_VSX |
235 | void giveup_vsx(struct task_struct *tsk) | 283 | static void __giveup_vsx(struct task_struct *tsk) |
236 | { | 284 | { |
237 | check_if_tm_restore_required(tsk); | ||
238 | |||
239 | msr_check_and_set(MSR_FP|MSR_VEC|MSR_VSX); | ||
240 | if (tsk->thread.regs->msr & MSR_FP) | 285 | if (tsk->thread.regs->msr & MSR_FP) |
241 | __giveup_fpu(tsk); | 286 | __giveup_fpu(tsk); |
242 | if (tsk->thread.regs->msr & MSR_VEC) | 287 | if (tsk->thread.regs->msr & MSR_VEC) |
243 | __giveup_altivec(tsk); | 288 | __giveup_altivec(tsk); |
289 | tsk->thread.regs->msr &= ~MSR_VSX; | ||
290 | } | ||
291 | |||
292 | static void giveup_vsx(struct task_struct *tsk) | ||
293 | { | ||
294 | check_if_tm_restore_required(tsk); | ||
295 | |||
296 | msr_check_and_set(MSR_FP|MSR_VEC|MSR_VSX); | ||
244 | __giveup_vsx(tsk); | 297 | __giveup_vsx(tsk); |
245 | msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); | 298 | msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); |
246 | } | 299 | } |
247 | EXPORT_SYMBOL(giveup_vsx); | 300 | |
301 | static void save_vsx(struct task_struct *tsk) | ||
302 | { | ||
303 | if (tsk->thread.regs->msr & MSR_FP) | ||
304 | save_fpu(tsk); | ||
305 | if (tsk->thread.regs->msr & MSR_VEC) | ||
306 | save_altivec(tsk); | ||
307 | } | ||
248 | 308 | ||
249 | void enable_kernel_vsx(void) | 309 | void enable_kernel_vsx(void) |
250 | { | 310 | { |
@@ -275,6 +335,19 @@ void flush_vsx_to_thread(struct task_struct *tsk) | |||
275 | } | 335 | } |
276 | } | 336 | } |
277 | EXPORT_SYMBOL_GPL(flush_vsx_to_thread); | 337 | EXPORT_SYMBOL_GPL(flush_vsx_to_thread); |
338 | |||
339 | static int restore_vsx(struct task_struct *tsk) | ||
340 | { | ||
341 | if (cpu_has_feature(CPU_FTR_VSX)) { | ||
342 | tsk->thread.used_vsr = 1; | ||
343 | return 1; | ||
344 | } | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | #else | ||
349 | static inline int restore_vsx(struct task_struct *tsk) { return 0; } | ||
350 | static inline void save_vsx(struct task_struct *tsk) { } | ||
278 | #endif /* CONFIG_VSX */ | 351 | #endif /* CONFIG_VSX */ |
279 | 352 | ||
280 | #ifdef CONFIG_SPE | 353 | #ifdef CONFIG_SPE |
@@ -374,12 +447,76 @@ void giveup_all(struct task_struct *tsk) | |||
374 | } | 447 | } |
375 | EXPORT_SYMBOL(giveup_all); | 448 | EXPORT_SYMBOL(giveup_all); |
376 | 449 | ||
450 | void restore_math(struct pt_regs *regs) | ||
451 | { | ||
452 | unsigned long msr; | ||
453 | |||
454 | if (!current->thread.load_fp && !loadvec(current->thread)) | ||
455 | return; | ||
456 | |||
457 | msr = regs->msr; | ||
458 | msr_check_and_set(msr_all_available); | ||
459 | |||
460 | /* | ||
461 | * Only reload if the bit is not set in the user MSR, the bit BEING set | ||
462 | * indicates that the registers are hot | ||
463 | */ | ||
464 | if ((!(msr & MSR_FP)) && restore_fp(current)) | ||
465 | msr |= MSR_FP | current->thread.fpexc_mode; | ||
466 | |||
467 | if ((!(msr & MSR_VEC)) && restore_altivec(current)) | ||
468 | msr |= MSR_VEC; | ||
469 | |||
470 | if ((msr & (MSR_FP | MSR_VEC)) == (MSR_FP | MSR_VEC) && | ||
471 | restore_vsx(current)) { | ||
472 | msr |= MSR_VSX; | ||
473 | } | ||
474 | |||
475 | msr_check_and_clear(msr_all_available); | ||
476 | |||
477 | regs->msr = msr; | ||
478 | } | ||
479 | |||
480 | void save_all(struct task_struct *tsk) | ||
481 | { | ||
482 | unsigned long usermsr; | ||
483 | |||
484 | if (!tsk->thread.regs) | ||
485 | return; | ||
486 | |||
487 | usermsr = tsk->thread.regs->msr; | ||
488 | |||
489 | if ((usermsr & msr_all_available) == 0) | ||
490 | return; | ||
491 | |||
492 | msr_check_and_set(msr_all_available); | ||
493 | |||
494 | /* | ||
495 | * Saving the way the register space is in hardware, save_vsx boils | ||
496 | * down to a save_fpu() and save_altivec() | ||
497 | */ | ||
498 | if (usermsr & MSR_VSX) { | ||
499 | save_vsx(tsk); | ||
500 | } else { | ||
501 | if (usermsr & MSR_FP) | ||
502 | save_fpu(tsk); | ||
503 | |||
504 | if (usermsr & MSR_VEC) | ||
505 | save_altivec(tsk); | ||
506 | } | ||
507 | |||
508 | if (usermsr & MSR_SPE) | ||
509 | __giveup_spe(tsk); | ||
510 | |||
511 | msr_check_and_clear(msr_all_available); | ||
512 | } | ||
513 | |||
377 | void flush_all_to_thread(struct task_struct *tsk) | 514 | void flush_all_to_thread(struct task_struct *tsk) |
378 | { | 515 | { |
379 | if (tsk->thread.regs) { | 516 | if (tsk->thread.regs) { |
380 | preempt_disable(); | 517 | preempt_disable(); |
381 | BUG_ON(tsk != current); | 518 | BUG_ON(tsk != current); |
382 | giveup_all(tsk); | 519 | save_all(tsk); |
383 | 520 | ||
384 | #ifdef CONFIG_SPE | 521 | #ifdef CONFIG_SPE |
385 | if (tsk->thread.regs->msr & MSR_SPE) | 522 | if (tsk->thread.regs->msr & MSR_SPE) |
@@ -832,17 +969,9 @@ void restore_tm_state(struct pt_regs *regs) | |||
832 | 969 | ||
833 | msr_diff = current->thread.ckpt_regs.msr & ~regs->msr; | 970 | msr_diff = current->thread.ckpt_regs.msr & ~regs->msr; |
834 | msr_diff &= MSR_FP | MSR_VEC | MSR_VSX; | 971 | msr_diff &= MSR_FP | MSR_VEC | MSR_VSX; |
835 | if (msr_diff & MSR_FP) { | 972 | |
836 | msr_check_and_set(MSR_FP); | 973 | restore_math(regs); |
837 | load_fp_state(¤t->thread.fp_state); | 974 | |
838 | msr_check_and_clear(MSR_FP); | ||
839 | regs->msr |= current->thread.fpexc_mode; | ||
840 | } | ||
841 | if (msr_diff & MSR_VEC) { | ||
842 | msr_check_and_set(MSR_VEC); | ||
843 | load_vr_state(¤t->thread.vr_state); | ||
844 | msr_check_and_clear(MSR_VEC); | ||
845 | } | ||
846 | regs->msr |= msr_diff; | 975 | regs->msr |= msr_diff; |
847 | } | 976 | } |
848 | 977 | ||
@@ -1006,6 +1135,10 @@ struct task_struct *__switch_to(struct task_struct *prev, | |||
1006 | batch = this_cpu_ptr(&ppc64_tlb_batch); | 1135 | batch = this_cpu_ptr(&ppc64_tlb_batch); |
1007 | batch->active = 1; | 1136 | batch->active = 1; |
1008 | } | 1137 | } |
1138 | |||
1139 | if (current_thread_info()->task->thread.regs) | ||
1140 | restore_math(current_thread_info()->task->thread.regs); | ||
1141 | |||
1009 | #endif /* CONFIG_PPC_BOOK3S_64 */ | 1142 | #endif /* CONFIG_PPC_BOOK3S_64 */ |
1010 | 1143 | ||
1011 | return last; | 1144 | return last; |
@@ -1307,6 +1440,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
1307 | 1440 | ||
1308 | f = ret_from_fork; | 1441 | f = ret_from_fork; |
1309 | } | 1442 | } |
1443 | childregs->msr &= ~(MSR_FP|MSR_VEC|MSR_VSX); | ||
1310 | sp -= STACK_FRAME_OVERHEAD; | 1444 | sp -= STACK_FRAME_OVERHEAD; |
1311 | 1445 | ||
1312 | /* | 1446 | /* |
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index cf8c7e4e0b21..cb64d6feb45a 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Common signal handling code for both 32 and 64 bits | 2 | * Common signal handling code for both 32 and 64 bits |
3 | * | 3 | * |
4 | * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Coproration | 4 | * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Corporation |
5 | * Extracted from signal_32.c and signal_64.c | 5 | * Extracted from signal_32.c and signal_64.c |
6 | * | 6 | * |
7 | * This file is subject to the terms and conditions of the GNU General | 7 | * This file is subject to the terms and conditions of the GNU General |
@@ -178,7 +178,7 @@ unsigned long get_tm_stackpointer(struct pt_regs *regs) | |||
178 | * need to use the stack pointer from the checkpointed state, rather | 178 | * need to use the stack pointer from the checkpointed state, rather |
179 | * than the speculated state. This ensures that the signal context | 179 | * than the speculated state. This ensures that the signal context |
180 | * (written tm suspended) will be written below the stack required for | 180 | * (written tm suspended) will be written below the stack required for |
181 | * the rollback. The transaction is aborted becuase of the treclaim, | 181 | * the rollback. The transaction is aborted because of the treclaim, |
182 | * so any memory written between the tbegin and the signal will be | 182 | * so any memory written between the tbegin and the signal will be |
183 | * rolled back anyway. | 183 | * rolled back anyway. |
184 | * | 184 | * |
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index 51b274199dd9..be305c858e51 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Coproration | 2 | * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Corporation |
3 | * Extracted from signal_32.c and signal_64.c | 3 | * Extracted from signal_32.c and signal_64.c |
4 | * | 4 | * |
5 | * This file is subject to the terms and conditions of the GNU General | 5 | * This file is subject to the terms and conditions of the GNU General |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index b7dea05f0725..8cac1eb41466 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -445,7 +445,7 @@ void generic_cpu_die(unsigned int cpu) | |||
445 | 445 | ||
446 | for (i = 0; i < 100; i++) { | 446 | for (i = 0; i < 100; i++) { |
447 | smp_rmb(); | 447 | smp_rmb(); |
448 | if (per_cpu(cpu_state, cpu) == CPU_DEAD) | 448 | if (is_cpu_dead(cpu)) |
449 | return; | 449 | return; |
450 | msleep(100); | 450 | msleep(100); |
451 | } | 451 | } |
@@ -472,6 +472,11 @@ int generic_check_cpu_restart(unsigned int cpu) | |||
472 | return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; | 472 | return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; |
473 | } | 473 | } |
474 | 474 | ||
475 | int is_cpu_dead(unsigned int cpu) | ||
476 | { | ||
477 | return per_cpu(cpu_state, cpu) == CPU_DEAD; | ||
478 | } | ||
479 | |||
475 | static bool secondaries_inhibited(void) | 480 | static bool secondaries_inhibited(void) |
476 | { | 481 | { |
477 | return kvm_hv_mode_active(); | 482 | return kvm_hv_mode_active(); |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 33c47fcc455a..9229ba63c370 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -1147,6 +1147,7 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
1147 | goto bail; | 1147 | goto bail; |
1148 | } | 1148 | } |
1149 | if (reason & REASON_TRAP) { | 1149 | if (reason & REASON_TRAP) { |
1150 | unsigned long bugaddr; | ||
1150 | /* Debugger is first in line to stop recursive faults in | 1151 | /* Debugger is first in line to stop recursive faults in |
1151 | * rcu_lock, notify_die, or atomic_notifier_call_chain */ | 1152 | * rcu_lock, notify_die, or atomic_notifier_call_chain */ |
1152 | if (debugger_bpt(regs)) | 1153 | if (debugger_bpt(regs)) |
@@ -1157,8 +1158,15 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
1157 | == NOTIFY_STOP) | 1158 | == NOTIFY_STOP) |
1158 | goto bail; | 1159 | goto bail; |
1159 | 1160 | ||
1161 | bugaddr = regs->nip; | ||
1162 | /* | ||
1163 | * Fixup bugaddr for BUG_ON() in real mode | ||
1164 | */ | ||
1165 | if (!is_kernel_addr(bugaddr) && !(regs->msr & MSR_IR)) | ||
1166 | bugaddr += PAGE_OFFSET; | ||
1167 | |||
1160 | if (!(regs->msr & MSR_PR) && /* not user-mode */ | 1168 | if (!(regs->msr & MSR_PR) && /* not user-mode */ |
1161 | report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { | 1169 | report_bug(bugaddr, regs) == BUG_TRAP_TYPE_WARN) { |
1162 | regs->nip += 4; | 1170 | regs->nip += 4; |
1163 | goto bail; | 1171 | goto bail; |
1164 | } | 1172 | } |
@@ -1393,7 +1401,7 @@ void facility_unavailable_exception(struct pt_regs *regs) | |||
1393 | * is a read DSCR attempt through a mfspr instruction, we | 1401 | * is a read DSCR attempt through a mfspr instruction, we |
1394 | * just emulate the instruction instead. This code path will | 1402 | * just emulate the instruction instead. This code path will |
1395 | * always emulate all the mfspr instructions till the user | 1403 | * always emulate all the mfspr instructions till the user |
1396 | * has attempted atleast one mtspr instruction. This way it | 1404 | * has attempted at least one mtspr instruction. This way it |
1397 | * preserves the same behaviour when the user is accessing | 1405 | * preserves the same behaviour when the user is accessing |
1398 | * the DSCR through privilege level only SPR number (0x11) | 1406 | * the DSCR through privilege level only SPR number (0x11) |
1399 | * which is emulated through illegal instruction exception. | 1407 | * which is emulated through illegal instruction exception. |
diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S index 162d0f714941..1c2e7a343bf5 100644 --- a/arch/powerpc/kernel/vector.S +++ b/arch/powerpc/kernel/vector.S | |||
@@ -91,6 +91,10 @@ _GLOBAL(load_up_altivec) | |||
91 | oris r12,r12,MSR_VEC@h | 91 | oris r12,r12,MSR_VEC@h |
92 | std r12,_MSR(r1) | 92 | std r12,_MSR(r1) |
93 | #endif | 93 | #endif |
94 | /* Don't care if r4 overflows, this is desired behaviour */ | ||
95 | lbz r4,THREAD_LOAD_VEC(r5) | ||
96 | addi r4,r4,1 | ||
97 | stb r4,THREAD_LOAD_VEC(r5) | ||
94 | addi r6,r5,THREAD_VRSTATE | 98 | addi r6,r5,THREAD_VRSTATE |
95 | li r4,1 | 99 | li r4,1 |
96 | li r10,VRSTATE_VSCR | 100 | li r10,VRSTATE_VSCR |
@@ -102,36 +106,20 @@ _GLOBAL(load_up_altivec) | |||
102 | blr | 106 | blr |
103 | 107 | ||
104 | /* | 108 | /* |
105 | * __giveup_altivec(tsk) | 109 | * save_altivec(tsk) |
106 | * Disable VMX for the task given as the argument, | 110 | * Save the vector registers to its thread_struct |
107 | * and save the vector registers in its thread_struct. | ||
108 | */ | 111 | */ |
109 | _GLOBAL(__giveup_altivec) | 112 | _GLOBAL(save_altivec) |
110 | addi r3,r3,THREAD /* want THREAD of task */ | 113 | addi r3,r3,THREAD /* want THREAD of task */ |
111 | PPC_LL r7,THREAD_VRSAVEAREA(r3) | 114 | PPC_LL r7,THREAD_VRSAVEAREA(r3) |
112 | PPC_LL r5,PT_REGS(r3) | 115 | PPC_LL r5,PT_REGS(r3) |
113 | PPC_LCMPI 0,r7,0 | 116 | PPC_LCMPI 0,r7,0 |
114 | bne 2f | 117 | bne 2f |
115 | addi r7,r3,THREAD_VRSTATE | 118 | addi r7,r3,THREAD_VRSTATE |
116 | 2: PPC_LCMPI 0,r5,0 | 119 | 2: SAVE_32VRS(0,r4,r7) |
117 | SAVE_32VRS(0,r4,r7) | ||
118 | mfvscr v0 | 120 | mfvscr v0 |
119 | li r4,VRSTATE_VSCR | 121 | li r4,VRSTATE_VSCR |
120 | stvx v0,r4,r7 | 122 | stvx v0,r4,r7 |
121 | beq 1f | ||
122 | PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
123 | #ifdef CONFIG_VSX | ||
124 | BEGIN_FTR_SECTION | ||
125 | lis r3,(MSR_VEC|MSR_VSX)@h | ||
126 | FTR_SECTION_ELSE | ||
127 | lis r3,MSR_VEC@h | ||
128 | ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX) | ||
129 | #else | ||
130 | lis r3,MSR_VEC@h | ||
131 | #endif | ||
132 | andc r4,r4,r3 /* disable FP for previous task */ | ||
133 | PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
134 | 1: | ||
135 | blr | 123 | blr |
136 | 124 | ||
137 | #ifdef CONFIG_VSX | 125 | #ifdef CONFIG_VSX |
@@ -163,23 +151,6 @@ _GLOBAL(load_up_vsx) | |||
163 | std r12,_MSR(r1) | 151 | std r12,_MSR(r1) |
164 | b fast_exception_return | 152 | b fast_exception_return |
165 | 153 | ||
166 | /* | ||
167 | * __giveup_vsx(tsk) | ||
168 | * Disable VSX for the task given as the argument. | ||
169 | * Does NOT save vsx registers. | ||
170 | */ | ||
171 | _GLOBAL(__giveup_vsx) | ||
172 | addi r3,r3,THREAD /* want THREAD of task */ | ||
173 | ld r5,PT_REGS(r3) | ||
174 | cmpdi 0,r5,0 | ||
175 | beq 1f | ||
176 | ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
177 | lis r3,MSR_VSX@h | ||
178 | andc r4,r4,r3 /* disable VSX for previous task */ | ||
179 | std r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
180 | 1: | ||
181 | blr | ||
182 | |||
183 | #endif /* CONFIG_VSX */ | 154 | #endif /* CONFIG_VSX */ |
184 | 155 | ||
185 | 156 | ||
diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c index 55c4d51ea3e2..999106991a76 100644 --- a/arch/powerpc/kvm/book3s_32_mmu_host.c +++ b/arch/powerpc/kvm/book3s_32_mmu_host.c | |||
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | #include <asm/kvm_ppc.h> | 23 | #include <asm/kvm_ppc.h> |
24 | #include <asm/kvm_book3s.h> | 24 | #include <asm/kvm_book3s.h> |
25 | #include <asm/mmu-hash32.h> | 25 | #include <asm/book3s/32/mmu-hash.h> |
26 | #include <asm/machdep.h> | 26 | #include <asm/machdep.h> |
27 | #include <asm/mmu_context.h> | 27 | #include <asm/mmu_context.h> |
28 | #include <asm/hw_irq.h> | 28 | #include <asm/hw_irq.h> |
diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c index 9bf7031a67ff..b9131aa1aedf 100644 --- a/arch/powerpc/kvm/book3s_64_mmu.c +++ b/arch/powerpc/kvm/book3s_64_mmu.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <asm/tlbflush.h> | 26 | #include <asm/tlbflush.h> |
27 | #include <asm/kvm_ppc.h> | 27 | #include <asm/kvm_ppc.h> |
28 | #include <asm/kvm_book3s.h> | 28 | #include <asm/kvm_book3s.h> |
29 | #include <asm/mmu-hash64.h> | 29 | #include <asm/book3s/64/mmu-hash.h> |
30 | 30 | ||
31 | /* #define DEBUG_MMU */ | 31 | /* #define DEBUG_MMU */ |
32 | 32 | ||
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index 913cd2198fa6..114edace6cdd 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | #include <asm/kvm_ppc.h> | 24 | #include <asm/kvm_ppc.h> |
25 | #include <asm/kvm_book3s.h> | 25 | #include <asm/kvm_book3s.h> |
26 | #include <asm/mmu-hash64.h> | 26 | #include <asm/book3s/64/mmu-hash.h> |
27 | #include <asm/machdep.h> | 27 | #include <asm/machdep.h> |
28 | #include <asm/mmu_context.h> | 28 | #include <asm/mmu_context.h> |
29 | #include <asm/hw_irq.h> | 29 | #include <asm/hw_irq.h> |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index fb37290a57b4..c7b78d8336b2 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <asm/tlbflush.h> | 32 | #include <asm/tlbflush.h> |
33 | #include <asm/kvm_ppc.h> | 33 | #include <asm/kvm_ppc.h> |
34 | #include <asm/kvm_book3s.h> | 34 | #include <asm/kvm_book3s.h> |
35 | #include <asm/mmu-hash64.h> | 35 | #include <asm/book3s/64/mmu-hash.h> |
36 | #include <asm/hvcall.h> | 36 | #include <asm/hvcall.h> |
37 | #include <asm/synch.h> | 37 | #include <asm/synch.h> |
38 | #include <asm/ppc-opcode.h> | 38 | #include <asm/ppc-opcode.h> |
diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c index 2c2d1030843a..82970042295e 100644 --- a/arch/powerpc/kvm/book3s_64_vio.c +++ b/arch/powerpc/kvm/book3s_64_vio.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <asm/tlbflush.h> | 31 | #include <asm/tlbflush.h> |
32 | #include <asm/kvm_ppc.h> | 32 | #include <asm/kvm_ppc.h> |
33 | #include <asm/kvm_book3s.h> | 33 | #include <asm/kvm_book3s.h> |
34 | #include <asm/mmu-hash64.h> | 34 | #include <asm/book3s/64/mmu-hash.h> |
35 | #include <asm/hvcall.h> | 35 | #include <asm/hvcall.h> |
36 | #include <asm/synch.h> | 36 | #include <asm/synch.h> |
37 | #include <asm/ppc-opcode.h> | 37 | #include <asm/ppc-opcode.h> |
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c index 44be73e6aa26..f88b859af53b 100644 --- a/arch/powerpc/kvm/book3s_64_vio_hv.c +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <asm/tlbflush.h> | 30 | #include <asm/tlbflush.h> |
31 | #include <asm/kvm_ppc.h> | 31 | #include <asm/kvm_ppc.h> |
32 | #include <asm/kvm_book3s.h> | 32 | #include <asm/kvm_book3s.h> |
33 | #include <asm/mmu-hash64.h> | 33 | #include <asm/book3s/64/mmu-hash.h> |
34 | #include <asm/mmu_context.h> | 34 | #include <asm/mmu_context.h> |
35 | #include <asm/hvcall.h> | 35 | #include <asm/hvcall.h> |
36 | #include <asm/synch.h> | 36 | #include <asm/synch.h> |
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index 91700518bbf3..4cb8db05f3e5 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <asm/tlbflush.h> | 17 | #include <asm/tlbflush.h> |
18 | #include <asm/kvm_ppc.h> | 18 | #include <asm/kvm_ppc.h> |
19 | #include <asm/kvm_book3s.h> | 19 | #include <asm/kvm_book3s.h> |
20 | #include <asm/mmu-hash64.h> | 20 | #include <asm/book3s/64/mmu-hash.h> |
21 | #include <asm/hvcall.h> | 21 | #include <asm/hvcall.h> |
22 | #include <asm/synch.h> | 22 | #include <asm/synch.h> |
23 | #include <asm/ppc-opcode.h> | 23 | #include <asm/ppc-opcode.h> |
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 85b32f16fa74..62ea3c6acdee 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <asm/asm-offsets.h> | 27 | #include <asm/asm-offsets.h> |
28 | #include <asm/exception-64s.h> | 28 | #include <asm/exception-64s.h> |
29 | #include <asm/kvm_book3s_asm.h> | 29 | #include <asm/kvm_book3s_asm.h> |
30 | #include <asm/mmu-hash64.h> | 30 | #include <asm/book3s/64/mmu-hash.h> |
31 | #include <asm/tm.h> | 31 | #include <asm/tm.h> |
32 | 32 | ||
33 | #define VCPU_GPRS_TM(reg) (((reg) * ULONG_SIZE) + VCPU_GPR_TM) | 33 | #define VCPU_GPRS_TM(reg) (((reg) * ULONG_SIZE) + VCPU_GPR_TM) |
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c index 905e94a1370f..46871d554057 100644 --- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c | |||
@@ -432,7 +432,7 @@ static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp, | |||
432 | * the whole masked_pending business which is about not | 432 | * the whole masked_pending business which is about not |
433 | * losing interrupts that occur while masked. | 433 | * losing interrupts that occur while masked. |
434 | * | 434 | * |
435 | * I don't differenciate normal deliveries and resends, this | 435 | * I don't differentiate normal deliveries and resends, this |
436 | * implementation will differ from PAPR and not lose such | 436 | * implementation will differ from PAPR and not lose such |
437 | * interrupts. | 437 | * interrupts. |
438 | */ | 438 | */ |
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 778ef86e187e..4d66f44a1657 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c | |||
@@ -992,7 +992,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
992 | kvmppc_restart_interrupt(vcpu, exit_nr); | 992 | kvmppc_restart_interrupt(vcpu, exit_nr); |
993 | 993 | ||
994 | /* | 994 | /* |
995 | * get last instruction before beeing preempted | 995 | * get last instruction before being preempted |
996 | * TODO: for e6500 check also BOOKE_INTERRUPT_LRAT_ERROR & ESR_DATA | 996 | * TODO: for e6500 check also BOOKE_INTERRUPT_LRAT_ERROR & ESR_DATA |
997 | */ | 997 | */ |
998 | switch (exit_nr) { | 998 | switch (exit_nr) { |
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index cda695de8aa7..f48a0c22e8f9 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c | |||
@@ -182,7 +182,7 @@ int kvmppc_core_check_processor_compat(void) | |||
182 | r = 0; | 182 | r = 0; |
183 | #ifdef CONFIG_ALTIVEC | 183 | #ifdef CONFIG_ALTIVEC |
184 | /* | 184 | /* |
185 | * Since guests have the priviledge to enable AltiVec, we need AltiVec | 185 | * Since guests have the privilege to enable AltiVec, we need AltiVec |
186 | * support in the host to save/restore their context. | 186 | * support in the host to save/restore their context. |
187 | * Don't use CPU_FTR_ALTIVEC to identify cores with AltiVec unit | 187 | * Don't use CPU_FTR_ALTIVEC to identify cores with AltiVec unit |
188 | * because it's cleared in the absence of CONFIG_ALTIVEC! | 188 | * because it's cleared in the absence of CONFIG_ALTIVEC! |
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index a47e14277fd8..ba21be15310f 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile | |||
@@ -6,8 +6,8 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror | |||
6 | 6 | ||
7 | ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) | 7 | ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) |
8 | 8 | ||
9 | CFLAGS_REMOVE_code-patching.o = -pg | 9 | CFLAGS_REMOVE_code-patching.o = $(CC_FLAGS_FTRACE) |
10 | CFLAGS_REMOVE_feature-fixups.o = -pg | 10 | CFLAGS_REMOVE_feature-fixups.o = $(CC_FLAGS_FTRACE) |
11 | 11 | ||
12 | obj-y += string.o alloc.o crtsavres.o ppc_ksyms.o code-patching.o \ | 12 | obj-y += string.o alloc.o crtsavres.o ppc_ksyms.o code-patching.o \ |
13 | feature-fixups.o | 13 | feature-fixups.o |
@@ -22,8 +22,7 @@ obj64-$(CONFIG_SMP) += locks.o | |||
22 | obj64-$(CONFIG_ALTIVEC) += vmx-helper.o | 22 | obj64-$(CONFIG_ALTIVEC) += vmx-helper.o |
23 | 23 | ||
24 | ifeq ($(CONFIG_GENERIC_CSUM),) | 24 | ifeq ($(CONFIG_GENERIC_CSUM),) |
25 | obj-y += checksum_$(CONFIG_WORD_SIZE).o | 25 | obj-y += checksum_$(CONFIG_WORD_SIZE).o checksum_wrappers.o |
26 | obj-$(CONFIG_PPC64) += checksum_wrappers_64.o | ||
27 | endif | 26 | endif |
28 | 27 | ||
29 | obj-$(CONFIG_PPC_EMULATE_SSTEP) += sstep.o ldstfp.o | 28 | obj-$(CONFIG_PPC_EMULATE_SSTEP) += sstep.o ldstfp.o |
diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S index 6d67e057f15e..d90870a66b60 100644 --- a/arch/powerpc/lib/checksum_32.S +++ b/arch/powerpc/lib/checksum_32.S | |||
@@ -14,68 +14,59 @@ | |||
14 | 14 | ||
15 | #include <linux/sys.h> | 15 | #include <linux/sys.h> |
16 | #include <asm/processor.h> | 16 | #include <asm/processor.h> |
17 | #include <asm/cache.h> | ||
17 | #include <asm/errno.h> | 18 | #include <asm/errno.h> |
18 | #include <asm/ppc_asm.h> | 19 | #include <asm/ppc_asm.h> |
19 | 20 | ||
20 | .text | 21 | .text |
21 | 22 | ||
22 | /* | 23 | /* |
23 | * ip_fast_csum(buf, len) -- Optimized for IP header | ||
24 | * len is in words and is always >= 5. | ||
25 | */ | ||
26 | _GLOBAL(ip_fast_csum) | ||
27 | lwz r0,0(r3) | ||
28 | lwzu r5,4(r3) | ||
29 | addic. r4,r4,-2 | ||
30 | addc r0,r0,r5 | ||
31 | mtctr r4 | ||
32 | blelr- | ||
33 | 1: lwzu r4,4(r3) | ||
34 | adde r0,r0,r4 | ||
35 | bdnz 1b | ||
36 | addze r0,r0 /* add in final carry */ | ||
37 | rlwinm r3,r0,16,0,31 /* fold two halves together */ | ||
38 | add r3,r0,r3 | ||
39 | not r3,r3 | ||
40 | srwi r3,r3,16 | ||
41 | blr | ||
42 | |||
43 | /* | ||
44 | * computes the checksum of a memory block at buff, length len, | 24 | * computes the checksum of a memory block at buff, length len, |
45 | * and adds in "sum" (32-bit) | 25 | * and adds in "sum" (32-bit) |
46 | * | 26 | * |
47 | * csum_partial(buff, len, sum) | 27 | * __csum_partial(buff, len, sum) |
48 | */ | 28 | */ |
49 | _GLOBAL(csum_partial) | 29 | _GLOBAL(__csum_partial) |
50 | addic r0,r5,0 | ||
51 | subi r3,r3,4 | 30 | subi r3,r3,4 |
52 | srwi. r6,r4,2 | 31 | srawi. r6,r4,2 /* Divide len by 4 and also clear carry */ |
53 | beq 3f /* if we're doing < 4 bytes */ | 32 | beq 3f /* if we're doing < 4 bytes */ |
54 | andi. r5,r3,2 /* Align buffer to longword boundary */ | 33 | andi. r0,r3,2 /* Align buffer to longword boundary */ |
55 | beq+ 1f | 34 | beq+ 1f |
56 | lhz r5,4(r3) /* do 2 bytes to get aligned */ | 35 | lhz r0,4(r3) /* do 2 bytes to get aligned */ |
57 | addi r3,r3,2 | ||
58 | subi r4,r4,2 | 36 | subi r4,r4,2 |
59 | addc r0,r0,r5 | 37 | addi r3,r3,2 |
60 | srwi. r6,r4,2 /* # words to do */ | 38 | srwi. r6,r4,2 /* # words to do */ |
39 | adde r5,r5,r0 | ||
61 | beq 3f | 40 | beq 3f |
62 | 1: mtctr r6 | 41 | 1: andi. r6,r6,3 /* Prepare to handle words 4 by 4 */ |
63 | 2: lwzu r5,4(r3) /* the bdnz has zero overhead, so it should */ | 42 | beq 21f |
64 | adde r0,r0,r5 /* be unnecessary to unroll this loop */ | 43 | mtctr r6 |
44 | 2: lwzu r0,4(r3) | ||
45 | adde r5,r5,r0 | ||
65 | bdnz 2b | 46 | bdnz 2b |
66 | andi. r4,r4,3 | 47 | 21: srwi. r6,r4,4 /* # blocks of 4 words to do */ |
67 | 3: cmpwi 0,r4,2 | 48 | beq 3f |
68 | blt+ 4f | 49 | mtctr r6 |
69 | lhz r5,4(r3) | 50 | 22: lwz r0,4(r3) |
51 | lwz r6,8(r3) | ||
52 | lwz r7,12(r3) | ||
53 | lwzu r8,16(r3) | ||
54 | adde r5,r5,r0 | ||
55 | adde r5,r5,r6 | ||
56 | adde r5,r5,r7 | ||
57 | adde r5,r5,r8 | ||
58 | bdnz 22b | ||
59 | 3: andi. r0,r4,2 | ||
60 | beq+ 4f | ||
61 | lhz r0,4(r3) | ||
70 | addi r3,r3,2 | 62 | addi r3,r3,2 |
71 | subi r4,r4,2 | 63 | adde r5,r5,r0 |
72 | adde r0,r0,r5 | 64 | 4: andi. r0,r4,1 |
73 | 4: cmpwi 0,r4,1 | 65 | beq+ 5f |
74 | bne+ 5f | 66 | lbz r0,4(r3) |
75 | lbz r5,4(r3) | 67 | slwi r0,r0,8 /* Upper byte of word */ |
76 | slwi r5,r5,8 /* Upper byte of word */ | 68 | adde r5,r5,r0 |
77 | adde r0,r0,r5 | 69 | 5: addze r3,r5 /* add in final carry */ |
78 | 5: addze r3,r0 /* add in final carry */ | ||
79 | blr | 70 | blr |
80 | 71 | ||
81 | /* | 72 | /* |
@@ -87,123 +78,220 @@ _GLOBAL(csum_partial) | |||
87 | * | 78 | * |
88 | * csum_partial_copy_generic(src, dst, len, sum, src_err, dst_err) | 79 | * csum_partial_copy_generic(src, dst, len, sum, src_err, dst_err) |
89 | */ | 80 | */ |
81 | #define CSUM_COPY_16_BYTES_WITHEX(n) \ | ||
82 | 8 ## n ## 0: \ | ||
83 | lwz r7,4(r4); \ | ||
84 | 8 ## n ## 1: \ | ||
85 | lwz r8,8(r4); \ | ||
86 | 8 ## n ## 2: \ | ||
87 | lwz r9,12(r4); \ | ||
88 | 8 ## n ## 3: \ | ||
89 | lwzu r10,16(r4); \ | ||
90 | 8 ## n ## 4: \ | ||
91 | stw r7,4(r6); \ | ||
92 | adde r12,r12,r7; \ | ||
93 | 8 ## n ## 5: \ | ||
94 | stw r8,8(r6); \ | ||
95 | adde r12,r12,r8; \ | ||
96 | 8 ## n ## 6: \ | ||
97 | stw r9,12(r6); \ | ||
98 | adde r12,r12,r9; \ | ||
99 | 8 ## n ## 7: \ | ||
100 | stwu r10,16(r6); \ | ||
101 | adde r12,r12,r10 | ||
102 | |||
103 | #define CSUM_COPY_16_BYTES_EXCODE(n) \ | ||
104 | .section __ex_table,"a"; \ | ||
105 | .align 2; \ | ||
106 | .long 8 ## n ## 0b,src_error; \ | ||
107 | .long 8 ## n ## 1b,src_error; \ | ||
108 | .long 8 ## n ## 2b,src_error; \ | ||
109 | .long 8 ## n ## 3b,src_error; \ | ||
110 | .long 8 ## n ## 4b,dst_error; \ | ||
111 | .long 8 ## n ## 5b,dst_error; \ | ||
112 | .long 8 ## n ## 6b,dst_error; \ | ||
113 | .long 8 ## n ## 7b,dst_error; \ | ||
114 | .text | ||
115 | |||
116 | .text | ||
117 | .stabs "arch/powerpc/lib/",N_SO,0,0,0f | ||
118 | .stabs "checksum_32.S",N_SO,0,0,0f | ||
119 | 0: | ||
120 | |||
121 | CACHELINE_BYTES = L1_CACHE_BYTES | ||
122 | LG_CACHELINE_BYTES = L1_CACHE_SHIFT | ||
123 | CACHELINE_MASK = (L1_CACHE_BYTES-1) | ||
124 | |||
90 | _GLOBAL(csum_partial_copy_generic) | 125 | _GLOBAL(csum_partial_copy_generic) |
91 | addic r0,r6,0 | 126 | stwu r1,-16(r1) |
92 | subi r3,r3,4 | 127 | stw r7,12(r1) |
93 | subi r4,r4,4 | 128 | stw r8,8(r1) |
94 | srwi. r6,r5,2 | 129 | |
95 | beq 3f /* if we're doing < 4 bytes */ | 130 | andi. r0,r4,1 /* is destination address even ? */ |
96 | andi. r9,r4,2 /* Align dst to longword boundary */ | 131 | cmplwi cr7,r0,0 |
97 | beq+ 1f | 132 | addic r12,r6,0 |
98 | 81: lhz r6,4(r3) /* do 2 bytes to get aligned */ | 133 | addi r6,r4,-4 |
99 | addi r3,r3,2 | 134 | neg r0,r4 |
100 | subi r5,r5,2 | 135 | addi r4,r3,-4 |
101 | 91: sth r6,4(r4) | 136 | andi. r0,r0,CACHELINE_MASK /* # bytes to start of cache line */ |
102 | addi r4,r4,2 | 137 | beq 58f |
103 | addc r0,r0,r6 | 138 | |
104 | srwi. r6,r5,2 /* # words to do */ | 139 | cmplw 0,r5,r0 /* is this more than total to do? */ |
105 | beq 3f | 140 | blt 63f /* if not much to do */ |
106 | 1: srwi. r6,r5,4 /* # groups of 4 words to do */ | 141 | andi. r8,r0,3 /* get it word-aligned first */ |
107 | beq 10f | 142 | mtctr r8 |
108 | mtctr r6 | 143 | beq+ 61f |
109 | 71: lwz r6,4(r3) | 144 | li r3,0 |
110 | 72: lwz r9,8(r3) | 145 | 70: lbz r9,4(r4) /* do some bytes */ |
111 | 73: lwz r10,12(r3) | 146 | addi r4,r4,1 |
112 | 74: lwzu r11,16(r3) | 147 | slwi r3,r3,8 |
113 | adde r0,r0,r6 | 148 | rlwimi r3,r9,0,24,31 |
114 | 75: stw r6,4(r4) | 149 | 71: stb r9,4(r6) |
115 | adde r0,r0,r9 | 150 | addi r6,r6,1 |
116 | 76: stw r9,8(r4) | 151 | bdnz 70b |
117 | adde r0,r0,r10 | 152 | adde r12,r12,r3 |
118 | 77: stw r10,12(r4) | 153 | 61: subf r5,r0,r5 |
119 | adde r0,r0,r11 | 154 | srwi. r0,r0,2 |
120 | 78: stwu r11,16(r4) | 155 | mtctr r0 |
121 | bdnz 71b | 156 | beq 58f |
122 | 10: rlwinm. r6,r5,30,30,31 /* # words left to do */ | 157 | 72: lwzu r9,4(r4) /* do some words */ |
123 | beq 13f | 158 | adde r12,r12,r9 |
124 | mtctr r6 | 159 | 73: stwu r9,4(r6) |
125 | 82: lwzu r9,4(r3) | 160 | bdnz 72b |
126 | 92: stwu r9,4(r4) | 161 | |
127 | adde r0,r0,r9 | 162 | 58: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */ |
128 | bdnz 82b | 163 | clrlwi r5,r5,32-LG_CACHELINE_BYTES |
129 | 13: andi. r5,r5,3 | 164 | li r11,4 |
130 | 3: cmpwi 0,r5,2 | 165 | beq 63f |
131 | blt+ 4f | 166 | |
132 | 83: lhz r6,4(r3) | 167 | /* Here we decide how far ahead to prefetch the source */ |
133 | addi r3,r3,2 | 168 | li r3,4 |
134 | subi r5,r5,2 | 169 | cmpwi r0,1 |
135 | 93: sth r6,4(r4) | 170 | li r7,0 |
171 | ble 114f | ||
172 | li r7,1 | ||
173 | #if MAX_COPY_PREFETCH > 1 | ||
174 | /* Heuristically, for large transfers we prefetch | ||
175 | MAX_COPY_PREFETCH cachelines ahead. For small transfers | ||
176 | we prefetch 1 cacheline ahead. */ | ||
177 | cmpwi r0,MAX_COPY_PREFETCH | ||
178 | ble 112f | ||
179 | li r7,MAX_COPY_PREFETCH | ||
180 | 112: mtctr r7 | ||
181 | 111: dcbt r3,r4 | ||
182 | addi r3,r3,CACHELINE_BYTES | ||
183 | bdnz 111b | ||
184 | #else | ||
185 | dcbt r3,r4 | ||
186 | addi r3,r3,CACHELINE_BYTES | ||
187 | #endif /* MAX_COPY_PREFETCH > 1 */ | ||
188 | |||
189 | 114: subf r8,r7,r0 | ||
190 | mr r0,r7 | ||
191 | mtctr r8 | ||
192 | |||
193 | 53: dcbt r3,r4 | ||
194 | 54: dcbz r11,r6 | ||
195 | /* the main body of the cacheline loop */ | ||
196 | CSUM_COPY_16_BYTES_WITHEX(0) | ||
197 | #if L1_CACHE_BYTES >= 32 | ||
198 | CSUM_COPY_16_BYTES_WITHEX(1) | ||
199 | #if L1_CACHE_BYTES >= 64 | ||
200 | CSUM_COPY_16_BYTES_WITHEX(2) | ||
201 | CSUM_COPY_16_BYTES_WITHEX(3) | ||
202 | #if L1_CACHE_BYTES >= 128 | ||
203 | CSUM_COPY_16_BYTES_WITHEX(4) | ||
204 | CSUM_COPY_16_BYTES_WITHEX(5) | ||
205 | CSUM_COPY_16_BYTES_WITHEX(6) | ||
206 | CSUM_COPY_16_BYTES_WITHEX(7) | ||
207 | #endif | ||
208 | #endif | ||
209 | #endif | ||
210 | bdnz 53b | ||
211 | cmpwi r0,0 | ||
212 | li r3,4 | ||
213 | li r7,0 | ||
214 | bne 114b | ||
215 | |||
216 | 63: srwi. r0,r5,2 | ||
217 | mtctr r0 | ||
218 | beq 64f | ||
219 | 30: lwzu r0,4(r4) | ||
220 | adde r12,r12,r0 | ||
221 | 31: stwu r0,4(r6) | ||
222 | bdnz 30b | ||
223 | |||
224 | 64: andi. r0,r5,2 | ||
225 | beq+ 65f | ||
226 | 40: lhz r0,4(r4) | ||
136 | addi r4,r4,2 | 227 | addi r4,r4,2 |
137 | adde r0,r0,r6 | 228 | 41: sth r0,4(r6) |
138 | 4: cmpwi 0,r5,1 | 229 | adde r12,r12,r0 |
139 | bne+ 5f | 230 | addi r6,r6,2 |
140 | 84: lbz r6,4(r3) | 231 | 65: andi. r0,r5,1 |
141 | 94: stb r6,4(r4) | 232 | beq+ 66f |
142 | slwi r6,r6,8 /* Upper byte of word */ | 233 | 50: lbz r0,4(r4) |
143 | adde r0,r0,r6 | 234 | 51: stb r0,4(r6) |
144 | 5: addze r3,r0 /* add in final carry */ | 235 | slwi r0,r0,8 |
236 | adde r12,r12,r0 | ||
237 | 66: addze r3,r12 | ||
238 | addi r1,r1,16 | ||
239 | beqlr+ cr7 | ||
240 | rlwinm r3,r3,8,0,31 /* swap bytes for odd destination */ | ||
145 | blr | 241 | blr |
146 | 242 | ||
147 | /* These shouldn't go in the fixup section, since that would | 243 | /* read fault */ |
148 | cause the ex_table addresses to get out of order. */ | ||
149 | |||
150 | src_error_4: | ||
151 | mfctr r6 /* update # bytes remaining from ctr */ | ||
152 | rlwimi r5,r6,4,0,27 | ||
153 | b 79f | ||
154 | src_error_1: | ||
155 | li r6,0 | ||
156 | subi r5,r5,2 | ||
157 | 95: sth r6,4(r4) | ||
158 | addi r4,r4,2 | ||
159 | 79: srwi. r6,r5,2 | ||
160 | beq 3f | ||
161 | mtctr r6 | ||
162 | src_error_2: | ||
163 | li r6,0 | ||
164 | 96: stwu r6,4(r4) | ||
165 | bdnz 96b | ||
166 | 3: andi. r5,r5,3 | ||
167 | beq src_error | ||
168 | src_error_3: | ||
169 | li r6,0 | ||
170 | mtctr r5 | ||
171 | addi r4,r4,3 | ||
172 | 97: stbu r6,1(r4) | ||
173 | bdnz 97b | ||
174 | src_error: | 244 | src_error: |
175 | cmpwi 0,r7,0 | 245 | lwz r7,12(r1) |
176 | beq 1f | 246 | addi r1,r1,16 |
177 | li r6,-EFAULT | 247 | cmpwi cr0,r7,0 |
178 | stw r6,0(r7) | 248 | beqlr |
179 | 1: addze r3,r0 | 249 | li r0,-EFAULT |
250 | stw r0,0(r7) | ||
180 | blr | 251 | blr |
181 | 252 | /* write fault */ | |
182 | dst_error: | 253 | dst_error: |
183 | cmpwi 0,r8,0 | 254 | lwz r8,8(r1) |
184 | beq 1f | 255 | addi r1,r1,16 |
185 | li r6,-EFAULT | 256 | cmpwi cr0,r8,0 |
186 | stw r6,0(r8) | 257 | beqlr |
187 | 1: addze r3,r0 | 258 | li r0,-EFAULT |
259 | stw r0,0(r8) | ||
188 | blr | 260 | blr |
189 | 261 | ||
190 | .section __ex_table,"a" | 262 | .section __ex_table,"a" |
191 | .long 81b,src_error_1 | 263 | .align 2 |
192 | .long 91b,dst_error | 264 | .long 70b,src_error |
193 | .long 71b,src_error_4 | 265 | .long 71b,dst_error |
194 | .long 72b,src_error_4 | 266 | .long 72b,src_error |
195 | .long 73b,src_error_4 | 267 | .long 73b,dst_error |
196 | .long 74b,src_error_4 | 268 | .long 54b,dst_error |
197 | .long 75b,dst_error | 269 | .text |
198 | .long 76b,dst_error | 270 | |
199 | .long 77b,dst_error | 271 | /* |
200 | .long 78b,dst_error | 272 | * this stuff handles faults in the cacheline loop and branches to either |
201 | .long 82b,src_error_2 | 273 | * src_error (if in read part) or dst_error (if in write part) |
202 | .long 92b,dst_error | 274 | */ |
203 | .long 83b,src_error_3 | 275 | CSUM_COPY_16_BYTES_EXCODE(0) |
204 | .long 93b,dst_error | 276 | #if L1_CACHE_BYTES >= 32 |
205 | .long 84b,src_error_3 | 277 | CSUM_COPY_16_BYTES_EXCODE(1) |
206 | .long 94b,dst_error | 278 | #if L1_CACHE_BYTES >= 64 |
207 | .long 95b,dst_error | 279 | CSUM_COPY_16_BYTES_EXCODE(2) |
208 | .long 96b,dst_error | 280 | CSUM_COPY_16_BYTES_EXCODE(3) |
209 | .long 97b,dst_error | 281 | #if L1_CACHE_BYTES >= 128 |
282 | CSUM_COPY_16_BYTES_EXCODE(4) | ||
283 | CSUM_COPY_16_BYTES_EXCODE(5) | ||
284 | CSUM_COPY_16_BYTES_EXCODE(6) | ||
285 | CSUM_COPY_16_BYTES_EXCODE(7) | ||
286 | #endif | ||
287 | #endif | ||
288 | #endif | ||
289 | |||
290 | .section __ex_table,"a" | ||
291 | .align 2 | ||
292 | .long 30b,src_error | ||
293 | .long 31b,dst_error | ||
294 | .long 40b,src_error | ||
295 | .long 41b,dst_error | ||
296 | .long 50b,src_error | ||
297 | .long 51b,dst_error | ||
diff --git a/arch/powerpc/lib/checksum_64.S b/arch/powerpc/lib/checksum_64.S index f3ef35436612..8e6e51016cc5 100644 --- a/arch/powerpc/lib/checksum_64.S +++ b/arch/powerpc/lib/checksum_64.S | |||
@@ -18,39 +18,12 @@ | |||
18 | #include <asm/ppc_asm.h> | 18 | #include <asm/ppc_asm.h> |
19 | 19 | ||
20 | /* | 20 | /* |
21 | * ip_fast_csum(r3=buf, r4=len) -- Optimized for IP header | ||
22 | * len is in words and is always >= 5. | ||
23 | * | ||
24 | * In practice len == 5, but this is not guaranteed. So this code does not | ||
25 | * attempt to use doubleword instructions. | ||
26 | */ | ||
27 | _GLOBAL(ip_fast_csum) | ||
28 | lwz r0,0(r3) | ||
29 | lwzu r5,4(r3) | ||
30 | addic. r4,r4,-2 | ||
31 | addc r0,r0,r5 | ||
32 | mtctr r4 | ||
33 | blelr- | ||
34 | 1: lwzu r4,4(r3) | ||
35 | adde r0,r0,r4 | ||
36 | bdnz 1b | ||
37 | addze r0,r0 /* add in final carry */ | ||
38 | rldicl r4,r0,32,0 /* fold two 32-bit halves together */ | ||
39 | add r0,r0,r4 | ||
40 | srdi r0,r0,32 | ||
41 | rlwinm r3,r0,16,0,31 /* fold two halves together */ | ||
42 | add r3,r0,r3 | ||
43 | not r3,r3 | ||
44 | srwi r3,r3,16 | ||
45 | blr | ||
46 | |||
47 | /* | ||
48 | * Computes the checksum of a memory block at buff, length len, | 21 | * Computes the checksum of a memory block at buff, length len, |
49 | * and adds in "sum" (32-bit). | 22 | * and adds in "sum" (32-bit). |
50 | * | 23 | * |
51 | * csum_partial(r3=buff, r4=len, r5=sum) | 24 | * __csum_partial(r3=buff, r4=len, r5=sum) |
52 | */ | 25 | */ |
53 | _GLOBAL(csum_partial) | 26 | _GLOBAL(__csum_partial) |
54 | addic r0,r5,0 /* clear carry */ | 27 | addic r0,r5,0 /* clear carry */ |
55 | 28 | ||
56 | srdi. r6,r4,3 /* less than 8 bytes? */ | 29 | srdi. r6,r4,3 /* less than 8 bytes? */ |
diff --git a/arch/powerpc/lib/checksum_wrappers_64.c b/arch/powerpc/lib/checksum_wrappers.c index 08e3a3356c40..08e3a3356c40 100644 --- a/arch/powerpc/lib/checksum_wrappers_64.c +++ b/arch/powerpc/lib/checksum_wrappers.c | |||
diff --git a/arch/powerpc/lib/ppc_ksyms.c b/arch/powerpc/lib/ppc_ksyms.c index c7f8e9586316..c422812f7405 100644 --- a/arch/powerpc/lib/ppc_ksyms.c +++ b/arch/powerpc/lib/ppc_ksyms.c | |||
@@ -17,10 +17,8 @@ EXPORT_SYMBOL(strcmp); | |||
17 | EXPORT_SYMBOL(strncmp); | 17 | EXPORT_SYMBOL(strncmp); |
18 | 18 | ||
19 | #ifndef CONFIG_GENERIC_CSUM | 19 | #ifndef CONFIG_GENERIC_CSUM |
20 | EXPORT_SYMBOL(csum_partial); | 20 | EXPORT_SYMBOL(__csum_partial); |
21 | EXPORT_SYMBOL(csum_partial_copy_generic); | 21 | EXPORT_SYMBOL(csum_partial_copy_generic); |
22 | EXPORT_SYMBOL(ip_fast_csum); | ||
23 | EXPORT_SYMBOL(csum_tcpudp_magic); | ||
24 | #endif | 22 | #endif |
25 | 23 | ||
26 | EXPORT_SYMBOL(__copy_tofrom_user); | 24 | EXPORT_SYMBOL(__copy_tofrom_user); |
diff --git a/arch/powerpc/mm/8xx_mmu.c b/arch/powerpc/mm/8xx_mmu.c new file mode 100644 index 000000000000..949100577db5 --- /dev/null +++ b/arch/powerpc/mm/8xx_mmu.c | |||
@@ -0,0 +1,141 @@ | |||
1 | /* | ||
2 | * This file contains the routines for initializing the MMU | ||
3 | * on the 8xx series of chips. | ||
4 | * -- christophe | ||
5 | * | ||
6 | * Derived from arch/powerpc/mm/40x_mmu.c: | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the License, or (at your option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/memblock.h> | ||
16 | |||
17 | #include "mmu_decl.h" | ||
18 | |||
19 | extern int __map_without_ltlbs; | ||
20 | /* | ||
21 | * MMU_init_hw does the chip-specific initialization of the MMU hardware. | ||
22 | */ | ||
23 | void __init MMU_init_hw(void) | ||
24 | { | ||
25 | /* Nothing to do for the time being but keep it similar to other PPC */ | ||
26 | } | ||
27 | |||
28 | #define LARGE_PAGE_SIZE_4M (1<<22) | ||
29 | #define LARGE_PAGE_SIZE_8M (1<<23) | ||
30 | #define LARGE_PAGE_SIZE_64M (1<<26) | ||
31 | |||
32 | unsigned long __init mmu_mapin_ram(unsigned long top) | ||
33 | { | ||
34 | unsigned long v, s, mapped; | ||
35 | phys_addr_t p; | ||
36 | |||
37 | v = KERNELBASE; | ||
38 | p = 0; | ||
39 | s = top; | ||
40 | |||
41 | if (__map_without_ltlbs) | ||
42 | return 0; | ||
43 | |||
44 | #ifdef CONFIG_PPC_4K_PAGES | ||
45 | while (s >= LARGE_PAGE_SIZE_8M) { | ||
46 | pmd_t *pmdp; | ||
47 | unsigned long val = p | MD_PS8MEG; | ||
48 | |||
49 | pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v); | ||
50 | *pmdp++ = __pmd(val); | ||
51 | *pmdp++ = __pmd(val + LARGE_PAGE_SIZE_4M); | ||
52 | |||
53 | v += LARGE_PAGE_SIZE_8M; | ||
54 | p += LARGE_PAGE_SIZE_8M; | ||
55 | s -= LARGE_PAGE_SIZE_8M; | ||
56 | } | ||
57 | #else /* CONFIG_PPC_16K_PAGES */ | ||
58 | while (s >= LARGE_PAGE_SIZE_64M) { | ||
59 | pmd_t *pmdp; | ||
60 | unsigned long val = p | MD_PS8MEG; | ||
61 | |||
62 | pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v); | ||
63 | *pmdp++ = __pmd(val); | ||
64 | |||
65 | v += LARGE_PAGE_SIZE_64M; | ||
66 | p += LARGE_PAGE_SIZE_64M; | ||
67 | s -= LARGE_PAGE_SIZE_64M; | ||
68 | } | ||
69 | #endif | ||
70 | |||
71 | mapped = top - s; | ||
72 | |||
73 | /* If the size of RAM is not an exact power of two, we may not | ||
74 | * have covered RAM in its entirety with 8 MiB | ||
75 | * pages. Consequently, restrict the top end of RAM currently | ||
76 | * allocable so that calls to the MEMBLOCK to allocate PTEs for "tail" | ||
77 | * coverage with normal-sized pages (or other reasons) do not | ||
78 | * attempt to allocate outside the allowed range. | ||
79 | */ | ||
80 | memblock_set_current_limit(mapped); | ||
81 | |||
82 | return mapped; | ||
83 | } | ||
84 | |||
85 | void setup_initial_memory_limit(phys_addr_t first_memblock_base, | ||
86 | phys_addr_t first_memblock_size) | ||
87 | { | ||
88 | /* We don't currently support the first MEMBLOCK not mapping 0 | ||
89 | * physical on those processors | ||
90 | */ | ||
91 | BUG_ON(first_memblock_base != 0); | ||
92 | |||
93 | #ifdef CONFIG_PIN_TLB | ||
94 | /* 8xx can only access 24MB at the moment */ | ||
95 | memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01800000)); | ||
96 | #else | ||
97 | /* 8xx can only access 8MB at the moment */ | ||
98 | memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000)); | ||
99 | #endif | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * Set up to use a given MMU context. | ||
104 | * id is context number, pgd is PGD pointer. | ||
105 | * | ||
106 | * We place the physical address of the new task page directory loaded | ||
107 | * into the MMU base register, and set the ASID compare register with | ||
108 | * the new "context." | ||
109 | */ | ||
110 | void set_context(unsigned long id, pgd_t *pgd) | ||
111 | { | ||
112 | s16 offset = (s16)(__pa(swapper_pg_dir)); | ||
113 | |||
114 | #ifdef CONFIG_BDI_SWITCH | ||
115 | pgd_t **ptr = *(pgd_t ***)(KERNELBASE + 0xf0); | ||
116 | |||
117 | /* Context switch the PTE pointer for the Abatron BDI2000. | ||
118 | * The PGDIR is passed as second argument. | ||
119 | */ | ||
120 | *(ptr + 1) = pgd; | ||
121 | #endif | ||
122 | |||
123 | /* Register M_TW will contain base address of level 1 table minus the | ||
124 | * lower part of the kernel PGDIR base address, so that all accesses to | ||
125 | * level 1 table are done relative to lower part of kernel PGDIR base | ||
126 | * address. | ||
127 | */ | ||
128 | mtspr(SPRN_M_TW, __pa(pgd) - offset); | ||
129 | |||
130 | /* Update context */ | ||
131 | mtspr(SPRN_M_CASID, id); | ||
132 | /* sync */ | ||
133 | mb(); | ||
134 | } | ||
135 | |||
136 | void flush_instruction_cache(void) | ||
137 | { | ||
138 | isync(); | ||
139 | mtspr(SPRN_IC_CST, IDC_INVALL); | ||
140 | isync(); | ||
141 | } | ||
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index 1ffeda85c086..adfee3f1aeb9 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile | |||
@@ -25,6 +25,7 @@ obj-$(CONFIG_PPC_ICSWX) += icswx.o | |||
25 | obj-$(CONFIG_PPC_ICSWX_PID) += icswx_pid.o | 25 | obj-$(CONFIG_PPC_ICSWX_PID) += icswx_pid.o |
26 | obj-$(CONFIG_40x) += 40x_mmu.o | 26 | obj-$(CONFIG_40x) += 40x_mmu.o |
27 | obj-$(CONFIG_44x) += 44x_mmu.o | 27 | obj-$(CONFIG_44x) += 44x_mmu.o |
28 | obj-$(CONFIG_PPC_8xx) += 8xx_mmu.o | ||
28 | obj-$(CONFIG_PPC_FSL_BOOK3E) += fsl_booke_mmu.o | 29 | obj-$(CONFIG_PPC_FSL_BOOK3E) += fsl_booke_mmu.o |
29 | obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o | 30 | obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o |
30 | obj-$(CONFIG_PPC_SPLPAR) += vphn.o | 31 | obj-$(CONFIG_PPC_SPLPAR) += vphn.o |
diff --git a/arch/powerpc/mm/dma-noncoherent.c b/arch/powerpc/mm/dma-noncoherent.c index 169aba446a74..2dc74e5c6458 100644 --- a/arch/powerpc/mm/dma-noncoherent.c +++ b/arch/powerpc/mm/dma-noncoherent.c | |||
@@ -327,7 +327,7 @@ void __dma_sync(void *vaddr, size_t size, int direction) | |||
327 | * invalidate only when cache-line aligned otherwise there is | 327 | * invalidate only when cache-line aligned otherwise there is |
328 | * the potential for discarding uncommitted data from the cache | 328 | * the potential for discarding uncommitted data from the cache |
329 | */ | 329 | */ |
330 | if ((start & (L1_CACHE_BYTES - 1)) || (size & (L1_CACHE_BYTES - 1))) | 330 | if ((start | end) & (L1_CACHE_BYTES - 1)) |
331 | flush_dcache_range(start, end); | 331 | flush_dcache_range(start, end); |
332 | else | 332 | else |
333 | invalidate_dcache_range(start, end); | 333 | invalidate_dcache_range(start, end); |
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index f3afe3d97f6b..a1b2713f6e96 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c | |||
@@ -72,10 +72,11 @@ unsigned long tlbcam_sz(int idx) | |||
72 | return tlbcam_addrs[idx].limit - tlbcam_addrs[idx].start + 1; | 72 | return tlbcam_addrs[idx].limit - tlbcam_addrs[idx].start + 1; |
73 | } | 73 | } |
74 | 74 | ||
75 | #ifdef CONFIG_FSL_BOOKE | ||
75 | /* | 76 | /* |
76 | * Return PA for this VA if it is mapped by a CAM, or 0 | 77 | * Return PA for this VA if it is mapped by a CAM, or 0 |
77 | */ | 78 | */ |
78 | phys_addr_t v_mapped_by_tlbcam(unsigned long va) | 79 | phys_addr_t v_block_mapped(unsigned long va) |
79 | { | 80 | { |
80 | int b; | 81 | int b; |
81 | for (b = 0; b < tlbcam_index; ++b) | 82 | for (b = 0; b < tlbcam_index; ++b) |
@@ -87,7 +88,7 @@ phys_addr_t v_mapped_by_tlbcam(unsigned long va) | |||
87 | /* | 88 | /* |
88 | * Return VA for a given PA or 0 if not mapped | 89 | * Return VA for a given PA or 0 if not mapped |
89 | */ | 90 | */ |
90 | unsigned long p_mapped_by_tlbcam(phys_addr_t pa) | 91 | unsigned long p_block_mapped(phys_addr_t pa) |
91 | { | 92 | { |
92 | int b; | 93 | int b; |
93 | for (b = 0; b < tlbcam_index; ++b) | 94 | for (b = 0; b < tlbcam_index; ++b) |
@@ -97,6 +98,7 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa) | |||
97 | return tlbcam_addrs[b].start+(pa-tlbcam_addrs[b].phys); | 98 | return tlbcam_addrs[b].start+(pa-tlbcam_addrs[b].phys); |
98 | return 0; | 99 | return 0; |
99 | } | 100 | } |
101 | #endif | ||
100 | 102 | ||
101 | /* | 103 | /* |
102 | * Set up a variable-size TLB entry (tlbcam). The parameters are not checked; | 104 | * Set up a variable-size TLB entry (tlbcam). The parameters are not checked; |
diff --git a/arch/powerpc/mm/hash64_4k.c b/arch/powerpc/mm/hash64_4k.c index e7c04542ba62..47d1b26effc6 100644 --- a/arch/powerpc/mm/hash64_4k.c +++ b/arch/powerpc/mm/hash64_4k.c | |||
@@ -44,7 +44,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, | |||
44 | * a write access. Since this is 4K insert of 64K page size | 44 | * a write access. Since this is 4K insert of 64K page size |
45 | * also add _PAGE_COMBO | 45 | * also add _PAGE_COMBO |
46 | */ | 46 | */ |
47 | new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE; | 47 | new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED; |
48 | if (access & _PAGE_RW) | 48 | if (access & _PAGE_RW) |
49 | new_pte |= _PAGE_DIRTY; | 49 | new_pte |= _PAGE_DIRTY; |
50 | } while (old_pte != __cmpxchg_u64((unsigned long *)ptep, | 50 | } while (old_pte != __cmpxchg_u64((unsigned long *)ptep, |
@@ -106,7 +106,7 @@ repeat: | |||
106 | } | 106 | } |
107 | } | 107 | } |
108 | /* | 108 | /* |
109 | * Hypervisor failure. Restore old pmd and return -1 | 109 | * Hypervisor failure. Restore old pte and return -1 |
110 | * similar to __hash_page_* | 110 | * similar to __hash_page_* |
111 | */ | 111 | */ |
112 | if (unlikely(slot == -2)) { | 112 | if (unlikely(slot == -2)) { |
diff --git a/arch/powerpc/mm/hash64_64k.c b/arch/powerpc/mm/hash64_64k.c index edb09912f0c9..b2d659cf51c6 100644 --- a/arch/powerpc/mm/hash64_64k.c +++ b/arch/powerpc/mm/hash64_64k.c | |||
@@ -188,7 +188,7 @@ repeat: | |||
188 | } | 188 | } |
189 | } | 189 | } |
190 | /* | 190 | /* |
191 | * Hypervisor failure. Restore old pmd and return -1 | 191 | * Hypervisor failure. Restore old pte and return -1 |
192 | * similar to __hash_page_* | 192 | * similar to __hash_page_* |
193 | */ | 193 | */ |
194 | if (unlikely(slot == -2)) { | 194 | if (unlikely(slot == -2)) { |
@@ -249,8 +249,7 @@ int __hash_page_64K(unsigned long ea, unsigned long access, | |||
249 | return 0; | 249 | return 0; |
250 | /* | 250 | /* |
251 | * Try to lock the PTE, add ACCESSED and DIRTY if it was | 251 | * Try to lock the PTE, add ACCESSED and DIRTY if it was |
252 | * a write access. Since this is 4K insert of 64K page size | 252 | * a write access. |
253 | * also add _PAGE_COMBO | ||
254 | */ | 253 | */ |
255 | new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED; | 254 | new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED; |
256 | if (access & _PAGE_RW) | 255 | if (access & _PAGE_RW) |
@@ -311,7 +310,7 @@ repeat: | |||
311 | } | 310 | } |
312 | } | 311 | } |
313 | /* | 312 | /* |
314 | * Hypervisor failure. Restore old pmd and return -1 | 313 | * Hypervisor failure. Restore old pte and return -1 |
315 | * similar to __hash_page_* | 314 | * similar to __hash_page_* |
316 | */ | 315 | */ |
317 | if (unlikely(slot == -2)) { | 316 | if (unlikely(slot == -2)) { |
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 1005281be9a6..7635b1c6b5da 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -168,11 +168,11 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags) | |||
168 | rflags |= HPTE_R_N; | 168 | rflags |= HPTE_R_N; |
169 | /* | 169 | /* |
170 | * PP bits: | 170 | * PP bits: |
171 | * Linux use slb key 0 for kernel and 1 for user. | 171 | * Linux uses slb key 0 for kernel and 1 for user. |
172 | * kernel areas are mapped by PP bits 00 | 172 | * kernel areas are mapped with PP=00 |
173 | * and and there is no kernel RO (_PAGE_KERNEL_RO). | 173 | * and there is no kernel RO (_PAGE_KERNEL_RO). |
174 | * User area mapped by 0x2 and read only use by | 174 | * User area is mapped with PP=0x2 for read/write |
175 | * 0x3. | 175 | * or PP=0x3 for read-only (including writeable but clean pages). |
176 | */ | 176 | */ |
177 | if (pteflags & _PAGE_USER) { | 177 | if (pteflags & _PAGE_USER) { |
178 | rflags |= 0x2; | 178 | rflags |= 0x2; |
@@ -265,28 +265,32 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | |||
265 | return ret < 0 ? ret : 0; | 265 | return ret < 0 ? ret : 0; |
266 | } | 266 | } |
267 | 267 | ||
268 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
269 | int htab_remove_mapping(unsigned long vstart, unsigned long vend, | 268 | int htab_remove_mapping(unsigned long vstart, unsigned long vend, |
270 | int psize, int ssize) | 269 | int psize, int ssize) |
271 | { | 270 | { |
272 | unsigned long vaddr; | 271 | unsigned long vaddr; |
273 | unsigned int step, shift; | 272 | unsigned int step, shift; |
273 | int rc; | ||
274 | int ret = 0; | ||
274 | 275 | ||
275 | shift = mmu_psize_defs[psize].shift; | 276 | shift = mmu_psize_defs[psize].shift; |
276 | step = 1 << shift; | 277 | step = 1 << shift; |
277 | 278 | ||
278 | if (!ppc_md.hpte_removebolted) { | 279 | if (!ppc_md.hpte_removebolted) |
279 | printk(KERN_WARNING "Platform doesn't implement " | 280 | return -ENODEV; |
280 | "hpte_removebolted\n"); | ||
281 | return -EINVAL; | ||
282 | } | ||
283 | 281 | ||
284 | for (vaddr = vstart; vaddr < vend; vaddr += step) | 282 | for (vaddr = vstart; vaddr < vend; vaddr += step) { |
285 | ppc_md.hpte_removebolted(vaddr, psize, ssize); | 283 | rc = ppc_md.hpte_removebolted(vaddr, psize, ssize); |
284 | if (rc == -ENOENT) { | ||
285 | ret = -ENOENT; | ||
286 | continue; | ||
287 | } | ||
288 | if (rc < 0) | ||
289 | return rc; | ||
290 | } | ||
286 | 291 | ||
287 | return 0; | 292 | return ret; |
288 | } | 293 | } |
289 | #endif /* CONFIG_MEMORY_HOTPLUG */ | ||
290 | 294 | ||
291 | static int __init htab_dt_scan_seg_sizes(unsigned long node, | 295 | static int __init htab_dt_scan_seg_sizes(unsigned long node, |
292 | const char *uname, int depth, | 296 | const char *uname, int depth, |
@@ -607,10 +611,28 @@ static int __init htab_dt_scan_pftsize(unsigned long node, | |||
607 | return 0; | 611 | return 0; |
608 | } | 612 | } |
609 | 613 | ||
610 | static unsigned long __init htab_get_table_size(void) | 614 | unsigned htab_shift_for_mem_size(unsigned long mem_size) |
611 | { | 615 | { |
612 | unsigned long mem_size, rnd_mem_size, pteg_count, psize; | 616 | unsigned memshift = __ilog2(mem_size); |
617 | unsigned pshift = mmu_psize_defs[mmu_virtual_psize].shift; | ||
618 | unsigned pteg_shift; | ||
619 | |||
620 | /* round mem_size up to next power of 2 */ | ||
621 | if ((1UL << memshift) < mem_size) | ||
622 | memshift += 1; | ||
623 | |||
624 | /* aim for 2 pages / pteg */ | ||
625 | pteg_shift = memshift - (pshift + 1); | ||
613 | 626 | ||
627 | /* | ||
628 | * 2^11 PTEGS of 128 bytes each, ie. 2^18 bytes is the minimum htab | ||
629 | * size permitted by the architecture. | ||
630 | */ | ||
631 | return max(pteg_shift + 7, 18U); | ||
632 | } | ||
633 | |||
634 | static unsigned long __init htab_get_table_size(void) | ||
635 | { | ||
614 | /* If hash size isn't already provided by the platform, we try to | 636 | /* If hash size isn't already provided by the platform, we try to |
615 | * retrieve it from the device-tree. If it's not there neither, we | 637 | * retrieve it from the device-tree. If it's not there neither, we |
616 | * calculate it now based on the total RAM size | 638 | * calculate it now based on the total RAM size |
@@ -620,31 +642,30 @@ static unsigned long __init htab_get_table_size(void) | |||
620 | if (ppc64_pft_size) | 642 | if (ppc64_pft_size) |
621 | return 1UL << ppc64_pft_size; | 643 | return 1UL << ppc64_pft_size; |
622 | 644 | ||
623 | /* round mem_size up to next power of 2 */ | 645 | return 1UL << htab_shift_for_mem_size(memblock_phys_mem_size()); |
624 | mem_size = memblock_phys_mem_size(); | ||
625 | rnd_mem_size = 1UL << __ilog2(mem_size); | ||
626 | if (rnd_mem_size < mem_size) | ||
627 | rnd_mem_size <<= 1; | ||
628 | |||
629 | /* # pages / 2 */ | ||
630 | psize = mmu_psize_defs[mmu_virtual_psize].shift; | ||
631 | pteg_count = max(rnd_mem_size >> (psize + 1), 1UL << 11); | ||
632 | |||
633 | return pteg_count << 7; | ||
634 | } | 646 | } |
635 | 647 | ||
636 | #ifdef CONFIG_MEMORY_HOTPLUG | 648 | #ifdef CONFIG_MEMORY_HOTPLUG |
637 | int create_section_mapping(unsigned long start, unsigned long end) | 649 | int create_section_mapping(unsigned long start, unsigned long end) |
638 | { | 650 | { |
639 | return htab_bolt_mapping(start, end, __pa(start), | 651 | int rc = htab_bolt_mapping(start, end, __pa(start), |
640 | pgprot_val(PAGE_KERNEL), mmu_linear_psize, | 652 | pgprot_val(PAGE_KERNEL), mmu_linear_psize, |
641 | mmu_kernel_ssize); | 653 | mmu_kernel_ssize); |
654 | |||
655 | if (rc < 0) { | ||
656 | int rc2 = htab_remove_mapping(start, end, mmu_linear_psize, | ||
657 | mmu_kernel_ssize); | ||
658 | BUG_ON(rc2 && (rc2 != -ENOENT)); | ||
659 | } | ||
660 | return rc; | ||
642 | } | 661 | } |
643 | 662 | ||
644 | int remove_section_mapping(unsigned long start, unsigned long end) | 663 | int remove_section_mapping(unsigned long start, unsigned long end) |
645 | { | 664 | { |
646 | return htab_remove_mapping(start, end, mmu_linear_psize, | 665 | int rc = htab_remove_mapping(start, end, mmu_linear_psize, |
647 | mmu_kernel_ssize); | 666 | mmu_kernel_ssize); |
667 | WARN_ON(rc < 0); | ||
668 | return rc; | ||
648 | } | 669 | } |
649 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 670 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
650 | 671 | ||
diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c index e2138c7ae70f..8555fce902fe 100644 --- a/arch/powerpc/mm/hugetlbpage-hash64.c +++ b/arch/powerpc/mm/hugetlbpage-hash64.c | |||
@@ -76,7 +76,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, | |||
76 | if (old_pte & _PAGE_F_SECOND) | 76 | if (old_pte & _PAGE_F_SECOND) |
77 | hash = ~hash; | 77 | hash = ~hash; |
78 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; | 78 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; |
79 | slot += (old_pte & _PAGE_F_GIX) >> 12; | 79 | slot += (old_pte & _PAGE_F_GIX) >> _PAGE_F_GIX_SHIFT; |
80 | 80 | ||
81 | if (ppc_md.hpte_updatepp(slot, rflags, vpn, mmu_psize, | 81 | if (ppc_md.hpte_updatepp(slot, rflags, vpn, mmu_psize, |
82 | mmu_psize, ssize, flags) == -1) | 82 | mmu_psize, ssize, flags) == -1) |
@@ -105,7 +105,8 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, | |||
105 | return -1; | 105 | return -1; |
106 | } | 106 | } |
107 | 107 | ||
108 | new_pte |= (slot << 12) & (_PAGE_F_SECOND | _PAGE_F_GIX); | 108 | new_pte |= (slot << _PAGE_F_GIX_SHIFT) & |
109 | (_PAGE_F_SECOND | _PAGE_F_GIX); | ||
109 | } | 110 | } |
110 | 111 | ||
111 | /* | 112 | /* |
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 744e24bcb85c..6dd272b6196f 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c | |||
@@ -107,8 +107,7 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, | |||
107 | kmem_cache_free(cachep, new); | 107 | kmem_cache_free(cachep, new); |
108 | else { | 108 | else { |
109 | #ifdef CONFIG_PPC_BOOK3S_64 | 109 | #ifdef CONFIG_PPC_BOOK3S_64 |
110 | hpdp->pd = (unsigned long)new | | 110 | hpdp->pd = __pa(new) | (shift_to_mmu_psize(pshift) << 2); |
111 | (shift_to_mmu_psize(pshift) << 2); | ||
112 | #else | 111 | #else |
113 | hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift; | 112 | hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift; |
114 | #endif | 113 | #endif |
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index c2b771614d4f..c899fe340bbd 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c | |||
@@ -178,10 +178,6 @@ void __init MMU_init(void) | |||
178 | /* Initialize early top-down ioremap allocator */ | 178 | /* Initialize early top-down ioremap allocator */ |
179 | ioremap_bot = IOREMAP_TOP; | 179 | ioremap_bot = IOREMAP_TOP; |
180 | 180 | ||
181 | /* Map in I/O resources */ | ||
182 | if (ppc_md.progress) | ||
183 | ppc_md.progress("MMU:setio", 0x302); | ||
184 | |||
185 | if (ppc_md.progress) | 181 | if (ppc_md.progress) |
186 | ppc_md.progress("MMU:exit", 0x211); | 182 | ppc_md.progress("MMU:exit", 0x211); |
187 | 183 | ||
@@ -193,22 +189,3 @@ void __init MMU_init(void) | |||
193 | /* Shortly after that, the entire linear mapping will be available */ | 189 | /* Shortly after that, the entire linear mapping will be available */ |
194 | memblock_set_current_limit(lowmem_end_addr); | 190 | memblock_set_current_limit(lowmem_end_addr); |
195 | } | 191 | } |
196 | |||
197 | #ifdef CONFIG_8xx /* No 8xx specific .c file to put that in ... */ | ||
198 | void setup_initial_memory_limit(phys_addr_t first_memblock_base, | ||
199 | phys_addr_t first_memblock_size) | ||
200 | { | ||
201 | /* We don't currently support the first MEMBLOCK not mapping 0 | ||
202 | * physical on those processors | ||
203 | */ | ||
204 | BUG_ON(first_memblock_base != 0); | ||
205 | |||
206 | #ifdef CONFIG_PIN_TLB | ||
207 | /* 8xx can only access 24MB at the moment */ | ||
208 | memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01800000)); | ||
209 | #else | ||
210 | /* 8xx can only access 8MB at the moment */ | ||
211 | memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000)); | ||
212 | #endif | ||
213 | } | ||
214 | #endif /* CONFIG_8xx */ | ||
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 379a6a90644b..ba655666186d 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c | |||
@@ -85,6 +85,11 @@ static void pgd_ctor(void *addr) | |||
85 | memset(addr, 0, PGD_TABLE_SIZE); | 85 | memset(addr, 0, PGD_TABLE_SIZE); |
86 | } | 86 | } |
87 | 87 | ||
88 | static void pud_ctor(void *addr) | ||
89 | { | ||
90 | memset(addr, 0, PUD_TABLE_SIZE); | ||
91 | } | ||
92 | |||
88 | static void pmd_ctor(void *addr) | 93 | static void pmd_ctor(void *addr) |
89 | { | 94 | { |
90 | memset(addr, 0, PMD_TABLE_SIZE); | 95 | memset(addr, 0, PMD_TABLE_SIZE); |
@@ -138,14 +143,18 @@ void pgtable_cache_init(void) | |||
138 | { | 143 | { |
139 | pgtable_cache_add(PGD_INDEX_SIZE, pgd_ctor); | 144 | pgtable_cache_add(PGD_INDEX_SIZE, pgd_ctor); |
140 | pgtable_cache_add(PMD_CACHE_INDEX, pmd_ctor); | 145 | pgtable_cache_add(PMD_CACHE_INDEX, pmd_ctor); |
146 | /* | ||
147 | * In all current configs, when the PUD index exists it's the | ||
148 | * same size as either the pgd or pmd index except with THP enabled | ||
149 | * on book3s 64 | ||
150 | */ | ||
151 | if (PUD_INDEX_SIZE && !PGT_CACHE(PUD_INDEX_SIZE)) | ||
152 | pgtable_cache_add(PUD_INDEX_SIZE, pud_ctor); | ||
153 | |||
141 | if (!PGT_CACHE(PGD_INDEX_SIZE) || !PGT_CACHE(PMD_CACHE_INDEX)) | 154 | if (!PGT_CACHE(PGD_INDEX_SIZE) || !PGT_CACHE(PMD_CACHE_INDEX)) |
142 | panic("Couldn't allocate pgtable caches"); | 155 | panic("Couldn't allocate pgtable caches"); |
143 | /* In all current configs, when the PUD index exists it's the | 156 | if (PUD_INDEX_SIZE && !PGT_CACHE(PUD_INDEX_SIZE)) |
144 | * same size as either the pgd or pmd index. Verify that the | 157 | panic("Couldn't allocate pud pgtable caches"); |
145 | * initialization above has also created a PUD cache. This | ||
146 | * will need re-examiniation if we add new possibilities for | ||
147 | * the pagetable layout. */ | ||
148 | BUG_ON(PUD_INDEX_SIZE && !PGT_CACHE(PUD_INDEX_SIZE)); | ||
149 | } | 158 | } |
150 | 159 | ||
151 | #ifdef CONFIG_SPARSEMEM_VMEMMAP | 160 | #ifdef CONFIG_SPARSEMEM_VMEMMAP |
@@ -188,9 +197,9 @@ static int __meminit vmemmap_populated(unsigned long start, int page_size) | |||
188 | */ | 197 | */ |
189 | 198 | ||
190 | #ifdef CONFIG_PPC_BOOK3E | 199 | #ifdef CONFIG_PPC_BOOK3E |
191 | static void __meminit vmemmap_create_mapping(unsigned long start, | 200 | static int __meminit vmemmap_create_mapping(unsigned long start, |
192 | unsigned long page_size, | 201 | unsigned long page_size, |
193 | unsigned long phys) | 202 | unsigned long phys) |
194 | { | 203 | { |
195 | /* Create a PTE encoding without page size */ | 204 | /* Create a PTE encoding without page size */ |
196 | unsigned long i, flags = _PAGE_PRESENT | _PAGE_ACCESSED | | 205 | unsigned long i, flags = _PAGE_PRESENT | _PAGE_ACCESSED | |
@@ -208,6 +217,8 @@ static void __meminit vmemmap_create_mapping(unsigned long start, | |||
208 | */ | 217 | */ |
209 | for (i = 0; i < page_size; i += PAGE_SIZE) | 218 | for (i = 0; i < page_size; i += PAGE_SIZE) |
210 | BUG_ON(map_kernel_page(start + i, phys, flags)); | 219 | BUG_ON(map_kernel_page(start + i, phys, flags)); |
220 | |||
221 | return 0; | ||
211 | } | 222 | } |
212 | 223 | ||
213 | #ifdef CONFIG_MEMORY_HOTPLUG | 224 | #ifdef CONFIG_MEMORY_HOTPLUG |
@@ -217,25 +228,31 @@ static void vmemmap_remove_mapping(unsigned long start, | |||
217 | } | 228 | } |
218 | #endif | 229 | #endif |
219 | #else /* CONFIG_PPC_BOOK3E */ | 230 | #else /* CONFIG_PPC_BOOK3E */ |
220 | static void __meminit vmemmap_create_mapping(unsigned long start, | 231 | static int __meminit vmemmap_create_mapping(unsigned long start, |
221 | unsigned long page_size, | 232 | unsigned long page_size, |
222 | unsigned long phys) | 233 | unsigned long phys) |
223 | { | 234 | { |
224 | int mapped = htab_bolt_mapping(start, start + page_size, phys, | 235 | int rc = htab_bolt_mapping(start, start + page_size, phys, |
225 | pgprot_val(PAGE_KERNEL), | 236 | pgprot_val(PAGE_KERNEL), |
226 | mmu_vmemmap_psize, | 237 | mmu_vmemmap_psize, mmu_kernel_ssize); |
227 | mmu_kernel_ssize); | 238 | if (rc < 0) { |
228 | BUG_ON(mapped < 0); | 239 | int rc2 = htab_remove_mapping(start, start + page_size, |
240 | mmu_vmemmap_psize, | ||
241 | mmu_kernel_ssize); | ||
242 | BUG_ON(rc2 && (rc2 != -ENOENT)); | ||
243 | } | ||
244 | return rc; | ||
229 | } | 245 | } |
230 | 246 | ||
231 | #ifdef CONFIG_MEMORY_HOTPLUG | 247 | #ifdef CONFIG_MEMORY_HOTPLUG |
232 | static void vmemmap_remove_mapping(unsigned long start, | 248 | static void vmemmap_remove_mapping(unsigned long start, |
233 | unsigned long page_size) | 249 | unsigned long page_size) |
234 | { | 250 | { |
235 | int mapped = htab_remove_mapping(start, start + page_size, | 251 | int rc = htab_remove_mapping(start, start + page_size, |
236 | mmu_vmemmap_psize, | 252 | mmu_vmemmap_psize, |
237 | mmu_kernel_ssize); | 253 | mmu_kernel_ssize); |
238 | BUG_ON(mapped < 0); | 254 | BUG_ON((rc < 0) && (rc != -ENOENT)); |
255 | WARN_ON(rc == -ENOENT); | ||
239 | } | 256 | } |
240 | #endif | 257 | #endif |
241 | 258 | ||
@@ -303,6 +320,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) | |||
303 | 320 | ||
304 | for (; start < end; start += page_size) { | 321 | for (; start < end; start += page_size) { |
305 | void *p; | 322 | void *p; |
323 | int rc; | ||
306 | 324 | ||
307 | if (vmemmap_populated(start, page_size)) | 325 | if (vmemmap_populated(start, page_size)) |
308 | continue; | 326 | continue; |
@@ -316,7 +334,13 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) | |||
316 | pr_debug(" * %016lx..%016lx allocated at %p\n", | 334 | pr_debug(" * %016lx..%016lx allocated at %p\n", |
317 | start, start + page_size, p); | 335 | start, start + page_size, p); |
318 | 336 | ||
319 | vmemmap_create_mapping(start, page_size, __pa(p)); | 337 | rc = vmemmap_create_mapping(start, page_size, __pa(p)); |
338 | if (rc < 0) { | ||
339 | pr_warning( | ||
340 | "vmemmap_populate: Unable to create vmemmap mapping: %d\n", | ||
341 | rc); | ||
342 | return -EFAULT; | ||
343 | } | ||
320 | } | 344 | } |
321 | 345 | ||
322 | return 0; | 346 | return 0; |
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index f078a1f94fc2..ac79dbde1015 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c | |||
@@ -119,12 +119,18 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device) | |||
119 | struct zone *zone; | 119 | struct zone *zone; |
120 | unsigned long start_pfn = start >> PAGE_SHIFT; | 120 | unsigned long start_pfn = start >> PAGE_SHIFT; |
121 | unsigned long nr_pages = size >> PAGE_SHIFT; | 121 | unsigned long nr_pages = size >> PAGE_SHIFT; |
122 | int rc; | ||
122 | 123 | ||
123 | pgdata = NODE_DATA(nid); | 124 | pgdata = NODE_DATA(nid); |
124 | 125 | ||
125 | start = (unsigned long)__va(start); | 126 | start = (unsigned long)__va(start); |
126 | if (create_section_mapping(start, start + size)) | 127 | rc = create_section_mapping(start, start + size); |
127 | return -EINVAL; | 128 | if (rc) { |
129 | pr_warning( | ||
130 | "Unable to create mapping for hot added memory 0x%llx..0x%llx: %d\n", | ||
131 | start, start + size, rc); | ||
132 | return -EFAULT; | ||
133 | } | ||
128 | 134 | ||
129 | /* this should work for most non-highmem platforms */ | 135 | /* this should work for most non-highmem platforms */ |
130 | zone = pgdata->node_zones + | 136 | zone = pgdata->node_zones + |
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 9f58ff44a075..bfb7c0bcabd5 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h | |||
@@ -100,7 +100,6 @@ extern void setbat(int index, unsigned long virt, phys_addr_t phys, | |||
100 | 100 | ||
101 | extern int __map_without_bats; | 101 | extern int __map_without_bats; |
102 | extern int __allow_ioremap_reserved; | 102 | extern int __allow_ioremap_reserved; |
103 | extern unsigned long ioremap_base; | ||
104 | extern unsigned int rtas_data, rtas_size; | 103 | extern unsigned int rtas_data, rtas_size; |
105 | 104 | ||
106 | struct hash_pte; | 105 | struct hash_pte; |
@@ -110,7 +109,8 @@ extern unsigned long Hash_size, Hash_mask; | |||
110 | #endif /* CONFIG_PPC32 */ | 109 | #endif /* CONFIG_PPC32 */ |
111 | 110 | ||
112 | #ifdef CONFIG_PPC64 | 111 | #ifdef CONFIG_PPC64 |
113 | extern int map_kernel_page(unsigned long ea, unsigned long pa, int flags); | 112 | extern int map_kernel_page(unsigned long ea, unsigned long pa, |
113 | unsigned long flags); | ||
114 | #endif /* CONFIG_PPC64 */ | 114 | #endif /* CONFIG_PPC64 */ |
115 | 115 | ||
116 | extern unsigned long ioremap_bot; | 116 | extern unsigned long ioremap_bot; |
@@ -132,22 +132,17 @@ extern void wii_memory_fixups(void); | |||
132 | /* ...and now those things that may be slightly different between processor | 132 | /* ...and now those things that may be slightly different between processor |
133 | * architectures. -- Dan | 133 | * architectures. -- Dan |
134 | */ | 134 | */ |
135 | #if defined(CONFIG_8xx) | 135 | #ifdef CONFIG_PPC32 |
136 | #define MMU_init_hw() do { } while(0) | ||
137 | #define mmu_mapin_ram(top) (0UL) | ||
138 | |||
139 | #elif defined(CONFIG_4xx) | ||
140 | extern void MMU_init_hw(void); | 136 | extern void MMU_init_hw(void); |
141 | extern unsigned long mmu_mapin_ram(unsigned long top); | 137 | extern unsigned long mmu_mapin_ram(unsigned long top); |
138 | #endif | ||
142 | 139 | ||
143 | #elif defined(CONFIG_PPC_FSL_BOOK3E) | 140 | #ifdef CONFIG_PPC_FSL_BOOK3E |
144 | extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx, | 141 | extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx, |
145 | bool dryrun); | 142 | bool dryrun); |
146 | extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt, | 143 | extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt, |
147 | phys_addr_t phys); | 144 | phys_addr_t phys); |
148 | #ifdef CONFIG_PPC32 | 145 | #ifdef CONFIG_PPC32 |
149 | extern void MMU_init_hw(void); | ||
150 | extern unsigned long mmu_mapin_ram(unsigned long top); | ||
151 | extern void adjust_total_lowmem(void); | 146 | extern void adjust_total_lowmem(void); |
152 | extern int switch_to_as1(void); | 147 | extern int switch_to_as1(void); |
153 | extern void restore_to_as0(int esel, int offset, void *dt_ptr, int bootcpu); | 148 | extern void restore_to_as0(int esel, int offset, void *dt_ptr, int bootcpu); |
@@ -162,8 +157,14 @@ struct tlbcam { | |||
162 | u32 MAS3; | 157 | u32 MAS3; |
163 | u32 MAS7; | 158 | u32 MAS7; |
164 | }; | 159 | }; |
165 | #elif defined(CONFIG_PPC32) | 160 | #endif |
166 | /* anything 32-bit except 4xx or 8xx */ | 161 | |
167 | extern void MMU_init_hw(void); | 162 | #if defined(CONFIG_6xx) || defined(CONFIG_FSL_BOOKE) |
168 | extern unsigned long mmu_mapin_ram(unsigned long top); | 163 | /* 6xx have BATS */ |
164 | /* FSL_BOOKE have TLBCAM */ | ||
165 | phys_addr_t v_block_mapped(unsigned long va); | ||
166 | unsigned long p_block_mapped(phys_addr_t pa); | ||
167 | #else | ||
168 | static inline phys_addr_t v_block_mapped(unsigned long va) { return 0; } | ||
169 | static inline unsigned long p_block_mapped(phys_addr_t pa) { return 0; } | ||
169 | #endif | 170 | #endif |
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 7692d1bb1bc6..bf7bf32b54f8 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c | |||
@@ -37,35 +37,10 @@ | |||
37 | 37 | ||
38 | #include "mmu_decl.h" | 38 | #include "mmu_decl.h" |
39 | 39 | ||
40 | unsigned long ioremap_base; | ||
41 | unsigned long ioremap_bot; | 40 | unsigned long ioremap_bot; |
42 | EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */ | 41 | EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */ |
43 | 42 | ||
44 | #ifdef CONFIG_6xx | 43 | extern char etext[], _stext[], _sinittext[], _einittext[]; |
45 | #define HAVE_BATS 1 | ||
46 | #endif | ||
47 | |||
48 | #if defined(CONFIG_FSL_BOOKE) | ||
49 | #define HAVE_TLBCAM 1 | ||
50 | #endif | ||
51 | |||
52 | extern char etext[], _stext[]; | ||
53 | |||
54 | #ifdef HAVE_BATS | ||
55 | extern phys_addr_t v_mapped_by_bats(unsigned long va); | ||
56 | extern unsigned long p_mapped_by_bats(phys_addr_t pa); | ||
57 | #else /* !HAVE_BATS */ | ||
58 | #define v_mapped_by_bats(x) (0UL) | ||
59 | #define p_mapped_by_bats(x) (0UL) | ||
60 | #endif /* HAVE_BATS */ | ||
61 | |||
62 | #ifdef HAVE_TLBCAM | ||
63 | extern phys_addr_t v_mapped_by_tlbcam(unsigned long va); | ||
64 | extern unsigned long p_mapped_by_tlbcam(phys_addr_t pa); | ||
65 | #else /* !HAVE_TLBCAM */ | ||
66 | #define v_mapped_by_tlbcam(x) (0UL) | ||
67 | #define p_mapped_by_tlbcam(x) (0UL) | ||
68 | #endif /* HAVE_TLBCAM */ | ||
69 | 44 | ||
70 | #define PGDIR_ORDER (32 + PGD_T_LOG2 - PGDIR_SHIFT) | 45 | #define PGDIR_ORDER (32 + PGD_T_LOG2 - PGDIR_SHIFT) |
71 | 46 | ||
@@ -197,7 +172,7 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags, | |||
197 | /* | 172 | /* |
198 | * Choose an address to map it to. | 173 | * Choose an address to map it to. |
199 | * Once the vmalloc system is running, we use it. | 174 | * Once the vmalloc system is running, we use it. |
200 | * Before then, we use space going down from ioremap_base | 175 | * Before then, we use space going down from IOREMAP_TOP |
201 | * (ioremap_bot records where we're up to). | 176 | * (ioremap_bot records where we're up to). |
202 | */ | 177 | */ |
203 | p = addr & PAGE_MASK; | 178 | p = addr & PAGE_MASK; |
@@ -228,19 +203,10 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags, | |||
228 | 203 | ||
229 | /* | 204 | /* |
230 | * Is it already mapped? Perhaps overlapped by a previous | 205 | * Is it already mapped? Perhaps overlapped by a previous |
231 | * BAT mapping. If the whole area is mapped then we're done, | 206 | * mapping. |
232 | * otherwise remap it since we want to keep the virt addrs for | ||
233 | * each request contiguous. | ||
234 | * | ||
235 | * We make the assumption here that if the bottom and top | ||
236 | * of the range we want are mapped then it's mapped to the | ||
237 | * same virt address (and this is contiguous). | ||
238 | * -- Cort | ||
239 | */ | 207 | */ |
240 | if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ ) | 208 | v = p_block_mapped(p); |
241 | goto out; | 209 | if (v) |
242 | |||
243 | if ((v = p_mapped_by_tlbcam(p))) | ||
244 | goto out; | 210 | goto out; |
245 | 211 | ||
246 | if (slab_is_available()) { | 212 | if (slab_is_available()) { |
@@ -278,7 +244,8 @@ void iounmap(volatile void __iomem *addr) | |||
278 | * If mapped by BATs then there is nothing to do. | 244 | * If mapped by BATs then there is nothing to do. |
279 | * Calling vfree() generates a benign warning. | 245 | * Calling vfree() generates a benign warning. |
280 | */ | 246 | */ |
281 | if (v_mapped_by_bats((unsigned long)addr)) return; | 247 | if (v_block_mapped((unsigned long)addr)) |
248 | return; | ||
282 | 249 | ||
283 | if (addr > high_memory && (unsigned long) addr < ioremap_bot) | 250 | if (addr > high_memory && (unsigned long) addr < ioremap_bot) |
284 | vunmap((void *) (PAGE_MASK & (unsigned long)addr)); | 251 | vunmap((void *) (PAGE_MASK & (unsigned long)addr)); |
@@ -322,7 +289,8 @@ void __init __mapin_ram_chunk(unsigned long offset, unsigned long top) | |||
322 | v = PAGE_OFFSET + s; | 289 | v = PAGE_OFFSET + s; |
323 | p = memstart_addr + s; | 290 | p = memstart_addr + s; |
324 | for (; s < top; s += PAGE_SIZE) { | 291 | for (; s < top; s += PAGE_SIZE) { |
325 | ktext = ((char *) v >= _stext && (char *) v < etext); | 292 | ktext = ((char *)v >= _stext && (char *)v < etext) || |
293 | ((char *)v >= _sinittext && (char *)v < _einittext); | ||
326 | f = ktext ? pgprot_val(PAGE_KERNEL_TEXT) : pgprot_val(PAGE_KERNEL); | 294 | f = ktext ? pgprot_val(PAGE_KERNEL_TEXT) : pgprot_val(PAGE_KERNEL); |
327 | map_page(v, p, f); | 295 | map_page(v, p, f); |
328 | #ifdef CONFIG_PPC_STD_MMU_32 | 296 | #ifdef CONFIG_PPC_STD_MMU_32 |
@@ -403,7 +371,7 @@ static int __change_page_attr(struct page *page, pgprot_t prot) | |||
403 | BUG_ON(PageHighMem(page)); | 371 | BUG_ON(PageHighMem(page)); |
404 | address = (unsigned long)page_address(page); | 372 | address = (unsigned long)page_address(page); |
405 | 373 | ||
406 | if (v_mapped_by_bats(address) || v_mapped_by_tlbcam(address)) | 374 | if (v_block_mapped(address)) |
407 | return 0; | 375 | return 0; |
408 | if (!get_pteptr(&init_mm, address, &kpte, &kpmd)) | 376 | if (!get_pteptr(&init_mm, address, &kpte, &kpmd)) |
409 | return -EINVAL; | 377 | return -EINVAL; |
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index d9cc66cbdbb7..347106080bb1 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c | |||
@@ -88,7 +88,7 @@ static __ref void *early_alloc_pgtable(unsigned long size) | |||
88 | * map_kernel_page adds an entry to the ioremap page table | 88 | * map_kernel_page adds an entry to the ioremap page table |
89 | * and adds an entry to the HPT, possibly bolting it | 89 | * and adds an entry to the HPT, possibly bolting it |
90 | */ | 90 | */ |
91 | int map_kernel_page(unsigned long ea, unsigned long pa, int flags) | 91 | int map_kernel_page(unsigned long ea, unsigned long pa, unsigned long flags) |
92 | { | 92 | { |
93 | pgd_t *pgdp; | 93 | pgd_t *pgdp; |
94 | pud_t *pudp; | 94 | pud_t *pudp; |
@@ -749,7 +749,7 @@ pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot) | |||
749 | { | 749 | { |
750 | unsigned long pmdv; | 750 | unsigned long pmdv; |
751 | 751 | ||
752 | pmdv = pfn << PTE_RPN_SHIFT; | 752 | pmdv = (pfn << PTE_RPN_SHIFT) & PTE_RPN_MASK; |
753 | return pmd_set_protbits(__pmd(pmdv), pgprot); | 753 | return pmd_set_protbits(__pmd(pmdv), pgprot); |
754 | } | 754 | } |
755 | 755 | ||
@@ -817,6 +817,13 @@ pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm, | |||
817 | 817 | ||
818 | int has_transparent_hugepage(void) | 818 | int has_transparent_hugepage(void) |
819 | { | 819 | { |
820 | |||
821 | BUILD_BUG_ON_MSG((PMD_SHIFT - PAGE_SHIFT) >= MAX_ORDER, | ||
822 | "hugepages can't be allocated by the buddy allocator"); | ||
823 | |||
824 | BUILD_BUG_ON_MSG((PMD_SHIFT - PAGE_SHIFT) < 2, | ||
825 | "We need more than 2 pages to do deferred thp split"); | ||
826 | |||
820 | if (!mmu_has_feature(MMU_FTR_16M_PAGE)) | 827 | if (!mmu_has_feature(MMU_FTR_16M_PAGE)) |
821 | return 0; | 828 | return 0; |
822 | /* | 829 | /* |
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c index 6b2f3e457171..2a049fb8523d 100644 --- a/arch/powerpc/mm/ppc_mmu_32.c +++ b/arch/powerpc/mm/ppc_mmu_32.c | |||
@@ -49,7 +49,7 @@ struct batrange { /* stores address ranges mapped by BATs */ | |||
49 | /* | 49 | /* |
50 | * Return PA for this VA if it is mapped by a BAT, or 0 | 50 | * Return PA for this VA if it is mapped by a BAT, or 0 |
51 | */ | 51 | */ |
52 | phys_addr_t v_mapped_by_bats(unsigned long va) | 52 | phys_addr_t v_block_mapped(unsigned long va) |
53 | { | 53 | { |
54 | int b; | 54 | int b; |
55 | for (b = 0; b < 4; ++b) | 55 | for (b = 0; b < 4; ++b) |
@@ -61,7 +61,7 @@ phys_addr_t v_mapped_by_bats(unsigned long va) | |||
61 | /* | 61 | /* |
62 | * Return VA for a given PA or 0 if not mapped | 62 | * Return VA for a given PA or 0 if not mapped |
63 | */ | 63 | */ |
64 | unsigned long p_mapped_by_bats(phys_addr_t pa) | 64 | unsigned long p_block_mapped(phys_addr_t pa) |
65 | { | 65 | { |
66 | int b; | 66 | int b; |
67 | for (b = 0; b < 4; ++b) | 67 | for (b = 0; b < 4; ++b) |
diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S index 29d6987c37ba..eb82d787d99a 100644 --- a/arch/powerpc/mm/tlb_low_64e.S +++ b/arch/powerpc/mm/tlb_low_64e.S | |||
@@ -895,7 +895,7 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_PAIRED_MAS) | |||
895 | BEGIN_MMU_FTR_SECTION | 895 | BEGIN_MMU_FTR_SECTION |
896 | virt_page_table_tlb_miss_done: | 896 | virt_page_table_tlb_miss_done: |
897 | 897 | ||
898 | /* We have overriden MAS2:EPN but currently our primary TLB miss | 898 | /* We have overridden MAS2:EPN but currently our primary TLB miss |
899 | * handler will always restore it so that should not be an issue, | 899 | * handler will always restore it so that should not be an issue, |
900 | * if we ever optimize the primary handler to not write MAS2 on | 900 | * if we ever optimize the primary handler to not write MAS2 on |
901 | * some cases, we'll have to restore MAS2:EPN here based on the | 901 | * some cases, we'll have to restore MAS2:EPN here based on the |
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index bb04e4df3100..f4668488512c 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c | |||
@@ -640,9 +640,7 @@ static void early_init_this_mmu(void) | |||
640 | * transient mapping would cause problems. | 640 | * transient mapping would cause problems. |
641 | */ | 641 | */ |
642 | #ifdef CONFIG_SMP | 642 | #ifdef CONFIG_SMP |
643 | if (cpu != boot_cpuid && | 643 | if (hweight32(get_tensr()) > 1) |
644 | (cpu != cpu_first_thread_sibling(cpu) || | ||
645 | cpu == cpu_first_thread_sibling(boot_cpuid))) | ||
646 | map = false; | 644 | map = false; |
647 | #endif | 645 | #endif |
648 | 646 | ||
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S index 68c477592e43..eabecfcaef7c 100644 --- a/arch/powerpc/mm/tlb_nohash_low.S +++ b/arch/powerpc/mm/tlb_nohash_low.S | |||
@@ -108,7 +108,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x) | |||
108 | blr | 108 | blr |
109 | 2: | 109 | 2: |
110 | #ifdef CONFIG_PPC_47x | 110 | #ifdef CONFIG_PPC_47x |
111 | oris r7,r6,0x8000 /* specify way explicitely */ | 111 | oris r7,r6,0x8000 /* specify way explicitly */ |
112 | clrrwi r4,r3,12 /* get an EPN for the hashing with V = 0 */ | 112 | clrrwi r4,r3,12 /* get an EPN for the hashing with V = 0 */ |
113 | ori r4,r4,PPC47x_TLBE_SIZE | 113 | ori r4,r4,PPC47x_TLBE_SIZE |
114 | tlbwe r4,r7,0 /* write it */ | 114 | tlbwe r4,r7,0 /* write it */ |
@@ -149,7 +149,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x) | |||
149 | li r3,-1 /* Current set */ | 149 | li r3,-1 /* Current set */ |
150 | lis r10,tlb_47x_boltmap@h | 150 | lis r10,tlb_47x_boltmap@h |
151 | ori r10,r10,tlb_47x_boltmap@l | 151 | ori r10,r10,tlb_47x_boltmap@l |
152 | lis r7,0x8000 /* Specify way explicitely */ | 152 | lis r7,0x8000 /* Specify way explicitly */ |
153 | 153 | ||
154 | b 9f /* For each set */ | 154 | b 9f /* For each set */ |
155 | 155 | ||
diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c index 863d89386f60..c82497a31c54 100644 --- a/arch/powerpc/oprofile/op_model_cell.c +++ b/arch/powerpc/oprofile/op_model_cell.c | |||
@@ -208,7 +208,7 @@ static void pm_rtas_reset_signals(u32 node) | |||
208 | 208 | ||
209 | /* | 209 | /* |
210 | * The debug bus is being set to the passthru disable state. | 210 | * The debug bus is being set to the passthru disable state. |
211 | * However, the FW still expects atleast one legal signal routing | 211 | * However, the FW still expects at least one legal signal routing |
212 | * entry or it will return an error on the arguments. If we don't | 212 | * entry or it will return an error on the arguments. If we don't |
213 | * supply a valid entry, we must ignore all return values. Ignoring | 213 | * supply a valid entry, we must ignore all return values. Ignoring |
214 | * all return values means we might miss an error we should be | 214 | * all return values means we might miss an error we should be |
@@ -1008,7 +1008,7 @@ static int initial_lfsr[] = { | |||
1008 | * | 1008 | * |
1009 | * To avoid the time to compute the LFSR, a lookup table is used. The 24 bit | 1009 | * To avoid the time to compute the LFSR, a lookup table is used. The 24 bit |
1010 | * LFSR sequence is broken into four ranges. The spacing of the precomputed | 1010 | * LFSR sequence is broken into four ranges. The spacing of the precomputed |
1011 | * values is adjusted in each range so the error between the user specifed | 1011 | * values is adjusted in each range so the error between the user specified |
1012 | * number (N) of events between samples and the actual number of events based | 1012 | * number (N) of events between samples and the actual number of events based |
1013 | * on the precomputed value will be les then about 6.2%. Note, if the user | 1013 | * on the precomputed value will be les then about 6.2%. Note, if the user |
1014 | * specifies N < 2^16, the LFSR value that is 2^16 from the end will be used. | 1014 | * specifies N < 2^16, the LFSR value that is 2^16 from the end will be used. |
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index d1e65ce545b3..97a1d40d8696 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c | |||
@@ -651,7 +651,7 @@ static void pmao_restore_workaround(bool ebb) | |||
651 | 651 | ||
652 | /* | 652 | /* |
653 | * We are already soft-disabled in power_pmu_enable(). We need to hard | 653 | * We are already soft-disabled in power_pmu_enable(). We need to hard |
654 | * enable to actually prevent the PMU exception from firing. | 654 | * disable to actually prevent the PMU exception from firing. |
655 | */ | 655 | */ |
656 | hard_irq_disable(); | 656 | hard_irq_disable(); |
657 | 657 | ||
diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 3b09ecfd0aee..2da41b78cb6d 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c | |||
@@ -27,20 +27,6 @@ | |||
27 | #include "hv-24x7-catalog.h" | 27 | #include "hv-24x7-catalog.h" |
28 | #include "hv-common.h" | 28 | #include "hv-common.h" |
29 | 29 | ||
30 | static const char *event_domain_suffix(unsigned domain) | ||
31 | { | ||
32 | switch (domain) { | ||
33 | #define DOMAIN(n, v, x, c) \ | ||
34 | case HV_PERF_DOMAIN_##n: \ | ||
35 | return "__" #n; | ||
36 | #include "hv-24x7-domains.h" | ||
37 | #undef DOMAIN | ||
38 | default: | ||
39 | WARN(1, "unknown domain %d\n", domain); | ||
40 | return "__UNKNOWN_DOMAIN_SUFFIX"; | ||
41 | } | ||
42 | } | ||
43 | |||
44 | static bool domain_is_valid(unsigned domain) | 30 | static bool domain_is_valid(unsigned domain) |
45 | { | 31 | { |
46 | switch (domain) { | 32 | switch (domain) { |
@@ -68,6 +54,24 @@ static bool is_physical_domain(unsigned domain) | |||
68 | } | 54 | } |
69 | } | 55 | } |
70 | 56 | ||
57 | static const char *domain_name(unsigned domain) | ||
58 | { | ||
59 | if (!domain_is_valid(domain)) | ||
60 | return NULL; | ||
61 | |||
62 | switch (domain) { | ||
63 | case HV_PERF_DOMAIN_PHYS_CHIP: return "Physical Chip"; | ||
64 | case HV_PERF_DOMAIN_PHYS_CORE: return "Physical Core"; | ||
65 | case HV_PERF_DOMAIN_VCPU_HOME_CORE: return "VCPU Home Core"; | ||
66 | case HV_PERF_DOMAIN_VCPU_HOME_CHIP: return "VCPU Home Chip"; | ||
67 | case HV_PERF_DOMAIN_VCPU_HOME_NODE: return "VCPU Home Node"; | ||
68 | case HV_PERF_DOMAIN_VCPU_REMOTE_NODE: return "VCPU Remote Node"; | ||
69 | } | ||
70 | |||
71 | WARN_ON_ONCE(domain); | ||
72 | return NULL; | ||
73 | } | ||
74 | |||
71 | static bool catalog_entry_domain_is_valid(unsigned domain) | 75 | static bool catalog_entry_domain_is_valid(unsigned domain) |
72 | { | 76 | { |
73 | return is_physical_domain(domain); | 77 | return is_physical_domain(domain); |
@@ -101,6 +105,7 @@ static bool catalog_entry_domain_is_valid(unsigned domain) | |||
101 | EVENT_DEFINE_RANGE_FORMAT(domain, config, 0, 3); | 105 | EVENT_DEFINE_RANGE_FORMAT(domain, config, 0, 3); |
102 | /* u16 */ | 106 | /* u16 */ |
103 | EVENT_DEFINE_RANGE_FORMAT(core, config, 16, 31); | 107 | EVENT_DEFINE_RANGE_FORMAT(core, config, 16, 31); |
108 | EVENT_DEFINE_RANGE_FORMAT(chip, config, 16, 31); | ||
104 | EVENT_DEFINE_RANGE_FORMAT(vcpu, config, 16, 31); | 109 | EVENT_DEFINE_RANGE_FORMAT(vcpu, config, 16, 31); |
105 | /* u32, see "data_offset" */ | 110 | /* u32, see "data_offset" */ |
106 | EVENT_DEFINE_RANGE_FORMAT(offset, config, 32, 63); | 111 | EVENT_DEFINE_RANGE_FORMAT(offset, config, 32, 63); |
@@ -115,6 +120,7 @@ static struct attribute *format_attrs[] = { | |||
115 | &format_attr_domain.attr, | 120 | &format_attr_domain.attr, |
116 | &format_attr_offset.attr, | 121 | &format_attr_offset.attr, |
117 | &format_attr_core.attr, | 122 | &format_attr_core.attr, |
123 | &format_attr_chip.attr, | ||
118 | &format_attr_vcpu.attr, | 124 | &format_attr_vcpu.attr, |
119 | &format_attr_lpar.attr, | 125 | &format_attr_lpar.attr, |
120 | NULL, | 126 | NULL, |
@@ -274,32 +280,70 @@ static unsigned long h_get_24x7_catalog_page(char page[], | |||
274 | version, index); | 280 | version, index); |
275 | } | 281 | } |
276 | 282 | ||
277 | static unsigned core_domains[] = { | 283 | /* |
278 | HV_PERF_DOMAIN_PHYS_CORE, | 284 | * Each event we find in the catalog, will have a sysfs entry. Format the |
279 | HV_PERF_DOMAIN_VCPU_HOME_CORE, | 285 | * data for this sysfs entry based on the event's domain. |
280 | HV_PERF_DOMAIN_VCPU_HOME_CHIP, | 286 | * |
281 | HV_PERF_DOMAIN_VCPU_HOME_NODE, | 287 | * Events belonging to the Chip domain can only be monitored in that domain. |
282 | HV_PERF_DOMAIN_VCPU_REMOTE_NODE, | 288 | * i.e the domain for these events is a fixed/knwon value. |
283 | }; | 289 | * |
284 | /* chip event data always yeilds a single event, core yeilds multiple */ | 290 | * Events belonging to the Core domain can be monitored either in the physical |
285 | #define MAX_EVENTS_PER_EVENT_DATA ARRAY_SIZE(core_domains) | 291 | * core or in one of the virtual CPU domains. So the domain value for these |
286 | 292 | * events must be specified by the user (i.e is a required parameter). Format | |
293 | * the Core events with 'domain=?' so the perf-tool can error check required | ||
294 | * parameters. | ||
295 | * | ||
296 | * NOTE: For the Core domain events, rather than making domain a required | ||
297 | * parameter we could default it to PHYS_CORE and allowe users to | ||
298 | * override the domain to one of the VCPU domains. | ||
299 | * | ||
300 | * However, this can make the interface a little inconsistent. | ||
301 | * | ||
302 | * If we set domain=2 (PHYS_CHIP) and allow user to override this field | ||
303 | * the user may be tempted to also modify the "offset=x" field in which | ||
304 | * can lead to confusing usage. Consider the HPM_PCYC (offset=0x18) and | ||
305 | * HPM_INST (offset=0x20) events. With: | ||
306 | * | ||
307 | * perf stat -e hv_24x7/HPM_PCYC,offset=0x20/ | ||
308 | * | ||
309 | * we end up monitoring HPM_INST, while the command line has HPM_PCYC. | ||
310 | * | ||
311 | * By not assigning a default value to the domain for the Core events, | ||
312 | * we can have simple guidelines: | ||
313 | * | ||
314 | * - Specifying values for parameters with "=?" is required. | ||
315 | * | ||
316 | * - Specifying (i.e overriding) values for other parameters | ||
317 | * is undefined. | ||
318 | */ | ||
287 | static char *event_fmt(struct hv_24x7_event_data *event, unsigned domain) | 319 | static char *event_fmt(struct hv_24x7_event_data *event, unsigned domain) |
288 | { | 320 | { |
289 | const char *sindex; | 321 | const char *sindex; |
290 | const char *lpar; | 322 | const char *lpar; |
323 | const char *domain_str; | ||
324 | char buf[8]; | ||
291 | 325 | ||
292 | if (is_physical_domain(domain)) { | 326 | switch (domain) { |
327 | case HV_PERF_DOMAIN_PHYS_CHIP: | ||
328 | snprintf(buf, sizeof(buf), "%d", domain); | ||
329 | domain_str = buf; | ||
330 | lpar = "0x0"; | ||
331 | sindex = "chip"; | ||
332 | break; | ||
333 | case HV_PERF_DOMAIN_PHYS_CORE: | ||
334 | domain_str = "?"; | ||
293 | lpar = "0x0"; | 335 | lpar = "0x0"; |
294 | sindex = "core"; | 336 | sindex = "core"; |
295 | } else { | 337 | break; |
338 | default: | ||
339 | domain_str = "?"; | ||
296 | lpar = "?"; | 340 | lpar = "?"; |
297 | sindex = "vcpu"; | 341 | sindex = "vcpu"; |
298 | } | 342 | } |
299 | 343 | ||
300 | return kasprintf(GFP_KERNEL, | 344 | return kasprintf(GFP_KERNEL, |
301 | "domain=0x%x,offset=0x%x,%s=?,lpar=%s", | 345 | "domain=%s,offset=0x%x,%s=?,lpar=%s", |
302 | domain, | 346 | domain_str, |
303 | be16_to_cpu(event->event_counter_offs) + | 347 | be16_to_cpu(event->event_counter_offs) + |
304 | be16_to_cpu(event->event_group_record_offs), | 348 | be16_to_cpu(event->event_group_record_offs), |
305 | sindex, | 349 | sindex, |
@@ -339,6 +383,15 @@ static struct attribute *device_str_attr_create_(char *name, char *str) | |||
339 | return &attr->attr.attr; | 383 | return &attr->attr.attr; |
340 | } | 384 | } |
341 | 385 | ||
386 | /* | ||
387 | * Allocate and initialize strings representing event attributes. | ||
388 | * | ||
389 | * NOTE: The strings allocated here are never destroyed and continue to | ||
390 | * exist till shutdown. This is to allow us to create as many events | ||
391 | * from the catalog as possible, even if we encounter errors with some. | ||
392 | * In case of changes to error paths in future, these may need to be | ||
393 | * freed by the caller. | ||
394 | */ | ||
342 | static struct attribute *device_str_attr_create(char *name, int name_max, | 395 | static struct attribute *device_str_attr_create(char *name, int name_max, |
343 | int name_nonce, | 396 | int name_nonce, |
344 | char *str, size_t str_max) | 397 | char *str, size_t str_max) |
@@ -370,16 +423,6 @@ out_s: | |||
370 | return NULL; | 423 | return NULL; |
371 | } | 424 | } |
372 | 425 | ||
373 | static void device_str_attr_destroy(struct attribute *attr) | ||
374 | { | ||
375 | struct dev_ext_attribute *d; | ||
376 | |||
377 | d = container_of(attr, struct dev_ext_attribute, attr.attr); | ||
378 | kfree(d->var); | ||
379 | kfree(d->attr.attr.name); | ||
380 | kfree(d); | ||
381 | } | ||
382 | |||
383 | static struct attribute *event_to_attr(unsigned ix, | 426 | static struct attribute *event_to_attr(unsigned ix, |
384 | struct hv_24x7_event_data *event, | 427 | struct hv_24x7_event_data *event, |
385 | unsigned domain, | 428 | unsigned domain, |
@@ -387,7 +430,6 @@ static struct attribute *event_to_attr(unsigned ix, | |||
387 | { | 430 | { |
388 | int event_name_len; | 431 | int event_name_len; |
389 | char *ev_name, *a_ev_name, *val; | 432 | char *ev_name, *a_ev_name, *val; |
390 | const char *ev_suffix; | ||
391 | struct attribute *attr; | 433 | struct attribute *attr; |
392 | 434 | ||
393 | if (!domain_is_valid(domain)) { | 435 | if (!domain_is_valid(domain)) { |
@@ -400,14 +442,13 @@ static struct attribute *event_to_attr(unsigned ix, | |||
400 | if (!val) | 442 | if (!val) |
401 | return NULL; | 443 | return NULL; |
402 | 444 | ||
403 | ev_suffix = event_domain_suffix(domain); | ||
404 | ev_name = event_name(event, &event_name_len); | 445 | ev_name = event_name(event, &event_name_len); |
405 | if (!nonce) | 446 | if (!nonce) |
406 | a_ev_name = kasprintf(GFP_KERNEL, "%.*s%s", | 447 | a_ev_name = kasprintf(GFP_KERNEL, "%.*s", |
407 | (int)event_name_len, ev_name, ev_suffix); | 448 | (int)event_name_len, ev_name); |
408 | else | 449 | else |
409 | a_ev_name = kasprintf(GFP_KERNEL, "%.*s%s__%d", | 450 | a_ev_name = kasprintf(GFP_KERNEL, "%.*s__%d", |
410 | (int)event_name_len, ev_name, ev_suffix, nonce); | 451 | (int)event_name_len, ev_name, nonce); |
411 | 452 | ||
412 | if (!a_ev_name) | 453 | if (!a_ev_name) |
413 | goto out_val; | 454 | goto out_val; |
@@ -452,45 +493,14 @@ event_to_long_desc_attr(struct hv_24x7_event_data *event, int nonce) | |||
452 | return device_str_attr_create(name, nl, nonce, desc, dl); | 493 | return device_str_attr_create(name, nl, nonce, desc, dl); |
453 | } | 494 | } |
454 | 495 | ||
455 | static ssize_t event_data_to_attrs(unsigned ix, struct attribute **attrs, | 496 | static int event_data_to_attrs(unsigned ix, struct attribute **attrs, |
456 | struct hv_24x7_event_data *event, int nonce) | 497 | struct hv_24x7_event_data *event, int nonce) |
457 | { | 498 | { |
458 | unsigned i; | 499 | *attrs = event_to_attr(ix, event, event->domain, nonce); |
459 | 500 | if (!*attrs) | |
460 | switch (event->domain) { | ||
461 | case HV_PERF_DOMAIN_PHYS_CHIP: | ||
462 | *attrs = event_to_attr(ix, event, event->domain, nonce); | ||
463 | return 1; | ||
464 | case HV_PERF_DOMAIN_PHYS_CORE: | ||
465 | for (i = 0; i < ARRAY_SIZE(core_domains); i++) { | ||
466 | attrs[i] = event_to_attr(ix, event, core_domains[i], | ||
467 | nonce); | ||
468 | if (!attrs[i]) { | ||
469 | pr_warn("catalog event %u: individual attr %u " | ||
470 | "creation failure\n", ix, i); | ||
471 | for (; i; i--) | ||
472 | device_str_attr_destroy(attrs[i - 1]); | ||
473 | return -1; | ||
474 | } | ||
475 | } | ||
476 | return i; | ||
477 | default: | ||
478 | pr_warn("catalog event %u: domain %u is not allowed in the " | ||
479 | "catalog\n", ix, event->domain); | ||
480 | return -1; | 501 | return -1; |
481 | } | ||
482 | } | ||
483 | 502 | ||
484 | static size_t event_to_attr_ct(struct hv_24x7_event_data *event) | 503 | return 0; |
485 | { | ||
486 | switch (event->domain) { | ||
487 | case HV_PERF_DOMAIN_PHYS_CHIP: | ||
488 | return 1; | ||
489 | case HV_PERF_DOMAIN_PHYS_CORE: | ||
490 | return ARRAY_SIZE(core_domains); | ||
491 | default: | ||
492 | return 0; | ||
493 | } | ||
494 | } | 504 | } |
495 | 505 | ||
496 | /* */ | 506 | /* */ |
@@ -718,9 +728,8 @@ static int create_events_from_catalog(struct attribute ***events_, | |||
718 | goto e_free; | 728 | goto e_free; |
719 | } | 729 | } |
720 | 730 | ||
721 | if (SIZE_MAX / MAX_EVENTS_PER_EVENT_DATA - 1 < event_entry_count) { | 731 | if (SIZE_MAX - 1 < event_entry_count) { |
722 | pr_err("event_entry_count %zu is invalid\n", | 732 | pr_err("event_entry_count %zu is invalid\n", event_entry_count); |
723 | event_entry_count); | ||
724 | ret = -EIO; | 733 | ret = -EIO; |
725 | goto e_free; | 734 | goto e_free; |
726 | } | 735 | } |
@@ -793,7 +802,7 @@ static int create_events_from_catalog(struct attribute ***events_, | |||
793 | continue; | 802 | continue; |
794 | } | 803 | } |
795 | 804 | ||
796 | attr_max += event_to_attr_ct(event); | 805 | attr_max++; |
797 | } | 806 | } |
798 | 807 | ||
799 | event_idx_last = event_idx; | 808 | event_idx_last = event_idx; |
@@ -843,12 +852,12 @@ static int create_events_from_catalog(struct attribute ***events_, | |||
843 | nonce = event_uniq_add(&ev_uniq, name, nl, event->domain); | 852 | nonce = event_uniq_add(&ev_uniq, name, nl, event->domain); |
844 | ct = event_data_to_attrs(event_idx, events + event_attr_ct, | 853 | ct = event_data_to_attrs(event_idx, events + event_attr_ct, |
845 | event, nonce); | 854 | event, nonce); |
846 | if (ct <= 0) { | 855 | if (ct < 0) { |
847 | pr_warn("event %zu (%.*s) creation failure, skipping\n", | 856 | pr_warn("event %zu (%.*s) creation failure, skipping\n", |
848 | event_idx, nl, name); | 857 | event_idx, nl, name); |
849 | junk_events++; | 858 | junk_events++; |
850 | } else { | 859 | } else { |
851 | event_attr_ct += ct; | 860 | event_attr_ct++; |
852 | event_descs[desc_ct] = event_to_desc_attr(event, nonce); | 861 | event_descs[desc_ct] = event_to_desc_attr(event, nonce); |
853 | if (event_descs[desc_ct]) | 862 | if (event_descs[desc_ct]) |
854 | desc_ct++; | 863 | desc_ct++; |
@@ -953,6 +962,27 @@ e_free: | |||
953 | return ret; | 962 | return ret; |
954 | } | 963 | } |
955 | 964 | ||
965 | static ssize_t domains_show(struct device *dev, struct device_attribute *attr, | ||
966 | char *page) | ||
967 | { | ||
968 | int d, n, count = 0; | ||
969 | const char *str; | ||
970 | |||
971 | for (d = 0; d < HV_PERF_DOMAIN_MAX; d++) { | ||
972 | str = domain_name(d); | ||
973 | if (!str) | ||
974 | continue; | ||
975 | |||
976 | n = sprintf(page, "%d: %s\n", d, str); | ||
977 | if (n < 0) | ||
978 | break; | ||
979 | |||
980 | count += n; | ||
981 | page += n; | ||
982 | } | ||
983 | return count; | ||
984 | } | ||
985 | |||
956 | #define PAGE_0_ATTR(_name, _fmt, _expr) \ | 986 | #define PAGE_0_ATTR(_name, _fmt, _expr) \ |
957 | static ssize_t _name##_show(struct device *dev, \ | 987 | static ssize_t _name##_show(struct device *dev, \ |
958 | struct device_attribute *dev_attr, \ | 988 | struct device_attribute *dev_attr, \ |
@@ -981,6 +1011,7 @@ PAGE_0_ATTR(catalog_version, "%lld\n", | |||
981 | PAGE_0_ATTR(catalog_len, "%lld\n", | 1011 | PAGE_0_ATTR(catalog_len, "%lld\n", |
982 | (unsigned long long)be32_to_cpu(page_0->length) * 4096); | 1012 | (unsigned long long)be32_to_cpu(page_0->length) * 4096); |
983 | static BIN_ATTR_RO(catalog, 0/* real length varies */); | 1013 | static BIN_ATTR_RO(catalog, 0/* real length varies */); |
1014 | static DEVICE_ATTR_RO(domains); | ||
984 | 1015 | ||
985 | static struct bin_attribute *if_bin_attrs[] = { | 1016 | static struct bin_attribute *if_bin_attrs[] = { |
986 | &bin_attr_catalog, | 1017 | &bin_attr_catalog, |
@@ -990,6 +1021,7 @@ static struct bin_attribute *if_bin_attrs[] = { | |||
990 | static struct attribute *if_attrs[] = { | 1021 | static struct attribute *if_attrs[] = { |
991 | &dev_attr_catalog_len.attr, | 1022 | &dev_attr_catalog_len.attr, |
992 | &dev_attr_catalog_version.attr, | 1023 | &dev_attr_catalog_version.attr, |
1024 | &dev_attr_domains.attr, | ||
993 | NULL, | 1025 | NULL, |
994 | }; | 1026 | }; |
995 | 1027 | ||
@@ -1081,10 +1113,16 @@ static int add_event_to_24x7_request(struct perf_event *event, | |||
1081 | return -EINVAL; | 1113 | return -EINVAL; |
1082 | } | 1114 | } |
1083 | 1115 | ||
1084 | if (is_physical_domain(event_get_domain(event))) | 1116 | switch (event_get_domain(event)) { |
1117 | case HV_PERF_DOMAIN_PHYS_CHIP: | ||
1118 | idx = event_get_chip(event); | ||
1119 | break; | ||
1120 | case HV_PERF_DOMAIN_PHYS_CORE: | ||
1085 | idx = event_get_core(event); | 1121 | idx = event_get_core(event); |
1086 | else | 1122 | break; |
1123 | default: | ||
1087 | idx = event_get_vcpu(event); | 1124 | idx = event_get_vcpu(event); |
1125 | } | ||
1088 | 1126 | ||
1089 | i = request_buffer->num_requests++; | 1127 | i = request_buffer->num_requests++; |
1090 | req = &request_buffer->requests[i]; | 1128 | req = &request_buffer->requests[i]; |
@@ -1200,11 +1238,12 @@ static int h_24x7_event_init(struct perf_event *event) | |||
1200 | return -EACCES; | 1238 | return -EACCES; |
1201 | } | 1239 | } |
1202 | 1240 | ||
1203 | /* see if the event complains */ | 1241 | /* Get the initial value of the counter for this event */ |
1204 | if (single_24x7_request(event, &ct)) { | 1242 | if (single_24x7_request(event, &ct)) { |
1205 | pr_devel("test hcall failed\n"); | 1243 | pr_devel("test hcall failed\n"); |
1206 | return -EIO; | 1244 | return -EIO; |
1207 | } | 1245 | } |
1246 | (void)local64_xchg(&event->hw.prev_count, ct); | ||
1208 | 1247 | ||
1209 | return 0; | 1248 | return 0; |
1210 | } | 1249 | } |
@@ -1267,6 +1306,16 @@ static void h_24x7_event_read(struct perf_event *event) | |||
1267 | h24x7hw = &get_cpu_var(hv_24x7_hw); | 1306 | h24x7hw = &get_cpu_var(hv_24x7_hw); |
1268 | h24x7hw->events[i] = event; | 1307 | h24x7hw->events[i] = event; |
1269 | put_cpu_var(h24x7hw); | 1308 | put_cpu_var(h24x7hw); |
1309 | /* | ||
1310 | * Clear the event count so we can compute the _change_ | ||
1311 | * in the 24x7 raw counter value at the end of the txn. | ||
1312 | * | ||
1313 | * Note that we could alternatively read the 24x7 value | ||
1314 | * now and save its value in event->hw.prev_count. But | ||
1315 | * that would require issuing a hcall, which would then | ||
1316 | * defeat the purpose of using the txn interface. | ||
1317 | */ | ||
1318 | local64_set(&event->count, 0); | ||
1270 | } | 1319 | } |
1271 | 1320 | ||
1272 | put_cpu_var(hv_24x7_reqb); | 1321 | put_cpu_var(hv_24x7_reqb); |
diff --git a/arch/powerpc/perf/hv-24x7.h b/arch/powerpc/perf/hv-24x7.h index 0f9fa21a29f2..791455e7f5cf 100644 --- a/arch/powerpc/perf/hv-24x7.h +++ b/arch/powerpc/perf/hv-24x7.h | |||
@@ -7,6 +7,7 @@ enum hv_perf_domains { | |||
7 | #define DOMAIN(n, v, x, c) HV_PERF_DOMAIN_##n = v, | 7 | #define DOMAIN(n, v, x, c) HV_PERF_DOMAIN_##n = v, |
8 | #include "hv-24x7-domains.h" | 8 | #include "hv-24x7-domains.h" |
9 | #undef DOMAIN | 9 | #undef DOMAIN |
10 | HV_PERF_DOMAIN_MAX, | ||
10 | }; | 11 | }; |
11 | 12 | ||
12 | struct hv_24x7_request { | 13 | struct hv_24x7_request { |
@@ -80,7 +81,7 @@ struct hv_24x7_result { | |||
80 | __u8 results_complete; | 81 | __u8 results_complete; |
81 | __be16 num_elements_returned; | 82 | __be16 num_elements_returned; |
82 | 83 | ||
83 | /* This is a copy of @data_size from the coresponding hv_24x7_request */ | 84 | /* This is a copy of @data_size from the corresponding hv_24x7_request */ |
84 | __be16 result_element_data_size; | 85 | __be16 result_element_data_size; |
85 | __u8 reserved[0x2]; | 86 | __u8 reserved[0x2]; |
86 | 87 | ||
diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c index 856fe6e03c2a..7aa37236bb70 100644 --- a/arch/powerpc/perf/hv-gpci.c +++ b/arch/powerpc/perf/hv-gpci.c | |||
@@ -127,8 +127,16 @@ static const struct attribute_group *attr_groups[] = { | |||
127 | NULL, | 127 | NULL, |
128 | }; | 128 | }; |
129 | 129 | ||
130 | #define GPCI_MAX_DATA_BYTES \ | 130 | #define HGPCI_REQ_BUFFER_SIZE 4096 |
131 | (1024 - sizeof(struct hv_get_perf_counter_info_params)) | 131 | #define HGPCI_MAX_DATA_BYTES \ |
132 | (HGPCI_REQ_BUFFER_SIZE - sizeof(struct hv_get_perf_counter_info_params)) | ||
133 | |||
134 | DEFINE_PER_CPU(char, hv_gpci_reqb[HGPCI_REQ_BUFFER_SIZE]) __aligned(sizeof(uint64_t)); | ||
135 | |||
136 | struct hv_gpci_request_buffer { | ||
137 | struct hv_get_perf_counter_info_params params; | ||
138 | uint8_t bytes[HGPCI_MAX_DATA_BYTES]; | ||
139 | } __packed; | ||
132 | 140 | ||
133 | static unsigned long single_gpci_request(u32 req, u32 starting_index, | 141 | static unsigned long single_gpci_request(u32 req, u32 starting_index, |
134 | u16 secondary_index, u8 version_in, u32 offset, u8 length, | 142 | u16 secondary_index, u8 version_in, u32 offset, u8 length, |
@@ -137,24 +145,21 @@ static unsigned long single_gpci_request(u32 req, u32 starting_index, | |||
137 | unsigned long ret; | 145 | unsigned long ret; |
138 | size_t i; | 146 | size_t i; |
139 | u64 count; | 147 | u64 count; |
148 | struct hv_gpci_request_buffer *arg; | ||
149 | |||
150 | arg = (void *)get_cpu_var(hv_gpci_reqb); | ||
151 | memset(arg, 0, HGPCI_REQ_BUFFER_SIZE); | ||
140 | 152 | ||
141 | struct { | 153 | arg->params.counter_request = cpu_to_be32(req); |
142 | struct hv_get_perf_counter_info_params params; | 154 | arg->params.starting_index = cpu_to_be32(starting_index); |
143 | uint8_t bytes[GPCI_MAX_DATA_BYTES]; | 155 | arg->params.secondary_index = cpu_to_be16(secondary_index); |
144 | } __packed __aligned(sizeof(uint64_t)) arg = { | 156 | arg->params.counter_info_version_in = version_in; |
145 | .params = { | ||
146 | .counter_request = cpu_to_be32(req), | ||
147 | .starting_index = cpu_to_be32(starting_index), | ||
148 | .secondary_index = cpu_to_be16(secondary_index), | ||
149 | .counter_info_version_in = version_in, | ||
150 | } | ||
151 | }; | ||
152 | 157 | ||
153 | ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO, | 158 | ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO, |
154 | virt_to_phys(&arg), sizeof(arg)); | 159 | virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE); |
155 | if (ret) { | 160 | if (ret) { |
156 | pr_devel("hcall failed: 0x%lx\n", ret); | 161 | pr_devel("hcall failed: 0x%lx\n", ret); |
157 | return ret; | 162 | goto out; |
158 | } | 163 | } |
159 | 164 | ||
160 | /* | 165 | /* |
@@ -163,9 +168,11 @@ static unsigned long single_gpci_request(u32 req, u32 starting_index, | |||
163 | */ | 168 | */ |
164 | count = 0; | 169 | count = 0; |
165 | for (i = offset; i < offset + length; i++) | 170 | for (i = offset; i < offset + length; i++) |
166 | count |= arg.bytes[i] << (i - offset); | 171 | count |= arg->bytes[i] << (i - offset); |
167 | 172 | ||
168 | *value = count; | 173 | *value = count; |
174 | out: | ||
175 | put_cpu_var(hv_gpci_reqb); | ||
169 | return ret; | 176 | return ret; |
170 | } | 177 | } |
171 | 178 | ||
@@ -245,10 +252,10 @@ static int h_gpci_event_init(struct perf_event *event) | |||
245 | } | 252 | } |
246 | 253 | ||
247 | /* last byte within the buffer? */ | 254 | /* last byte within the buffer? */ |
248 | if ((event_get_offset(event) + length) > GPCI_MAX_DATA_BYTES) { | 255 | if ((event_get_offset(event) + length) > HGPCI_MAX_DATA_BYTES) { |
249 | pr_devel("request outside of buffer: %zu > %zu\n", | 256 | pr_devel("request outside of buffer: %zu > %zu\n", |
250 | (size_t)event_get_offset(event) + length, | 257 | (size_t)event_get_offset(event) + length, |
251 | GPCI_MAX_DATA_BYTES); | 258 | HGPCI_MAX_DATA_BYTES); |
252 | return -EINVAL; | 259 | return -EINVAL; |
253 | } | 260 | } |
254 | 261 | ||
diff --git a/arch/powerpc/perf/power7-pmu.c b/arch/powerpc/perf/power7-pmu.c index 5b62f2389290..a383c23a9070 100644 --- a/arch/powerpc/perf/power7-pmu.c +++ b/arch/powerpc/perf/power7-pmu.c | |||
@@ -54,7 +54,7 @@ | |||
54 | * Power7 event codes. | 54 | * Power7 event codes. |
55 | */ | 55 | */ |
56 | #define EVENT(_name, _code) \ | 56 | #define EVENT(_name, _code) \ |
57 | PME_##_name = _code, | 57 | _name = _code, |
58 | 58 | ||
59 | enum { | 59 | enum { |
60 | #include "power7-events-list.h" | 60 | #include "power7-events-list.h" |
@@ -318,14 +318,14 @@ static void power7_disable_pmc(unsigned int pmc, unsigned long mmcr[]) | |||
318 | } | 318 | } |
319 | 319 | ||
320 | static int power7_generic_events[] = { | 320 | static int power7_generic_events[] = { |
321 | [PERF_COUNT_HW_CPU_CYCLES] = PME_PM_CYC, | 321 | [PERF_COUNT_HW_CPU_CYCLES] = PM_CYC, |
322 | [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = PME_PM_GCT_NOSLOT_CYC, | 322 | [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = PM_GCT_NOSLOT_CYC, |
323 | [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = PME_PM_CMPLU_STALL, | 323 | [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = PM_CMPLU_STALL, |
324 | [PERF_COUNT_HW_INSTRUCTIONS] = PME_PM_INST_CMPL, | 324 | [PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL, |
325 | [PERF_COUNT_HW_CACHE_REFERENCES] = PME_PM_LD_REF_L1, | 325 | [PERF_COUNT_HW_CACHE_REFERENCES] = PM_LD_REF_L1, |
326 | [PERF_COUNT_HW_CACHE_MISSES] = PME_PM_LD_MISS_L1, | 326 | [PERF_COUNT_HW_CACHE_MISSES] = PM_LD_MISS_L1, |
327 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PME_PM_BRU_FIN, | 327 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BRU_FIN, |
328 | [PERF_COUNT_HW_BRANCH_MISSES] = PME_PM_BR_MPRED, | 328 | [PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED, |
329 | }; | 329 | }; |
330 | 330 | ||
331 | #define C(x) PERF_COUNT_HW_CACHE_##x | 331 | #define C(x) PERF_COUNT_HW_CACHE_##x |
diff --git a/arch/powerpc/perf/power8-events-list.h b/arch/powerpc/perf/power8-events-list.h new file mode 100644 index 000000000000..741b77edd03e --- /dev/null +++ b/arch/powerpc/perf/power8-events-list.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | * Performance counter support for POWER8 processors. | ||
3 | * | ||
4 | * Copyright 2014 Sukadev Bhattiprolu, 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 | |||
12 | /* | ||
13 | * Power8 event codes. | ||
14 | */ | ||
15 | EVENT(PM_CYC, 0x0001e) | ||
16 | EVENT(PM_GCT_NOSLOT_CYC, 0x100f8) | ||
17 | EVENT(PM_CMPLU_STALL, 0x4000a) | ||
18 | EVENT(PM_INST_CMPL, 0x00002) | ||
19 | EVENT(PM_BRU_FIN, 0x10068) | ||
20 | EVENT(PM_BR_MPRED_CMPL, 0x400f6) | ||
21 | |||
22 | /* All L1 D cache load references counted at finish, gated by reject */ | ||
23 | EVENT(PM_LD_REF_L1, 0x100ee) | ||
24 | /* Load Missed L1 */ | ||
25 | EVENT(PM_LD_MISS_L1, 0x3e054) | ||
26 | /* Store Missed L1 */ | ||
27 | EVENT(PM_ST_MISS_L1, 0x300f0) | ||
28 | /* L1 cache data prefetches */ | ||
29 | EVENT(PM_L1_PREF, 0x0d8b8) | ||
30 | /* Instruction fetches from L1 */ | ||
31 | EVENT(PM_INST_FROM_L1, 0x04080) | ||
32 | /* Demand iCache Miss */ | ||
33 | EVENT(PM_L1_ICACHE_MISS, 0x200fd) | ||
34 | /* Instruction Demand sectors wriittent into IL1 */ | ||
35 | EVENT(PM_L1_DEMAND_WRITE, 0x0408c) | ||
36 | /* Instruction prefetch written into IL1 */ | ||
37 | EVENT(PM_IC_PREF_WRITE, 0x0408e) | ||
38 | /* The data cache was reloaded from local core's L3 due to a demand load */ | ||
39 | EVENT(PM_DATA_FROM_L3, 0x4c042) | ||
40 | /* Demand LD - L3 Miss (not L2 hit and not L3 hit) */ | ||
41 | EVENT(PM_DATA_FROM_L3MISS, 0x300fe) | ||
42 | /* All successful D-side store dispatches for this thread */ | ||
43 | EVENT(PM_L2_ST, 0x17080) | ||
44 | /* All successful D-side store dispatches for this thread that were L2 Miss */ | ||
45 | EVENT(PM_L2_ST_MISS, 0x17082) | ||
46 | /* Total HW L3 prefetches(Load+store) */ | ||
47 | EVENT(PM_L3_PREF_ALL, 0x4e052) | ||
48 | /* Data PTEG reload */ | ||
49 | EVENT(PM_DTLB_MISS, 0x300fc) | ||
50 | /* ITLB Reloaded */ | ||
51 | EVENT(PM_ITLB_MISS, 0x400fc) | ||
diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c index 9958ba8bf0d2..690d9186a855 100644 --- a/arch/powerpc/perf/power8-pmu.c +++ b/arch/powerpc/perf/power8-pmu.c | |||
@@ -17,48 +17,16 @@ | |||
17 | #include <asm/firmware.h> | 17 | #include <asm/firmware.h> |
18 | #include <asm/cputable.h> | 18 | #include <asm/cputable.h> |
19 | 19 | ||
20 | |||
21 | /* | 20 | /* |
22 | * Some power8 event codes. | 21 | * Some power8 event codes. |
23 | */ | 22 | */ |
24 | #define PM_CYC 0x0001e | 23 | #define EVENT(_name, _code) _name = _code, |
25 | #define PM_GCT_NOSLOT_CYC 0x100f8 | 24 | |
26 | #define PM_CMPLU_STALL 0x4000a | 25 | enum { |
27 | #define PM_INST_CMPL 0x00002 | 26 | #include "power8-events-list.h" |
28 | #define PM_BRU_FIN 0x10068 | 27 | }; |
29 | #define PM_BR_MPRED_CMPL 0x400f6 | ||
30 | |||
31 | /* All L1 D cache load references counted at finish, gated by reject */ | ||
32 | #define PM_LD_REF_L1 0x100ee | ||
33 | /* Load Missed L1 */ | ||
34 | #define PM_LD_MISS_L1 0x3e054 | ||
35 | /* Store Missed L1 */ | ||
36 | #define PM_ST_MISS_L1 0x300f0 | ||
37 | /* L1 cache data prefetches */ | ||
38 | #define PM_L1_PREF 0x0d8b8 | ||
39 | /* Instruction fetches from L1 */ | ||
40 | #define PM_INST_FROM_L1 0x04080 | ||
41 | /* Demand iCache Miss */ | ||
42 | #define PM_L1_ICACHE_MISS 0x200fd | ||
43 | /* Instruction Demand sectors wriittent into IL1 */ | ||
44 | #define PM_L1_DEMAND_WRITE 0x0408c | ||
45 | /* Instruction prefetch written into IL1 */ | ||
46 | #define PM_IC_PREF_WRITE 0x0408e | ||
47 | /* The data cache was reloaded from local core's L3 due to a demand load */ | ||
48 | #define PM_DATA_FROM_L3 0x4c042 | ||
49 | /* Demand LD - L3 Miss (not L2 hit and not L3 hit) */ | ||
50 | #define PM_DATA_FROM_L3MISS 0x300fe | ||
51 | /* All successful D-side store dispatches for this thread */ | ||
52 | #define PM_L2_ST 0x17080 | ||
53 | /* All successful D-side store dispatches for this thread that were L2 Miss */ | ||
54 | #define PM_L2_ST_MISS 0x17082 | ||
55 | /* Total HW L3 prefetches(Load+store) */ | ||
56 | #define PM_L3_PREF_ALL 0x4e052 | ||
57 | /* Data PTEG reload */ | ||
58 | #define PM_DTLB_MISS 0x300fc | ||
59 | /* ITLB Reloaded */ | ||
60 | #define PM_ITLB_MISS 0x400fc | ||
61 | 28 | ||
29 | #undef EVENT | ||
62 | 30 | ||
63 | /* | 31 | /* |
64 | * Raw event encoding for POWER8: | 32 | * Raw event encoding for POWER8: |
@@ -415,7 +383,7 @@ static int power8_compute_mmcr(u64 event[], int n_ev, | |||
415 | pmc_inuse |= 1 << pmc; | 383 | pmc_inuse |= 1 << pmc; |
416 | } | 384 | } |
417 | 385 | ||
418 | /* In continous sampling mode, update SDAR on TLB miss */ | 386 | /* In continuous sampling mode, update SDAR on TLB miss */ |
419 | mmcra = MMCRA_SDAR_MODE_TLB; | 387 | mmcra = MMCRA_SDAR_MODE_TLB; |
420 | mmcr1 = mmcr2 = 0; | 388 | mmcr1 = mmcr2 = 0; |
421 | 389 | ||
@@ -604,6 +572,71 @@ static void power8_disable_pmc(unsigned int pmc, unsigned long mmcr[]) | |||
604 | mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SHIFT(pmc + 1)); | 572 | mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SHIFT(pmc + 1)); |
605 | } | 573 | } |
606 | 574 | ||
575 | GENERIC_EVENT_ATTR(cpu-cycles, PM_CYC); | ||
576 | GENERIC_EVENT_ATTR(stalled-cycles-frontend, PM_GCT_NOSLOT_CYC); | ||
577 | GENERIC_EVENT_ATTR(stalled-cycles-backend, PM_CMPLU_STALL); | ||
578 | GENERIC_EVENT_ATTR(instructions, PM_INST_CMPL); | ||
579 | GENERIC_EVENT_ATTR(branch-instructions, PM_BRU_FIN); | ||
580 | GENERIC_EVENT_ATTR(branch-misses, PM_BR_MPRED_CMPL); | ||
581 | GENERIC_EVENT_ATTR(cache-references, PM_LD_REF_L1); | ||
582 | GENERIC_EVENT_ATTR(cache-misses, PM_LD_MISS_L1); | ||
583 | |||
584 | CACHE_EVENT_ATTR(L1-dcache-load-misses, PM_LD_MISS_L1); | ||
585 | CACHE_EVENT_ATTR(L1-dcache-loads, PM_LD_REF_L1); | ||
586 | |||
587 | CACHE_EVENT_ATTR(L1-dcache-prefetches, PM_L1_PREF); | ||
588 | CACHE_EVENT_ATTR(L1-dcache-store-misses, PM_ST_MISS_L1); | ||
589 | CACHE_EVENT_ATTR(L1-icache-load-misses, PM_L1_ICACHE_MISS); | ||
590 | CACHE_EVENT_ATTR(L1-icache-loads, PM_INST_FROM_L1); | ||
591 | CACHE_EVENT_ATTR(L1-icache-prefetches, PM_IC_PREF_WRITE); | ||
592 | |||
593 | CACHE_EVENT_ATTR(LLC-load-misses, PM_DATA_FROM_L3MISS); | ||
594 | CACHE_EVENT_ATTR(LLC-loads, PM_DATA_FROM_L3); | ||
595 | CACHE_EVENT_ATTR(LLC-prefetches, PM_L3_PREF_ALL); | ||
596 | CACHE_EVENT_ATTR(LLC-store-misses, PM_L2_ST_MISS); | ||
597 | CACHE_EVENT_ATTR(LLC-stores, PM_L2_ST); | ||
598 | |||
599 | CACHE_EVENT_ATTR(branch-load-misses, PM_BR_MPRED_CMPL); | ||
600 | CACHE_EVENT_ATTR(branch-loads, PM_BRU_FIN); | ||
601 | CACHE_EVENT_ATTR(dTLB-load-misses, PM_DTLB_MISS); | ||
602 | CACHE_EVENT_ATTR(iTLB-load-misses, PM_ITLB_MISS); | ||
603 | |||
604 | static struct attribute *power8_events_attr[] = { | ||
605 | GENERIC_EVENT_PTR(PM_CYC), | ||
606 | GENERIC_EVENT_PTR(PM_GCT_NOSLOT_CYC), | ||
607 | GENERIC_EVENT_PTR(PM_CMPLU_STALL), | ||
608 | GENERIC_EVENT_PTR(PM_INST_CMPL), | ||
609 | GENERIC_EVENT_PTR(PM_BRU_FIN), | ||
610 | GENERIC_EVENT_PTR(PM_BR_MPRED_CMPL), | ||
611 | GENERIC_EVENT_PTR(PM_LD_REF_L1), | ||
612 | GENERIC_EVENT_PTR(PM_LD_MISS_L1), | ||
613 | |||
614 | CACHE_EVENT_PTR(PM_LD_MISS_L1), | ||
615 | CACHE_EVENT_PTR(PM_LD_REF_L1), | ||
616 | CACHE_EVENT_PTR(PM_L1_PREF), | ||
617 | CACHE_EVENT_PTR(PM_ST_MISS_L1), | ||
618 | CACHE_EVENT_PTR(PM_L1_ICACHE_MISS), | ||
619 | CACHE_EVENT_PTR(PM_INST_FROM_L1), | ||
620 | CACHE_EVENT_PTR(PM_IC_PREF_WRITE), | ||
621 | CACHE_EVENT_PTR(PM_DATA_FROM_L3MISS), | ||
622 | CACHE_EVENT_PTR(PM_DATA_FROM_L3), | ||
623 | CACHE_EVENT_PTR(PM_L3_PREF_ALL), | ||
624 | CACHE_EVENT_PTR(PM_L2_ST_MISS), | ||
625 | CACHE_EVENT_PTR(PM_L2_ST), | ||
626 | |||
627 | CACHE_EVENT_PTR(PM_BR_MPRED_CMPL), | ||
628 | CACHE_EVENT_PTR(PM_BRU_FIN), | ||
629 | |||
630 | CACHE_EVENT_PTR(PM_DTLB_MISS), | ||
631 | CACHE_EVENT_PTR(PM_ITLB_MISS), | ||
632 | NULL | ||
633 | }; | ||
634 | |||
635 | static struct attribute_group power8_pmu_events_group = { | ||
636 | .name = "events", | ||
637 | .attrs = power8_events_attr, | ||
638 | }; | ||
639 | |||
607 | PMU_FORMAT_ATTR(event, "config:0-49"); | 640 | PMU_FORMAT_ATTR(event, "config:0-49"); |
608 | PMU_FORMAT_ATTR(pmcxsel, "config:0-7"); | 641 | PMU_FORMAT_ATTR(pmcxsel, "config:0-7"); |
609 | PMU_FORMAT_ATTR(mark, "config:8"); | 642 | PMU_FORMAT_ATTR(mark, "config:8"); |
@@ -640,6 +673,7 @@ struct attribute_group power8_pmu_format_group = { | |||
640 | 673 | ||
641 | static const struct attribute_group *power8_pmu_attr_groups[] = { | 674 | static const struct attribute_group *power8_pmu_attr_groups[] = { |
642 | &power8_pmu_format_group, | 675 | &power8_pmu_format_group, |
676 | &power8_pmu_events_group, | ||
643 | NULL, | 677 | NULL, |
644 | }; | 678 | }; |
645 | 679 | ||
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c index 6eb3b2abae90..00282c2b0cae 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c | |||
@@ -319,7 +319,7 @@ mpc52xx_pci_setup(struct pci_controller *hose, | |||
319 | 319 | ||
320 | tmp = in_be32(&pci_regs->gscr); | 320 | tmp = in_be32(&pci_regs->gscr); |
321 | #if 0 | 321 | #if 0 |
322 | /* Reset the exteral bus ( internal PCI controller is NOT resetted ) */ | 322 | /* Reset the exteral bus ( internal PCI controller is NOT reset ) */ |
323 | /* Not necessary and can be a bad thing if for example the bootloader | 323 | /* Not necessary and can be a bad thing if for example the bootloader |
324 | is displaying a splash screen or ... Just left here for | 324 | is displaying a splash screen or ... Just left here for |
325 | documentation purpose if anyone need it */ | 325 | documentation purpose if anyone need it */ |
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index 97915feffd42..e626461a63bd 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig | |||
@@ -8,6 +8,7 @@ menuconfig FSL_SOC_BOOKE | |||
8 | select FSL_PCI if PCI | 8 | select FSL_PCI if PCI |
9 | select SERIAL_8250_EXTENDED if SERIAL_8250 | 9 | select SERIAL_8250_EXTENDED if SERIAL_8250 |
10 | select SERIAL_8250_SHARE_IRQ if SERIAL_8250 | 10 | select SERIAL_8250_SHARE_IRQ if SERIAL_8250 |
11 | select FSL_CORENET_RCPM if PPC_E500MC | ||
11 | default y | 12 | default y |
12 | 13 | ||
13 | if FSL_SOC_BOOKE | 14 | if FSL_SOC_BOOKE |
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 1fe7fb95175a..7bc86dae9517 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile | |||
@@ -2,6 +2,7 @@ | |||
2 | # Makefile for the PowerPC 85xx linux kernel. | 2 | # Makefile for the PowerPC 85xx linux kernel. |
3 | # | 3 | # |
4 | obj-$(CONFIG_SMP) += smp.o | 4 | obj-$(CONFIG_SMP) += smp.o |
5 | obj-$(CONFIG_FSL_PMC) += mpc85xx_pm_ops.o | ||
5 | 6 | ||
6 | obj-y += common.o | 7 | obj-y += common.o |
7 | 8 | ||
diff --git a/arch/powerpc/platforms/85xx/common.c b/arch/powerpc/platforms/85xx/common.c index 949f22c86e61..28720a4ded7b 100644 --- a/arch/powerpc/platforms/85xx/common.c +++ b/arch/powerpc/platforms/85xx/common.c | |||
@@ -9,11 +9,14 @@ | |||
9 | #include <linux/of_irq.h> | 9 | #include <linux/of_irq.h> |
10 | #include <linux/of_platform.h> | 10 | #include <linux/of_platform.h> |
11 | 11 | ||
12 | #include <asm/fsl_pm.h> | ||
12 | #include <soc/fsl/qe/qe.h> | 13 | #include <soc/fsl/qe/qe.h> |
13 | #include <sysdev/cpm2_pic.h> | 14 | #include <sysdev/cpm2_pic.h> |
14 | 15 | ||
15 | #include "mpc85xx.h" | 16 | #include "mpc85xx.h" |
16 | 17 | ||
18 | const struct fsl_pm_ops *qoriq_pm_ops; | ||
19 | |||
17 | static const struct of_device_id mpc85xx_common_ids[] __initconst = { | 20 | static const struct of_device_id mpc85xx_common_ids[] __initconst = { |
18 | { .type = "soc", }, | 21 | { .type = "soc", }, |
19 | { .compatible = "soc", }, | 22 | { .compatible = "soc", }, |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 5ac70de3e48a..d7e87ff912d7 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c | |||
@@ -99,7 +99,7 @@ static void mpc85xx_cds_restart(char *cmd) | |||
99 | pci_read_config_byte(dev, 0x47, &tmp); | 99 | pci_read_config_byte(dev, 0x47, &tmp); |
100 | 100 | ||
101 | /* | 101 | /* |
102 | * At this point, the harware reset should have triggered. | 102 | * At this point, the hardware reset should have triggered. |
103 | * However, if it doesn't work for some mysterious reason, | 103 | * However, if it doesn't work for some mysterious reason, |
104 | * just fall through to the default reset below. | 104 | * just fall through to the default reset below. |
105 | */ | 105 | */ |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c new file mode 100644 index 000000000000..f05325f0cc03 --- /dev/null +++ b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c | |||
@@ -0,0 +1,106 @@ | |||
1 | /* | ||
2 | * MPC85xx PM operators | ||
3 | * | ||
4 | * Copyright 2015 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #define pr_fmt(fmt) "%s: " fmt, __func__ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/of_address.h> | ||
17 | #include <linux/fsl/guts.h> | ||
18 | |||
19 | #include <asm/io.h> | ||
20 | #include <asm/fsl_pm.h> | ||
21 | |||
22 | static struct ccsr_guts __iomem *guts; | ||
23 | |||
24 | static void mpc85xx_irq_mask(int cpu) | ||
25 | { | ||
26 | |||
27 | } | ||
28 | |||
29 | static void mpc85xx_irq_unmask(int cpu) | ||
30 | { | ||
31 | |||
32 | } | ||
33 | |||
34 | static void mpc85xx_cpu_die(int cpu) | ||
35 | { | ||
36 | u32 tmp; | ||
37 | |||
38 | tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP; | ||
39 | mtspr(SPRN_HID0, tmp); | ||
40 | |||
41 | /* Enter NAP mode. */ | ||
42 | tmp = mfmsr(); | ||
43 | tmp |= MSR_WE; | ||
44 | asm volatile( | ||
45 | "msync\n" | ||
46 | "mtmsr %0\n" | ||
47 | "isync\n" | ||
48 | : | ||
49 | : "r" (tmp)); | ||
50 | } | ||
51 | |||
52 | static void mpc85xx_cpu_up_prepare(int cpu) | ||
53 | { | ||
54 | |||
55 | } | ||
56 | |||
57 | static void mpc85xx_freeze_time_base(bool freeze) | ||
58 | { | ||
59 | uint32_t mask; | ||
60 | |||
61 | mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1; | ||
62 | if (freeze) | ||
63 | setbits32(&guts->devdisr, mask); | ||
64 | else | ||
65 | clrbits32(&guts->devdisr, mask); | ||
66 | |||
67 | in_be32(&guts->devdisr); | ||
68 | } | ||
69 | |||
70 | static const struct of_device_id mpc85xx_smp_guts_ids[] = { | ||
71 | { .compatible = "fsl,mpc8572-guts", }, | ||
72 | { .compatible = "fsl,p1020-guts", }, | ||
73 | { .compatible = "fsl,p1021-guts", }, | ||
74 | { .compatible = "fsl,p1022-guts", }, | ||
75 | { .compatible = "fsl,p1023-guts", }, | ||
76 | { .compatible = "fsl,p2020-guts", }, | ||
77 | { .compatible = "fsl,bsc9132-guts", }, | ||
78 | {}, | ||
79 | }; | ||
80 | |||
81 | static const struct fsl_pm_ops mpc85xx_pm_ops = { | ||
82 | .freeze_time_base = mpc85xx_freeze_time_base, | ||
83 | .irq_mask = mpc85xx_irq_mask, | ||
84 | .irq_unmask = mpc85xx_irq_unmask, | ||
85 | .cpu_die = mpc85xx_cpu_die, | ||
86 | .cpu_up_prepare = mpc85xx_cpu_up_prepare, | ||
87 | }; | ||
88 | |||
89 | int __init mpc85xx_setup_pmc(void) | ||
90 | { | ||
91 | struct device_node *np; | ||
92 | |||
93 | np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); | ||
94 | if (np) { | ||
95 | guts = of_iomap(np, 0); | ||
96 | of_node_put(np); | ||
97 | if (!guts) { | ||
98 | pr_err("Could not map guts node address\n"); | ||
99 | return -ENOMEM; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | qoriq_pm_ops = &mpc85xx_pm_ops; | ||
104 | |||
105 | return 0; | ||
106 | } | ||
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 6b107cea1c08..fe9f19e5e935 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Author: Andy Fleming <afleming@freescale.com> | 2 | * Author: Andy Fleming <afleming@freescale.com> |
3 | * Kumar Gala <galak@kernel.crashing.org> | 3 | * Kumar Gala <galak@kernel.crashing.org> |
4 | * | 4 | * |
5 | * Copyright 2006-2008, 2011-2012 Freescale Semiconductor Inc. | 5 | * Copyright 2006-2008, 2011-2012, 2015 Freescale Semiconductor Inc. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
18 | #include <linux/of_address.h> | ||
19 | #include <linux/kexec.h> | 18 | #include <linux/kexec.h> |
20 | #include <linux/highmem.h> | 19 | #include <linux/highmem.h> |
21 | #include <linux/cpu.h> | 20 | #include <linux/cpu.h> |
@@ -29,6 +28,7 @@ | |||
29 | #include <asm/dbell.h> | 28 | #include <asm/dbell.h> |
30 | #include <asm/code-patching.h> | 29 | #include <asm/code-patching.h> |
31 | #include <asm/cputhreads.h> | 30 | #include <asm/cputhreads.h> |
31 | #include <asm/fsl_pm.h> | ||
32 | 32 | ||
33 | #include <sysdev/fsl_soc.h> | 33 | #include <sysdev/fsl_soc.h> |
34 | #include <sysdev/mpic.h> | 34 | #include <sysdev/mpic.h> |
@@ -43,35 +43,23 @@ struct epapr_spin_table { | |||
43 | u32 pir; | 43 | u32 pir; |
44 | }; | 44 | }; |
45 | 45 | ||
46 | static struct ccsr_guts __iomem *guts; | 46 | #ifdef CONFIG_HOTPLUG_CPU |
47 | static u64 timebase; | 47 | static u64 timebase; |
48 | static int tb_req; | 48 | static int tb_req; |
49 | static int tb_valid; | 49 | static int tb_valid; |
50 | 50 | ||
51 | static void mpc85xx_timebase_freeze(int freeze) | ||
52 | { | ||
53 | uint32_t mask; | ||
54 | |||
55 | mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1; | ||
56 | if (freeze) | ||
57 | setbits32(&guts->devdisr, mask); | ||
58 | else | ||
59 | clrbits32(&guts->devdisr, mask); | ||
60 | |||
61 | in_be32(&guts->devdisr); | ||
62 | } | ||
63 | |||
64 | static void mpc85xx_give_timebase(void) | 51 | static void mpc85xx_give_timebase(void) |
65 | { | 52 | { |
66 | unsigned long flags; | 53 | unsigned long flags; |
67 | 54 | ||
68 | local_irq_save(flags); | 55 | local_irq_save(flags); |
56 | hard_irq_disable(); | ||
69 | 57 | ||
70 | while (!tb_req) | 58 | while (!tb_req) |
71 | barrier(); | 59 | barrier(); |
72 | tb_req = 0; | 60 | tb_req = 0; |
73 | 61 | ||
74 | mpc85xx_timebase_freeze(1); | 62 | qoriq_pm_ops->freeze_time_base(true); |
75 | #ifdef CONFIG_PPC64 | 63 | #ifdef CONFIG_PPC64 |
76 | /* | 64 | /* |
77 | * e5500/e6500 have a workaround for erratum A-006958 in place | 65 | * e5500/e6500 have a workaround for erratum A-006958 in place |
@@ -104,7 +92,7 @@ static void mpc85xx_give_timebase(void) | |||
104 | while (tb_valid) | 92 | while (tb_valid) |
105 | barrier(); | 93 | barrier(); |
106 | 94 | ||
107 | mpc85xx_timebase_freeze(0); | 95 | qoriq_pm_ops->freeze_time_base(false); |
108 | 96 | ||
109 | local_irq_restore(flags); | 97 | local_irq_restore(flags); |
110 | } | 98 | } |
@@ -114,6 +102,7 @@ static void mpc85xx_take_timebase(void) | |||
114 | unsigned long flags; | 102 | unsigned long flags; |
115 | 103 | ||
116 | local_irq_save(flags); | 104 | local_irq_save(flags); |
105 | hard_irq_disable(); | ||
117 | 106 | ||
118 | tb_req = 1; | 107 | tb_req = 1; |
119 | while (!tb_valid) | 108 | while (!tb_valid) |
@@ -126,36 +115,54 @@ static void mpc85xx_take_timebase(void) | |||
126 | local_irq_restore(flags); | 115 | local_irq_restore(flags); |
127 | } | 116 | } |
128 | 117 | ||
129 | #ifdef CONFIG_HOTPLUG_CPU | ||
130 | static void smp_85xx_mach_cpu_die(void) | 118 | static void smp_85xx_mach_cpu_die(void) |
131 | { | 119 | { |
132 | unsigned int cpu = smp_processor_id(); | 120 | unsigned int cpu = smp_processor_id(); |
133 | u32 tmp; | ||
134 | 121 | ||
135 | local_irq_disable(); | 122 | local_irq_disable(); |
123 | hard_irq_disable(); | ||
124 | /* mask all irqs to prevent cpu wakeup */ | ||
125 | qoriq_pm_ops->irq_mask(cpu); | ||
126 | |||
136 | idle_task_exit(); | 127 | idle_task_exit(); |
137 | generic_set_cpu_dead(cpu); | ||
138 | mb(); | ||
139 | 128 | ||
140 | mtspr(SPRN_TCR, 0); | 129 | mtspr(SPRN_TCR, 0); |
130 | mtspr(SPRN_TSR, mfspr(SPRN_TSR)); | ||
141 | 131 | ||
142 | __flush_disable_L1(); | 132 | generic_set_cpu_dead(cpu); |
143 | tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP; | ||
144 | mtspr(SPRN_HID0, tmp); | ||
145 | isync(); | ||
146 | 133 | ||
147 | /* Enter NAP mode. */ | 134 | cur_cpu_spec->cpu_down_flush(); |
148 | tmp = mfmsr(); | 135 | |
149 | tmp |= MSR_WE; | 136 | qoriq_pm_ops->cpu_die(cpu); |
150 | mb(); | ||
151 | mtmsr(tmp); | ||
152 | isync(); | ||
153 | 137 | ||
154 | while (1) | 138 | while (1) |
155 | ; | 139 | ; |
156 | } | 140 | } |
141 | |||
142 | static void qoriq_cpu_kill(unsigned int cpu) | ||
143 | { | ||
144 | int i; | ||
145 | |||
146 | for (i = 0; i < 500; i++) { | ||
147 | if (is_cpu_dead(cpu)) { | ||
148 | #ifdef CONFIG_PPC64 | ||
149 | paca[cpu].cpu_start = 0; | ||
150 | #endif | ||
151 | return; | ||
152 | } | ||
153 | msleep(20); | ||
154 | } | ||
155 | pr_err("CPU%d didn't die...\n", cpu); | ||
156 | } | ||
157 | #endif | 157 | #endif |
158 | 158 | ||
159 | /* | ||
160 | * To keep it compatible with old boot program which uses | ||
161 | * cache-inhibit spin table, we need to flush the cache | ||
162 | * before accessing spin table to invalidate any staled data. | ||
163 | * We also need to flush the cache after writing to spin | ||
164 | * table to push data out. | ||
165 | */ | ||
159 | static inline void flush_spin_table(void *spin_table) | 166 | static inline void flush_spin_table(void *spin_table) |
160 | { | 167 | { |
161 | flush_dcache_range((ulong)spin_table, | 168 | flush_dcache_range((ulong)spin_table, |
@@ -173,78 +180,28 @@ static inline u32 read_spin_table_addr_l(void *spin_table) | |||
173 | static void wake_hw_thread(void *info) | 180 | static void wake_hw_thread(void *info) |
174 | { | 181 | { |
175 | void fsl_secondary_thread_init(void); | 182 | void fsl_secondary_thread_init(void); |
176 | unsigned long imsr, inia; | 183 | unsigned long inia; |
177 | int nr = *(const int *)info; | 184 | int cpu = *(const int *)info; |
178 | 185 | ||
179 | imsr = MSR_KERNEL; | ||
180 | inia = *(unsigned long *)fsl_secondary_thread_init; | 186 | inia = *(unsigned long *)fsl_secondary_thread_init; |
181 | 187 | book3e_start_thread(cpu_thread_in_core(cpu), inia); | |
182 | if (cpu_thread_in_core(nr) == 0) { | ||
183 | /* For when we boot on a secondary thread with kdump */ | ||
184 | mttmr(TMRN_IMSR0, imsr); | ||
185 | mttmr(TMRN_INIA0, inia); | ||
186 | mtspr(SPRN_TENS, TEN_THREAD(0)); | ||
187 | } else { | ||
188 | mttmr(TMRN_IMSR1, imsr); | ||
189 | mttmr(TMRN_INIA1, inia); | ||
190 | mtspr(SPRN_TENS, TEN_THREAD(1)); | ||
191 | } | ||
192 | |||
193 | smp_generic_kick_cpu(nr); | ||
194 | } | 188 | } |
195 | #endif | 189 | #endif |
196 | 190 | ||
197 | static int smp_85xx_kick_cpu(int nr) | 191 | static int smp_85xx_start_cpu(int cpu) |
198 | { | 192 | { |
199 | unsigned long flags; | 193 | int ret = 0; |
200 | const u64 *cpu_rel_addr; | ||
201 | __iomem struct epapr_spin_table *spin_table; | ||
202 | struct device_node *np; | 194 | struct device_node *np; |
203 | int hw_cpu = get_hard_smp_processor_id(nr); | 195 | const u64 *cpu_rel_addr; |
196 | unsigned long flags; | ||
204 | int ioremappable; | 197 | int ioremappable; |
205 | int ret = 0; | 198 | int hw_cpu = get_hard_smp_processor_id(cpu); |
206 | 199 | struct epapr_spin_table __iomem *spin_table; | |
207 | WARN_ON(nr < 0 || nr >= NR_CPUS); | ||
208 | WARN_ON(hw_cpu < 0 || hw_cpu >= NR_CPUS); | ||
209 | |||
210 | pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr); | ||
211 | |||
212 | #ifdef CONFIG_PPC64 | ||
213 | /* Threads don't use the spin table */ | ||
214 | if (cpu_thread_in_core(nr) != 0) { | ||
215 | int primary = cpu_first_thread_sibling(nr); | ||
216 | |||
217 | if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT))) | ||
218 | return -ENOENT; | ||
219 | |||
220 | if (cpu_thread_in_core(nr) != 1) { | ||
221 | pr_err("%s: cpu %d: invalid hw thread %d\n", | ||
222 | __func__, nr, cpu_thread_in_core(nr)); | ||
223 | return -ENOENT; | ||
224 | } | ||
225 | 200 | ||
226 | if (!cpu_online(primary)) { | 201 | np = of_get_cpu_node(cpu, NULL); |
227 | pr_err("%s: cpu %d: primary %d not online\n", | ||
228 | __func__, nr, primary); | ||
229 | return -ENOENT; | ||
230 | } | ||
231 | |||
232 | smp_call_function_single(primary, wake_hw_thread, &nr, 0); | ||
233 | return 0; | ||
234 | } else if (cpu_thread_in_core(boot_cpuid) != 0 && | ||
235 | cpu_first_thread_sibling(boot_cpuid) == nr) { | ||
236 | if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT))) | ||
237 | return -ENOENT; | ||
238 | |||
239 | smp_call_function_single(boot_cpuid, wake_hw_thread, &nr, 0); | ||
240 | } | ||
241 | #endif | ||
242 | |||
243 | np = of_get_cpu_node(nr, NULL); | ||
244 | cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL); | 202 | cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL); |
245 | 203 | if (!cpu_rel_addr) { | |
246 | if (cpu_rel_addr == NULL) { | 204 | pr_err("No cpu-release-addr for cpu %d\n", cpu); |
247 | printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr); | ||
248 | return -ENOENT; | 205 | return -ENOENT; |
249 | } | 206 | } |
250 | 207 | ||
@@ -264,28 +221,18 @@ static int smp_85xx_kick_cpu(int nr) | |||
264 | spin_table = phys_to_virt(*cpu_rel_addr); | 221 | spin_table = phys_to_virt(*cpu_rel_addr); |
265 | 222 | ||
266 | local_irq_save(flags); | 223 | local_irq_save(flags); |
267 | #ifdef CONFIG_PPC32 | 224 | hard_irq_disable(); |
268 | #ifdef CONFIG_HOTPLUG_CPU | ||
269 | /* Corresponding to generic_set_cpu_dead() */ | ||
270 | generic_set_cpu_up(nr); | ||
271 | 225 | ||
272 | if (system_state == SYSTEM_RUNNING) { | 226 | if (qoriq_pm_ops) |
273 | /* | 227 | qoriq_pm_ops->cpu_up_prepare(cpu); |
274 | * To keep it compatible with old boot program which uses | ||
275 | * cache-inhibit spin table, we need to flush the cache | ||
276 | * before accessing spin table to invalidate any staled data. | ||
277 | * We also need to flush the cache after writing to spin | ||
278 | * table to push data out. | ||
279 | */ | ||
280 | flush_spin_table(spin_table); | ||
281 | out_be32(&spin_table->addr_l, 0); | ||
282 | flush_spin_table(spin_table); | ||
283 | 228 | ||
229 | /* if cpu is not spinning, reset it */ | ||
230 | if (read_spin_table_addr_l(spin_table) != 1) { | ||
284 | /* | 231 | /* |
285 | * We don't set the BPTR register here since it already points | 232 | * We don't set the BPTR register here since it already points |
286 | * to the boot page properly. | 233 | * to the boot page properly. |
287 | */ | 234 | */ |
288 | mpic_reset_core(nr); | 235 | mpic_reset_core(cpu); |
289 | 236 | ||
290 | /* | 237 | /* |
291 | * wait until core is ready... | 238 | * wait until core is ready... |
@@ -295,40 +242,23 @@ static int smp_85xx_kick_cpu(int nr) | |||
295 | if (!spin_event_timeout( | 242 | if (!spin_event_timeout( |
296 | read_spin_table_addr_l(spin_table) == 1, | 243 | read_spin_table_addr_l(spin_table) == 1, |
297 | 10000, 100)) { | 244 | 10000, 100)) { |
298 | pr_err("%s: timeout waiting for core %d to reset\n", | 245 | pr_err("timeout waiting for cpu %d to reset\n", |
299 | __func__, hw_cpu); | 246 | hw_cpu); |
300 | ret = -ENOENT; | 247 | ret = -EAGAIN; |
301 | goto out; | 248 | goto err; |
302 | } | 249 | } |
303 | |||
304 | /* clear the acknowledge status */ | ||
305 | __secondary_hold_acknowledge = -1; | ||
306 | } | 250 | } |
307 | #endif | ||
308 | flush_spin_table(spin_table); | ||
309 | out_be32(&spin_table->pir, hw_cpu); | ||
310 | out_be32(&spin_table->addr_l, __pa(__early_start)); | ||
311 | flush_spin_table(spin_table); | ||
312 | |||
313 | /* Wait a bit for the CPU to ack. */ | ||
314 | if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu, | ||
315 | 10000, 100)) { | ||
316 | pr_err("%s: timeout waiting for core %d to ack\n", | ||
317 | __func__, hw_cpu); | ||
318 | ret = -ENOENT; | ||
319 | goto out; | ||
320 | } | ||
321 | out: | ||
322 | #else | ||
323 | smp_generic_kick_cpu(nr); | ||
324 | 251 | ||
325 | flush_spin_table(spin_table); | 252 | flush_spin_table(spin_table); |
326 | out_be32(&spin_table->pir, hw_cpu); | 253 | out_be32(&spin_table->pir, hw_cpu); |
254 | #ifdef CONFIG_PPC64 | ||
327 | out_be64((u64 *)(&spin_table->addr_h), | 255 | out_be64((u64 *)(&spin_table->addr_h), |
328 | __pa(ppc_function_entry(generic_secondary_smp_init))); | 256 | __pa(ppc_function_entry(generic_secondary_smp_init))); |
329 | flush_spin_table(spin_table); | 257 | #else |
258 | out_be32(&spin_table->addr_l, __pa(__early_start)); | ||
330 | #endif | 259 | #endif |
331 | 260 | flush_spin_table(spin_table); | |
261 | err: | ||
332 | local_irq_restore(flags); | 262 | local_irq_restore(flags); |
333 | 263 | ||
334 | if (ioremappable) | 264 | if (ioremappable) |
@@ -337,6 +267,81 @@ out: | |||
337 | return ret; | 267 | return ret; |
338 | } | 268 | } |
339 | 269 | ||
270 | static int smp_85xx_kick_cpu(int nr) | ||
271 | { | ||
272 | int ret = 0; | ||
273 | #ifdef CONFIG_PPC64 | ||
274 | int primary = nr; | ||
275 | #endif | ||
276 | |||
277 | WARN_ON(nr < 0 || nr >= num_possible_cpus()); | ||
278 | |||
279 | pr_debug("kick CPU #%d\n", nr); | ||
280 | |||
281 | #ifdef CONFIG_PPC64 | ||
282 | if (threads_per_core == 2) { | ||
283 | if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT))) | ||
284 | return -ENOENT; | ||
285 | |||
286 | booting_thread_hwid = cpu_thread_in_core(nr); | ||
287 | primary = cpu_first_thread_sibling(nr); | ||
288 | |||
289 | if (qoriq_pm_ops) | ||
290 | qoriq_pm_ops->cpu_up_prepare(nr); | ||
291 | |||
292 | /* | ||
293 | * If either thread in the core is online, use it to start | ||
294 | * the other. | ||
295 | */ | ||
296 | if (cpu_online(primary)) { | ||
297 | smp_call_function_single(primary, | ||
298 | wake_hw_thread, &nr, 1); | ||
299 | goto done; | ||
300 | } else if (cpu_online(primary + 1)) { | ||
301 | smp_call_function_single(primary + 1, | ||
302 | wake_hw_thread, &nr, 1); | ||
303 | goto done; | ||
304 | } | ||
305 | |||
306 | /* | ||
307 | * If getting here, it means both threads in the core are | ||
308 | * offline. So start the primary thread, then it will start | ||
309 | * the thread specified in booting_thread_hwid, the one | ||
310 | * corresponding to nr. | ||
311 | */ | ||
312 | |||
313 | } else if (threads_per_core == 1) { | ||
314 | /* | ||
315 | * If one core has only one thread, set booting_thread_hwid to | ||
316 | * an invalid value. | ||
317 | */ | ||
318 | booting_thread_hwid = INVALID_THREAD_HWID; | ||
319 | |||
320 | } else if (threads_per_core > 2) { | ||
321 | pr_err("Do not support more than 2 threads per CPU."); | ||
322 | return -EINVAL; | ||
323 | } | ||
324 | |||
325 | ret = smp_85xx_start_cpu(primary); | ||
326 | if (ret) | ||
327 | return ret; | ||
328 | |||
329 | done: | ||
330 | paca[nr].cpu_start = 1; | ||
331 | generic_set_cpu_up(nr); | ||
332 | |||
333 | return ret; | ||
334 | #else | ||
335 | ret = smp_85xx_start_cpu(nr); | ||
336 | if (ret) | ||
337 | return ret; | ||
338 | |||
339 | generic_set_cpu_up(nr); | ||
340 | |||
341 | return ret; | ||
342 | #endif | ||
343 | } | ||
344 | |||
340 | struct smp_ops_t smp_85xx_ops = { | 345 | struct smp_ops_t smp_85xx_ops = { |
341 | .kick_cpu = smp_85xx_kick_cpu, | 346 | .kick_cpu = smp_85xx_kick_cpu, |
342 | .cpu_bootable = smp_generic_cpu_bootable, | 347 | .cpu_bootable = smp_generic_cpu_bootable, |
@@ -359,7 +364,7 @@ void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary) | |||
359 | local_irq_disable(); | 364 | local_irq_disable(); |
360 | 365 | ||
361 | if (secondary) { | 366 | if (secondary) { |
362 | __flush_disable_L1(); | 367 | cur_cpu_spec->cpu_down_flush(); |
363 | atomic_inc(&kexec_down_cpus); | 368 | atomic_inc(&kexec_down_cpus); |
364 | /* loop forever */ | 369 | /* loop forever */ |
365 | while (1); | 370 | while (1); |
@@ -467,16 +472,6 @@ static void smp_85xx_setup_cpu(int cpu_nr) | |||
467 | smp_85xx_basic_setup(cpu_nr); | 472 | smp_85xx_basic_setup(cpu_nr); |
468 | } | 473 | } |
469 | 474 | ||
470 | static const struct of_device_id mpc85xx_smp_guts_ids[] = { | ||
471 | { .compatible = "fsl,mpc8572-guts", }, | ||
472 | { .compatible = "fsl,p1020-guts", }, | ||
473 | { .compatible = "fsl,p1021-guts", }, | ||
474 | { .compatible = "fsl,p1022-guts", }, | ||
475 | { .compatible = "fsl,p1023-guts", }, | ||
476 | { .compatible = "fsl,p2020-guts", }, | ||
477 | {}, | ||
478 | }; | ||
479 | |||
480 | void __init mpc85xx_smp_init(void) | 475 | void __init mpc85xx_smp_init(void) |
481 | { | 476 | { |
482 | struct device_node *np; | 477 | struct device_node *np; |
@@ -500,22 +495,21 @@ void __init mpc85xx_smp_init(void) | |||
500 | smp_85xx_ops.probe = NULL; | 495 | smp_85xx_ops.probe = NULL; |
501 | } | 496 | } |
502 | 497 | ||
503 | np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); | 498 | #ifdef CONFIG_HOTPLUG_CPU |
504 | if (np) { | 499 | #ifdef CONFIG_FSL_CORENET_RCPM |
505 | guts = of_iomap(np, 0); | 500 | fsl_rcpm_init(); |
506 | of_node_put(np); | 501 | #endif |
507 | if (!guts) { | 502 | |
508 | pr_err("%s: Could not map guts node address\n", | 503 | #ifdef CONFIG_FSL_PMC |
509 | __func__); | 504 | mpc85xx_setup_pmc(); |
510 | return; | 505 | #endif |
511 | } | 506 | if (qoriq_pm_ops) { |
512 | smp_85xx_ops.give_timebase = mpc85xx_give_timebase; | 507 | smp_85xx_ops.give_timebase = mpc85xx_give_timebase; |
513 | smp_85xx_ops.take_timebase = mpc85xx_take_timebase; | 508 | smp_85xx_ops.take_timebase = mpc85xx_take_timebase; |
514 | #ifdef CONFIG_HOTPLUG_CPU | ||
515 | ppc_md.cpu_die = smp_85xx_mach_cpu_die; | 509 | ppc_md.cpu_die = smp_85xx_mach_cpu_die; |
516 | #endif | 510 | smp_85xx_ops.cpu_die = qoriq_cpu_kill; |
517 | } | 511 | } |
518 | 512 | #endif | |
519 | smp_ops = &smp_85xx_ops; | 513 | smp_ops = &smp_85xx_ops; |
520 | 514 | ||
521 | #ifdef CONFIG_KEXEC | 515 | #ifdef CONFIG_KEXEC |
diff --git a/arch/powerpc/platforms/85xx/smp.h b/arch/powerpc/platforms/85xx/smp.h index e2b44933ff19..0b20ae315c53 100644 --- a/arch/powerpc/platforms/85xx/smp.h +++ b/arch/powerpc/platforms/85xx/smp.h | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | #ifdef CONFIG_SMP | 6 | #ifdef CONFIG_SMP |
7 | void __init mpc85xx_smp_init(void); | 7 | void __init mpc85xx_smp_init(void); |
8 | int __init mpc85xx_setup_pmc(void); | ||
8 | #else | 9 | #else |
9 | static inline void mpc85xx_smp_init(void) | 10 | static inline void mpc85xx_smp_init(void) |
10 | { | 11 | { |
diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile index ede815d6489d..2d889ad7dc89 100644 --- a/arch/powerpc/platforms/86xx/Makefile +++ b/arch/powerpc/platforms/86xx/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the PowerPC 86xx linux kernel. | 2 | # Makefile for the PowerPC 86xx linux kernel. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := pic.o | 5 | obj-y := pic.o common.o |
6 | obj-$(CONFIG_SMP) += mpc86xx_smp.o | 6 | obj-$(CONFIG_SMP) += mpc86xx_smp.o |
7 | obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o | 7 | obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o |
8 | obj-$(CONFIG_SBC8641D) += sbc8641d.o | 8 | obj-$(CONFIG_SBC8641D) += sbc8641d.o |
diff --git a/arch/powerpc/platforms/86xx/common.c b/arch/powerpc/platforms/86xx/common.c new file mode 100644 index 000000000000..0f7b7fcf1ba2 --- /dev/null +++ b/arch/powerpc/platforms/86xx/common.c | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * Routines common to most mpc86xx-based boards. | ||
3 | * | ||
4 | * This is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/of_platform.h> | ||
10 | #include <asm/synch.h> | ||
11 | |||
12 | #include "mpc86xx.h" | ||
13 | |||
14 | static const struct of_device_id mpc86xx_common_ids[] __initconst = { | ||
15 | { .type = "soc", }, | ||
16 | { .compatible = "soc", }, | ||
17 | { .compatible = "simple-bus", }, | ||
18 | { .name = "localbus", }, | ||
19 | { .compatible = "gianfar", }, | ||
20 | { .compatible = "fsl,mpc8641-pcie", }, | ||
21 | {}, | ||
22 | }; | ||
23 | |||
24 | int __init mpc86xx_common_publish_devices(void) | ||
25 | { | ||
26 | return of_platform_bus_probe(NULL, mpc86xx_common_ids, NULL); | ||
27 | } | ||
28 | |||
29 | long __init mpc86xx_time_init(void) | ||
30 | { | ||
31 | unsigned int temp; | ||
32 | |||
33 | /* Set the time base to zero */ | ||
34 | mtspr(SPRN_TBWL, 0); | ||
35 | mtspr(SPRN_TBWU, 0); | ||
36 | |||
37 | temp = mfspr(SPRN_HID0); | ||
38 | temp |= HID0_TBEN; | ||
39 | mtspr(SPRN_HID0, temp); | ||
40 | isync(); | ||
41 | |||
42 | return 0; | ||
43 | } | ||
diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c index bf17933b20f3..8e63b752712c 100644 --- a/arch/powerpc/platforms/86xx/gef_ppc9a.c +++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c | |||
@@ -197,37 +197,7 @@ static int __init gef_ppc9a_probe(void) | |||
197 | return 0; | 197 | return 0; |
198 | } | 198 | } |
199 | 199 | ||
200 | static long __init mpc86xx_time_init(void) | 200 | machine_arch_initcall(gef_ppc9a, mpc86xx_common_publish_devices); |
201 | { | ||
202 | unsigned int temp; | ||
203 | |||
204 | /* Set the time base to zero */ | ||
205 | mtspr(SPRN_TBWL, 0); | ||
206 | mtspr(SPRN_TBWU, 0); | ||
207 | |||
208 | temp = mfspr(SPRN_HID0); | ||
209 | temp |= HID0_TBEN; | ||
210 | mtspr(SPRN_HID0, temp); | ||
211 | asm volatile("isync"); | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static const struct of_device_id of_bus_ids[] __initconst = { | ||
217 | { .compatible = "simple-bus", }, | ||
218 | { .compatible = "gianfar", }, | ||
219 | { .compatible = "fsl,mpc8641-pcie", }, | ||
220 | {}, | ||
221 | }; | ||
222 | |||
223 | static int __init declare_of_platform_devices(void) | ||
224 | { | ||
225 | printk(KERN_DEBUG "Probe platform devices\n"); | ||
226 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | machine_arch_initcall(gef_ppc9a, declare_of_platform_devices); | ||
231 | 201 | ||
232 | define_machine(gef_ppc9a) { | 202 | define_machine(gef_ppc9a) { |
233 | .name = "GE PPC9A", | 203 | .name = "GE PPC9A", |
diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c index 8facf5873866..0e0be94f551f 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc310.c +++ b/arch/powerpc/platforms/86xx/gef_sbc310.c | |||
@@ -184,37 +184,7 @@ static int __init gef_sbc310_probe(void) | |||
184 | return 0; | 184 | return 0; |
185 | } | 185 | } |
186 | 186 | ||
187 | static long __init mpc86xx_time_init(void) | 187 | machine_arch_initcall(gef_sbc310, mpc86xx_common_publish_devices); |
188 | { | ||
189 | unsigned int temp; | ||
190 | |||
191 | /* Set the time base to zero */ | ||
192 | mtspr(SPRN_TBWL, 0); | ||
193 | mtspr(SPRN_TBWU, 0); | ||
194 | |||
195 | temp = mfspr(SPRN_HID0); | ||
196 | temp |= HID0_TBEN; | ||
197 | mtspr(SPRN_HID0, temp); | ||
198 | asm volatile("isync"); | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static const struct of_device_id of_bus_ids[] __initconst = { | ||
204 | { .compatible = "simple-bus", }, | ||
205 | { .compatible = "gianfar", }, | ||
206 | { .compatible = "fsl,mpc8641-pcie", }, | ||
207 | {}, | ||
208 | }; | ||
209 | |||
210 | static int __init declare_of_platform_devices(void) | ||
211 | { | ||
212 | printk(KERN_DEBUG "Probe platform devices\n"); | ||
213 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | machine_arch_initcall(gef_sbc310, declare_of_platform_devices); | ||
218 | 188 | ||
219 | define_machine(gef_sbc310) { | 189 | define_machine(gef_sbc310) { |
220 | .name = "GE SBC310", | 190 | .name = "GE SBC310", |
diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c index 8c9058df5642..e8292b492d7e 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc610.c +++ b/arch/powerpc/platforms/86xx/gef_sbc610.c | |||
@@ -174,37 +174,7 @@ static int __init gef_sbc610_probe(void) | |||
174 | return 0; | 174 | return 0; |
175 | } | 175 | } |
176 | 176 | ||
177 | static long __init mpc86xx_time_init(void) | 177 | machine_arch_initcall(gef_sbc610, mpc86xx_common_publish_devices); |
178 | { | ||
179 | unsigned int temp; | ||
180 | |||
181 | /* Set the time base to zero */ | ||
182 | mtspr(SPRN_TBWL, 0); | ||
183 | mtspr(SPRN_TBWU, 0); | ||
184 | |||
185 | temp = mfspr(SPRN_HID0); | ||
186 | temp |= HID0_TBEN; | ||
187 | mtspr(SPRN_HID0, temp); | ||
188 | asm volatile("isync"); | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static const struct of_device_id of_bus_ids[] __initconst = { | ||
194 | { .compatible = "simple-bus", }, | ||
195 | { .compatible = "gianfar", }, | ||
196 | { .compatible = "fsl,mpc8641-pcie", }, | ||
197 | {}, | ||
198 | }; | ||
199 | |||
200 | static int __init declare_of_platform_devices(void) | ||
201 | { | ||
202 | printk(KERN_DEBUG "Probe platform devices\n"); | ||
203 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | machine_arch_initcall(gef_sbc610, declare_of_platform_devices); | ||
208 | 178 | ||
209 | define_machine(gef_sbc610) { | 179 | define_machine(gef_sbc610) { |
210 | .name = "GE SBC610", | 180 | .name = "GE SBC610", |
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c index 437a9c372ae1..957473e5c8e5 100644 --- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c +++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c | |||
@@ -88,12 +88,10 @@ static inline void mpc8610_suspend_init(void) { } | |||
88 | static const struct of_device_id mpc8610_ids[] __initconst = { | 88 | static const struct of_device_id mpc8610_ids[] __initconst = { |
89 | { .compatible = "fsl,mpc8610-immr", }, | 89 | { .compatible = "fsl,mpc8610-immr", }, |
90 | { .compatible = "fsl,mpc8610-guts", }, | 90 | { .compatible = "fsl,mpc8610-guts", }, |
91 | { .compatible = "simple-bus", }, | ||
92 | /* So that the DMA channel nodes can be probed individually: */ | 91 | /* So that the DMA channel nodes can be probed individually: */ |
93 | { .compatible = "fsl,eloplus-dma", }, | 92 | { .compatible = "fsl,eloplus-dma", }, |
94 | /* PCI controllers */ | 93 | /* PCI controllers */ |
95 | { .compatible = "fsl,mpc8610-pci", }, | 94 | { .compatible = "fsl,mpc8610-pci", }, |
96 | { .compatible = "fsl,mpc8641-pcie", }, | ||
97 | {} | 95 | {} |
98 | }; | 96 | }; |
99 | 97 | ||
@@ -105,6 +103,8 @@ static int __init mpc8610_declare_of_platform_devices(void) | |||
105 | /* Enable wakeup on PIXIS' event IRQ. */ | 103 | /* Enable wakeup on PIXIS' event IRQ. */ |
106 | mpc8610_suspend_init(); | 104 | mpc8610_suspend_init(); |
107 | 105 | ||
106 | mpc86xx_common_publish_devices(); | ||
107 | |||
108 | /* Without this call, the SSI device driver won't get probed. */ | 108 | /* Without this call, the SSI device driver won't get probed. */ |
109 | of_platform_bus_probe(NULL, mpc8610_ids, NULL); | 109 | of_platform_bus_probe(NULL, mpc8610_ids, NULL); |
110 | 110 | ||
@@ -327,22 +327,6 @@ static int __init mpc86xx_hpcd_probe(void) | |||
327 | return 0; | 327 | return 0; |
328 | } | 328 | } |
329 | 329 | ||
330 | static long __init mpc86xx_time_init(void) | ||
331 | { | ||
332 | unsigned int temp; | ||
333 | |||
334 | /* Set the time base to zero */ | ||
335 | mtspr(SPRN_TBWL, 0); | ||
336 | mtspr(SPRN_TBWU, 0); | ||
337 | |||
338 | temp = mfspr(SPRN_HID0); | ||
339 | temp |= HID0_TBEN; | ||
340 | mtspr(SPRN_HID0, temp); | ||
341 | asm volatile("isync"); | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | define_machine(mpc86xx_hpcd) { | 330 | define_machine(mpc86xx_hpcd) { |
347 | .name = "MPC86xx HPCD", | 331 | .name = "MPC86xx HPCD", |
348 | .probe = mpc86xx_hpcd_probe, | 332 | .probe = mpc86xx_hpcd_probe, |
diff --git a/arch/powerpc/platforms/86xx/mpc86xx.h b/arch/powerpc/platforms/86xx/mpc86xx.h index 08efb57559d1..53500db6b644 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx.h +++ b/arch/powerpc/platforms/86xx/mpc86xx.h | |||
@@ -17,5 +17,7 @@ | |||
17 | 17 | ||
18 | extern void mpc86xx_smp_init(void); | 18 | extern void mpc86xx_smp_init(void); |
19 | extern void mpc86xx_init_irq(void); | 19 | extern void mpc86xx_init_irq(void); |
20 | extern long mpc86xx_time_init(void); | ||
21 | extern int mpc86xx_common_publish_devices(void); | ||
20 | 22 | ||
21 | #endif /* __MPC86XX_H__ */ | 23 | #endif /* __MPC86XX_H__ */ |
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 07ccb1b0cc7d..e5084811b9c6 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | |||
@@ -110,33 +110,14 @@ static int __init mpc86xx_hpcn_probe(void) | |||
110 | return 0; | 110 | return 0; |
111 | } | 111 | } |
112 | 112 | ||
113 | static long __init | ||
114 | mpc86xx_time_init(void) | ||
115 | { | ||
116 | unsigned int temp; | ||
117 | |||
118 | /* Set the time base to zero */ | ||
119 | mtspr(SPRN_TBWL, 0); | ||
120 | mtspr(SPRN_TBWU, 0); | ||
121 | |||
122 | temp = mfspr(SPRN_HID0); | ||
123 | temp |= HID0_TBEN; | ||
124 | mtspr(SPRN_HID0, temp); | ||
125 | asm volatile("isync"); | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static const struct of_device_id of_bus_ids[] __initconst = { | 113 | static const struct of_device_id of_bus_ids[] __initconst = { |
131 | { .compatible = "simple-bus", }, | ||
132 | { .compatible = "fsl,srio", }, | 114 | { .compatible = "fsl,srio", }, |
133 | { .compatible = "gianfar", }, | ||
134 | { .compatible = "fsl,mpc8641-pcie", }, | ||
135 | {}, | 115 | {}, |
136 | }; | 116 | }; |
137 | 117 | ||
138 | static int __init declare_of_platform_devices(void) | 118 | static int __init declare_of_platform_devices(void) |
139 | { | 119 | { |
120 | mpc86xx_common_publish_devices(); | ||
140 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | 121 | of_platform_bus_probe(NULL, of_bus_ids, NULL); |
141 | 122 | ||
142 | return 0; | 123 | return 0; |
diff --git a/arch/powerpc/platforms/86xx/sbc8641d.c b/arch/powerpc/platforms/86xx/sbc8641d.c index 6810b71d54a7..2a9cf278c12a 100644 --- a/arch/powerpc/platforms/86xx/sbc8641d.c +++ b/arch/powerpc/platforms/86xx/sbc8641d.c | |||
@@ -75,37 +75,7 @@ static int __init sbc8641_probe(void) | |||
75 | return 0; | 75 | return 0; |
76 | } | 76 | } |
77 | 77 | ||
78 | static long __init | 78 | machine_arch_initcall(sbc8641, mpc86xx_common_publish_devices); |
79 | mpc86xx_time_init(void) | ||
80 | { | ||
81 | unsigned int temp; | ||
82 | |||
83 | /* Set the time base to zero */ | ||
84 | mtspr(SPRN_TBWL, 0); | ||
85 | mtspr(SPRN_TBWU, 0); | ||
86 | |||
87 | temp = mfspr(SPRN_HID0); | ||
88 | temp |= HID0_TBEN; | ||
89 | mtspr(SPRN_HID0, temp); | ||
90 | asm volatile("isync"); | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static const struct of_device_id of_bus_ids[] __initconst = { | ||
96 | { .compatible = "simple-bus", }, | ||
97 | { .compatible = "gianfar", }, | ||
98 | { .compatible = "fsl,mpc8641-pcie", }, | ||
99 | {}, | ||
100 | }; | ||
101 | |||
102 | static int __init declare_of_platform_devices(void) | ||
103 | { | ||
104 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | machine_arch_initcall(sbc8641, declare_of_platform_devices); | ||
109 | 79 | ||
110 | define_machine(sbc8641) { | 80 | define_machine(sbc8641) { |
111 | .name = "SBC8641D", | 81 | .name = "SBC8641D", |
diff --git a/arch/powerpc/platforms/embedded6xx/mpc10x.h b/arch/powerpc/platforms/embedded6xx/mpc10x.h index b290b63661f1..5ad12023e562 100644 --- a/arch/powerpc/platforms/embedded6xx/mpc10x.h +++ b/arch/powerpc/platforms/embedded6xx/mpc10x.h | |||
@@ -24,13 +24,11 @@ | |||
24 | * Processor: 0x80000000 - 0x807fffff -> PCI I/O: 0x00000000 - 0x007fffff | 24 | * Processor: 0x80000000 - 0x807fffff -> PCI I/O: 0x00000000 - 0x007fffff |
25 | * Processor: 0xc0000000 - 0xdfffffff -> PCI MEM: 0x00000000 - 0x1fffffff | 25 | * Processor: 0xc0000000 - 0xdfffffff -> PCI MEM: 0x00000000 - 0x1fffffff |
26 | * PCI MEM: 0x80000000 -> Processor System Memory: 0x00000000 | 26 | * PCI MEM: 0x80000000 -> Processor System Memory: 0x00000000 |
27 | * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB) | ||
28 | * | 27 | * |
29 | * MAP B (CHRP Map) | 28 | * MAP B (CHRP Map) |
30 | * Processor: 0xfe000000 - 0xfebfffff -> PCI I/O: 0x00000000 - 0x00bfffff | 29 | * Processor: 0xfe000000 - 0xfebfffff -> PCI I/O: 0x00000000 - 0x00bfffff |
31 | * Processor: 0x80000000 - 0xbfffffff -> PCI MEM: 0x80000000 - 0xbfffffff | 30 | * Processor: 0x80000000 - 0xbfffffff -> PCI MEM: 0x80000000 - 0xbfffffff |
32 | * PCI MEM: 0x00000000 -> Processor System Memory: 0x00000000 | 31 | * PCI MEM: 0x00000000 -> Processor System Memory: 0x00000000 |
33 | * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB) | ||
34 | */ | 32 | */ |
35 | 33 | ||
36 | /* | 34 | /* |
@@ -138,14 +136,6 @@ | |||
138 | #define MPC10X_EUMB_WP_OFFSET 0x000ff000 /* Data path diagnostic, watchpoint reg offset */ | 136 | #define MPC10X_EUMB_WP_OFFSET 0x000ff000 /* Data path diagnostic, watchpoint reg offset */ |
139 | #define MPC10X_EUMB_WP_SIZE 0x00001000 /* Data path diagnostic, watchpoint reg size */ | 137 | #define MPC10X_EUMB_WP_SIZE 0x00001000 /* Data path diagnostic, watchpoint reg size */ |
140 | 138 | ||
141 | /* | ||
142 | * Define some recommended places to put the EUMB regs. | ||
143 | * For both maps, recommend putting the EUMB from 0xeff00000 to 0xefffffff. | ||
144 | */ | ||
145 | extern unsigned long ioremap_base; | ||
146 | #define MPC10X_MAPA_EUMB_BASE (ioremap_base - MPC10X_EUMB_SIZE) | ||
147 | #define MPC10X_MAPB_EUMB_BASE MPC10X_MAPA_EUMB_BASE | ||
148 | |||
149 | enum ppc_sys_devices { | 139 | enum ppc_sys_devices { |
150 | MPC10X_IIC1, | 140 | MPC10X_IIC1, |
151 | MPC10X_DMA0, | 141 | MPC10X_DMA0, |
diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile index 52c6ce1cc985..1eb7b45e017d 100644 --- a/arch/powerpc/platforms/powermac/Makefile +++ b/arch/powerpc/platforms/powermac/Makefile | |||
@@ -2,7 +2,7 @@ CFLAGS_bootx_init.o += -fPIC | |||
2 | 2 | ||
3 | ifdef CONFIG_FUNCTION_TRACER | 3 | ifdef CONFIG_FUNCTION_TRACER |
4 | # Do not trace early boot code | 4 | # Do not trace early boot code |
5 | CFLAGS_REMOVE_bootx_init.o = -pg -mno-sched-epilog | 5 | CFLAGS_REMOVE_bootx_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) |
6 | endif | 6 | endif |
7 | 7 | ||
8 | obj-y += pic.o setup.o time.o feature.o pci.o \ | 8 | obj-y += pic.o setup.o time.o feature.o pci.o \ |
diff --git a/arch/powerpc/platforms/powermac/cache.S b/arch/powerpc/platforms/powermac/cache.S index 6be1a4af3359..cc5347eb1662 100644 --- a/arch/powerpc/platforms/powermac/cache.S +++ b/arch/powerpc/platforms/powermac/cache.S | |||
@@ -23,7 +23,7 @@ | |||
23 | * when going to sleep, when doing a PMU based cpufreq transition, | 23 | * when going to sleep, when doing a PMU based cpufreq transition, |
24 | * or when "offlining" a CPU on SMP machines. This code is over | 24 | * or when "offlining" a CPU on SMP machines. This code is over |
25 | * paranoid, but I've had enough issues with various CPU revs and | 25 | * paranoid, but I've had enough issues with various CPU revs and |
26 | * bugs that I decided it was worth beeing over cautious | 26 | * bugs that I decided it was worth being over cautious |
27 | */ | 27 | */ |
28 | 28 | ||
29 | _GLOBAL(flush_disable_caches) | 29 | _GLOBAL(flush_disable_caches) |
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index 4882bfd90e27..1e02328c3f2d 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c | |||
@@ -198,7 +198,7 @@ static long ohare_htw_scc_enable(struct device_node *node, long param, | |||
198 | if (htw) { | 198 | if (htw) { |
199 | /* Side effect: this will also power up the | 199 | /* Side effect: this will also power up the |
200 | * modem, but it's too messy to figure out on which | 200 | * modem, but it's too messy to figure out on which |
201 | * ports this controls the tranceiver and on which | 201 | * ports this controls the transceiver and on which |
202 | * it controls the modem | 202 | * it controls the modem |
203 | */ | 203 | */ |
204 | if (trans) | 204 | if (trans) |
@@ -463,7 +463,7 @@ static long heathrow_sound_enable(struct device_node *node, long param, | |||
463 | unsigned long flags; | 463 | unsigned long flags; |
464 | 464 | ||
465 | /* B&W G3 and Yikes don't support that properly (the | 465 | /* B&W G3 and Yikes don't support that properly (the |
466 | * sound appear to never come back after beeing shut down). | 466 | * sound appear to never come back after being shut down). |
467 | */ | 467 | */ |
468 | if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE || | 468 | if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE || |
469 | pmac_mb.model_id == PMAC_TYPE_YIKES) | 469 | pmac_mb.model_id == PMAC_TYPE_YIKES) |
@@ -2770,7 +2770,7 @@ set_initial_features(void) | |||
2770 | * but I'm not too sure it was audited for side-effects on other | 2770 | * but I'm not too sure it was audited for side-effects on other |
2771 | * ohare based machines... | 2771 | * ohare based machines... |
2772 | * Since I still have difficulties figuring the right way to | 2772 | * Since I still have difficulties figuring the right way to |
2773 | * differenciate them all and since that hack was there for a long | 2773 | * differentiate them all and since that hack was there for a long |
2774 | * time, I'll keep it around | 2774 | * time, I'll keep it around |
2775 | */ | 2775 | */ |
2776 | if (macio_chips[0].type == macio_ohare) { | 2776 | if (macio_chips[0].type == macio_ohare) { |
diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index f1516b5ecec9..cd9711e72df6 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile | |||
@@ -5,7 +5,7 @@ obj-y += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o | |||
5 | obj-y += opal-kmsg.o | 5 | obj-y += opal-kmsg.o |
6 | 6 | ||
7 | obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o | 7 | obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o |
8 | obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o npu-dma.o | 8 | obj-$(CONFIG_PCI) += pci.o pci-ioda.o npu-dma.o |
9 | obj-$(CONFIG_EEH) += eeh-powernv.o | 9 | obj-$(CONFIG_EEH) += eeh-powernv.o |
10 | obj-$(CONFIG_PPC_SCOM) += opal-xscom.o | 10 | obj-$(CONFIG_PPC_SCOM) += opal-xscom.o |
11 | obj-$(CONFIG_MEMORY_FAILURE) += opal-memory-errors.o | 11 | obj-$(CONFIG_MEMORY_FAILURE) += opal-memory-errors.o |
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 87f47e55aab6..950b3e539057 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c | |||
@@ -167,42 +167,26 @@ static int pnv_eeh_dbgfs_get(void *data, int offset, u64 *val) | |||
167 | return 0; | 167 | return 0; |
168 | } | 168 | } |
169 | 169 | ||
170 | static int pnv_eeh_outb_dbgfs_set(void *data, u64 val) | 170 | #define PNV_EEH_DBGFS_ENTRY(name, reg) \ |
171 | { | 171 | static int pnv_eeh_dbgfs_set_##name(void *data, u64 val) \ |
172 | return pnv_eeh_dbgfs_set(data, 0xD10, val); | 172 | { \ |
173 | } | 173 | return pnv_eeh_dbgfs_set(data, reg, val); \ |
174 | 174 | } \ | |
175 | static int pnv_eeh_outb_dbgfs_get(void *data, u64 *val) | 175 | \ |
176 | { | 176 | static int pnv_eeh_dbgfs_get_##name(void *data, u64 *val) \ |
177 | return pnv_eeh_dbgfs_get(data, 0xD10, val); | 177 | { \ |
178 | } | 178 | return pnv_eeh_dbgfs_get(data, reg, val); \ |
179 | 179 | } \ | |
180 | static int pnv_eeh_inbA_dbgfs_set(void *data, u64 val) | 180 | \ |
181 | { | 181 | DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_dbgfs_ops_##name, \ |
182 | return pnv_eeh_dbgfs_set(data, 0xD90, val); | 182 | pnv_eeh_dbgfs_get_##name, \ |
183 | } | 183 | pnv_eeh_dbgfs_set_##name, \ |
184 | 184 | "0x%llx\n") | |
185 | static int pnv_eeh_inbA_dbgfs_get(void *data, u64 *val) | 185 | |
186 | { | 186 | PNV_EEH_DBGFS_ENTRY(outb, 0xD10); |
187 | return pnv_eeh_dbgfs_get(data, 0xD90, val); | 187 | PNV_EEH_DBGFS_ENTRY(inbA, 0xD90); |
188 | } | 188 | PNV_EEH_DBGFS_ENTRY(inbB, 0xE10); |
189 | |||
190 | static int pnv_eeh_inbB_dbgfs_set(void *data, u64 val) | ||
191 | { | ||
192 | return pnv_eeh_dbgfs_set(data, 0xE10, val); | ||
193 | } | ||
194 | 189 | ||
195 | static int pnv_eeh_inbB_dbgfs_get(void *data, u64 *val) | ||
196 | { | ||
197 | return pnv_eeh_dbgfs_get(data, 0xE10, val); | ||
198 | } | ||
199 | |||
200 | DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_outb_dbgfs_ops, pnv_eeh_outb_dbgfs_get, | ||
201 | pnv_eeh_outb_dbgfs_set, "0x%llx\n"); | ||
202 | DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_inbA_dbgfs_ops, pnv_eeh_inbA_dbgfs_get, | ||
203 | pnv_eeh_inbA_dbgfs_set, "0x%llx\n"); | ||
204 | DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_inbB_dbgfs_ops, pnv_eeh_inbB_dbgfs_get, | ||
205 | pnv_eeh_inbB_dbgfs_set, "0x%llx\n"); | ||
206 | #endif /* CONFIG_DEBUG_FS */ | 190 | #endif /* CONFIG_DEBUG_FS */ |
207 | 191 | ||
208 | /** | 192 | /** |
@@ -268,13 +252,13 @@ static int pnv_eeh_post_init(void) | |||
268 | 252 | ||
269 | debugfs_create_file("err_injct_outbound", 0600, | 253 | debugfs_create_file("err_injct_outbound", 0600, |
270 | phb->dbgfs, hose, | 254 | phb->dbgfs, hose, |
271 | &pnv_eeh_outb_dbgfs_ops); | 255 | &pnv_eeh_dbgfs_ops_outb); |
272 | debugfs_create_file("err_injct_inboundA", 0600, | 256 | debugfs_create_file("err_injct_inboundA", 0600, |
273 | phb->dbgfs, hose, | 257 | phb->dbgfs, hose, |
274 | &pnv_eeh_inbA_dbgfs_ops); | 258 | &pnv_eeh_dbgfs_ops_inbA); |
275 | debugfs_create_file("err_injct_inboundB", 0600, | 259 | debugfs_create_file("err_injct_inboundB", 0600, |
276 | phb->dbgfs, hose, | 260 | phb->dbgfs, hose, |
277 | &pnv_eeh_inbB_dbgfs_ops); | 261 | &pnv_eeh_dbgfs_ops_inbB); |
278 | #endif /* CONFIG_DEBUG_FS */ | 262 | #endif /* CONFIG_DEBUG_FS */ |
279 | } | 263 | } |
280 | 264 | ||
@@ -387,6 +371,7 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data) | |||
387 | edev->mode &= 0xFFFFFF00; | 371 | edev->mode &= 0xFFFFFF00; |
388 | edev->pcix_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_PCIX); | 372 | edev->pcix_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_PCIX); |
389 | edev->pcie_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_EXP); | 373 | edev->pcie_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_EXP); |
374 | edev->af_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_AF); | ||
390 | edev->aer_cap = pnv_eeh_find_ecap(pdn, PCI_EXT_CAP_ID_ERR); | 375 | edev->aer_cap = pnv_eeh_find_ecap(pdn, PCI_EXT_CAP_ID_ERR); |
391 | if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) { | 376 | if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) { |
392 | edev->mode |= EEH_DEV_BRIDGE; | 377 | edev->mode |= EEH_DEV_BRIDGE; |
@@ -895,6 +880,120 @@ void pnv_pci_reset_secondary_bus(struct pci_dev *dev) | |||
895 | } | 880 | } |
896 | } | 881 | } |
897 | 882 | ||
883 | static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, const char *type, | ||
884 | int pos, u16 mask) | ||
885 | { | ||
886 | struct eeh_dev *edev = pdn_to_eeh_dev(pdn); | ||
887 | int i, status = 0; | ||
888 | |||
889 | /* Wait for Transaction Pending bit to be cleared */ | ||
890 | for (i = 0; i < 4; i++) { | ||
891 | eeh_ops->read_config(pdn, pos, 2, &status); | ||
892 | if (!(status & mask)) | ||
893 | return; | ||
894 | |||
895 | msleep((1 << i) * 100); | ||
896 | } | ||
897 | |||
898 | pr_warn("%s: Pending transaction while issuing %sFLR to %04x:%02x:%02x.%01x\n", | ||
899 | __func__, type, | ||
900 | edev->phb->global_number, pdn->busno, | ||
901 | PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn)); | ||
902 | } | ||
903 | |||
904 | static int pnv_eeh_do_flr(struct pci_dn *pdn, int option) | ||
905 | { | ||
906 | struct eeh_dev *edev = pdn_to_eeh_dev(pdn); | ||
907 | u32 reg = 0; | ||
908 | |||
909 | if (WARN_ON(!edev->pcie_cap)) | ||
910 | return -ENOTTY; | ||
911 | |||
912 | eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCAP, 4, ®); | ||
913 | if (!(reg & PCI_EXP_DEVCAP_FLR)) | ||
914 | return -ENOTTY; | ||
915 | |||
916 | switch (option) { | ||
917 | case EEH_RESET_HOT: | ||
918 | case EEH_RESET_FUNDAMENTAL: | ||
919 | pnv_eeh_wait_for_pending(pdn, "", | ||
920 | edev->pcie_cap + PCI_EXP_DEVSTA, | ||
921 | PCI_EXP_DEVSTA_TRPND); | ||
922 | eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, | ||
923 | 4, ®); | ||
924 | reg |= PCI_EXP_DEVCTL_BCR_FLR; | ||
925 | eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, | ||
926 | 4, reg); | ||
927 | msleep(EEH_PE_RST_HOLD_TIME); | ||
928 | break; | ||
929 | case EEH_RESET_DEACTIVATE: | ||
930 | eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, | ||
931 | 4, ®); | ||
932 | reg &= ~PCI_EXP_DEVCTL_BCR_FLR; | ||
933 | eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, | ||
934 | 4, reg); | ||
935 | msleep(EEH_PE_RST_SETTLE_TIME); | ||
936 | break; | ||
937 | } | ||
938 | |||
939 | return 0; | ||
940 | } | ||
941 | |||
942 | static int pnv_eeh_do_af_flr(struct pci_dn *pdn, int option) | ||
943 | { | ||
944 | struct eeh_dev *edev = pdn_to_eeh_dev(pdn); | ||
945 | u32 cap = 0; | ||
946 | |||
947 | if (WARN_ON(!edev->af_cap)) | ||
948 | return -ENOTTY; | ||
949 | |||
950 | eeh_ops->read_config(pdn, edev->af_cap + PCI_AF_CAP, 1, &cap); | ||
951 | if (!(cap & PCI_AF_CAP_TP) || !(cap & PCI_AF_CAP_FLR)) | ||
952 | return -ENOTTY; | ||
953 | |||
954 | switch (option) { | ||
955 | case EEH_RESET_HOT: | ||
956 | case EEH_RESET_FUNDAMENTAL: | ||
957 | /* | ||
958 | * Wait for Transaction Pending bit to clear. A word-aligned | ||
959 | * test is used, so we use the conrol offset rather than status | ||
960 | * and shift the test bit to match. | ||
961 | */ | ||
962 | pnv_eeh_wait_for_pending(pdn, "AF", | ||
963 | edev->af_cap + PCI_AF_CTRL, | ||
964 | PCI_AF_STATUS_TP << 8); | ||
965 | eeh_ops->write_config(pdn, edev->af_cap + PCI_AF_CTRL, | ||
966 | 1, PCI_AF_CTRL_FLR); | ||
967 | msleep(EEH_PE_RST_HOLD_TIME); | ||
968 | break; | ||
969 | case EEH_RESET_DEACTIVATE: | ||
970 | eeh_ops->write_config(pdn, edev->af_cap + PCI_AF_CTRL, 1, 0); | ||
971 | msleep(EEH_PE_RST_SETTLE_TIME); | ||
972 | break; | ||
973 | } | ||
974 | |||
975 | return 0; | ||
976 | } | ||
977 | |||
978 | static int pnv_eeh_reset_vf_pe(struct eeh_pe *pe, int option) | ||
979 | { | ||
980 | struct eeh_dev *edev; | ||
981 | struct pci_dn *pdn; | ||
982 | int ret; | ||
983 | |||
984 | /* The VF PE should have only one child device */ | ||
985 | edev = list_first_entry_or_null(&pe->edevs, struct eeh_dev, list); | ||
986 | pdn = eeh_dev_to_pdn(edev); | ||
987 | if (!pdn) | ||
988 | return -ENXIO; | ||
989 | |||
990 | ret = pnv_eeh_do_flr(pdn, option); | ||
991 | if (!ret) | ||
992 | return ret; | ||
993 | |||
994 | return pnv_eeh_do_af_flr(pdn, option); | ||
995 | } | ||
996 | |||
898 | /** | 997 | /** |
899 | * pnv_eeh_reset - Reset the specified PE | 998 | * pnv_eeh_reset - Reset the specified PE |
900 | * @pe: EEH PE | 999 | * @pe: EEH PE |
@@ -956,7 +1055,9 @@ static int pnv_eeh_reset(struct eeh_pe *pe, int option) | |||
956 | } | 1055 | } |
957 | 1056 | ||
958 | bus = eeh_pe_bus_get(pe); | 1057 | bus = eeh_pe_bus_get(pe); |
959 | if (pci_is_root_bus(bus) || | 1058 | if (pe->type & EEH_PE_VF) |
1059 | ret = pnv_eeh_reset_vf_pe(pe, option); | ||
1060 | else if (pci_is_root_bus(bus) || | ||
960 | pci_is_root_bus(bus->parent)) | 1061 | pci_is_root_bus(bus->parent)) |
961 | ret = pnv_eeh_root_reset(hose, option); | 1062 | ret = pnv_eeh_root_reset(hose, option); |
962 | else | 1063 | else |
@@ -1095,6 +1196,14 @@ static inline bool pnv_eeh_cfg_blocked(struct pci_dn *pdn) | |||
1095 | if (!edev || !edev->pe) | 1196 | if (!edev || !edev->pe) |
1096 | return false; | 1197 | return false; |
1097 | 1198 | ||
1199 | /* | ||
1200 | * We will issue FLR or AF FLR to all VFs, which are contained | ||
1201 | * in VF PE. It relies on the EEH PCI config accessors. So we | ||
1202 | * can't block them during the window. | ||
1203 | */ | ||
1204 | if (edev->physfn && (edev->pe->state & EEH_PE_RESET)) | ||
1205 | return false; | ||
1206 | |||
1098 | if (edev->pe->state & EEH_PE_CFG_BLOCKED) | 1207 | if (edev->pe->state & EEH_PE_CFG_BLOCKED) |
1099 | return true; | 1208 | return true; |
1100 | 1209 | ||
@@ -1479,6 +1588,65 @@ static int pnv_eeh_next_error(struct eeh_pe **pe) | |||
1479 | return ret; | 1588 | return ret; |
1480 | } | 1589 | } |
1481 | 1590 | ||
1591 | static int pnv_eeh_restore_vf_config(struct pci_dn *pdn) | ||
1592 | { | ||
1593 | struct eeh_dev *edev = pdn_to_eeh_dev(pdn); | ||
1594 | u32 devctl, cmd, cap2, aer_capctl; | ||
1595 | int old_mps; | ||
1596 | |||
1597 | if (edev->pcie_cap) { | ||
1598 | /* Restore MPS */ | ||
1599 | old_mps = (ffs(pdn->mps) - 8) << 5; | ||
1600 | eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, | ||
1601 | 2, &devctl); | ||
1602 | devctl &= ~PCI_EXP_DEVCTL_PAYLOAD; | ||
1603 | devctl |= old_mps; | ||
1604 | eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, | ||
1605 | 2, devctl); | ||
1606 | |||
1607 | /* Disable Completion Timeout */ | ||
1608 | eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCAP2, | ||
1609 | 4, &cap2); | ||
1610 | if (cap2 & 0x10) { | ||
1611 | eeh_ops->read_config(pdn, | ||
1612 | edev->pcie_cap + PCI_EXP_DEVCTL2, | ||
1613 | 4, &cap2); | ||
1614 | cap2 |= 0x10; | ||
1615 | eeh_ops->write_config(pdn, | ||
1616 | edev->pcie_cap + PCI_EXP_DEVCTL2, | ||
1617 | 4, cap2); | ||
1618 | } | ||
1619 | } | ||
1620 | |||
1621 | /* Enable SERR and parity checking */ | ||
1622 | eeh_ops->read_config(pdn, PCI_COMMAND, 2, &cmd); | ||
1623 | cmd |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); | ||
1624 | eeh_ops->write_config(pdn, PCI_COMMAND, 2, cmd); | ||
1625 | |||
1626 | /* Enable report various errors */ | ||
1627 | if (edev->pcie_cap) { | ||
1628 | eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, | ||
1629 | 2, &devctl); | ||
1630 | devctl &= ~PCI_EXP_DEVCTL_CERE; | ||
1631 | devctl |= (PCI_EXP_DEVCTL_NFERE | | ||
1632 | PCI_EXP_DEVCTL_FERE | | ||
1633 | PCI_EXP_DEVCTL_URRE); | ||
1634 | eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, | ||
1635 | 2, devctl); | ||
1636 | } | ||
1637 | |||
1638 | /* Enable ECRC generation and check */ | ||
1639 | if (edev->pcie_cap && edev->aer_cap) { | ||
1640 | eeh_ops->read_config(pdn, edev->aer_cap + PCI_ERR_CAP, | ||
1641 | 4, &aer_capctl); | ||
1642 | aer_capctl |= (PCI_ERR_CAP_ECRC_GENE | PCI_ERR_CAP_ECRC_CHKE); | ||
1643 | eeh_ops->write_config(pdn, edev->aer_cap + PCI_ERR_CAP, | ||
1644 | 4, aer_capctl); | ||
1645 | } | ||
1646 | |||
1647 | return 0; | ||
1648 | } | ||
1649 | |||
1482 | static int pnv_eeh_restore_config(struct pci_dn *pdn) | 1650 | static int pnv_eeh_restore_config(struct pci_dn *pdn) |
1483 | { | 1651 | { |
1484 | struct eeh_dev *edev = pdn_to_eeh_dev(pdn); | 1652 | struct eeh_dev *edev = pdn_to_eeh_dev(pdn); |
@@ -1488,9 +1656,21 @@ static int pnv_eeh_restore_config(struct pci_dn *pdn) | |||
1488 | if (!edev) | 1656 | if (!edev) |
1489 | return -EEXIST; | 1657 | return -EEXIST; |
1490 | 1658 | ||
1491 | phb = edev->phb->private_data; | 1659 | /* |
1492 | ret = opal_pci_reinit(phb->opal_id, | 1660 | * We have to restore the PCI config space after reset since the |
1493 | OPAL_REINIT_PCI_DEV, edev->config_addr); | 1661 | * firmware can't see SRIOV VFs. |
1662 | * | ||
1663 | * FIXME: The MPS, error routing rules, timeout setting are worthy | ||
1664 | * to be exported by firmware in extendible way. | ||
1665 | */ | ||
1666 | if (edev->physfn) { | ||
1667 | ret = pnv_eeh_restore_vf_config(pdn); | ||
1668 | } else { | ||
1669 | phb = edev->phb->private_data; | ||
1670 | ret = opal_pci_reinit(phb->opal_id, | ||
1671 | OPAL_REINIT_PCI_DEV, edev->config_addr); | ||
1672 | } | ||
1673 | |||
1494 | if (ret) { | 1674 | if (ret) { |
1495 | pr_warn("%s: Can't reinit PCI dev 0x%x (%lld)\n", | 1675 | pr_warn("%s: Can't reinit PCI dev 0x%x (%lld)\n", |
1496 | __func__, edev->config_addr, ret); | 1676 | __func__, edev->config_addr, ret); |
@@ -1519,6 +1699,40 @@ static struct eeh_ops pnv_eeh_ops = { | |||
1519 | .restore_config = pnv_eeh_restore_config | 1699 | .restore_config = pnv_eeh_restore_config |
1520 | }; | 1700 | }; |
1521 | 1701 | ||
1702 | void pcibios_bus_add_device(struct pci_dev *pdev) | ||
1703 | { | ||
1704 | struct pci_dn *pdn = pci_get_pdn(pdev); | ||
1705 | |||
1706 | if (!pdev->is_virtfn) | ||
1707 | return; | ||
1708 | |||
1709 | /* | ||
1710 | * The following operations will fail if VF's sysfs files | ||
1711 | * aren't created or its resources aren't finalized. | ||
1712 | */ | ||
1713 | eeh_add_device_early(pdn); | ||
1714 | eeh_add_device_late(pdev); | ||
1715 | eeh_sysfs_add_device(pdev); | ||
1716 | } | ||
1717 | |||
1718 | #ifdef CONFIG_PCI_IOV | ||
1719 | static void pnv_pci_fixup_vf_mps(struct pci_dev *pdev) | ||
1720 | { | ||
1721 | struct pci_dn *pdn = pci_get_pdn(pdev); | ||
1722 | int parent_mps; | ||
1723 | |||
1724 | if (!pdev->is_virtfn) | ||
1725 | return; | ||
1726 | |||
1727 | /* Synchronize MPS for VF and PF */ | ||
1728 | parent_mps = pcie_get_mps(pdev->physfn); | ||
1729 | if ((128 << pdev->pcie_mpss) >= parent_mps) | ||
1730 | pcie_set_mps(pdev, parent_mps); | ||
1731 | pdn->mps = pcie_get_mps(pdev); | ||
1732 | } | ||
1733 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pnv_pci_fixup_vf_mps); | ||
1734 | #endif /* CONFIG_PCI_IOV */ | ||
1735 | |||
1522 | /** | 1736 | /** |
1523 | * eeh_powernv_init - Register platform dependent EEH operations | 1737 | * eeh_powernv_init - Register platform dependent EEH operations |
1524 | * | 1738 | * |
diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index 15bfbcd5debc..fcc8b6861b63 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c | |||
@@ -35,9 +35,9 @@ int pnv_save_sprs_for_winkle(void) | |||
35 | int rc; | 35 | int rc; |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * hid0, hid1, hid4, hid5, hmeer and lpcr values are symmetric accross | 38 | * hid0, hid1, hid4, hid5, hmeer and lpcr values are symmetric across |
39 | * all cpus at boot. Get these reg values of current cpu and use the | 39 | * all cpus at boot. Get these reg values of current cpu and use the |
40 | * same accross all cpus. | 40 | * same across all cpus. |
41 | */ | 41 | */ |
42 | uint64_t lpcr_val = mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1; | 42 | uint64_t lpcr_val = mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1; |
43 | uint64_t hid0_val = mfspr(SPRN_HID0); | 43 | uint64_t hid0_val = mfspr(SPRN_HID0); |
@@ -185,7 +185,7 @@ static ssize_t store_fastsleep_workaround_applyonce(struct device *dev, | |||
185 | * fastsleep workaround needs to be left in 'applied' state on all | 185 | * fastsleep workaround needs to be left in 'applied' state on all |
186 | * the cores. Do this by- | 186 | * the cores. Do this by- |
187 | * 1. Patching out the call to 'undo' workaround in fastsleep exit path | 187 | * 1. Patching out the call to 'undo' workaround in fastsleep exit path |
188 | * 2. Sending ipi to all the cores which have atleast one online thread | 188 | * 2. Sending ipi to all the cores which have at least one online thread |
189 | * 3. Patching out the call to 'apply' workaround in fastsleep entry | 189 | * 3. Patching out the call to 'apply' workaround in fastsleep entry |
190 | * path | 190 | * path |
191 | * There is no need to send ipi to cores which have all threads | 191 | * There is no need to send ipi to cores which have all threads |
diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c index e85aa900f5c0..7229acd9bb3a 100644 --- a/arch/powerpc/platforms/powernv/npu-dma.c +++ b/arch/powerpc/platforms/powernv/npu-dma.c | |||
@@ -278,7 +278,7 @@ static void pnv_npu_disable_bypass(struct pnv_ioda_pe *npe) | |||
278 | 278 | ||
279 | /* | 279 | /* |
280 | * Enable/disable bypass mode on the NPU. The NPU only supports one | 280 | * Enable/disable bypass mode on the NPU. The NPU only supports one |
281 | * window per link, so bypass needs to be explicity enabled or | 281 | * window per link, so bypass needs to be explicitly enabled or |
282 | * disabled. Unlike for a PHB3 bypass and non-bypass modes can't be | 282 | * disabled. Unlike for a PHB3 bypass and non-bypass modes can't be |
283 | * active at the same time. | 283 | * active at the same time. |
284 | */ | 284 | */ |
diff --git a/arch/powerpc/platforms/powernv/opal-msglog.c b/arch/powerpc/platforms/powernv/opal-msglog.c index 44ed78af1a0d..39d6ff9e5630 100644 --- a/arch/powerpc/platforms/powernv/opal-msglog.c +++ b/arch/powerpc/platforms/powernv/opal-msglog.c | |||
@@ -31,26 +31,25 @@ struct memcons { | |||
31 | __be32 in_cons; | 31 | __be32 in_cons; |
32 | }; | 32 | }; |
33 | 33 | ||
34 | static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj, | 34 | static struct memcons *opal_memcons = NULL; |
35 | struct bin_attribute *bin_attr, char *to, | 35 | |
36 | loff_t pos, size_t count) | 36 | ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count) |
37 | { | 37 | { |
38 | struct memcons *mc = bin_attr->private; | ||
39 | const char *conbuf; | 38 | const char *conbuf; |
40 | ssize_t ret; | 39 | ssize_t ret; |
41 | size_t first_read = 0; | 40 | size_t first_read = 0; |
42 | uint32_t out_pos, avail; | 41 | uint32_t out_pos, avail; |
43 | 42 | ||
44 | if (!mc) | 43 | if (!opal_memcons) |
45 | return -ENODEV; | 44 | return -ENODEV; |
46 | 45 | ||
47 | out_pos = be32_to_cpu(ACCESS_ONCE(mc->out_pos)); | 46 | out_pos = be32_to_cpu(ACCESS_ONCE(opal_memcons->out_pos)); |
48 | 47 | ||
49 | /* Now we've read out_pos, put a barrier in before reading the new | 48 | /* Now we've read out_pos, put a barrier in before reading the new |
50 | * data it points to in conbuf. */ | 49 | * data it points to in conbuf. */ |
51 | smp_rmb(); | 50 | smp_rmb(); |
52 | 51 | ||
53 | conbuf = phys_to_virt(be64_to_cpu(mc->obuf_phys)); | 52 | conbuf = phys_to_virt(be64_to_cpu(opal_memcons->obuf_phys)); |
54 | 53 | ||
55 | /* When the buffer has wrapped, read from the out_pos marker to the end | 54 | /* When the buffer has wrapped, read from the out_pos marker to the end |
56 | * of the buffer, and then read the remaining data as in the un-wrapped | 55 | * of the buffer, and then read the remaining data as in the un-wrapped |
@@ -58,7 +57,7 @@ static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj, | |||
58 | if (out_pos & MEMCONS_OUT_POS_WRAP) { | 57 | if (out_pos & MEMCONS_OUT_POS_WRAP) { |
59 | 58 | ||
60 | out_pos &= MEMCONS_OUT_POS_MASK; | 59 | out_pos &= MEMCONS_OUT_POS_MASK; |
61 | avail = be32_to_cpu(mc->obuf_size) - out_pos; | 60 | avail = be32_to_cpu(opal_memcons->obuf_size) - out_pos; |
62 | 61 | ||
63 | ret = memory_read_from_buffer(to, count, &pos, | 62 | ret = memory_read_from_buffer(to, count, &pos, |
64 | conbuf + out_pos, avail); | 63 | conbuf + out_pos, avail); |
@@ -76,7 +75,7 @@ static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj, | |||
76 | } | 75 | } |
77 | 76 | ||
78 | /* Sanity check. The firmware should not do this to us. */ | 77 | /* Sanity check. The firmware should not do this to us. */ |
79 | if (out_pos > be32_to_cpu(mc->obuf_size)) { | 78 | if (out_pos > be32_to_cpu(opal_memcons->obuf_size)) { |
80 | pr_err("OPAL: memory console corruption. Aborting read.\n"); | 79 | pr_err("OPAL: memory console corruption. Aborting read.\n"); |
81 | return -EINVAL; | 80 | return -EINVAL; |
82 | } | 81 | } |
@@ -91,6 +90,13 @@ out: | |||
91 | return ret; | 90 | return ret; |
92 | } | 91 | } |
93 | 92 | ||
93 | static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj, | ||
94 | struct bin_attribute *bin_attr, char *to, | ||
95 | loff_t pos, size_t count) | ||
96 | { | ||
97 | return opal_msglog_copy(to, pos, count); | ||
98 | } | ||
99 | |||
94 | static struct bin_attribute opal_msglog_attr = { | 100 | static struct bin_attribute opal_msglog_attr = { |
95 | .attr = {.name = "msglog", .mode = 0444}, | 101 | .attr = {.name = "msglog", .mode = 0444}, |
96 | .read = opal_msglog_read | 102 | .read = opal_msglog_read |
@@ -117,7 +123,15 @@ void __init opal_msglog_init(void) | |||
117 | return; | 123 | return; |
118 | } | 124 | } |
119 | 125 | ||
120 | opal_msglog_attr.private = mc; | 126 | opal_memcons = mc; |
127 | } | ||
128 | |||
129 | void __init opal_msglog_sysfs_init(void) | ||
130 | { | ||
131 | if (!opal_memcons) { | ||
132 | pr_warn("OPAL: message log initialisation failed, not creating sysfs entry\n"); | ||
133 | return; | ||
134 | } | ||
121 | 135 | ||
122 | if (sysfs_create_bin_file(opal_kobj, &opal_msglog_attr) != 0) | 136 | if (sysfs_create_bin_file(opal_kobj, &opal_msglog_attr) != 0) |
123 | pr_warn("OPAL: sysfs file creation failed\n"); | 137 | pr_warn("OPAL: sysfs file creation failed\n"); |
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 4e0da5af94a1..0256d0729252 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c | |||
@@ -724,6 +724,9 @@ static int __init opal_init(void) | |||
724 | of_node_put(leds); | 724 | of_node_put(leds); |
725 | } | 725 | } |
726 | 726 | ||
727 | /* Initialise OPAL message log interface */ | ||
728 | opal_msglog_init(); | ||
729 | |||
727 | /* Create "opal" kobject under /sys/firmware */ | 730 | /* Create "opal" kobject under /sys/firmware */ |
728 | rc = opal_sysfs_init(); | 731 | rc = opal_sysfs_init(); |
729 | if (rc == 0) { | 732 | if (rc == 0) { |
@@ -739,8 +742,8 @@ static int __init opal_init(void) | |||
739 | opal_platform_dump_init(); | 742 | opal_platform_dump_init(); |
740 | /* Setup system parameters interface */ | 743 | /* Setup system parameters interface */ |
741 | opal_sys_param_init(); | 744 | opal_sys_param_init(); |
742 | /* Setup message log interface. */ | 745 | /* Setup message log sysfs interface. */ |
743 | opal_msglog_init(); | 746 | opal_msglog_sysfs_init(); |
744 | } | 747 | } |
745 | 748 | ||
746 | /* Initialize platform devices: IPMI backend, PRD & flash interface */ | 749 | /* Initialize platform devices: IPMI backend, PRD & flash interface */ |
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index f90dc04395bf..c5baaf3cc4e5 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
@@ -872,9 +872,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset) | |||
872 | if (!res->flags || !res->parent) | 872 | if (!res->flags || !res->parent) |
873 | continue; | 873 | continue; |
874 | 874 | ||
875 | if (!pnv_pci_is_mem_pref_64(res->flags)) | ||
876 | continue; | ||
877 | |||
878 | /* | 875 | /* |
879 | * The actual IOV BAR range is determined by the start address | 876 | * The actual IOV BAR range is determined by the start address |
880 | * and the actual size for num_vfs VFs BAR. This check is to | 877 | * and the actual size for num_vfs VFs BAR. This check is to |
@@ -903,9 +900,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset) | |||
903 | if (!res->flags || !res->parent) | 900 | if (!res->flags || !res->parent) |
904 | continue; | 901 | continue; |
905 | 902 | ||
906 | if (!pnv_pci_is_mem_pref_64(res->flags)) | ||
907 | continue; | ||
908 | |||
909 | size = pci_iov_resource_size(dev, i + PCI_IOV_RESOURCES); | 903 | size = pci_iov_resource_size(dev, i + PCI_IOV_RESOURCES); |
910 | res2 = *res; | 904 | res2 = *res; |
911 | res->start += size * offset; | 905 | res->start += size * offset; |
@@ -1196,29 +1190,36 @@ static void pnv_pci_ioda_setup_PEs(void) | |||
1196 | } | 1190 | } |
1197 | 1191 | ||
1198 | #ifdef CONFIG_PCI_IOV | 1192 | #ifdef CONFIG_PCI_IOV |
1199 | static int pnv_pci_vf_release_m64(struct pci_dev *pdev) | 1193 | static int pnv_pci_vf_release_m64(struct pci_dev *pdev, u16 num_vfs) |
1200 | { | 1194 | { |
1201 | struct pci_bus *bus; | 1195 | struct pci_bus *bus; |
1202 | struct pci_controller *hose; | 1196 | struct pci_controller *hose; |
1203 | struct pnv_phb *phb; | 1197 | struct pnv_phb *phb; |
1204 | struct pci_dn *pdn; | 1198 | struct pci_dn *pdn; |
1205 | int i, j; | 1199 | int i, j; |
1200 | int m64_bars; | ||
1206 | 1201 | ||
1207 | bus = pdev->bus; | 1202 | bus = pdev->bus; |
1208 | hose = pci_bus_to_host(bus); | 1203 | hose = pci_bus_to_host(bus); |
1209 | phb = hose->private_data; | 1204 | phb = hose->private_data; |
1210 | pdn = pci_get_pdn(pdev); | 1205 | pdn = pci_get_pdn(pdev); |
1211 | 1206 | ||
1207 | if (pdn->m64_single_mode) | ||
1208 | m64_bars = num_vfs; | ||
1209 | else | ||
1210 | m64_bars = 1; | ||
1211 | |||
1212 | for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) | 1212 | for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) |
1213 | for (j = 0; j < M64_PER_IOV; j++) { | 1213 | for (j = 0; j < m64_bars; j++) { |
1214 | if (pdn->m64_wins[i][j] == IODA_INVALID_M64) | 1214 | if (pdn->m64_map[j][i] == IODA_INVALID_M64) |
1215 | continue; | 1215 | continue; |
1216 | opal_pci_phb_mmio_enable(phb->opal_id, | 1216 | opal_pci_phb_mmio_enable(phb->opal_id, |
1217 | OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 0); | 1217 | OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 0); |
1218 | clear_bit(pdn->m64_wins[i][j], &phb->ioda.m64_bar_alloc); | 1218 | clear_bit(pdn->m64_map[j][i], &phb->ioda.m64_bar_alloc); |
1219 | pdn->m64_wins[i][j] = IODA_INVALID_M64; | 1219 | pdn->m64_map[j][i] = IODA_INVALID_M64; |
1220 | } | 1220 | } |
1221 | 1221 | ||
1222 | kfree(pdn->m64_map); | ||
1222 | return 0; | 1223 | return 0; |
1223 | } | 1224 | } |
1224 | 1225 | ||
@@ -1235,8 +1236,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) | |||
1235 | int total_vfs; | 1236 | int total_vfs; |
1236 | resource_size_t size, start; | 1237 | resource_size_t size, start; |
1237 | int pe_num; | 1238 | int pe_num; |
1238 | int vf_groups; | 1239 | int m64_bars; |
1239 | int vf_per_group; | ||
1240 | 1240 | ||
1241 | bus = pdev->bus; | 1241 | bus = pdev->bus; |
1242 | hose = pci_bus_to_host(bus); | 1242 | hose = pci_bus_to_host(bus); |
@@ -1244,29 +1244,26 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) | |||
1244 | pdn = pci_get_pdn(pdev); | 1244 | pdn = pci_get_pdn(pdev); |
1245 | total_vfs = pci_sriov_get_totalvfs(pdev); | 1245 | total_vfs = pci_sriov_get_totalvfs(pdev); |
1246 | 1246 | ||
1247 | /* Initialize the m64_wins to IODA_INVALID_M64 */ | 1247 | if (pdn->m64_single_mode) |
1248 | for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) | 1248 | m64_bars = num_vfs; |
1249 | for (j = 0; j < M64_PER_IOV; j++) | 1249 | else |
1250 | pdn->m64_wins[i][j] = IODA_INVALID_M64; | 1250 | m64_bars = 1; |
1251 | |||
1252 | pdn->m64_map = kmalloc(sizeof(*pdn->m64_map) * m64_bars, GFP_KERNEL); | ||
1253 | if (!pdn->m64_map) | ||
1254 | return -ENOMEM; | ||
1255 | /* Initialize the m64_map to IODA_INVALID_M64 */ | ||
1256 | for (i = 0; i < m64_bars ; i++) | ||
1257 | for (j = 0; j < PCI_SRIOV_NUM_BARS; j++) | ||
1258 | pdn->m64_map[i][j] = IODA_INVALID_M64; | ||
1251 | 1259 | ||
1252 | if (pdn->m64_per_iov == M64_PER_IOV) { | ||
1253 | vf_groups = (num_vfs <= M64_PER_IOV) ? num_vfs: M64_PER_IOV; | ||
1254 | vf_per_group = (num_vfs <= M64_PER_IOV)? 1: | ||
1255 | roundup_pow_of_two(num_vfs) / pdn->m64_per_iov; | ||
1256 | } else { | ||
1257 | vf_groups = 1; | ||
1258 | vf_per_group = 1; | ||
1259 | } | ||
1260 | 1260 | ||
1261 | for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { | 1261 | for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { |
1262 | res = &pdev->resource[i + PCI_IOV_RESOURCES]; | 1262 | res = &pdev->resource[i + PCI_IOV_RESOURCES]; |
1263 | if (!res->flags || !res->parent) | 1263 | if (!res->flags || !res->parent) |
1264 | continue; | 1264 | continue; |
1265 | 1265 | ||
1266 | if (!pnv_pci_is_mem_pref_64(res->flags)) | 1266 | for (j = 0; j < m64_bars; j++) { |
1267 | continue; | ||
1268 | |||
1269 | for (j = 0; j < vf_groups; j++) { | ||
1270 | do { | 1267 | do { |
1271 | win = find_next_zero_bit(&phb->ioda.m64_bar_alloc, | 1268 | win = find_next_zero_bit(&phb->ioda.m64_bar_alloc, |
1272 | phb->ioda.m64_bar_idx + 1, 0); | 1269 | phb->ioda.m64_bar_idx + 1, 0); |
@@ -1275,12 +1272,11 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) | |||
1275 | goto m64_failed; | 1272 | goto m64_failed; |
1276 | } while (test_and_set_bit(win, &phb->ioda.m64_bar_alloc)); | 1273 | } while (test_and_set_bit(win, &phb->ioda.m64_bar_alloc)); |
1277 | 1274 | ||
1278 | pdn->m64_wins[i][j] = win; | 1275 | pdn->m64_map[j][i] = win; |
1279 | 1276 | ||
1280 | if (pdn->m64_per_iov == M64_PER_IOV) { | 1277 | if (pdn->m64_single_mode) { |
1281 | size = pci_iov_resource_size(pdev, | 1278 | size = pci_iov_resource_size(pdev, |
1282 | PCI_IOV_RESOURCES + i); | 1279 | PCI_IOV_RESOURCES + i); |
1283 | size = size * vf_per_group; | ||
1284 | start = res->start + size * j; | 1280 | start = res->start + size * j; |
1285 | } else { | 1281 | } else { |
1286 | size = resource_size(res); | 1282 | size = resource_size(res); |
@@ -1288,16 +1284,16 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) | |||
1288 | } | 1284 | } |
1289 | 1285 | ||
1290 | /* Map the M64 here */ | 1286 | /* Map the M64 here */ |
1291 | if (pdn->m64_per_iov == M64_PER_IOV) { | 1287 | if (pdn->m64_single_mode) { |
1292 | pe_num = pdn->offset + j; | 1288 | pe_num = pdn->pe_num_map[j]; |
1293 | rc = opal_pci_map_pe_mmio_window(phb->opal_id, | 1289 | rc = opal_pci_map_pe_mmio_window(phb->opal_id, |
1294 | pe_num, OPAL_M64_WINDOW_TYPE, | 1290 | pe_num, OPAL_M64_WINDOW_TYPE, |
1295 | pdn->m64_wins[i][j], 0); | 1291 | pdn->m64_map[j][i], 0); |
1296 | } | 1292 | } |
1297 | 1293 | ||
1298 | rc = opal_pci_set_phb_mem_window(phb->opal_id, | 1294 | rc = opal_pci_set_phb_mem_window(phb->opal_id, |
1299 | OPAL_M64_WINDOW_TYPE, | 1295 | OPAL_M64_WINDOW_TYPE, |
1300 | pdn->m64_wins[i][j], | 1296 | pdn->m64_map[j][i], |
1301 | start, | 1297 | start, |
1302 | 0, /* unused */ | 1298 | 0, /* unused */ |
1303 | size); | 1299 | size); |
@@ -1309,12 +1305,12 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) | |||
1309 | goto m64_failed; | 1305 | goto m64_failed; |
1310 | } | 1306 | } |
1311 | 1307 | ||
1312 | if (pdn->m64_per_iov == M64_PER_IOV) | 1308 | if (pdn->m64_single_mode) |
1313 | rc = opal_pci_phb_mmio_enable(phb->opal_id, | 1309 | rc = opal_pci_phb_mmio_enable(phb->opal_id, |
1314 | OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 2); | 1310 | OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 2); |
1315 | else | 1311 | else |
1316 | rc = opal_pci_phb_mmio_enable(phb->opal_id, | 1312 | rc = opal_pci_phb_mmio_enable(phb->opal_id, |
1317 | OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 1); | 1313 | OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 1); |
1318 | 1314 | ||
1319 | if (rc != OPAL_SUCCESS) { | 1315 | if (rc != OPAL_SUCCESS) { |
1320 | dev_err(&pdev->dev, "Failed to enable M64 window #%d: %llx\n", | 1316 | dev_err(&pdev->dev, "Failed to enable M64 window #%d: %llx\n", |
@@ -1326,7 +1322,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) | |||
1326 | return 0; | 1322 | return 0; |
1327 | 1323 | ||
1328 | m64_failed: | 1324 | m64_failed: |
1329 | pnv_pci_vf_release_m64(pdev); | 1325 | pnv_pci_vf_release_m64(pdev, num_vfs); |
1330 | return -EBUSY; | 1326 | return -EBUSY; |
1331 | } | 1327 | } |
1332 | 1328 | ||
@@ -1353,15 +1349,13 @@ static void pnv_pci_ioda2_release_dma_pe(struct pci_dev *dev, struct pnv_ioda_pe | |||
1353 | iommu_free_table(tbl, of_node_full_name(dev->dev.of_node)); | 1349 | iommu_free_table(tbl, of_node_full_name(dev->dev.of_node)); |
1354 | } | 1350 | } |
1355 | 1351 | ||
1356 | static void pnv_ioda_release_vf_PE(struct pci_dev *pdev, u16 num_vfs) | 1352 | static void pnv_ioda_release_vf_PE(struct pci_dev *pdev) |
1357 | { | 1353 | { |
1358 | struct pci_bus *bus; | 1354 | struct pci_bus *bus; |
1359 | struct pci_controller *hose; | 1355 | struct pci_controller *hose; |
1360 | struct pnv_phb *phb; | 1356 | struct pnv_phb *phb; |
1361 | struct pnv_ioda_pe *pe, *pe_n; | 1357 | struct pnv_ioda_pe *pe, *pe_n; |
1362 | struct pci_dn *pdn; | 1358 | struct pci_dn *pdn; |
1363 | u16 vf_index; | ||
1364 | int64_t rc; | ||
1365 | 1359 | ||
1366 | bus = pdev->bus; | 1360 | bus = pdev->bus; |
1367 | hose = pci_bus_to_host(bus); | 1361 | hose = pci_bus_to_host(bus); |
@@ -1371,35 +1365,6 @@ static void pnv_ioda_release_vf_PE(struct pci_dev *pdev, u16 num_vfs) | |||
1371 | if (!pdev->is_physfn) | 1365 | if (!pdev->is_physfn) |
1372 | return; | 1366 | return; |
1373 | 1367 | ||
1374 | if (pdn->m64_per_iov == M64_PER_IOV && num_vfs > M64_PER_IOV) { | ||
1375 | int vf_group; | ||
1376 | int vf_per_group; | ||
1377 | int vf_index1; | ||
1378 | |||
1379 | vf_per_group = roundup_pow_of_two(num_vfs) / pdn->m64_per_iov; | ||
1380 | |||
1381 | for (vf_group = 0; vf_group < M64_PER_IOV; vf_group++) | ||
1382 | for (vf_index = vf_group * vf_per_group; | ||
1383 | vf_index < (vf_group + 1) * vf_per_group && | ||
1384 | vf_index < num_vfs; | ||
1385 | vf_index++) | ||
1386 | for (vf_index1 = vf_group * vf_per_group; | ||
1387 | vf_index1 < (vf_group + 1) * vf_per_group && | ||
1388 | vf_index1 < num_vfs; | ||
1389 | vf_index1++){ | ||
1390 | |||
1391 | rc = opal_pci_set_peltv(phb->opal_id, | ||
1392 | pdn->offset + vf_index, | ||
1393 | pdn->offset + vf_index1, | ||
1394 | OPAL_REMOVE_PE_FROM_DOMAIN); | ||
1395 | |||
1396 | if (rc) | ||
1397 | dev_warn(&pdev->dev, "%s: Failed to unlink same group PE#%d(%lld)\n", | ||
1398 | __func__, | ||
1399 | pdn->offset + vf_index1, rc); | ||
1400 | } | ||
1401 | } | ||
1402 | |||
1403 | list_for_each_entry_safe(pe, pe_n, &phb->ioda.pe_list, list) { | 1368 | list_for_each_entry_safe(pe, pe_n, &phb->ioda.pe_list, list) { |
1404 | if (pe->parent_dev != pdev) | 1369 | if (pe->parent_dev != pdev) |
1405 | continue; | 1370 | continue; |
@@ -1424,7 +1389,7 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev) | |||
1424 | struct pnv_phb *phb; | 1389 | struct pnv_phb *phb; |
1425 | struct pci_dn *pdn; | 1390 | struct pci_dn *pdn; |
1426 | struct pci_sriov *iov; | 1391 | struct pci_sriov *iov; |
1427 | u16 num_vfs; | 1392 | u16 num_vfs, i; |
1428 | 1393 | ||
1429 | bus = pdev->bus; | 1394 | bus = pdev->bus; |
1430 | hose = pci_bus_to_host(bus); | 1395 | hose = pci_bus_to_host(bus); |
@@ -1434,18 +1399,25 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev) | |||
1434 | num_vfs = pdn->num_vfs; | 1399 | num_vfs = pdn->num_vfs; |
1435 | 1400 | ||
1436 | /* Release VF PEs */ | 1401 | /* Release VF PEs */ |
1437 | pnv_ioda_release_vf_PE(pdev, num_vfs); | 1402 | pnv_ioda_release_vf_PE(pdev); |
1438 | 1403 | ||
1439 | if (phb->type == PNV_PHB_IODA2) { | 1404 | if (phb->type == PNV_PHB_IODA2) { |
1440 | if (pdn->m64_per_iov == 1) | 1405 | if (!pdn->m64_single_mode) |
1441 | pnv_pci_vf_resource_shift(pdev, -pdn->offset); | 1406 | pnv_pci_vf_resource_shift(pdev, -*pdn->pe_num_map); |
1442 | 1407 | ||
1443 | /* Release M64 windows */ | 1408 | /* Release M64 windows */ |
1444 | pnv_pci_vf_release_m64(pdev); | 1409 | pnv_pci_vf_release_m64(pdev, num_vfs); |
1445 | 1410 | ||
1446 | /* Release PE numbers */ | 1411 | /* Release PE numbers */ |
1447 | bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs); | 1412 | if (pdn->m64_single_mode) { |
1448 | pdn->offset = 0; | 1413 | for (i = 0; i < num_vfs; i++) { |
1414 | if (pdn->pe_num_map[i] != IODA_INVALID_PE) | ||
1415 | pnv_ioda_free_pe(phb, pdn->pe_num_map[i]); | ||
1416 | } | ||
1417 | } else | ||
1418 | bitmap_clear(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs); | ||
1419 | /* Releasing pe_num_map */ | ||
1420 | kfree(pdn->pe_num_map); | ||
1449 | } | 1421 | } |
1450 | } | 1422 | } |
1451 | 1423 | ||
@@ -1460,7 +1432,6 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs) | |||
1460 | int pe_num; | 1432 | int pe_num; |
1461 | u16 vf_index; | 1433 | u16 vf_index; |
1462 | struct pci_dn *pdn; | 1434 | struct pci_dn *pdn; |
1463 | int64_t rc; | ||
1464 | 1435 | ||
1465 | bus = pdev->bus; | 1436 | bus = pdev->bus; |
1466 | hose = pci_bus_to_host(bus); | 1437 | hose = pci_bus_to_host(bus); |
@@ -1472,7 +1443,10 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs) | |||
1472 | 1443 | ||
1473 | /* Reserve PE for each VF */ | 1444 | /* Reserve PE for each VF */ |
1474 | for (vf_index = 0; vf_index < num_vfs; vf_index++) { | 1445 | for (vf_index = 0; vf_index < num_vfs; vf_index++) { |
1475 | pe_num = pdn->offset + vf_index; | 1446 | if (pdn->m64_single_mode) |
1447 | pe_num = pdn->pe_num_map[vf_index]; | ||
1448 | else | ||
1449 | pe_num = *pdn->pe_num_map + vf_index; | ||
1476 | 1450 | ||
1477 | pe = &phb->ioda.pe_array[pe_num]; | 1451 | pe = &phb->ioda.pe_array[pe_num]; |
1478 | pe->pe_number = pe_num; | 1452 | pe->pe_number = pe_num; |
@@ -1505,37 +1479,6 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs) | |||
1505 | 1479 | ||
1506 | pnv_pci_ioda2_setup_dma_pe(phb, pe); | 1480 | pnv_pci_ioda2_setup_dma_pe(phb, pe); |
1507 | } | 1481 | } |
1508 | |||
1509 | if (pdn->m64_per_iov == M64_PER_IOV && num_vfs > M64_PER_IOV) { | ||
1510 | int vf_group; | ||
1511 | int vf_per_group; | ||
1512 | int vf_index1; | ||
1513 | |||
1514 | vf_per_group = roundup_pow_of_two(num_vfs) / pdn->m64_per_iov; | ||
1515 | |||
1516 | for (vf_group = 0; vf_group < M64_PER_IOV; vf_group++) { | ||
1517 | for (vf_index = vf_group * vf_per_group; | ||
1518 | vf_index < (vf_group + 1) * vf_per_group && | ||
1519 | vf_index < num_vfs; | ||
1520 | vf_index++) { | ||
1521 | for (vf_index1 = vf_group * vf_per_group; | ||
1522 | vf_index1 < (vf_group + 1) * vf_per_group && | ||
1523 | vf_index1 < num_vfs; | ||
1524 | vf_index1++) { | ||
1525 | |||
1526 | rc = opal_pci_set_peltv(phb->opal_id, | ||
1527 | pdn->offset + vf_index, | ||
1528 | pdn->offset + vf_index1, | ||
1529 | OPAL_ADD_PE_TO_DOMAIN); | ||
1530 | |||
1531 | if (rc) | ||
1532 | dev_warn(&pdev->dev, "%s: Failed to link same group PE#%d(%lld)\n", | ||
1533 | __func__, | ||
1534 | pdn->offset + vf_index1, rc); | ||
1535 | } | ||
1536 | } | ||
1537 | } | ||
1538 | } | ||
1539 | } | 1482 | } |
1540 | 1483 | ||
1541 | int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) | 1484 | int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) |
@@ -1545,6 +1488,7 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) | |||
1545 | struct pnv_phb *phb; | 1488 | struct pnv_phb *phb; |
1546 | struct pci_dn *pdn; | 1489 | struct pci_dn *pdn; |
1547 | int ret; | 1490 | int ret; |
1491 | u16 i; | ||
1548 | 1492 | ||
1549 | bus = pdev->bus; | 1493 | bus = pdev->bus; |
1550 | hose = pci_bus_to_host(bus); | 1494 | hose = pci_bus_to_host(bus); |
@@ -1552,20 +1496,59 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) | |||
1552 | pdn = pci_get_pdn(pdev); | 1496 | pdn = pci_get_pdn(pdev); |
1553 | 1497 | ||
1554 | if (phb->type == PNV_PHB_IODA2) { | 1498 | if (phb->type == PNV_PHB_IODA2) { |
1499 | if (!pdn->vfs_expanded) { | ||
1500 | dev_info(&pdev->dev, "don't support this SRIOV device" | ||
1501 | " with non 64bit-prefetchable IOV BAR\n"); | ||
1502 | return -ENOSPC; | ||
1503 | } | ||
1504 | |||
1505 | /* | ||
1506 | * When M64 BARs functions in Single PE mode, the number of VFs | ||
1507 | * could be enabled must be less than the number of M64 BARs. | ||
1508 | */ | ||
1509 | if (pdn->m64_single_mode && num_vfs > phb->ioda.m64_bar_idx) { | ||
1510 | dev_info(&pdev->dev, "Not enough M64 BAR for VFs\n"); | ||
1511 | return -EBUSY; | ||
1512 | } | ||
1513 | |||
1514 | /* Allocating pe_num_map */ | ||
1515 | if (pdn->m64_single_mode) | ||
1516 | pdn->pe_num_map = kmalloc(sizeof(*pdn->pe_num_map) * num_vfs, | ||
1517 | GFP_KERNEL); | ||
1518 | else | ||
1519 | pdn->pe_num_map = kmalloc(sizeof(*pdn->pe_num_map), GFP_KERNEL); | ||
1520 | |||
1521 | if (!pdn->pe_num_map) | ||
1522 | return -ENOMEM; | ||
1523 | |||
1524 | if (pdn->m64_single_mode) | ||
1525 | for (i = 0; i < num_vfs; i++) | ||
1526 | pdn->pe_num_map[i] = IODA_INVALID_PE; | ||
1527 | |||
1555 | /* Calculate available PE for required VFs */ | 1528 | /* Calculate available PE for required VFs */ |
1556 | mutex_lock(&phb->ioda.pe_alloc_mutex); | 1529 | if (pdn->m64_single_mode) { |
1557 | pdn->offset = bitmap_find_next_zero_area( | 1530 | for (i = 0; i < num_vfs; i++) { |
1558 | phb->ioda.pe_alloc, phb->ioda.total_pe, | 1531 | pdn->pe_num_map[i] = pnv_ioda_alloc_pe(phb); |
1559 | 0, num_vfs, 0); | 1532 | if (pdn->pe_num_map[i] == IODA_INVALID_PE) { |
1560 | if (pdn->offset >= phb->ioda.total_pe) { | 1533 | ret = -EBUSY; |
1534 | goto m64_failed; | ||
1535 | } | ||
1536 | } | ||
1537 | } else { | ||
1538 | mutex_lock(&phb->ioda.pe_alloc_mutex); | ||
1539 | *pdn->pe_num_map = bitmap_find_next_zero_area( | ||
1540 | phb->ioda.pe_alloc, phb->ioda.total_pe, | ||
1541 | 0, num_vfs, 0); | ||
1542 | if (*pdn->pe_num_map >= phb->ioda.total_pe) { | ||
1543 | mutex_unlock(&phb->ioda.pe_alloc_mutex); | ||
1544 | dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs); | ||
1545 | kfree(pdn->pe_num_map); | ||
1546 | return -EBUSY; | ||
1547 | } | ||
1548 | bitmap_set(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs); | ||
1561 | mutex_unlock(&phb->ioda.pe_alloc_mutex); | 1549 | mutex_unlock(&phb->ioda.pe_alloc_mutex); |
1562 | dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs); | ||
1563 | pdn->offset = 0; | ||
1564 | return -EBUSY; | ||
1565 | } | 1550 | } |
1566 | bitmap_set(phb->ioda.pe_alloc, pdn->offset, num_vfs); | ||
1567 | pdn->num_vfs = num_vfs; | 1551 | pdn->num_vfs = num_vfs; |
1568 | mutex_unlock(&phb->ioda.pe_alloc_mutex); | ||
1569 | 1552 | ||
1570 | /* Assign M64 window accordingly */ | 1553 | /* Assign M64 window accordingly */ |
1571 | ret = pnv_pci_vf_assign_m64(pdev, num_vfs); | 1554 | ret = pnv_pci_vf_assign_m64(pdev, num_vfs); |
@@ -1579,8 +1562,8 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) | |||
1579 | * the IOV BAR according to the PE# allocated to the VFs. | 1562 | * the IOV BAR according to the PE# allocated to the VFs. |
1580 | * Otherwise, the PE# for the VF will conflict with others. | 1563 | * Otherwise, the PE# for the VF will conflict with others. |
1581 | */ | 1564 | */ |
1582 | if (pdn->m64_per_iov == 1) { | 1565 | if (!pdn->m64_single_mode) { |
1583 | ret = pnv_pci_vf_resource_shift(pdev, pdn->offset); | 1566 | ret = pnv_pci_vf_resource_shift(pdev, *pdn->pe_num_map); |
1584 | if (ret) | 1567 | if (ret) |
1585 | goto m64_failed; | 1568 | goto m64_failed; |
1586 | } | 1569 | } |
@@ -1592,8 +1575,16 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) | |||
1592 | return 0; | 1575 | return 0; |
1593 | 1576 | ||
1594 | m64_failed: | 1577 | m64_failed: |
1595 | bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs); | 1578 | if (pdn->m64_single_mode) { |
1596 | pdn->offset = 0; | 1579 | for (i = 0; i < num_vfs; i++) { |
1580 | if (pdn->pe_num_map[i] != IODA_INVALID_PE) | ||
1581 | pnv_ioda_free_pe(phb, pdn->pe_num_map[i]); | ||
1582 | } | ||
1583 | } else | ||
1584 | bitmap_clear(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs); | ||
1585 | |||
1586 | /* Releasing pe_num_map */ | ||
1587 | kfree(pdn->pe_num_map); | ||
1597 | 1588 | ||
1598 | return ret; | 1589 | return ret; |
1599 | } | 1590 | } |
@@ -1612,8 +1603,7 @@ int pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs) | |||
1612 | /* Allocate PCI data */ | 1603 | /* Allocate PCI data */ |
1613 | add_dev_pci_data(pdev); | 1604 | add_dev_pci_data(pdev); |
1614 | 1605 | ||
1615 | pnv_pci_sriov_enable(pdev, num_vfs); | 1606 | return pnv_pci_sriov_enable(pdev, num_vfs); |
1616 | return 0; | ||
1617 | } | 1607 | } |
1618 | #endif /* CONFIG_PCI_IOV */ | 1608 | #endif /* CONFIG_PCI_IOV */ |
1619 | 1609 | ||
@@ -2851,45 +2841,58 @@ static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { } | |||
2851 | #ifdef CONFIG_PCI_IOV | 2841 | #ifdef CONFIG_PCI_IOV |
2852 | static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) | 2842 | static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) |
2853 | { | 2843 | { |
2854 | struct pci_controller *hose; | 2844 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); |
2855 | struct pnv_phb *phb; | 2845 | struct pnv_phb *phb = hose->private_data; |
2846 | const resource_size_t gate = phb->ioda.m64_segsize >> 2; | ||
2856 | struct resource *res; | 2847 | struct resource *res; |
2857 | int i; | 2848 | int i; |
2858 | resource_size_t size; | 2849 | resource_size_t size, total_vf_bar_sz; |
2859 | struct pci_dn *pdn; | 2850 | struct pci_dn *pdn; |
2860 | int mul, total_vfs; | 2851 | int mul, total_vfs; |
2861 | 2852 | ||
2862 | if (!pdev->is_physfn || pdev->is_added) | 2853 | if (!pdev->is_physfn || pdev->is_added) |
2863 | return; | 2854 | return; |
2864 | 2855 | ||
2865 | hose = pci_bus_to_host(pdev->bus); | ||
2866 | phb = hose->private_data; | ||
2867 | |||
2868 | pdn = pci_get_pdn(pdev); | 2856 | pdn = pci_get_pdn(pdev); |
2869 | pdn->vfs_expanded = 0; | 2857 | pdn->vfs_expanded = 0; |
2858 | pdn->m64_single_mode = false; | ||
2870 | 2859 | ||
2871 | total_vfs = pci_sriov_get_totalvfs(pdev); | 2860 | total_vfs = pci_sriov_get_totalvfs(pdev); |
2872 | pdn->m64_per_iov = 1; | ||
2873 | mul = phb->ioda.total_pe; | 2861 | mul = phb->ioda.total_pe; |
2862 | total_vf_bar_sz = 0; | ||
2874 | 2863 | ||
2875 | for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { | 2864 | for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { |
2876 | res = &pdev->resource[i + PCI_IOV_RESOURCES]; | 2865 | res = &pdev->resource[i + PCI_IOV_RESOURCES]; |
2877 | if (!res->flags || res->parent) | 2866 | if (!res->flags || res->parent) |
2878 | continue; | 2867 | continue; |
2879 | if (!pnv_pci_is_mem_pref_64(res->flags)) { | 2868 | if (!pnv_pci_is_mem_pref_64(res->flags)) { |
2880 | dev_warn(&pdev->dev, " non M64 VF BAR%d: %pR\n", | 2869 | dev_warn(&pdev->dev, "Don't support SR-IOV with" |
2870 | " non M64 VF BAR%d: %pR. \n", | ||
2881 | i, res); | 2871 | i, res); |
2882 | continue; | 2872 | goto truncate_iov; |
2883 | } | 2873 | } |
2884 | 2874 | ||
2885 | size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES); | 2875 | total_vf_bar_sz += pci_iov_resource_size(pdev, |
2876 | i + PCI_IOV_RESOURCES); | ||
2886 | 2877 | ||
2887 | /* bigger than 64M */ | 2878 | /* |
2888 | if (size > (1 << 26)) { | 2879 | * If bigger than quarter of M64 segment size, just round up |
2889 | dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size is bigger than 64M, roundup power2\n", | 2880 | * power of two. |
2890 | i, res); | 2881 | * |
2891 | pdn->m64_per_iov = M64_PER_IOV; | 2882 | * Generally, one M64 BAR maps one IOV BAR. To avoid conflict |
2883 | * with other devices, IOV BAR size is expanded to be | ||
2884 | * (total_pe * VF_BAR_size). When VF_BAR_size is half of M64 | ||
2885 | * segment size , the expanded size would equal to half of the | ||
2886 | * whole M64 space size, which will exhaust the M64 Space and | ||
2887 | * limit the system flexibility. This is a design decision to | ||
2888 | * set the boundary to quarter of the M64 segment size. | ||
2889 | */ | ||
2890 | if (total_vf_bar_sz > gate) { | ||
2892 | mul = roundup_pow_of_two(total_vfs); | 2891 | mul = roundup_pow_of_two(total_vfs); |
2892 | dev_info(&pdev->dev, | ||
2893 | "VF BAR Total IOV size %llx > %llx, roundup to %d VFs\n", | ||
2894 | total_vf_bar_sz, gate, mul); | ||
2895 | pdn->m64_single_mode = true; | ||
2893 | break; | 2896 | break; |
2894 | } | 2897 | } |
2895 | } | 2898 | } |
@@ -2898,20 +2901,31 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) | |||
2898 | res = &pdev->resource[i + PCI_IOV_RESOURCES]; | 2901 | res = &pdev->resource[i + PCI_IOV_RESOURCES]; |
2899 | if (!res->flags || res->parent) | 2902 | if (!res->flags || res->parent) |
2900 | continue; | 2903 | continue; |
2901 | if (!pnv_pci_is_mem_pref_64(res->flags)) { | ||
2902 | dev_warn(&pdev->dev, "Skipping expanding VF BAR%d: %pR\n", | ||
2903 | i, res); | ||
2904 | continue; | ||
2905 | } | ||
2906 | 2904 | ||
2907 | dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res); | ||
2908 | size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES); | 2905 | size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES); |
2906 | /* | ||
2907 | * On PHB3, the minimum size alignment of M64 BAR in single | ||
2908 | * mode is 32MB. | ||
2909 | */ | ||
2910 | if (pdn->m64_single_mode && (size < SZ_32M)) | ||
2911 | goto truncate_iov; | ||
2912 | dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res); | ||
2909 | res->end = res->start + size * mul - 1; | 2913 | res->end = res->start + size * mul - 1; |
2910 | dev_dbg(&pdev->dev, " %pR\n", res); | 2914 | dev_dbg(&pdev->dev, " %pR\n", res); |
2911 | dev_info(&pdev->dev, "VF BAR%d: %pR (expanded to %d VFs for PE alignment)", | 2915 | dev_info(&pdev->dev, "VF BAR%d: %pR (expanded to %d VFs for PE alignment)", |
2912 | i, res, mul); | 2916 | i, res, mul); |
2913 | } | 2917 | } |
2914 | pdn->vfs_expanded = mul; | 2918 | pdn->vfs_expanded = mul; |
2919 | |||
2920 | return; | ||
2921 | |||
2922 | truncate_iov: | ||
2923 | /* To save MMIO space, IOV BAR is truncated. */ | ||
2924 | for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { | ||
2925 | res = &pdev->resource[i + PCI_IOV_RESOURCES]; | ||
2926 | res->flags = 0; | ||
2927 | res->end = res->start - 1; | ||
2928 | } | ||
2915 | } | 2929 | } |
2916 | #endif /* CONFIG_PCI_IOV */ | 2930 | #endif /* CONFIG_PCI_IOV */ |
2917 | 2931 | ||
@@ -3125,18 +3139,35 @@ static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus, | |||
3125 | static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev, | 3139 | static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev, |
3126 | int resno) | 3140 | int resno) |
3127 | { | 3141 | { |
3142 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | ||
3143 | struct pnv_phb *phb = hose->private_data; | ||
3128 | struct pci_dn *pdn = pci_get_pdn(pdev); | 3144 | struct pci_dn *pdn = pci_get_pdn(pdev); |
3129 | resource_size_t align, iov_align; | 3145 | resource_size_t align; |
3130 | |||
3131 | iov_align = resource_size(&pdev->resource[resno]); | ||
3132 | if (iov_align) | ||
3133 | return iov_align; | ||
3134 | 3146 | ||
3147 | /* | ||
3148 | * On PowerNV platform, IOV BAR is mapped by M64 BAR to enable the | ||
3149 | * SR-IOV. While from hardware perspective, the range mapped by M64 | ||
3150 | * BAR should be size aligned. | ||
3151 | * | ||
3152 | * When IOV BAR is mapped with M64 BAR in Single PE mode, the extra | ||
3153 | * powernv-specific hardware restriction is gone. But if just use the | ||
3154 | * VF BAR size as the alignment, PF BAR / VF BAR may be allocated with | ||
3155 | * in one segment of M64 #15, which introduces the PE conflict between | ||
3156 | * PF and VF. Based on this, the minimum alignment of an IOV BAR is | ||
3157 | * m64_segsize. | ||
3158 | * | ||
3159 | * This function returns the total IOV BAR size if M64 BAR is in | ||
3160 | * Shared PE mode or just VF BAR size if not. | ||
3161 | * If the M64 BAR is in Single PE mode, return the VF BAR size or | ||
3162 | * M64 segment size if IOV BAR size is less. | ||
3163 | */ | ||
3135 | align = pci_iov_resource_size(pdev, resno); | 3164 | align = pci_iov_resource_size(pdev, resno); |
3136 | if (pdn->vfs_expanded) | 3165 | if (!pdn->vfs_expanded) |
3137 | return pdn->vfs_expanded * align; | 3166 | return align; |
3167 | if (pdn->m64_single_mode) | ||
3168 | return max(align, (resource_size_t)phb->ioda.m64_segsize); | ||
3138 | 3169 | ||
3139 | return align; | 3170 | return pdn->vfs_expanded * align; |
3140 | } | 3171 | } |
3141 | #endif /* CONFIG_PCI_IOV */ | 3172 | #endif /* CONFIG_PCI_IOV */ |
3142 | 3173 | ||
diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c deleted file mode 100644 index f2bdfea3b68d..000000000000 --- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c +++ /dev/null | |||
@@ -1,271 +0,0 @@ | |||
1 | /* | ||
2 | * Support PCI/PCIe on PowerNV platforms | ||
3 | * | ||
4 | * Currently supports only P5IOC2 | ||
5 | * | ||
6 | * Copyright 2011 Benjamin Herrenschmidt, IBM Corp. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the License, or (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/string.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/bootmem.h> | ||
20 | #include <linux/irq.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/msi.h> | ||
23 | |||
24 | #include <asm/sections.h> | ||
25 | #include <asm/io.h> | ||
26 | #include <asm/prom.h> | ||
27 | #include <asm/pci-bridge.h> | ||
28 | #include <asm/machdep.h> | ||
29 | #include <asm/msi_bitmap.h> | ||
30 | #include <asm/ppc-pci.h> | ||
31 | #include <asm/opal.h> | ||
32 | #include <asm/iommu.h> | ||
33 | #include <asm/tce.h> | ||
34 | |||
35 | #include "powernv.h" | ||
36 | #include "pci.h" | ||
37 | |||
38 | /* For now, use a fixed amount of TCE memory for each p5ioc2 | ||
39 | * hub, 16M will do | ||
40 | */ | ||
41 | #define P5IOC2_TCE_MEMORY 0x01000000 | ||
42 | |||
43 | #ifdef CONFIG_PCI_MSI | ||
44 | static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | ||
45 | unsigned int hwirq, unsigned int virq, | ||
46 | unsigned int is_64, struct msi_msg *msg) | ||
47 | { | ||
48 | if (WARN_ON(!is_64)) | ||
49 | return -ENXIO; | ||
50 | msg->data = hwirq - phb->msi_base; | ||
51 | msg->address_hi = 0x10000000; | ||
52 | msg->address_lo = 0; | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) | ||
58 | { | ||
59 | unsigned int count; | ||
60 | const __be32 *prop = of_get_property(phb->hose->dn, | ||
61 | "ibm,opal-msi-ranges", NULL); | ||
62 | if (!prop) | ||
63 | return; | ||
64 | |||
65 | /* Don't do MSI's on p5ioc2 PCI-X are they are not properly | ||
66 | * verified in HW | ||
67 | */ | ||
68 | if (of_device_is_compatible(phb->hose->dn, "ibm,p5ioc2-pcix")) | ||
69 | return; | ||
70 | phb->msi_base = be32_to_cpup(prop); | ||
71 | count = be32_to_cpup(prop + 1); | ||
72 | if (msi_bitmap_alloc(&phb->msi_bmp, count, phb->hose->dn)) { | ||
73 | pr_err("PCI %d: Failed to allocate MSI bitmap !\n", | ||
74 | phb->hose->global_number); | ||
75 | return; | ||
76 | } | ||
77 | phb->msi_setup = pnv_pci_p5ioc2_msi_setup; | ||
78 | phb->msi32_support = 0; | ||
79 | pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n", | ||
80 | count, phb->msi_base); | ||
81 | } | ||
82 | #else | ||
83 | static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) { } | ||
84 | #endif /* CONFIG_PCI_MSI */ | ||
85 | |||
86 | static struct iommu_table_ops pnv_p5ioc2_iommu_ops = { | ||
87 | .set = pnv_tce_build, | ||
88 | #ifdef CONFIG_IOMMU_API | ||
89 | .exchange = pnv_tce_xchg, | ||
90 | #endif | ||
91 | .clear = pnv_tce_free, | ||
92 | .get = pnv_tce_get, | ||
93 | }; | ||
94 | |||
95 | static void pnv_pci_p5ioc2_dma_dev_setup(struct pnv_phb *phb, | ||
96 | struct pci_dev *pdev) | ||
97 | { | ||
98 | struct iommu_table *tbl = phb->p5ioc2.table_group.tables[0]; | ||
99 | |||
100 | if (!tbl->it_map) { | ||
101 | tbl->it_ops = &pnv_p5ioc2_iommu_ops; | ||
102 | iommu_init_table(tbl, phb->hose->node); | ||
103 | iommu_register_group(&phb->p5ioc2.table_group, | ||
104 | pci_domain_nr(phb->hose->bus), phb->opal_id); | ||
105 | INIT_LIST_HEAD_RCU(&tbl->it_group_list); | ||
106 | pnv_pci_link_table_and_group(phb->hose->node, 0, | ||
107 | tbl, &phb->p5ioc2.table_group); | ||
108 | } | ||
109 | |||
110 | set_iommu_table_base(&pdev->dev, tbl); | ||
111 | iommu_add_device(&pdev->dev); | ||
112 | } | ||
113 | |||
114 | static const struct pci_controller_ops pnv_pci_p5ioc2_controller_ops = { | ||
115 | .dma_dev_setup = pnv_pci_dma_dev_setup, | ||
116 | #ifdef CONFIG_PCI_MSI | ||
117 | .setup_msi_irqs = pnv_setup_msi_irqs, | ||
118 | .teardown_msi_irqs = pnv_teardown_msi_irqs, | ||
119 | #endif | ||
120 | }; | ||
121 | |||
122 | static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id, | ||
123 | void *tce_mem, u64 tce_size) | ||
124 | { | ||
125 | struct pnv_phb *phb; | ||
126 | const __be64 *prop64; | ||
127 | u64 phb_id; | ||
128 | int64_t rc; | ||
129 | static int primary = 1; | ||
130 | struct iommu_table_group *table_group; | ||
131 | struct iommu_table *tbl; | ||
132 | |||
133 | pr_info(" Initializing p5ioc2 PHB %s\n", np->full_name); | ||
134 | |||
135 | prop64 = of_get_property(np, "ibm,opal-phbid", NULL); | ||
136 | if (!prop64) { | ||
137 | pr_err(" Missing \"ibm,opal-phbid\" property !\n"); | ||
138 | return; | ||
139 | } | ||
140 | phb_id = be64_to_cpup(prop64); | ||
141 | pr_devel(" PHB-ID : 0x%016llx\n", phb_id); | ||
142 | pr_devel(" TCE AT : 0x%016lx\n", __pa(tce_mem)); | ||
143 | pr_devel(" TCE SZ : 0x%016llx\n", tce_size); | ||
144 | |||
145 | rc = opal_pci_set_phb_tce_memory(phb_id, __pa(tce_mem), tce_size); | ||
146 | if (rc != OPAL_SUCCESS) { | ||
147 | pr_err(" Failed to set TCE memory, OPAL error %lld\n", rc); | ||
148 | return; | ||
149 | } | ||
150 | |||
151 | phb = memblock_virt_alloc(sizeof(struct pnv_phb), 0); | ||
152 | phb->hose = pcibios_alloc_controller(np); | ||
153 | if (!phb->hose) { | ||
154 | pr_err(" Failed to allocate PCI controller\n"); | ||
155 | return; | ||
156 | } | ||
157 | |||
158 | spin_lock_init(&phb->lock); | ||
159 | phb->hose->first_busno = 0; | ||
160 | phb->hose->last_busno = 0xff; | ||
161 | phb->hose->private_data = phb; | ||
162 | phb->hose->controller_ops = pnv_pci_p5ioc2_controller_ops; | ||
163 | phb->hub_id = hub_id; | ||
164 | phb->opal_id = phb_id; | ||
165 | phb->type = PNV_PHB_P5IOC2; | ||
166 | phb->model = PNV_PHB_MODEL_P5IOC2; | ||
167 | |||
168 | phb->regs = of_iomap(np, 0); | ||
169 | |||
170 | if (phb->regs == NULL) | ||
171 | pr_err(" Failed to map registers !\n"); | ||
172 | else { | ||
173 | pr_devel(" P_BUID = 0x%08x\n", in_be32(phb->regs + 0x100)); | ||
174 | pr_devel(" P_IOSZ = 0x%08x\n", in_be32(phb->regs + 0x1b0)); | ||
175 | pr_devel(" P_IO_ST = 0x%08x\n", in_be32(phb->regs + 0x1e0)); | ||
176 | pr_devel(" P_MEM1_H = 0x%08x\n", in_be32(phb->regs + 0x1a0)); | ||
177 | pr_devel(" P_MEM1_L = 0x%08x\n", in_be32(phb->regs + 0x190)); | ||
178 | pr_devel(" P_MSZ1_L = 0x%08x\n", in_be32(phb->regs + 0x1c0)); | ||
179 | pr_devel(" P_MEM_ST = 0x%08x\n", in_be32(phb->regs + 0x1d0)); | ||
180 | pr_devel(" P_MEM2_H = 0x%08x\n", in_be32(phb->regs + 0x2c0)); | ||
181 | pr_devel(" P_MEM2_L = 0x%08x\n", in_be32(phb->regs + 0x2b0)); | ||
182 | pr_devel(" P_MSZ2_H = 0x%08x\n", in_be32(phb->regs + 0x2d0)); | ||
183 | pr_devel(" P_MSZ2_L = 0x%08x\n", in_be32(phb->regs + 0x2e0)); | ||
184 | } | ||
185 | |||
186 | /* Interpret the "ranges" property */ | ||
187 | /* This also maps the I/O region and sets isa_io/mem_base */ | ||
188 | pci_process_bridge_OF_ranges(phb->hose, np, primary); | ||
189 | primary = 0; | ||
190 | |||
191 | phb->hose->ops = &pnv_pci_ops; | ||
192 | |||
193 | /* Setup MSI support */ | ||
194 | pnv_pci_init_p5ioc2_msis(phb); | ||
195 | |||
196 | /* Setup TCEs */ | ||
197 | phb->dma_dev_setup = pnv_pci_p5ioc2_dma_dev_setup; | ||
198 | pnv_pci_setup_iommu_table(&phb->p5ioc2.iommu_table, | ||
199 | tce_mem, tce_size, 0, | ||
200 | IOMMU_PAGE_SHIFT_4K); | ||
201 | /* | ||
202 | * We do not allocate iommu_table as we do not support | ||
203 | * hotplug or SRIOV on P5IOC2 and therefore iommu_free_table() | ||
204 | * should not be called for phb->p5ioc2.table_group.tables[0] ever. | ||
205 | */ | ||
206 | tbl = phb->p5ioc2.table_group.tables[0] = &phb->p5ioc2.iommu_table; | ||
207 | table_group = &phb->p5ioc2.table_group; | ||
208 | table_group->tce32_start = tbl->it_offset << tbl->it_page_shift; | ||
209 | table_group->tce32_size = tbl->it_size << tbl->it_page_shift; | ||
210 | } | ||
211 | |||
212 | void __init pnv_pci_init_p5ioc2_hub(struct device_node *np) | ||
213 | { | ||
214 | struct device_node *phbn; | ||
215 | const __be64 *prop64; | ||
216 | u64 hub_id; | ||
217 | void *tce_mem; | ||
218 | uint64_t tce_per_phb; | ||
219 | int64_t rc; | ||
220 | int phb_count = 0; | ||
221 | |||
222 | pr_info("Probing p5ioc2 IO-Hub %s\n", np->full_name); | ||
223 | |||
224 | prop64 = of_get_property(np, "ibm,opal-hubid", NULL); | ||
225 | if (!prop64) { | ||
226 | pr_err(" Missing \"ibm,opal-hubid\" property !\n"); | ||
227 | return; | ||
228 | } | ||
229 | hub_id = be64_to_cpup(prop64); | ||
230 | pr_info(" HUB-ID : 0x%016llx\n", hub_id); | ||
231 | |||
232 | /* Count child PHBs and calculate TCE space per PHB */ | ||
233 | for_each_child_of_node(np, phbn) { | ||
234 | if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") || | ||
235 | of_device_is_compatible(phbn, "ibm,p5ioc2-pciex")) | ||
236 | phb_count++; | ||
237 | } | ||
238 | |||
239 | if (phb_count <= 0) { | ||
240 | pr_info(" No PHBs for Hub %s\n", np->full_name); | ||
241 | return; | ||
242 | } | ||
243 | |||
244 | tce_per_phb = __rounddown_pow_of_two(P5IOC2_TCE_MEMORY / phb_count); | ||
245 | pr_info(" Allocating %lld MB of TCE memory per PHB\n", | ||
246 | tce_per_phb >> 20); | ||
247 | |||
248 | /* Currently allocate 16M of TCE memory for every Hub | ||
249 | * | ||
250 | * XXX TODO: Make it chip local if possible | ||
251 | */ | ||
252 | tce_mem = memblock_virt_alloc(P5IOC2_TCE_MEMORY, P5IOC2_TCE_MEMORY); | ||
253 | pr_debug(" TCE : 0x%016lx..0x%016lx\n", | ||
254 | __pa(tce_mem), __pa(tce_mem) + P5IOC2_TCE_MEMORY - 1); | ||
255 | rc = opal_pci_set_hub_tce_memory(hub_id, __pa(tce_mem), | ||
256 | P5IOC2_TCE_MEMORY); | ||
257 | if (rc != OPAL_SUCCESS) { | ||
258 | pr_err(" Failed to allocate TCE memory, OPAL error %lld\n", rc); | ||
259 | return; | ||
260 | } | ||
261 | |||
262 | /* Initialize PHBs */ | ||
263 | for_each_child_of_node(np, phbn) { | ||
264 | if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") || | ||
265 | of_device_is_compatible(phbn, "ibm,p5ioc2-pciex")) { | ||
266 | pnv_pci_init_p5ioc2_phb(phbn, hub_id, | ||
267 | tce_mem, tce_per_phb); | ||
268 | tce_mem += tce_per_phb; | ||
269 | } | ||
270 | } | ||
271 | } | ||
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index b1ef84a6c9d1..73c8dc2a353f 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -380,10 +380,7 @@ static void pnv_pci_config_check_eeh(struct pci_dn *pdn) | |||
380 | */ | 380 | */ |
381 | pe_no = pdn->pe_number; | 381 | pe_no = pdn->pe_number; |
382 | if (pe_no == IODA_INVALID_PE) { | 382 | if (pe_no == IODA_INVALID_PE) { |
383 | if (phb->type == PNV_PHB_P5IOC2) | 383 | pe_no = phb->ioda.reserved_pe; |
384 | pe_no = 0; | ||
385 | else | ||
386 | pe_no = phb->ioda.reserved_pe; | ||
387 | } | 384 | } |
388 | 385 | ||
389 | /* | 386 | /* |
@@ -805,7 +802,6 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IBM, 0x3b9, pnv_p7ioc_rc_quirk); | |||
805 | void __init pnv_pci_init(void) | 802 | void __init pnv_pci_init(void) |
806 | { | 803 | { |
807 | struct device_node *np; | 804 | struct device_node *np; |
808 | bool found_ioda = false; | ||
809 | 805 | ||
810 | pci_add_flags(PCI_CAN_SKIP_ISA_ALIGN); | 806 | pci_add_flags(PCI_CAN_SKIP_ISA_ALIGN); |
811 | 807 | ||
@@ -813,20 +809,11 @@ void __init pnv_pci_init(void) | |||
813 | if (!firmware_has_feature(FW_FEATURE_OPAL)) | 809 | if (!firmware_has_feature(FW_FEATURE_OPAL)) |
814 | return; | 810 | return; |
815 | 811 | ||
816 | /* Look for IODA IO-Hubs. We don't support mixing IODA | 812 | /* Look for IODA IO-Hubs. */ |
817 | * and p5ioc2 due to the need to change some global | ||
818 | * probing flags | ||
819 | */ | ||
820 | for_each_compatible_node(np, NULL, "ibm,ioda-hub") { | 813 | for_each_compatible_node(np, NULL, "ibm,ioda-hub") { |
821 | pnv_pci_init_ioda_hub(np); | 814 | pnv_pci_init_ioda_hub(np); |
822 | found_ioda = true; | ||
823 | } | 815 | } |
824 | 816 | ||
825 | /* Look for p5ioc2 IO-Hubs */ | ||
826 | if (!found_ioda) | ||
827 | for_each_compatible_node(np, NULL, "ibm,p5ioc2") | ||
828 | pnv_pci_init_p5ioc2_hub(np); | ||
829 | |||
830 | /* Look for ioda2 built-in PHB3's */ | 817 | /* Look for ioda2 built-in PHB3's */ |
831 | for_each_compatible_node(np, NULL, "ibm,ioda2-phb") | 818 | for_each_compatible_node(np, NULL, "ibm,ioda2-phb") |
832 | pnv_pci_init_ioda2_phb(np); | 819 | pnv_pci_init_ioda2_phb(np); |
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 00691a9b99af..3f814f382b2e 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h | |||
@@ -4,16 +4,14 @@ | |||
4 | struct pci_dn; | 4 | struct pci_dn; |
5 | 5 | ||
6 | enum pnv_phb_type { | 6 | enum pnv_phb_type { |
7 | PNV_PHB_P5IOC2 = 0, | 7 | PNV_PHB_IODA1 = 0, |
8 | PNV_PHB_IODA1 = 1, | 8 | PNV_PHB_IODA2 = 1, |
9 | PNV_PHB_IODA2 = 2, | 9 | PNV_PHB_NPU = 2, |
10 | PNV_PHB_NPU = 3, | ||
11 | }; | 10 | }; |
12 | 11 | ||
13 | /* Precise PHB model for error management */ | 12 | /* Precise PHB model for error management */ |
14 | enum pnv_phb_model { | 13 | enum pnv_phb_model { |
15 | PNV_PHB_MODEL_UNKNOWN, | 14 | PNV_PHB_MODEL_UNKNOWN, |
16 | PNV_PHB_MODEL_P5IOC2, | ||
17 | PNV_PHB_MODEL_P7IOC, | 15 | PNV_PHB_MODEL_P7IOC, |
18 | PNV_PHB_MODEL_PHB3, | 16 | PNV_PHB_MODEL_PHB3, |
19 | PNV_PHB_MODEL_NPU, | 17 | PNV_PHB_MODEL_NPU, |
@@ -121,81 +119,74 @@ struct pnv_phb { | |||
121 | void (*freeze_pe)(struct pnv_phb *phb, int pe_no); | 119 | void (*freeze_pe)(struct pnv_phb *phb, int pe_no); |
122 | int (*unfreeze_pe)(struct pnv_phb *phb, int pe_no, int opt); | 120 | int (*unfreeze_pe)(struct pnv_phb *phb, int pe_no, int opt); |
123 | 121 | ||
124 | union { | 122 | struct { |
125 | struct { | 123 | /* Global bridge info */ |
126 | struct iommu_table iommu_table; | 124 | unsigned int total_pe; |
127 | struct iommu_table_group table_group; | 125 | unsigned int reserved_pe; |
128 | } p5ioc2; | 126 | |
129 | 127 | /* 32-bit MMIO window */ | |
130 | struct { | 128 | unsigned int m32_size; |
131 | /* Global bridge info */ | 129 | unsigned int m32_segsize; |
132 | unsigned int total_pe; | 130 | unsigned int m32_pci_base; |
133 | unsigned int reserved_pe; | 131 | |
134 | 132 | /* 64-bit MMIO window */ | |
135 | /* 32-bit MMIO window */ | 133 | unsigned int m64_bar_idx; |
136 | unsigned int m32_size; | 134 | unsigned long m64_size; |
137 | unsigned int m32_segsize; | 135 | unsigned long m64_segsize; |
138 | unsigned int m32_pci_base; | 136 | unsigned long m64_base; |
139 | 137 | unsigned long m64_bar_alloc; | |
140 | /* 64-bit MMIO window */ | 138 | |
141 | unsigned int m64_bar_idx; | 139 | /* IO ports */ |
142 | unsigned long m64_size; | 140 | unsigned int io_size; |
143 | unsigned long m64_segsize; | 141 | unsigned int io_segsize; |
144 | unsigned long m64_base; | 142 | unsigned int io_pci_base; |
145 | unsigned long m64_bar_alloc; | 143 | |
146 | 144 | /* PE allocation bitmap */ | |
147 | /* IO ports */ | 145 | unsigned long *pe_alloc; |
148 | unsigned int io_size; | 146 | /* PE allocation mutex */ |
149 | unsigned int io_segsize; | 147 | struct mutex pe_alloc_mutex; |
150 | unsigned int io_pci_base; | 148 | |
151 | 149 | /* M32 & IO segment maps */ | |
152 | /* PE allocation bitmap */ | 150 | unsigned int *m32_segmap; |
153 | unsigned long *pe_alloc; | 151 | unsigned int *io_segmap; |
154 | /* PE allocation mutex */ | 152 | struct pnv_ioda_pe *pe_array; |
155 | struct mutex pe_alloc_mutex; | 153 | |
156 | 154 | /* IRQ chip */ | |
157 | /* M32 & IO segment maps */ | 155 | int irq_chip_init; |
158 | unsigned int *m32_segmap; | 156 | struct irq_chip irq_chip; |
159 | unsigned int *io_segmap; | 157 | |
160 | struct pnv_ioda_pe *pe_array; | 158 | /* Sorted list of used PE's based |
161 | 159 | * on the sequence of creation | |
162 | /* IRQ chip */ | 160 | */ |
163 | int irq_chip_init; | 161 | struct list_head pe_list; |
164 | struct irq_chip irq_chip; | 162 | struct mutex pe_list_mutex; |
165 | 163 | ||
166 | /* Sorted list of used PE's based | 164 | /* Reverse map of PEs, will have to extend if |
167 | * on the sequence of creation | 165 | * we are to support more than 256 PEs, indexed |
168 | */ | 166 | * bus { bus, devfn } |
169 | struct list_head pe_list; | 167 | */ |
170 | struct mutex pe_list_mutex; | 168 | unsigned char pe_rmap[0x10000]; |
171 | 169 | ||
172 | /* Reverse map of PEs, will have to extend if | 170 | /* 32-bit TCE tables allocation */ |
173 | * we are to support more than 256 PEs, indexed | 171 | unsigned long tce32_count; |
174 | * bus { bus, devfn } | 172 | |
175 | */ | 173 | /* Total "weight" for the sake of DMA resources |
176 | unsigned char pe_rmap[0x10000]; | 174 | * allocation |
177 | 175 | */ | |
178 | /* 32-bit TCE tables allocation */ | 176 | unsigned int dma_weight; |
179 | unsigned long tce32_count; | 177 | unsigned int dma_pe_count; |
180 | 178 | ||
181 | /* Total "weight" for the sake of DMA resources | 179 | /* Sorted list of used PE's, sorted at |
182 | * allocation | 180 | * boot for resource allocation purposes |
183 | */ | 181 | */ |
184 | unsigned int dma_weight; | 182 | struct list_head pe_dma_list; |
185 | unsigned int dma_pe_count; | 183 | |
186 | 184 | /* TCE cache invalidate registers (physical and | |
187 | /* Sorted list of used PE's, sorted at | 185 | * remapped) |
188 | * boot for resource allocation purposes | 186 | */ |
189 | */ | 187 | phys_addr_t tce_inval_reg_phys; |
190 | struct list_head pe_dma_list; | 188 | __be64 __iomem *tce_inval_reg; |
191 | 189 | } ioda; | |
192 | /* TCE cache invalidate registers (physical and | ||
193 | * remapped) | ||
194 | */ | ||
195 | phys_addr_t tce_inval_reg_phys; | ||
196 | __be64 __iomem *tce_inval_reg; | ||
197 | } ioda; | ||
198 | }; | ||
199 | 190 | ||
200 | /* PHB and hub status structure */ | 191 | /* PHB and hub status structure */ |
201 | union { | 192 | union { |
@@ -232,7 +223,6 @@ extern void pnv_pci_unlink_table_and_group(struct iommu_table *tbl, | |||
232 | extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl, | 223 | extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl, |
233 | void *tce_mem, u64 tce_size, | 224 | void *tce_mem, u64 tce_size, |
234 | u64 dma_offset, unsigned page_shift); | 225 | u64 dma_offset, unsigned page_shift); |
235 | extern void pnv_pci_init_p5ioc2_hub(struct device_node *np); | ||
236 | extern void pnv_pci_init_ioda_hub(struct device_node *np); | 226 | extern void pnv_pci_init_ioda_hub(struct device_node *np); |
237 | extern void pnv_pci_init_ioda2_phb(struct device_node *np); | 227 | extern void pnv_pci_init_ioda2_phb(struct device_node *np); |
238 | extern void pnv_pci_init_npu_phb(struct device_node *np); | 228 | extern void pnv_pci_init_npu_phb(struct device_node *np); |
diff --git a/arch/powerpc/platforms/powernv/subcore.c b/arch/powerpc/platforms/powernv/subcore.c index 503a73f59359..0babef11136f 100644 --- a/arch/powerpc/platforms/powernv/subcore.c +++ b/arch/powerpc/platforms/powernv/subcore.c | |||
@@ -407,7 +407,7 @@ static DEVICE_ATTR(subcores_per_core, 0644, | |||
407 | 407 | ||
408 | static int subcore_init(void) | 408 | static int subcore_init(void) |
409 | { | 409 | { |
410 | if (!cpu_has_feature(CPU_FTR_ARCH_207S)) | 410 | if (!cpu_has_feature(CPU_FTR_SUBCORE)) |
411 | return 0; | 411 | return 0; |
412 | 412 | ||
413 | /* | 413 | /* |
diff --git a/arch/powerpc/platforms/ps3/gelic_udbg.c b/arch/powerpc/platforms/ps3/gelic_udbg.c index 20b46a19a48f..09bf24d616a5 100644 --- a/arch/powerpc/platforms/ps3/gelic_udbg.c +++ b/arch/powerpc/platforms/ps3/gelic_udbg.c | |||
@@ -13,6 +13,12 @@ | |||
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/if_ether.h> | ||
17 | #include <linux/etherdevice.h> | ||
18 | #include <linux/if_vlan.h> | ||
19 | #include <linux/ip.h> | ||
20 | #include <linux/udp.h> | ||
21 | |||
16 | #include <asm/io.h> | 22 | #include <asm/io.h> |
17 | #include <asm/udbg.h> | 23 | #include <asm/udbg.h> |
18 | #include <asm/lv1call.h> | 24 | #include <asm/lv1call.h> |
@@ -56,39 +62,8 @@ struct debug_block { | |||
56 | u8 pkt[1520]; | 62 | u8 pkt[1520]; |
57 | } __packed; | 63 | } __packed; |
58 | 64 | ||
59 | struct ethhdr { | ||
60 | u8 dest[6]; | ||
61 | u8 src[6]; | ||
62 | u16 type; | ||
63 | } __packed; | ||
64 | |||
65 | struct vlantag { | ||
66 | u16 vlan; | ||
67 | u16 subtype; | ||
68 | } __packed; | ||
69 | |||
70 | struct iphdr { | ||
71 | u8 ver_len; | ||
72 | u8 dscp_ecn; | ||
73 | u16 total_length; | ||
74 | u16 ident; | ||
75 | u16 frag_off_flags; | ||
76 | u8 ttl; | ||
77 | u8 proto; | ||
78 | u16 checksum; | ||
79 | u32 src; | ||
80 | u32 dest; | ||
81 | } __packed; | ||
82 | |||
83 | struct udphdr { | ||
84 | u16 src; | ||
85 | u16 dest; | ||
86 | u16 len; | ||
87 | u16 checksum; | ||
88 | } __packed; | ||
89 | |||
90 | static __iomem struct ethhdr *h_eth; | 65 | static __iomem struct ethhdr *h_eth; |
91 | static __iomem struct vlantag *h_vlan; | 66 | static __iomem struct vlan_hdr *h_vlan; |
92 | static __iomem struct iphdr *h_ip; | 67 | static __iomem struct iphdr *h_ip; |
93 | static __iomem struct udphdr *h_udp; | 68 | static __iomem struct udphdr *h_udp; |
94 | 69 | ||
@@ -173,8 +148,8 @@ static void gelic_debug_init(void) | |||
173 | 148 | ||
174 | h_eth = (struct ethhdr *)dbg.pkt; | 149 | h_eth = (struct ethhdr *)dbg.pkt; |
175 | 150 | ||
176 | memset(&h_eth->dest, 0xff, 6); | 151 | eth_broadcast_addr(h_eth->h_dest); |
177 | memcpy(&h_eth->src, &mac, 6); | 152 | memcpy(&h_eth->h_source, &mac, ETH_ALEN); |
178 | 153 | ||
179 | header_size = sizeof(struct ethhdr); | 154 | header_size = sizeof(struct ethhdr); |
180 | 155 | ||
@@ -183,28 +158,29 @@ static void gelic_debug_init(void) | |||
183 | GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0, | 158 | GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0, |
184 | &vlan_id, &v2); | 159 | &vlan_id, &v2); |
185 | if (!result) { | 160 | if (!result) { |
186 | h_eth->type = 0x8100; | 161 | h_eth->h_proto= ETH_P_8021Q; |
187 | 162 | ||
188 | header_size += sizeof(struct vlantag); | 163 | header_size += sizeof(struct vlan_hdr); |
189 | h_vlan = (struct vlantag *)(h_eth + 1); | 164 | h_vlan = (struct vlan_hdr *)(h_eth + 1); |
190 | h_vlan->vlan = vlan_id; | 165 | h_vlan->h_vlan_TCI = vlan_id; |
191 | h_vlan->subtype = 0x0800; | 166 | h_vlan->h_vlan_encapsulated_proto = ETH_P_IP; |
192 | h_ip = (struct iphdr *)(h_vlan + 1); | 167 | h_ip = (struct iphdr *)(h_vlan + 1); |
193 | } else { | 168 | } else { |
194 | h_eth->type = 0x0800; | 169 | h_eth->h_proto= 0x0800; |
195 | h_ip = (struct iphdr *)(h_eth + 1); | 170 | h_ip = (struct iphdr *)(h_eth + 1); |
196 | } | 171 | } |
197 | 172 | ||
198 | header_size += sizeof(struct iphdr); | 173 | header_size += sizeof(struct iphdr); |
199 | h_ip->ver_len = 0x45; | 174 | h_ip->version = 4; |
175 | h_ip->ihl = 5; | ||
200 | h_ip->ttl = 10; | 176 | h_ip->ttl = 10; |
201 | h_ip->proto = 0x11; | 177 | h_ip->protocol = 0x11; |
202 | h_ip->src = 0x00000000; | 178 | h_ip->saddr = 0x00000000; |
203 | h_ip->dest = 0xffffffff; | 179 | h_ip->daddr = 0xffffffff; |
204 | 180 | ||
205 | header_size += sizeof(struct udphdr); | 181 | header_size += sizeof(struct udphdr); |
206 | h_udp = (struct udphdr *)(h_ip + 1); | 182 | h_udp = (struct udphdr *)(h_ip + 1); |
207 | h_udp->src = GELIC_DEBUG_PORT; | 183 | h_udp->source = GELIC_DEBUG_PORT; |
208 | h_udp->dest = GELIC_DEBUG_PORT; | 184 | h_udp->dest = GELIC_DEBUG_PORT; |
209 | 185 | ||
210 | pmsgc = pmsg = (char *)(h_udp + 1); | 186 | pmsgc = pmsg = (char *)(h_udp + 1); |
@@ -225,16 +201,16 @@ static void gelic_sendbuf(int msgsize) | |||
225 | int i; | 201 | int i; |
226 | 202 | ||
227 | dbg.descr.buf_size = header_size + msgsize; | 203 | dbg.descr.buf_size = header_size + msgsize; |
228 | h_ip->total_length = msgsize + sizeof(struct udphdr) + | 204 | h_ip->tot_len = msgsize + sizeof(struct udphdr) + |
229 | sizeof(struct iphdr); | 205 | sizeof(struct iphdr); |
230 | h_udp->len = msgsize + sizeof(struct udphdr); | 206 | h_udp->len = msgsize + sizeof(struct udphdr); |
231 | 207 | ||
232 | h_ip->checksum = 0; | 208 | h_ip->check = 0; |
233 | sum = 0; | 209 | sum = 0; |
234 | p = (u16 *)h_ip; | 210 | p = (u16 *)h_ip; |
235 | for (i = 0; i < 5; i++) | 211 | for (i = 0; i < 5; i++) |
236 | sum += *p++; | 212 | sum += *p++; |
237 | h_ip->checksum = ~(sum + (sum >> 16)); | 213 | h_ip->check = ~(sum + (sum >> 16)); |
238 | 214 | ||
239 | dbg.descr.dmac_cmd_status = GELIC_DESCR_DMA_CMD_NO_CHKSUM | | 215 | dbg.descr.dmac_cmd_status = GELIC_DESCR_DMA_CMD_NO_CHKSUM | |
240 | GELIC_DESCR_TX_DMA_FRAME_TAIL; | 216 | GELIC_DESCR_TX_DMA_FRAME_TAIL; |
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index 638c4060938e..b831638e6f4a 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c | |||
@@ -78,7 +78,7 @@ struct ps3_bmp { | |||
78 | /** | 78 | /** |
79 | * struct ps3_private - a per cpu data structure | 79 | * struct ps3_private - a per cpu data structure |
80 | * @bmp: ps3_bmp structure | 80 | * @bmp: ps3_bmp structure |
81 | * @bmp_lock: Syncronize access to bmp. | 81 | * @bmp_lock: Synchronize access to bmp. |
82 | * @ipi_debug_brk_mask: Mask for debug break IPIs | 82 | * @ipi_debug_brk_mask: Mask for debug break IPIs |
83 | * @ppe_id: HV logical_ppe_id | 83 | * @ppe_id: HV logical_ppe_id |
84 | * @thread_id: HV thread_id | 84 | * @thread_id: HV thread_id |
diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c index 849b29b3e9ae..74da18de853a 100644 --- a/arch/powerpc/platforms/pseries/hvconsole.c +++ b/arch/powerpc/platforms/pseries/hvconsole.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <asm/plpar_wrappers.h> | 31 | #include <asm/plpar_wrappers.h> |
32 | 32 | ||
33 | /** | 33 | /** |
34 | * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper | 34 | * hvc_get_chars - retrieve characters from firmware for denoted vterm adapter |
35 | * @vtermno: The vtermno or unit_address of the adapter from which to fetch the | 35 | * @vtermno: The vtermno or unit_address of the adapter from which to fetch the |
36 | * data. | 36 | * data. |
37 | * @buf: The character buffer into which to put the character data fetched from | 37 | * @buf: The character buffer into which to put the character data fetched from |
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 477290ad855e..2415a0d31f8f 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
@@ -505,8 +505,8 @@ static void pSeries_lpar_hugepage_invalidate(unsigned long vsid, | |||
505 | } | 505 | } |
506 | #endif | 506 | #endif |
507 | 507 | ||
508 | static void pSeries_lpar_hpte_removebolted(unsigned long ea, | 508 | static int pSeries_lpar_hpte_removebolted(unsigned long ea, |
509 | int psize, int ssize) | 509 | int psize, int ssize) |
510 | { | 510 | { |
511 | unsigned long vpn; | 511 | unsigned long vpn; |
512 | unsigned long slot, vsid; | 512 | unsigned long slot, vsid; |
@@ -515,11 +515,14 @@ static void pSeries_lpar_hpte_removebolted(unsigned long ea, | |||
515 | vpn = hpt_vpn(ea, vsid, ssize); | 515 | vpn = hpt_vpn(ea, vsid, ssize); |
516 | 516 | ||
517 | slot = pSeries_lpar_hpte_find(vpn, psize, ssize); | 517 | slot = pSeries_lpar_hpte_find(vpn, psize, ssize); |
518 | BUG_ON(slot == -1); | 518 | if (slot == -1) |
519 | return -ENOENT; | ||
520 | |||
519 | /* | 521 | /* |
520 | * lpar doesn't use the passed actual page size | 522 | * lpar doesn't use the passed actual page size |
521 | */ | 523 | */ |
522 | pSeries_lpar_hpte_invalidate(slot, vpn, psize, 0, ssize, 0); | 524 | pSeries_lpar_hpte_invalidate(slot, vpn, psize, 0, ssize, 0); |
525 | return 0; | ||
523 | } | 526 | } |
524 | 527 | ||
525 | /* | 528 | /* |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 36df46eaba24..6e944fc6e5f9 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -515,7 +515,7 @@ static void __init pSeries_setup_arch(void) | |||
515 | 515 | ||
516 | fwnmi_init(); | 516 | fwnmi_init(); |
517 | 517 | ||
518 | /* By default, only probe PCI (can be overriden by rtas_pci) */ | 518 | /* By default, only probe PCI (can be overridden by rtas_pci) */ |
519 | pci_add_flags(PCI_PROBE_ONLY); | 519 | pci_add_flags(PCI_PROBE_ONLY); |
520 | 520 | ||
521 | /* Find and initialize PCI host bridges */ | 521 | /* Find and initialize PCI host bridges */ |
diff --git a/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh b/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh new file mode 100755 index 000000000000..c658d8cf760b --- /dev/null +++ b/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh | |||
@@ -0,0 +1,23 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | set -e | ||
4 | set -o pipefail | ||
5 | |||
6 | # To debug, uncomment the following line | ||
7 | # set -x | ||
8 | |||
9 | # Test whether the compile option -mprofile-kernel exists and generates | ||
10 | # profiling code (ie. a call to _mcount()). | ||
11 | echo "int func() { return 0; }" | \ | ||
12 | $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \ | ||
13 | grep -q "_mcount" | ||
14 | |||
15 | # Test whether the notrace attribute correctly suppresses calls to _mcount(). | ||
16 | |||
17 | echo -e "#include <linux/compiler.h>\nnotrace int func() { return 0; }" | \ | ||
18 | $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \ | ||
19 | grep -q "_mcount" && \ | ||
20 | exit 1 | ||
21 | |||
22 | echo "OK" | ||
23 | exit 0 | ||
diff --git a/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig index a19332a38715..52dc165c0efb 100644 --- a/arch/powerpc/sysdev/Kconfig +++ b/arch/powerpc/sysdev/Kconfig | |||
@@ -40,3 +40,8 @@ config SCOM_DEBUGFS | |||
40 | config GE_FPGA | 40 | config GE_FPGA |
41 | bool | 41 | bool |
42 | default n | 42 | default n |
43 | |||
44 | config FSL_CORENET_RCPM | ||
45 | bool | ||
46 | help | ||
47 | This option enables support for RCPM (Run Control/Power Management). | ||
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index bd6bd729969c..a254824719f1 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile | |||
@@ -20,6 +20,7 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o | |||
20 | obj-$(CONFIG_FSL_SOC) += fsl_soc.o fsl_mpic_err.o | 20 | obj-$(CONFIG_FSL_SOC) += fsl_soc.o fsl_mpic_err.o |
21 | obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y) | 21 | obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y) |
22 | obj-$(CONFIG_FSL_PMC) += fsl_pmc.o | 22 | obj-$(CONFIG_FSL_PMC) += fsl_pmc.o |
23 | obj-$(CONFIG_FSL_CORENET_RCPM) += fsl_rcpm.o | ||
23 | obj-$(CONFIG_FSL_LBC) += fsl_lbc.o | 24 | obj-$(CONFIG_FSL_LBC) += fsl_lbc.o |
24 | obj-$(CONFIG_FSL_GTM) += fsl_gtm.o | 25 | obj-$(CONFIG_FSL_GTM) += fsl_gtm.o |
25 | obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o | 26 | obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o |
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index 5e6ff38ea69f..8ed65365be50 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c | |||
@@ -228,7 +228,10 @@ void __init cpm_reset(void) | |||
228 | * Bit 25, FAM can also be set to use FEC aggressive mode (860T). | 228 | * Bit 25, FAM can also be set to use FEC aggressive mode (860T). |
229 | */ | 229 | */ |
230 | siu_conf = immr_map(im_siu_conf); | 230 | siu_conf = immr_map(im_siu_conf); |
231 | out_be32(&siu_conf->sc_sdcr, 1); | 231 | if ((mfspr(SPRN_IMMR) & 0xffff) == 0x0900) /* MPC885 */ |
232 | out_be32(&siu_conf->sc_sdcr, 0x40); | ||
233 | else | ||
234 | out_be32(&siu_conf->sc_sdcr, 1); | ||
232 | immr_unmap(siu_conf); | 235 | immr_unmap(siu_conf); |
233 | 236 | ||
234 | cpm_muram_init(); | 237 | cpm_muram_init(); |
diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c index 47f781059eeb..424b67fdb57f 100644 --- a/arch/powerpc/sysdev/fsl_lbc.c +++ b/arch/powerpc/sysdev/fsl_lbc.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
29 | #include <linux/mod_devicetable.h> | 29 | #include <linux/mod_devicetable.h> |
30 | #include <linux/syscore_ops.h> | ||
30 | #include <asm/prom.h> | 31 | #include <asm/prom.h> |
31 | #include <asm/fsl_lbc.h> | 32 | #include <asm/fsl_lbc.h> |
32 | 33 | ||
@@ -352,24 +353,42 @@ err: | |||
352 | #ifdef CONFIG_SUSPEND | 353 | #ifdef CONFIG_SUSPEND |
353 | 354 | ||
354 | /* save lbc registers */ | 355 | /* save lbc registers */ |
355 | static int fsl_lbc_suspend(struct platform_device *pdev, pm_message_t state) | 356 | static int fsl_lbc_syscore_suspend(void) |
356 | { | 357 | { |
357 | struct fsl_lbc_ctrl *ctrl = dev_get_drvdata(&pdev->dev); | 358 | struct fsl_lbc_ctrl *ctrl; |
358 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; | 359 | struct fsl_lbc_regs __iomem *lbc; |
360 | |||
361 | ctrl = fsl_lbc_ctrl_dev; | ||
362 | if (!ctrl) | ||
363 | goto out; | ||
364 | |||
365 | lbc = ctrl->regs; | ||
366 | if (!lbc) | ||
367 | goto out; | ||
359 | 368 | ||
360 | ctrl->saved_regs = kmalloc(sizeof(struct fsl_lbc_regs), GFP_KERNEL); | 369 | ctrl->saved_regs = kmalloc(sizeof(struct fsl_lbc_regs), GFP_KERNEL); |
361 | if (!ctrl->saved_regs) | 370 | if (!ctrl->saved_regs) |
362 | return -ENOMEM; | 371 | return -ENOMEM; |
363 | 372 | ||
364 | _memcpy_fromio(ctrl->saved_regs, lbc, sizeof(struct fsl_lbc_regs)); | 373 | _memcpy_fromio(ctrl->saved_regs, lbc, sizeof(struct fsl_lbc_regs)); |
374 | |||
375 | out: | ||
365 | return 0; | 376 | return 0; |
366 | } | 377 | } |
367 | 378 | ||
368 | /* restore lbc registers */ | 379 | /* restore lbc registers */ |
369 | static int fsl_lbc_resume(struct platform_device *pdev) | 380 | static void fsl_lbc_syscore_resume(void) |
370 | { | 381 | { |
371 | struct fsl_lbc_ctrl *ctrl = dev_get_drvdata(&pdev->dev); | 382 | struct fsl_lbc_ctrl *ctrl; |
372 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; | 383 | struct fsl_lbc_regs __iomem *lbc; |
384 | |||
385 | ctrl = fsl_lbc_ctrl_dev; | ||
386 | if (!ctrl) | ||
387 | goto out; | ||
388 | |||
389 | lbc = ctrl->regs; | ||
390 | if (!lbc) | ||
391 | goto out; | ||
373 | 392 | ||
374 | if (ctrl->saved_regs) { | 393 | if (ctrl->saved_regs) { |
375 | _memcpy_toio(lbc, ctrl->saved_regs, | 394 | _memcpy_toio(lbc, ctrl->saved_regs, |
@@ -377,7 +396,9 @@ static int fsl_lbc_resume(struct platform_device *pdev) | |||
377 | kfree(ctrl->saved_regs); | 396 | kfree(ctrl->saved_regs); |
378 | ctrl->saved_regs = NULL; | 397 | ctrl->saved_regs = NULL; |
379 | } | 398 | } |
380 | return 0; | 399 | |
400 | out: | ||
401 | return; | ||
381 | } | 402 | } |
382 | #endif /* CONFIG_SUSPEND */ | 403 | #endif /* CONFIG_SUSPEND */ |
383 | 404 | ||
@@ -389,20 +410,26 @@ static const struct of_device_id fsl_lbc_match[] = { | |||
389 | {}, | 410 | {}, |
390 | }; | 411 | }; |
391 | 412 | ||
413 | #ifdef CONFIG_SUSPEND | ||
414 | static struct syscore_ops lbc_syscore_pm_ops = { | ||
415 | .suspend = fsl_lbc_syscore_suspend, | ||
416 | .resume = fsl_lbc_syscore_resume, | ||
417 | }; | ||
418 | #endif | ||
419 | |||
392 | static struct platform_driver fsl_lbc_ctrl_driver = { | 420 | static struct platform_driver fsl_lbc_ctrl_driver = { |
393 | .driver = { | 421 | .driver = { |
394 | .name = "fsl-lbc", | 422 | .name = "fsl-lbc", |
395 | .of_match_table = fsl_lbc_match, | 423 | .of_match_table = fsl_lbc_match, |
396 | }, | 424 | }, |
397 | .probe = fsl_lbc_ctrl_probe, | 425 | .probe = fsl_lbc_ctrl_probe, |
398 | #ifdef CONFIG_SUSPEND | ||
399 | .suspend = fsl_lbc_suspend, | ||
400 | .resume = fsl_lbc_resume, | ||
401 | #endif | ||
402 | }; | 426 | }; |
403 | 427 | ||
404 | static int __init fsl_lbc_init(void) | 428 | static int __init fsl_lbc_init(void) |
405 | { | 429 | { |
430 | #ifdef CONFIG_SUSPEND | ||
431 | register_syscore_ops(&lbc_syscore_pm_ops); | ||
432 | #endif | ||
406 | return platform_driver_register(&fsl_lbc_ctrl_driver); | 433 | return platform_driver_register(&fsl_lbc_ctrl_driver); |
407 | } | 434 | } |
408 | subsys_initcall(fsl_lbc_init); | 435 | subsys_initcall(fsl_lbc_init); |
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index c69e88e91459..85729f49764f 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
@@ -575,7 +575,7 @@ int fsl_add_bridge(struct platform_device *pdev, int is_primary) | |||
575 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { | 575 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { |
576 | /* use fsl_indirect_read_config for PCIe */ | 576 | /* use fsl_indirect_read_config for PCIe */ |
577 | hose->ops = &fsl_indirect_pcie_ops; | 577 | hose->ops = &fsl_indirect_pcie_ops; |
578 | /* For PCIE read HEADER_TYPE to identify controler mode */ | 578 | /* For PCIE read HEADER_TYPE to identify controller mode */ |
579 | early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type); | 579 | early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type); |
580 | if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) | 580 | if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) |
581 | goto no_bridge; | 581 | goto no_bridge; |
diff --git a/arch/powerpc/sysdev/fsl_rcpm.c b/arch/powerpc/sysdev/fsl_rcpm.c new file mode 100644 index 000000000000..9259a94f70e1 --- /dev/null +++ b/arch/powerpc/sysdev/fsl_rcpm.c | |||
@@ -0,0 +1,386 @@ | |||
1 | /* | ||
2 | * RCPM(Run Control/Power Management) support | ||
3 | * | ||
4 | * Copyright 2012-2015 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * Author: Chenhui Zhao <chenhui.zhao@freescale.com> | ||
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 | #define pr_fmt(fmt) "%s: " fmt, __func__ | ||
15 | |||
16 | #include <linux/types.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/of_address.h> | ||
19 | #include <linux/export.h> | ||
20 | |||
21 | #include <asm/io.h> | ||
22 | #include <linux/fsl/guts.h> | ||
23 | #include <asm/cputhreads.h> | ||
24 | #include <asm/fsl_pm.h> | ||
25 | #include <asm/smp.h> | ||
26 | |||
27 | static struct ccsr_rcpm_v1 __iomem *rcpm_v1_regs; | ||
28 | static struct ccsr_rcpm_v2 __iomem *rcpm_v2_regs; | ||
29 | static unsigned int fsl_supported_pm_modes; | ||
30 | |||
31 | static void rcpm_v1_irq_mask(int cpu) | ||
32 | { | ||
33 | int hw_cpu = get_hard_smp_processor_id(cpu); | ||
34 | unsigned int mask = 1 << hw_cpu; | ||
35 | |||
36 | setbits32(&rcpm_v1_regs->cpmimr, mask); | ||
37 | setbits32(&rcpm_v1_regs->cpmcimr, mask); | ||
38 | setbits32(&rcpm_v1_regs->cpmmcmr, mask); | ||
39 | setbits32(&rcpm_v1_regs->cpmnmimr, mask); | ||
40 | } | ||
41 | |||
42 | static void rcpm_v2_irq_mask(int cpu) | ||
43 | { | ||
44 | int hw_cpu = get_hard_smp_processor_id(cpu); | ||
45 | unsigned int mask = 1 << hw_cpu; | ||
46 | |||
47 | setbits32(&rcpm_v2_regs->tpmimr0, mask); | ||
48 | setbits32(&rcpm_v2_regs->tpmcimr0, mask); | ||
49 | setbits32(&rcpm_v2_regs->tpmmcmr0, mask); | ||
50 | setbits32(&rcpm_v2_regs->tpmnmimr0, mask); | ||
51 | } | ||
52 | |||
53 | static void rcpm_v1_irq_unmask(int cpu) | ||
54 | { | ||
55 | int hw_cpu = get_hard_smp_processor_id(cpu); | ||
56 | unsigned int mask = 1 << hw_cpu; | ||
57 | |||
58 | clrbits32(&rcpm_v1_regs->cpmimr, mask); | ||
59 | clrbits32(&rcpm_v1_regs->cpmcimr, mask); | ||
60 | clrbits32(&rcpm_v1_regs->cpmmcmr, mask); | ||
61 | clrbits32(&rcpm_v1_regs->cpmnmimr, mask); | ||
62 | } | ||
63 | |||
64 | static void rcpm_v2_irq_unmask(int cpu) | ||
65 | { | ||
66 | int hw_cpu = get_hard_smp_processor_id(cpu); | ||
67 | unsigned int mask = 1 << hw_cpu; | ||
68 | |||
69 | clrbits32(&rcpm_v2_regs->tpmimr0, mask); | ||
70 | clrbits32(&rcpm_v2_regs->tpmcimr0, mask); | ||
71 | clrbits32(&rcpm_v2_regs->tpmmcmr0, mask); | ||
72 | clrbits32(&rcpm_v2_regs->tpmnmimr0, mask); | ||
73 | } | ||
74 | |||
75 | static void rcpm_v1_set_ip_power(bool enable, u32 mask) | ||
76 | { | ||
77 | if (enable) | ||
78 | setbits32(&rcpm_v1_regs->ippdexpcr, mask); | ||
79 | else | ||
80 | clrbits32(&rcpm_v1_regs->ippdexpcr, mask); | ||
81 | } | ||
82 | |||
83 | static void rcpm_v2_set_ip_power(bool enable, u32 mask) | ||
84 | { | ||
85 | if (enable) | ||
86 | setbits32(&rcpm_v2_regs->ippdexpcr[0], mask); | ||
87 | else | ||
88 | clrbits32(&rcpm_v2_regs->ippdexpcr[0], mask); | ||
89 | } | ||
90 | |||
91 | static void rcpm_v1_cpu_enter_state(int cpu, int state) | ||
92 | { | ||
93 | int hw_cpu = get_hard_smp_processor_id(cpu); | ||
94 | unsigned int mask = 1 << hw_cpu; | ||
95 | |||
96 | switch (state) { | ||
97 | case E500_PM_PH10: | ||
98 | setbits32(&rcpm_v1_regs->cdozcr, mask); | ||
99 | break; | ||
100 | case E500_PM_PH15: | ||
101 | setbits32(&rcpm_v1_regs->cnapcr, mask); | ||
102 | break; | ||
103 | default: | ||
104 | pr_warn("Unknown cpu PM state (%d)\n", state); | ||
105 | break; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | static void rcpm_v2_cpu_enter_state(int cpu, int state) | ||
110 | { | ||
111 | int hw_cpu = get_hard_smp_processor_id(cpu); | ||
112 | u32 mask = 1 << cpu_core_index_of_thread(cpu); | ||
113 | |||
114 | switch (state) { | ||
115 | case E500_PM_PH10: | ||
116 | /* one bit corresponds to one thread for PH10 of 6500 */ | ||
117 | setbits32(&rcpm_v2_regs->tph10setr0, 1 << hw_cpu); | ||
118 | break; | ||
119 | case E500_PM_PH15: | ||
120 | setbits32(&rcpm_v2_regs->pcph15setr, mask); | ||
121 | break; | ||
122 | case E500_PM_PH20: | ||
123 | setbits32(&rcpm_v2_regs->pcph20setr, mask); | ||
124 | break; | ||
125 | case E500_PM_PH30: | ||
126 | setbits32(&rcpm_v2_regs->pcph30setr, mask); | ||
127 | break; | ||
128 | default: | ||
129 | pr_warn("Unknown cpu PM state (%d)\n", state); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | static void rcpm_v1_cpu_die(int cpu) | ||
134 | { | ||
135 | rcpm_v1_cpu_enter_state(cpu, E500_PM_PH15); | ||
136 | } | ||
137 | |||
138 | #ifdef CONFIG_PPC64 | ||
139 | static void qoriq_disable_thread(int cpu) | ||
140 | { | ||
141 | int thread = cpu_thread_in_core(cpu); | ||
142 | |||
143 | book3e_stop_thread(thread); | ||
144 | } | ||
145 | #endif | ||
146 | |||
147 | static void rcpm_v2_cpu_die(int cpu) | ||
148 | { | ||
149 | #ifdef CONFIG_PPC64 | ||
150 | int primary; | ||
151 | |||
152 | if (threads_per_core == 2) { | ||
153 | primary = cpu_first_thread_sibling(cpu); | ||
154 | if (cpu_is_offline(primary) && cpu_is_offline(primary + 1)) { | ||
155 | /* if both threads are offline, put the cpu in PH20 */ | ||
156 | rcpm_v2_cpu_enter_state(cpu, E500_PM_PH20); | ||
157 | } else { | ||
158 | /* if only one thread is offline, disable the thread */ | ||
159 | qoriq_disable_thread(cpu); | ||
160 | } | ||
161 | } | ||
162 | #endif | ||
163 | |||
164 | if (threads_per_core == 1) | ||
165 | rcpm_v2_cpu_enter_state(cpu, E500_PM_PH20); | ||
166 | } | ||
167 | |||
168 | static void rcpm_v1_cpu_exit_state(int cpu, int state) | ||
169 | { | ||
170 | int hw_cpu = get_hard_smp_processor_id(cpu); | ||
171 | unsigned int mask = 1 << hw_cpu; | ||
172 | |||
173 | switch (state) { | ||
174 | case E500_PM_PH10: | ||
175 | clrbits32(&rcpm_v1_regs->cdozcr, mask); | ||
176 | break; | ||
177 | case E500_PM_PH15: | ||
178 | clrbits32(&rcpm_v1_regs->cnapcr, mask); | ||
179 | break; | ||
180 | default: | ||
181 | pr_warn("Unknown cpu PM state (%d)\n", state); | ||
182 | break; | ||
183 | } | ||
184 | } | ||
185 | |||
186 | static void rcpm_v1_cpu_up_prepare(int cpu) | ||
187 | { | ||
188 | rcpm_v1_cpu_exit_state(cpu, E500_PM_PH15); | ||
189 | rcpm_v1_irq_unmask(cpu); | ||
190 | } | ||
191 | |||
192 | static void rcpm_v2_cpu_exit_state(int cpu, int state) | ||
193 | { | ||
194 | int hw_cpu = get_hard_smp_processor_id(cpu); | ||
195 | u32 mask = 1 << cpu_core_index_of_thread(cpu); | ||
196 | |||
197 | switch (state) { | ||
198 | case E500_PM_PH10: | ||
199 | setbits32(&rcpm_v2_regs->tph10clrr0, 1 << hw_cpu); | ||
200 | break; | ||
201 | case E500_PM_PH15: | ||
202 | setbits32(&rcpm_v2_regs->pcph15clrr, mask); | ||
203 | break; | ||
204 | case E500_PM_PH20: | ||
205 | setbits32(&rcpm_v2_regs->pcph20clrr, mask); | ||
206 | break; | ||
207 | case E500_PM_PH30: | ||
208 | setbits32(&rcpm_v2_regs->pcph30clrr, mask); | ||
209 | break; | ||
210 | default: | ||
211 | pr_warn("Unknown cpu PM state (%d)\n", state); | ||
212 | } | ||
213 | } | ||
214 | |||
215 | static void rcpm_v2_cpu_up_prepare(int cpu) | ||
216 | { | ||
217 | rcpm_v2_cpu_exit_state(cpu, E500_PM_PH20); | ||
218 | rcpm_v2_irq_unmask(cpu); | ||
219 | } | ||
220 | |||
221 | static int rcpm_v1_plat_enter_state(int state) | ||
222 | { | ||
223 | u32 *pmcsr_reg = &rcpm_v1_regs->powmgtcsr; | ||
224 | int ret = 0; | ||
225 | int result; | ||
226 | |||
227 | switch (state) { | ||
228 | case PLAT_PM_SLEEP: | ||
229 | setbits32(pmcsr_reg, RCPM_POWMGTCSR_SLP); | ||
230 | |||
231 | /* Upon resume, wait for RCPM_POWMGTCSR_SLP bit to be clear. */ | ||
232 | result = spin_event_timeout( | ||
233 | !(in_be32(pmcsr_reg) & RCPM_POWMGTCSR_SLP), 10000, 10); | ||
234 | if (!result) { | ||
235 | pr_err("timeout waiting for SLP bit to be cleared\n"); | ||
236 | ret = -ETIMEDOUT; | ||
237 | } | ||
238 | break; | ||
239 | default: | ||
240 | pr_warn("Unknown platform PM state (%d)", state); | ||
241 | ret = -EINVAL; | ||
242 | } | ||
243 | |||
244 | return ret; | ||
245 | } | ||
246 | |||
247 | static int rcpm_v2_plat_enter_state(int state) | ||
248 | { | ||
249 | u32 *pmcsr_reg = &rcpm_v2_regs->powmgtcsr; | ||
250 | int ret = 0; | ||
251 | int result; | ||
252 | |||
253 | switch (state) { | ||
254 | case PLAT_PM_LPM20: | ||
255 | /* clear previous LPM20 status */ | ||
256 | setbits32(pmcsr_reg, RCPM_POWMGTCSR_P_LPM20_ST); | ||
257 | /* enter LPM20 status */ | ||
258 | setbits32(pmcsr_reg, RCPM_POWMGTCSR_LPM20_RQ); | ||
259 | |||
260 | /* At this point, the device is in LPM20 status. */ | ||
261 | |||
262 | /* resume ... */ | ||
263 | result = spin_event_timeout( | ||
264 | !(in_be32(pmcsr_reg) & RCPM_POWMGTCSR_LPM20_ST), 10000, 10); | ||
265 | if (!result) { | ||
266 | pr_err("timeout waiting for LPM20 bit to be cleared\n"); | ||
267 | ret = -ETIMEDOUT; | ||
268 | } | ||
269 | break; | ||
270 | default: | ||
271 | pr_warn("Unknown platform PM state (%d)\n", state); | ||
272 | ret = -EINVAL; | ||
273 | } | ||
274 | |||
275 | return ret; | ||
276 | } | ||
277 | |||
278 | static int rcpm_v1_plat_enter_sleep(void) | ||
279 | { | ||
280 | return rcpm_v1_plat_enter_state(PLAT_PM_SLEEP); | ||
281 | } | ||
282 | |||
283 | static int rcpm_v2_plat_enter_sleep(void) | ||
284 | { | ||
285 | return rcpm_v2_plat_enter_state(PLAT_PM_LPM20); | ||
286 | } | ||
287 | |||
288 | static void rcpm_common_freeze_time_base(u32 *tben_reg, int freeze) | ||
289 | { | ||
290 | static u32 mask; | ||
291 | |||
292 | if (freeze) { | ||
293 | mask = in_be32(tben_reg); | ||
294 | clrbits32(tben_reg, mask); | ||
295 | } else { | ||
296 | setbits32(tben_reg, mask); | ||
297 | } | ||
298 | |||
299 | /* read back to push the previous write */ | ||
300 | in_be32(tben_reg); | ||
301 | } | ||
302 | |||
303 | static void rcpm_v1_freeze_time_base(bool freeze) | ||
304 | { | ||
305 | rcpm_common_freeze_time_base(&rcpm_v1_regs->ctbenr, freeze); | ||
306 | } | ||
307 | |||
308 | static void rcpm_v2_freeze_time_base(bool freeze) | ||
309 | { | ||
310 | rcpm_common_freeze_time_base(&rcpm_v2_regs->pctbenr, freeze); | ||
311 | } | ||
312 | |||
313 | static unsigned int rcpm_get_pm_modes(void) | ||
314 | { | ||
315 | return fsl_supported_pm_modes; | ||
316 | } | ||
317 | |||
318 | static const struct fsl_pm_ops qoriq_rcpm_v1_ops = { | ||
319 | .irq_mask = rcpm_v1_irq_mask, | ||
320 | .irq_unmask = rcpm_v1_irq_unmask, | ||
321 | .cpu_enter_state = rcpm_v1_cpu_enter_state, | ||
322 | .cpu_exit_state = rcpm_v1_cpu_exit_state, | ||
323 | .cpu_up_prepare = rcpm_v1_cpu_up_prepare, | ||
324 | .cpu_die = rcpm_v1_cpu_die, | ||
325 | .plat_enter_sleep = rcpm_v1_plat_enter_sleep, | ||
326 | .set_ip_power = rcpm_v1_set_ip_power, | ||
327 | .freeze_time_base = rcpm_v1_freeze_time_base, | ||
328 | .get_pm_modes = rcpm_get_pm_modes, | ||
329 | }; | ||
330 | |||
331 | static const struct fsl_pm_ops qoriq_rcpm_v2_ops = { | ||
332 | .irq_mask = rcpm_v2_irq_mask, | ||
333 | .irq_unmask = rcpm_v2_irq_unmask, | ||
334 | .cpu_enter_state = rcpm_v2_cpu_enter_state, | ||
335 | .cpu_exit_state = rcpm_v2_cpu_exit_state, | ||
336 | .cpu_up_prepare = rcpm_v2_cpu_up_prepare, | ||
337 | .cpu_die = rcpm_v2_cpu_die, | ||
338 | .plat_enter_sleep = rcpm_v2_plat_enter_sleep, | ||
339 | .set_ip_power = rcpm_v2_set_ip_power, | ||
340 | .freeze_time_base = rcpm_v2_freeze_time_base, | ||
341 | .get_pm_modes = rcpm_get_pm_modes, | ||
342 | }; | ||
343 | |||
344 | static const struct of_device_id rcpm_matches[] = { | ||
345 | { | ||
346 | .compatible = "fsl,qoriq-rcpm-1.0", | ||
347 | .data = &qoriq_rcpm_v1_ops, | ||
348 | }, | ||
349 | { | ||
350 | .compatible = "fsl,qoriq-rcpm-2.0", | ||
351 | .data = &qoriq_rcpm_v2_ops, | ||
352 | }, | ||
353 | { | ||
354 | .compatible = "fsl,qoriq-rcpm-2.1", | ||
355 | .data = &qoriq_rcpm_v2_ops, | ||
356 | }, | ||
357 | {}, | ||
358 | }; | ||
359 | |||
360 | int __init fsl_rcpm_init(void) | ||
361 | { | ||
362 | struct device_node *np; | ||
363 | const struct of_device_id *match; | ||
364 | void __iomem *base; | ||
365 | |||
366 | np = of_find_matching_node_and_match(NULL, rcpm_matches, &match); | ||
367 | if (!np) | ||
368 | return 0; | ||
369 | |||
370 | base = of_iomap(np, 0); | ||
371 | of_node_put(np); | ||
372 | if (!base) { | ||
373 | pr_err("of_iomap() error.\n"); | ||
374 | return -ENOMEM; | ||
375 | } | ||
376 | |||
377 | rcpm_v1_regs = base; | ||
378 | rcpm_v2_regs = base; | ||
379 | |||
380 | /* support sleep by default */ | ||
381 | fsl_supported_pm_modes = FSL_PM_SLEEP; | ||
382 | |||
383 | qoriq_pm_ops = match->data; | ||
384 | |||
385 | return 0; | ||
386 | } | ||
diff --git a/arch/powerpc/sysdev/fsl_rmu.c b/arch/powerpc/sysdev/fsl_rmu.c index b48197ae44d0..ffe0ee832768 100644 --- a/arch/powerpc/sysdev/fsl_rmu.c +++ b/arch/powerpc/sysdev/fsl_rmu.c | |||
@@ -570,7 +570,7 @@ int fsl_rio_port_write_init(struct fsl_rio_pw *pw) | |||
570 | out_be32(&pw->pw_regs->pwsr, | 570 | out_be32(&pw->pw_regs->pwsr, |
571 | (RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD)); | 571 | (RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD)); |
572 | 572 | ||
573 | /* Configure port write contoller for snooping enable all reporting, | 573 | /* Configure port write controller for snooping enable all reporting, |
574 | clear queue full */ | 574 | clear queue full */ |
575 | out_be32(&pw->pw_regs->pwmr, | 575 | out_be32(&pw->pw_regs->pwmr, |
576 | RIO_IPWMR_SEN | RIO_IPWMR_QFIE | RIO_IPWMR_EIE | RIO_IPWMR_CQ); | 576 | RIO_IPWMR_SEN | RIO_IPWMR_QFIE | RIO_IPWMR_EIE | RIO_IPWMR_CQ); |
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c index 6f99ed3967fd..aa2c186d3115 100644 --- a/arch/powerpc/sysdev/i8259.c +++ b/arch/powerpc/sysdev/i8259.c | |||
@@ -238,7 +238,7 @@ void i8259_init(struct device_node *node, unsigned long intack_addr) | |||
238 | /* init master interrupt controller */ | 238 | /* init master interrupt controller */ |
239 | outb(0x11, 0x20); /* Start init sequence */ | 239 | outb(0x11, 0x20); /* Start init sequence */ |
240 | outb(0x00, 0x21); /* Vector base */ | 240 | outb(0x00, 0x21); /* Vector base */ |
241 | outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */ | 241 | outb(0x04, 0x21); /* edge triggered, Cascade (slave) on IRQ2 */ |
242 | outb(0x01, 0x21); /* Select 8086 mode */ | 242 | outb(0x01, 0x21); /* Select 8086 mode */ |
243 | 243 | ||
244 | /* init slave interrupt controller */ | 244 | /* init slave interrupt controller */ |
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 2a0452e364ba..afe3c7cd395d 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * arch/powerpc/kernel/mpic.c | 2 | * arch/powerpc/kernel/mpic.c |
3 | * | 3 | * |
4 | * Driver for interrupt controllers following the OpenPIC standard, the | 4 | * Driver for interrupt controllers following the OpenPIC standard, the |
5 | * common implementation beeing IBM's MPIC. This driver also can deal | 5 | * common implementation being IBM's MPIC. This driver also can deal |
6 | * with various broken implementations of this HW. | 6 | * with various broken implementations of this HW. |
7 | * | 7 | * |
8 | * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. | 8 | * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. |
@@ -1657,7 +1657,7 @@ void __init mpic_init(struct mpic *mpic) | |||
1657 | } | 1657 | } |
1658 | } | 1658 | } |
1659 | 1659 | ||
1660 | /* FSL mpic error interrupt intialization */ | 1660 | /* FSL mpic error interrupt initialization */ |
1661 | if (mpic->flags & MPIC_FSL_HAS_EIMR) | 1661 | if (mpic->flags & MPIC_FSL_HAS_EIMR) |
1662 | mpic_err_int_init(mpic, MPIC_FSL_ERR_INT); | 1662 | mpic_err_int_init(mpic, MPIC_FSL_ERR_INT); |
1663 | } | 1663 | } |
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 07a8508cb7fa..942796fa4767 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
@@ -47,6 +47,9 @@ | |||
47 | #include <asm/debug.h> | 47 | #include <asm/debug.h> |
48 | #include <asm/hw_breakpoint.h> | 48 | #include <asm/hw_breakpoint.h> |
49 | 49 | ||
50 | #include <asm/opal.h> | ||
51 | #include <asm/firmware.h> | ||
52 | |||
50 | #ifdef CONFIG_PPC64 | 53 | #ifdef CONFIG_PPC64 |
51 | #include <asm/hvcall.h> | 54 | #include <asm/hvcall.h> |
52 | #include <asm/paca.h> | 55 | #include <asm/paca.h> |
@@ -119,6 +122,16 @@ static void dump(void); | |||
119 | static void prdump(unsigned long, long); | 122 | static void prdump(unsigned long, long); |
120 | static int ppc_inst_dump(unsigned long, long, int); | 123 | static int ppc_inst_dump(unsigned long, long, int); |
121 | static void dump_log_buf(void); | 124 | static void dump_log_buf(void); |
125 | |||
126 | #ifdef CONFIG_PPC_POWERNV | ||
127 | static void dump_opal_msglog(void); | ||
128 | #else | ||
129 | static inline void dump_opal_msglog(void) | ||
130 | { | ||
131 | printf("Machine is not running OPAL firmware.\n"); | ||
132 | } | ||
133 | #endif | ||
134 | |||
122 | static void backtrace(struct pt_regs *); | 135 | static void backtrace(struct pt_regs *); |
123 | static void excprint(struct pt_regs *); | 136 | static void excprint(struct pt_regs *); |
124 | static void prregs(struct pt_regs *); | 137 | static void prregs(struct pt_regs *); |
@@ -150,6 +163,7 @@ static int cpu_cmd(void); | |||
150 | static void csum(void); | 163 | static void csum(void); |
151 | static void bootcmds(void); | 164 | static void bootcmds(void); |
152 | static void proccall(void); | 165 | static void proccall(void); |
166 | static void show_tasks(void); | ||
153 | void dump_segments(void); | 167 | void dump_segments(void); |
154 | static void symbol_lookup(void); | 168 | static void symbol_lookup(void); |
155 | static void xmon_show_stack(unsigned long sp, unsigned long lr, | 169 | static void xmon_show_stack(unsigned long sp, unsigned long lr, |
@@ -202,6 +216,10 @@ Commands:\n\ | |||
202 | df dump float values\n\ | 216 | df dump float values\n\ |
203 | dd dump double values\n\ | 217 | dd dump double values\n\ |
204 | dl dump the kernel log buffer\n" | 218 | dl dump the kernel log buffer\n" |
219 | #ifdef CONFIG_PPC_POWERNV | ||
220 | "\ | ||
221 | do dump the OPAL message log\n" | ||
222 | #endif | ||
205 | #ifdef CONFIG_PPC64 | 223 | #ifdef CONFIG_PPC64 |
206 | "\ | 224 | "\ |
207 | dp[#] dump paca for current cpu, or cpu #\n\ | 225 | dp[#] dump paca for current cpu, or cpu #\n\ |
@@ -221,6 +239,7 @@ Commands:\n\ | |||
221 | mz zero a block of memory\n\ | 239 | mz zero a block of memory\n\ |
222 | mi show information about memory allocation\n\ | 240 | mi show information about memory allocation\n\ |
223 | p call a procedure\n\ | 241 | p call a procedure\n\ |
242 | P list processes/tasks\n\ | ||
224 | r print registers\n\ | 243 | r print registers\n\ |
225 | s single step\n" | 244 | s single step\n" |
226 | #ifdef CONFIG_SPU_BASE | 245 | #ifdef CONFIG_SPU_BASE |
@@ -233,7 +252,7 @@ Commands:\n\ | |||
233 | " S print special registers\n\ | 252 | " S print special registers\n\ |
234 | t print backtrace\n\ | 253 | t print backtrace\n\ |
235 | x exit monitor and recover\n\ | 254 | x exit monitor and recover\n\ |
236 | X exit monitor and dont recover\n" | 255 | X exit monitor and don't recover\n" |
237 | #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E) | 256 | #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E) |
238 | " u dump segment table or SLB\n" | 257 | " u dump segment table or SLB\n" |
239 | #elif defined(CONFIG_PPC_STD_MMU_32) | 258 | #elif defined(CONFIG_PPC_STD_MMU_32) |
@@ -950,6 +969,9 @@ cmds(struct pt_regs *excp) | |||
950 | case 'p': | 969 | case 'p': |
951 | proccall(); | 970 | proccall(); |
952 | break; | 971 | break; |
972 | case 'P': | ||
973 | show_tasks(); | ||
974 | break; | ||
953 | #ifdef CONFIG_PPC_STD_MMU | 975 | #ifdef CONFIG_PPC_STD_MMU |
954 | case 'u': | 976 | case 'u': |
955 | dump_segments(); | 977 | dump_segments(); |
@@ -2253,6 +2275,8 @@ dump(void) | |||
2253 | last_cmd = "di\n"; | 2275 | last_cmd = "di\n"; |
2254 | } else if (c == 'l') { | 2276 | } else if (c == 'l') { |
2255 | dump_log_buf(); | 2277 | dump_log_buf(); |
2278 | } else if (c == 'o') { | ||
2279 | dump_opal_msglog(); | ||
2256 | } else if (c == 'r') { | 2280 | } else if (c == 'r') { |
2257 | scanhex(&ndump); | 2281 | scanhex(&ndump); |
2258 | if (ndump == 0) | 2282 | if (ndump == 0) |
@@ -2395,6 +2419,45 @@ dump_log_buf(void) | |||
2395 | catch_memory_errors = 0; | 2419 | catch_memory_errors = 0; |
2396 | } | 2420 | } |
2397 | 2421 | ||
2422 | #ifdef CONFIG_PPC_POWERNV | ||
2423 | static void dump_opal_msglog(void) | ||
2424 | { | ||
2425 | unsigned char buf[128]; | ||
2426 | ssize_t res; | ||
2427 | loff_t pos = 0; | ||
2428 | |||
2429 | if (!firmware_has_feature(FW_FEATURE_OPAL)) { | ||
2430 | printf("Machine is not running OPAL firmware.\n"); | ||
2431 | return; | ||
2432 | } | ||
2433 | |||
2434 | if (setjmp(bus_error_jmp) != 0) { | ||
2435 | printf("Error dumping OPAL msglog!\n"); | ||
2436 | return; | ||
2437 | } | ||
2438 | |||
2439 | catch_memory_errors = 1; | ||
2440 | sync(); | ||
2441 | |||
2442 | xmon_start_pagination(); | ||
2443 | while ((res = opal_msglog_copy(buf, pos, sizeof(buf) - 1))) { | ||
2444 | if (res < 0) { | ||
2445 | printf("Error dumping OPAL msglog! Error: %zd\n", res); | ||
2446 | break; | ||
2447 | } | ||
2448 | buf[res] = '\0'; | ||
2449 | printf("%s", buf); | ||
2450 | pos += res; | ||
2451 | } | ||
2452 | xmon_end_pagination(); | ||
2453 | |||
2454 | sync(); | ||
2455 | /* wait a little while to see if we get a machine check */ | ||
2456 | __delay(200); | ||
2457 | catch_memory_errors = 0; | ||
2458 | } | ||
2459 | #endif | ||
2460 | |||
2398 | /* | 2461 | /* |
2399 | * Memory operations - move, set, print differences | 2462 | * Memory operations - move, set, print differences |
2400 | */ | 2463 | */ |
@@ -2508,6 +2571,61 @@ memzcan(void) | |||
2508 | printf("%.8x\n", a - mskip); | 2571 | printf("%.8x\n", a - mskip); |
2509 | } | 2572 | } |
2510 | 2573 | ||
2574 | static void show_task(struct task_struct *tsk) | ||
2575 | { | ||
2576 | char state; | ||
2577 | |||
2578 | /* | ||
2579 | * Cloned from kdb_task_state_char(), which is not entirely | ||
2580 | * appropriate for calling from xmon. This could be moved | ||
2581 | * to a common, generic, routine used by both. | ||
2582 | */ | ||
2583 | state = (tsk->state == 0) ? 'R' : | ||
2584 | (tsk->state < 0) ? 'U' : | ||
2585 | (tsk->state & TASK_UNINTERRUPTIBLE) ? 'D' : | ||
2586 | (tsk->state & TASK_STOPPED) ? 'T' : | ||
2587 | (tsk->state & TASK_TRACED) ? 'C' : | ||
2588 | (tsk->exit_state & EXIT_ZOMBIE) ? 'Z' : | ||
2589 | (tsk->exit_state & EXIT_DEAD) ? 'E' : | ||
2590 | (tsk->state & TASK_INTERRUPTIBLE) ? 'S' : '?'; | ||
2591 | |||
2592 | printf("%p %016lx %6d %6d %c %2d %s\n", tsk, | ||
2593 | tsk->thread.ksp, | ||
2594 | tsk->pid, tsk->parent->pid, | ||
2595 | state, task_thread_info(tsk)->cpu, | ||
2596 | tsk->comm); | ||
2597 | } | ||
2598 | |||
2599 | static void show_tasks(void) | ||
2600 | { | ||
2601 | unsigned long tskv; | ||
2602 | struct task_struct *tsk = NULL; | ||
2603 | |||
2604 | printf(" task_struct ->thread.ksp PID PPID S P CMD\n"); | ||
2605 | |||
2606 | if (scanhex(&tskv)) | ||
2607 | tsk = (struct task_struct *)tskv; | ||
2608 | |||
2609 | if (setjmp(bus_error_jmp) != 0) { | ||
2610 | catch_memory_errors = 0; | ||
2611 | printf("*** Error dumping task %p\n", tsk); | ||
2612 | return; | ||
2613 | } | ||
2614 | |||
2615 | catch_memory_errors = 1; | ||
2616 | sync(); | ||
2617 | |||
2618 | if (tsk) | ||
2619 | show_task(tsk); | ||
2620 | else | ||
2621 | for_each_process(tsk) | ||
2622 | show_task(tsk); | ||
2623 | |||
2624 | sync(); | ||
2625 | __delay(200); | ||
2626 | catch_memory_errors = 0; | ||
2627 | } | ||
2628 | |||
2511 | static void proccall(void) | 2629 | static void proccall(void) |
2512 | { | 2630 | { |
2513 | unsigned long args[8]; | 2631 | unsigned long args[8]; |
diff --git a/drivers/misc/cxl/Makefile b/drivers/misc/cxl/Makefile index be2ac5ce349f..8a55c1aa11aa 100644 --- a/drivers/misc/cxl/Makefile +++ b/drivers/misc/cxl/Makefile | |||
@@ -4,6 +4,7 @@ ccflags-$(CONFIG_PPC_WERROR) += -Werror | |||
4 | cxl-y += main.o file.o irq.o fault.o native.o | 4 | cxl-y += main.o file.o irq.o fault.o native.o |
5 | cxl-y += context.o sysfs.o debugfs.o pci.o trace.o | 5 | cxl-y += context.o sysfs.o debugfs.o pci.o trace.o |
6 | cxl-y += vphb.o api.o | 6 | cxl-y += vphb.o api.o |
7 | cxl-$(CONFIG_PPC_PSERIES) += flash.o guest.o of.o hcalls.o | ||
7 | obj-$(CONFIG_CXL) += cxl.o | 8 | obj-$(CONFIG_CXL) += cxl.o |
8 | obj-$(CONFIG_CXL_BASE) += base.o | 9 | obj-$(CONFIG_CXL_BASE) += base.o |
9 | 10 | ||
diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c index ea3eeb7011e1..2107c948406d 100644 --- a/drivers/misc/cxl/api.c +++ b/drivers/misc/cxl/api.c | |||
@@ -51,8 +51,6 @@ struct cxl_context *cxl_dev_context_init(struct pci_dev *dev) | |||
51 | if (rc) | 51 | if (rc) |
52 | goto err_mapping; | 52 | goto err_mapping; |
53 | 53 | ||
54 | cxl_assign_psn_space(ctx); | ||
55 | |||
56 | return ctx; | 54 | return ctx; |
57 | 55 | ||
58 | err_mapping: | 56 | err_mapping: |
@@ -78,7 +76,6 @@ struct device *cxl_get_phys_dev(struct pci_dev *dev) | |||
78 | 76 | ||
79 | return afu->adapter->dev.parent; | 77 | return afu->adapter->dev.parent; |
80 | } | 78 | } |
81 | EXPORT_SYMBOL_GPL(cxl_get_phys_dev); | ||
82 | 79 | ||
83 | int cxl_release_context(struct cxl_context *ctx) | 80 | int cxl_release_context(struct cxl_context *ctx) |
84 | { | 81 | { |
@@ -91,28 +88,11 @@ int cxl_release_context(struct cxl_context *ctx) | |||
91 | } | 88 | } |
92 | EXPORT_SYMBOL_GPL(cxl_release_context); | 89 | EXPORT_SYMBOL_GPL(cxl_release_context); |
93 | 90 | ||
94 | int cxl_allocate_afu_irqs(struct cxl_context *ctx, int num) | ||
95 | { | ||
96 | if (num == 0) | ||
97 | num = ctx->afu->pp_irqs; | ||
98 | return afu_allocate_irqs(ctx, num); | ||
99 | } | ||
100 | EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs); | ||
101 | |||
102 | void cxl_free_afu_irqs(struct cxl_context *ctx) | ||
103 | { | ||
104 | afu_irq_name_free(ctx); | ||
105 | cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter); | ||
106 | } | ||
107 | EXPORT_SYMBOL_GPL(cxl_free_afu_irqs); | ||
108 | |||
109 | static irq_hw_number_t cxl_find_afu_irq(struct cxl_context *ctx, int num) | 91 | static irq_hw_number_t cxl_find_afu_irq(struct cxl_context *ctx, int num) |
110 | { | 92 | { |
111 | __u16 range; | 93 | __u16 range; |
112 | int r; | 94 | int r; |
113 | 95 | ||
114 | WARN_ON(num == 0); | ||
115 | |||
116 | for (r = 0; r < CXL_IRQ_RANGES; r++) { | 96 | for (r = 0; r < CXL_IRQ_RANGES; r++) { |
117 | range = ctx->irqs.range[r]; | 97 | range = ctx->irqs.range[r]; |
118 | if (num < range) { | 98 | if (num < range) { |
@@ -123,6 +103,44 @@ static irq_hw_number_t cxl_find_afu_irq(struct cxl_context *ctx, int num) | |||
123 | return 0; | 103 | return 0; |
124 | } | 104 | } |
125 | 105 | ||
106 | int cxl_allocate_afu_irqs(struct cxl_context *ctx, int num) | ||
107 | { | ||
108 | int res; | ||
109 | irq_hw_number_t hwirq; | ||
110 | |||
111 | if (num == 0) | ||
112 | num = ctx->afu->pp_irqs; | ||
113 | res = afu_allocate_irqs(ctx, num); | ||
114 | if (!res && !cpu_has_feature(CPU_FTR_HVMODE)) { | ||
115 | /* In a guest, the PSL interrupt is not multiplexed. It was | ||
116 | * allocated above, and we need to set its handler | ||
117 | */ | ||
118 | hwirq = cxl_find_afu_irq(ctx, 0); | ||
119 | if (hwirq) | ||
120 | cxl_map_irq(ctx->afu->adapter, hwirq, cxl_ops->psl_interrupt, ctx, "psl"); | ||
121 | } | ||
122 | return res; | ||
123 | } | ||
124 | EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs); | ||
125 | |||
126 | void cxl_free_afu_irqs(struct cxl_context *ctx) | ||
127 | { | ||
128 | irq_hw_number_t hwirq; | ||
129 | unsigned int virq; | ||
130 | |||
131 | if (!cpu_has_feature(CPU_FTR_HVMODE)) { | ||
132 | hwirq = cxl_find_afu_irq(ctx, 0); | ||
133 | if (hwirq) { | ||
134 | virq = irq_find_mapping(NULL, hwirq); | ||
135 | if (virq) | ||
136 | cxl_unmap_irq(virq, ctx); | ||
137 | } | ||
138 | } | ||
139 | afu_irq_name_free(ctx); | ||
140 | cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter); | ||
141 | } | ||
142 | EXPORT_SYMBOL_GPL(cxl_free_afu_irqs); | ||
143 | |||
126 | int cxl_map_afu_irq(struct cxl_context *ctx, int num, | 144 | int cxl_map_afu_irq(struct cxl_context *ctx, int num, |
127 | irq_handler_t handler, void *cookie, char *name) | 145 | irq_handler_t handler, void *cookie, char *name) |
128 | { | 146 | { |
@@ -178,7 +196,7 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed, | |||
178 | 196 | ||
179 | cxl_ctx_get(); | 197 | cxl_ctx_get(); |
180 | 198 | ||
181 | if ((rc = cxl_attach_process(ctx, kernel, wed , 0))) { | 199 | if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) { |
182 | put_pid(ctx->pid); | 200 | put_pid(ctx->pid); |
183 | cxl_ctx_put(); | 201 | cxl_ctx_put(); |
184 | goto out; | 202 | goto out; |
@@ -193,7 +211,7 @@ EXPORT_SYMBOL_GPL(cxl_start_context); | |||
193 | 211 | ||
194 | int cxl_process_element(struct cxl_context *ctx) | 212 | int cxl_process_element(struct cxl_context *ctx) |
195 | { | 213 | { |
196 | return ctx->pe; | 214 | return ctx->external_pe; |
197 | } | 215 | } |
198 | EXPORT_SYMBOL_GPL(cxl_process_element); | 216 | EXPORT_SYMBOL_GPL(cxl_process_element); |
199 | 217 | ||
@@ -207,7 +225,6 @@ EXPORT_SYMBOL_GPL(cxl_stop_context); | |||
207 | void cxl_set_master(struct cxl_context *ctx) | 225 | void cxl_set_master(struct cxl_context *ctx) |
208 | { | 226 | { |
209 | ctx->master = true; | 227 | ctx->master = true; |
210 | cxl_assign_psn_space(ctx); | ||
211 | } | 228 | } |
212 | EXPORT_SYMBOL_GPL(cxl_set_master); | 229 | EXPORT_SYMBOL_GPL(cxl_set_master); |
213 | 230 | ||
@@ -325,15 +342,11 @@ EXPORT_SYMBOL_GPL(cxl_start_work); | |||
325 | 342 | ||
326 | void __iomem *cxl_psa_map(struct cxl_context *ctx) | 343 | void __iomem *cxl_psa_map(struct cxl_context *ctx) |
327 | { | 344 | { |
328 | struct cxl_afu *afu = ctx->afu; | 345 | if (ctx->status != STARTED) |
329 | int rc; | ||
330 | |||
331 | rc = cxl_afu_check_and_enable(afu); | ||
332 | if (rc) | ||
333 | return NULL; | 346 | return NULL; |
334 | 347 | ||
335 | pr_devel("%s: psn_phys%llx size:%llx\n", | 348 | pr_devel("%s: psn_phys%llx size:%llx\n", |
336 | __func__, afu->psn_phys, afu->adapter->ps_size); | 349 | __func__, ctx->psn_phys, ctx->psn_size); |
337 | return ioremap(ctx->psn_phys, ctx->psn_size); | 350 | return ioremap(ctx->psn_phys, ctx->psn_size); |
338 | } | 351 | } |
339 | EXPORT_SYMBOL_GPL(cxl_psa_map); | 352 | EXPORT_SYMBOL_GPL(cxl_psa_map); |
@@ -349,11 +362,11 @@ int cxl_afu_reset(struct cxl_context *ctx) | |||
349 | struct cxl_afu *afu = ctx->afu; | 362 | struct cxl_afu *afu = ctx->afu; |
350 | int rc; | 363 | int rc; |
351 | 364 | ||
352 | rc = __cxl_afu_reset(afu); | 365 | rc = cxl_ops->afu_reset(afu); |
353 | if (rc) | 366 | if (rc) |
354 | return rc; | 367 | return rc; |
355 | 368 | ||
356 | return cxl_afu_check_and_enable(afu); | 369 | return cxl_ops->afu_check_and_enable(afu); |
357 | } | 370 | } |
358 | EXPORT_SYMBOL_GPL(cxl_afu_reset); | 371 | EXPORT_SYMBOL_GPL(cxl_afu_reset); |
359 | 372 | ||
@@ -363,3 +376,11 @@ void cxl_perst_reloads_same_image(struct cxl_afu *afu, | |||
363 | afu->adapter->perst_same_image = perst_reloads_same_image; | 376 | afu->adapter->perst_same_image = perst_reloads_same_image; |
364 | } | 377 | } |
365 | EXPORT_SYMBOL_GPL(cxl_perst_reloads_same_image); | 378 | EXPORT_SYMBOL_GPL(cxl_perst_reloads_same_image); |
379 | |||
380 | ssize_t cxl_read_adapter_vpd(struct pci_dev *dev, void *buf, size_t count) | ||
381 | { | ||
382 | struct cxl_afu *afu = cxl_pci_to_afu(dev); | ||
383 | |||
384 | return cxl_ops->read_adapter_vpd(afu->adapter, buf, count); | ||
385 | } | ||
386 | EXPORT_SYMBOL_GPL(cxl_read_adapter_vpd); | ||
diff --git a/drivers/misc/cxl/base.c b/drivers/misc/cxl/base.c index a9f0dd3255a2..9b90ec6c07cd 100644 --- a/drivers/misc/cxl/base.c +++ b/drivers/misc/cxl/base.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/rcupdate.h> | 11 | #include <linux/rcupdate.h> |
12 | #include <asm/errno.h> | 12 | #include <asm/errno.h> |
13 | #include <misc/cxl-base.h> | 13 | #include <misc/cxl-base.h> |
14 | #include <linux/of_platform.h> | ||
14 | #include "cxl.h" | 15 | #include "cxl.h" |
15 | 16 | ||
16 | /* protected by rcu */ | 17 | /* protected by rcu */ |
@@ -84,3 +85,34 @@ void unregister_cxl_calls(struct cxl_calls *calls) | |||
84 | synchronize_rcu(); | 85 | synchronize_rcu(); |
85 | } | 86 | } |
86 | EXPORT_SYMBOL_GPL(unregister_cxl_calls); | 87 | EXPORT_SYMBOL_GPL(unregister_cxl_calls); |
88 | |||
89 | int cxl_update_properties(struct device_node *dn, | ||
90 | struct property *new_prop) | ||
91 | { | ||
92 | return of_update_property(dn, new_prop); | ||
93 | } | ||
94 | EXPORT_SYMBOL_GPL(cxl_update_properties); | ||
95 | |||
96 | static int __init cxl_base_init(void) | ||
97 | { | ||
98 | struct device_node *np = NULL; | ||
99 | struct platform_device *dev; | ||
100 | int count = 0; | ||
101 | |||
102 | /* | ||
103 | * Scan for compatible devices in guest only | ||
104 | */ | ||
105 | if (cpu_has_feature(CPU_FTR_HVMODE)) | ||
106 | return 0; | ||
107 | |||
108 | while ((np = of_find_compatible_node(np, NULL, | ||
109 | "ibm,coherent-platform-facility"))) { | ||
110 | dev = of_platform_device_create(np, NULL, NULL); | ||
111 | if (dev) | ||
112 | count++; | ||
113 | } | ||
114 | pr_devel("Found %d cxl device(s)\n", count); | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | module_init(cxl_base_init); | ||
diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c index 262b88eac414..10370f280500 100644 --- a/drivers/misc/cxl/context.c +++ b/drivers/misc/cxl/context.c | |||
@@ -95,7 +95,12 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master, | |||
95 | return i; | 95 | return i; |
96 | 96 | ||
97 | ctx->pe = i; | 97 | ctx->pe = i; |
98 | ctx->elem = &ctx->afu->spa[i]; | 98 | if (cpu_has_feature(CPU_FTR_HVMODE)) { |
99 | ctx->elem = &ctx->afu->native->spa[i]; | ||
100 | ctx->external_pe = ctx->pe; | ||
101 | } else { | ||
102 | ctx->external_pe = -1; /* assigned when attaching */ | ||
103 | } | ||
99 | ctx->pe_inserted = false; | 104 | ctx->pe_inserted = false; |
100 | 105 | ||
101 | /* | 106 | /* |
@@ -214,8 +219,8 @@ int __detach_context(struct cxl_context *ctx) | |||
214 | /* Only warn if we detached while the link was OK. | 219 | /* Only warn if we detached while the link was OK. |
215 | * If detach fails when hw is down, we don't care. | 220 | * If detach fails when hw is down, we don't care. |
216 | */ | 221 | */ |
217 | WARN_ON(cxl_detach_process(ctx) && | 222 | WARN_ON(cxl_ops->detach_process(ctx) && |
218 | cxl_adapter_link_ok(ctx->afu->adapter)); | 223 | cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)); |
219 | flush_work(&ctx->fault_work); /* Only needed for dedicated process */ | 224 | flush_work(&ctx->fault_work); /* Only needed for dedicated process */ |
220 | 225 | ||
221 | /* release the reference to the group leader and mm handling pid */ | 226 | /* release the reference to the group leader and mm handling pid */ |
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index a521bc72cec2..38e21cf7806e 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h | |||
@@ -324,6 +324,10 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0}; | |||
324 | #define CXL_MODE_TIME_SLICED 0x4 | 324 | #define CXL_MODE_TIME_SLICED 0x4 |
325 | #define CXL_SUPPORTED_MODES (CXL_MODE_DEDICATED | CXL_MODE_DIRECTED) | 325 | #define CXL_SUPPORTED_MODES (CXL_MODE_DEDICATED | CXL_MODE_DIRECTED) |
326 | 326 | ||
327 | #define CXL_DEV_MINORS 13 /* 1 control + 4 AFUs * 3 (dedicated/master/shared) */ | ||
328 | #define CXL_CARD_MINOR(adapter) (adapter->adapter_num * CXL_DEV_MINORS) | ||
329 | #define CXL_DEVT_ADAPTER(dev) (MINOR(dev) / CXL_DEV_MINORS) | ||
330 | |||
327 | enum cxl_context_status { | 331 | enum cxl_context_status { |
328 | CLOSED, | 332 | CLOSED, |
329 | OPENED, | 333 | OPENED, |
@@ -336,6 +340,12 @@ enum prefault_modes { | |||
336 | CXL_PREFAULT_ALL, | 340 | CXL_PREFAULT_ALL, |
337 | }; | 341 | }; |
338 | 342 | ||
343 | enum cxl_attrs { | ||
344 | CXL_ADAPTER_ATTRS, | ||
345 | CXL_AFU_MASTER_ATTRS, | ||
346 | CXL_AFU_ATTRS, | ||
347 | }; | ||
348 | |||
339 | struct cxl_sste { | 349 | struct cxl_sste { |
340 | __be64 esid_data; | 350 | __be64 esid_data; |
341 | __be64 vsid_data; | 351 | __be64 vsid_data; |
@@ -344,18 +354,46 @@ struct cxl_sste { | |||
344 | #define to_cxl_adapter(d) container_of(d, struct cxl, dev) | 354 | #define to_cxl_adapter(d) container_of(d, struct cxl, dev) |
345 | #define to_cxl_afu(d) container_of(d, struct cxl_afu, dev) | 355 | #define to_cxl_afu(d) container_of(d, struct cxl_afu, dev) |
346 | 356 | ||
347 | struct cxl_afu { | 357 | struct cxl_afu_native { |
358 | void __iomem *p1n_mmio; | ||
359 | void __iomem *afu_desc_mmio; | ||
348 | irq_hw_number_t psl_hwirq; | 360 | irq_hw_number_t psl_hwirq; |
361 | unsigned int psl_virq; | ||
362 | struct mutex spa_mutex; | ||
363 | /* | ||
364 | * Only the first part of the SPA is used for the process element | ||
365 | * linked list. The only other part that software needs to worry about | ||
366 | * is sw_command_status, which we store a separate pointer to. | ||
367 | * Everything else in the SPA is only used by hardware | ||
368 | */ | ||
369 | struct cxl_process_element *spa; | ||
370 | __be64 *sw_command_status; | ||
371 | unsigned int spa_size; | ||
372 | int spa_order; | ||
373 | int spa_max_procs; | ||
374 | u64 pp_offset; | ||
375 | }; | ||
376 | |||
377 | struct cxl_afu_guest { | ||
378 | u64 handle; | ||
379 | phys_addr_t p2n_phys; | ||
380 | u64 p2n_size; | ||
381 | int max_ints; | ||
382 | struct mutex recovery_lock; | ||
383 | int previous_state; | ||
384 | }; | ||
385 | |||
386 | struct cxl_afu { | ||
387 | struct cxl_afu_native *native; | ||
388 | struct cxl_afu_guest *guest; | ||
349 | irq_hw_number_t serr_hwirq; | 389 | irq_hw_number_t serr_hwirq; |
350 | char *err_irq_name; | ||
351 | char *psl_irq_name; | ||
352 | unsigned int serr_virq; | 390 | unsigned int serr_virq; |
353 | void __iomem *p1n_mmio; | 391 | char *psl_irq_name; |
392 | char *err_irq_name; | ||
354 | void __iomem *p2n_mmio; | 393 | void __iomem *p2n_mmio; |
355 | phys_addr_t psn_phys; | 394 | phys_addr_t psn_phys; |
356 | u64 pp_offset; | ||
357 | u64 pp_size; | 395 | u64 pp_size; |
358 | void __iomem *afu_desc_mmio; | 396 | |
359 | struct cxl *adapter; | 397 | struct cxl *adapter; |
360 | struct device dev; | 398 | struct device dev; |
361 | struct cdev afu_cdev_s, afu_cdev_m, afu_cdev_d; | 399 | struct cdev afu_cdev_s, afu_cdev_m, afu_cdev_d; |
@@ -363,26 +401,12 @@ struct cxl_afu { | |||
363 | struct idr contexts_idr; | 401 | struct idr contexts_idr; |
364 | struct dentry *debugfs; | 402 | struct dentry *debugfs; |
365 | struct mutex contexts_lock; | 403 | struct mutex contexts_lock; |
366 | struct mutex spa_mutex; | ||
367 | spinlock_t afu_cntl_lock; | 404 | spinlock_t afu_cntl_lock; |
368 | 405 | ||
369 | /* AFU error buffer fields and bin attribute for sysfs */ | 406 | /* AFU error buffer fields and bin attribute for sysfs */ |
370 | u64 eb_len, eb_offset; | 407 | u64 eb_len, eb_offset; |
371 | struct bin_attribute attr_eb; | 408 | struct bin_attribute attr_eb; |
372 | 409 | ||
373 | /* | ||
374 | * Only the first part of the SPA is used for the process element | ||
375 | * linked list. The only other part that software needs to worry about | ||
376 | * is sw_command_status, which we store a separate pointer to. | ||
377 | * Everything else in the SPA is only used by hardware | ||
378 | */ | ||
379 | struct cxl_process_element *spa; | ||
380 | __be64 *sw_command_status; | ||
381 | unsigned int spa_size; | ||
382 | int spa_order; | ||
383 | int spa_max_procs; | ||
384 | unsigned int psl_virq; | ||
385 | |||
386 | /* pointer to the vphb */ | 410 | /* pointer to the vphb */ |
387 | struct pci_controller *phb; | 411 | struct pci_controller *phb; |
388 | 412 | ||
@@ -421,6 +445,12 @@ struct cxl_irq_name { | |||
421 | char *name; | 445 | char *name; |
422 | }; | 446 | }; |
423 | 447 | ||
448 | struct irq_avail { | ||
449 | irq_hw_number_t offset; | ||
450 | irq_hw_number_t range; | ||
451 | unsigned long *bitmap; | ||
452 | }; | ||
453 | |||
424 | /* | 454 | /* |
425 | * This is a cxl context. If the PSL is in dedicated mode, there will be one | 455 | * This is a cxl context. If the PSL is in dedicated mode, there will be one |
426 | * of these per AFU. If in AFU directed there can be lots of these. | 456 | * of these per AFU. If in AFU directed there can be lots of these. |
@@ -476,7 +506,19 @@ struct cxl_context { | |||
476 | 506 | ||
477 | struct cxl_process_element *elem; | 507 | struct cxl_process_element *elem; |
478 | 508 | ||
479 | int pe; /* process element handle */ | 509 | /* |
510 | * pe is the process element handle, assigned by this driver when the | ||
511 | * context is initialized. | ||
512 | * | ||
513 | * external_pe is the PE shown outside of cxl. | ||
514 | * On bare-metal, pe=external_pe, because we decide what the handle is. | ||
515 | * In a guest, we only find out about the pe used by pHyp when the | ||
516 | * context is attached, and that's the value we want to report outside | ||
517 | * of cxl. | ||
518 | */ | ||
519 | int pe; | ||
520 | int external_pe; | ||
521 | |||
480 | u32 irq_count; | 522 | u32 irq_count; |
481 | bool pe_inserted; | 523 | bool pe_inserted; |
482 | bool master; | 524 | bool master; |
@@ -488,11 +530,34 @@ struct cxl_context { | |||
488 | struct rcu_head rcu; | 530 | struct rcu_head rcu; |
489 | }; | 531 | }; |
490 | 532 | ||
491 | struct cxl { | 533 | struct cxl_native { |
534 | u64 afu_desc_off; | ||
535 | u64 afu_desc_size; | ||
492 | void __iomem *p1_mmio; | 536 | void __iomem *p1_mmio; |
493 | void __iomem *p2_mmio; | 537 | void __iomem *p2_mmio; |
494 | irq_hw_number_t err_hwirq; | 538 | irq_hw_number_t err_hwirq; |
495 | unsigned int err_virq; | 539 | unsigned int err_virq; |
540 | u64 ps_off; | ||
541 | }; | ||
542 | |||
543 | struct cxl_guest { | ||
544 | struct platform_device *pdev; | ||
545 | int irq_nranges; | ||
546 | struct cdev cdev; | ||
547 | irq_hw_number_t irq_base_offset; | ||
548 | struct irq_avail *irq_avail; | ||
549 | spinlock_t irq_alloc_lock; | ||
550 | u64 handle; | ||
551 | char *status; | ||
552 | u16 vendor; | ||
553 | u16 device; | ||
554 | u16 subsystem_vendor; | ||
555 | u16 subsystem; | ||
556 | }; | ||
557 | |||
558 | struct cxl { | ||
559 | struct cxl_native *native; | ||
560 | struct cxl_guest *guest; | ||
496 | spinlock_t afu_list_lock; | 561 | spinlock_t afu_list_lock; |
497 | struct cxl_afu *afu[CXL_MAX_SLICES]; | 562 | struct cxl_afu *afu[CXL_MAX_SLICES]; |
498 | struct device dev; | 563 | struct device dev; |
@@ -503,9 +568,6 @@ struct cxl { | |||
503 | struct bin_attribute cxl_attr; | 568 | struct bin_attribute cxl_attr; |
504 | int adapter_num; | 569 | int adapter_num; |
505 | int user_irqs; | 570 | int user_irqs; |
506 | u64 afu_desc_off; | ||
507 | u64 afu_desc_size; | ||
508 | u64 ps_off; | ||
509 | u64 ps_size; | 571 | u64 ps_size; |
510 | u16 psl_rev; | 572 | u16 psl_rev; |
511 | u16 base_image; | 573 | u16 base_image; |
@@ -519,13 +581,15 @@ struct cxl { | |||
519 | bool perst_same_image; | 581 | bool perst_same_image; |
520 | }; | 582 | }; |
521 | 583 | ||
522 | int cxl_alloc_one_irq(struct cxl *adapter); | 584 | int cxl_pci_alloc_one_irq(struct cxl *adapter); |
523 | void cxl_release_one_irq(struct cxl *adapter, int hwirq); | 585 | void cxl_pci_release_one_irq(struct cxl *adapter, int hwirq); |
524 | int cxl_alloc_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter, unsigned int num); | 586 | int cxl_pci_alloc_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter, unsigned int num); |
525 | void cxl_release_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter); | 587 | void cxl_pci_release_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter); |
526 | int cxl_setup_irq(struct cxl *adapter, unsigned int hwirq, unsigned int virq); | 588 | int cxl_pci_setup_irq(struct cxl *adapter, unsigned int hwirq, unsigned int virq); |
527 | int cxl_update_image_control(struct cxl *adapter); | 589 | int cxl_update_image_control(struct cxl *adapter); |
528 | int cxl_reset(struct cxl *adapter); | 590 | int cxl_pci_reset(struct cxl *adapter); |
591 | void cxl_pci_release_afu(struct device *dev); | ||
592 | ssize_t cxl_pci_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len); | ||
529 | 593 | ||
530 | /* common == phyp + powernv */ | 594 | /* common == phyp + powernv */ |
531 | struct cxl_process_element_common { | 595 | struct cxl_process_element_common { |
@@ -555,29 +619,32 @@ struct cxl_process_element { | |||
555 | __be32 software_state; | 619 | __be32 software_state; |
556 | } __packed; | 620 | } __packed; |
557 | 621 | ||
558 | static inline bool cxl_adapter_link_ok(struct cxl *cxl) | 622 | static inline bool cxl_adapter_link_ok(struct cxl *cxl, struct cxl_afu *afu) |
559 | { | 623 | { |
560 | struct pci_dev *pdev; | 624 | struct pci_dev *pdev; |
561 | 625 | ||
562 | pdev = to_pci_dev(cxl->dev.parent); | 626 | if (cpu_has_feature(CPU_FTR_HVMODE)) { |
563 | return !pci_channel_offline(pdev); | 627 | pdev = to_pci_dev(cxl->dev.parent); |
628 | return !pci_channel_offline(pdev); | ||
629 | } | ||
630 | return true; | ||
564 | } | 631 | } |
565 | 632 | ||
566 | static inline void __iomem *_cxl_p1_addr(struct cxl *cxl, cxl_p1_reg_t reg) | 633 | static inline void __iomem *_cxl_p1_addr(struct cxl *cxl, cxl_p1_reg_t reg) |
567 | { | 634 | { |
568 | WARN_ON(!cpu_has_feature(CPU_FTR_HVMODE)); | 635 | WARN_ON(!cpu_has_feature(CPU_FTR_HVMODE)); |
569 | return cxl->p1_mmio + cxl_reg_off(reg); | 636 | return cxl->native->p1_mmio + cxl_reg_off(reg); |
570 | } | 637 | } |
571 | 638 | ||
572 | static inline void cxl_p1_write(struct cxl *cxl, cxl_p1_reg_t reg, u64 val) | 639 | static inline void cxl_p1_write(struct cxl *cxl, cxl_p1_reg_t reg, u64 val) |
573 | { | 640 | { |
574 | if (likely(cxl_adapter_link_ok(cxl))) | 641 | if (likely(cxl_adapter_link_ok(cxl, NULL))) |
575 | out_be64(_cxl_p1_addr(cxl, reg), val); | 642 | out_be64(_cxl_p1_addr(cxl, reg), val); |
576 | } | 643 | } |
577 | 644 | ||
578 | static inline u64 cxl_p1_read(struct cxl *cxl, cxl_p1_reg_t reg) | 645 | static inline u64 cxl_p1_read(struct cxl *cxl, cxl_p1_reg_t reg) |
579 | { | 646 | { |
580 | if (likely(cxl_adapter_link_ok(cxl))) | 647 | if (likely(cxl_adapter_link_ok(cxl, NULL))) |
581 | return in_be64(_cxl_p1_addr(cxl, reg)); | 648 | return in_be64(_cxl_p1_addr(cxl, reg)); |
582 | else | 649 | else |
583 | return ~0ULL; | 650 | return ~0ULL; |
@@ -586,18 +653,18 @@ static inline u64 cxl_p1_read(struct cxl *cxl, cxl_p1_reg_t reg) | |||
586 | static inline void __iomem *_cxl_p1n_addr(struct cxl_afu *afu, cxl_p1n_reg_t reg) | 653 | static inline void __iomem *_cxl_p1n_addr(struct cxl_afu *afu, cxl_p1n_reg_t reg) |
587 | { | 654 | { |
588 | WARN_ON(!cpu_has_feature(CPU_FTR_HVMODE)); | 655 | WARN_ON(!cpu_has_feature(CPU_FTR_HVMODE)); |
589 | return afu->p1n_mmio + cxl_reg_off(reg); | 656 | return afu->native->p1n_mmio + cxl_reg_off(reg); |
590 | } | 657 | } |
591 | 658 | ||
592 | static inline void cxl_p1n_write(struct cxl_afu *afu, cxl_p1n_reg_t reg, u64 val) | 659 | static inline void cxl_p1n_write(struct cxl_afu *afu, cxl_p1n_reg_t reg, u64 val) |
593 | { | 660 | { |
594 | if (likely(cxl_adapter_link_ok(afu->adapter))) | 661 | if (likely(cxl_adapter_link_ok(afu->adapter, afu))) |
595 | out_be64(_cxl_p1n_addr(afu, reg), val); | 662 | out_be64(_cxl_p1n_addr(afu, reg), val); |
596 | } | 663 | } |
597 | 664 | ||
598 | static inline u64 cxl_p1n_read(struct cxl_afu *afu, cxl_p1n_reg_t reg) | 665 | static inline u64 cxl_p1n_read(struct cxl_afu *afu, cxl_p1n_reg_t reg) |
599 | { | 666 | { |
600 | if (likely(cxl_adapter_link_ok(afu->adapter))) | 667 | if (likely(cxl_adapter_link_ok(afu->adapter, afu))) |
601 | return in_be64(_cxl_p1n_addr(afu, reg)); | 668 | return in_be64(_cxl_p1n_addr(afu, reg)); |
602 | else | 669 | else |
603 | return ~0ULL; | 670 | return ~0ULL; |
@@ -610,39 +677,19 @@ static inline void __iomem *_cxl_p2n_addr(struct cxl_afu *afu, cxl_p2n_reg_t reg | |||
610 | 677 | ||
611 | static inline void cxl_p2n_write(struct cxl_afu *afu, cxl_p2n_reg_t reg, u64 val) | 678 | static inline void cxl_p2n_write(struct cxl_afu *afu, cxl_p2n_reg_t reg, u64 val) |
612 | { | 679 | { |
613 | if (likely(cxl_adapter_link_ok(afu->adapter))) | 680 | if (likely(cxl_adapter_link_ok(afu->adapter, afu))) |
614 | out_be64(_cxl_p2n_addr(afu, reg), val); | 681 | out_be64(_cxl_p2n_addr(afu, reg), val); |
615 | } | 682 | } |
616 | 683 | ||
617 | static inline u64 cxl_p2n_read(struct cxl_afu *afu, cxl_p2n_reg_t reg) | 684 | static inline u64 cxl_p2n_read(struct cxl_afu *afu, cxl_p2n_reg_t reg) |
618 | { | 685 | { |
619 | if (likely(cxl_adapter_link_ok(afu->adapter))) | 686 | if (likely(cxl_adapter_link_ok(afu->adapter, afu))) |
620 | return in_be64(_cxl_p2n_addr(afu, reg)); | 687 | return in_be64(_cxl_p2n_addr(afu, reg)); |
621 | else | 688 | else |
622 | return ~0ULL; | 689 | return ~0ULL; |
623 | } | 690 | } |
624 | 691 | ||
625 | static inline u64 cxl_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off) | 692 | ssize_t cxl_pci_afu_read_err_buffer(struct cxl_afu *afu, char *buf, |
626 | { | ||
627 | if (likely(cxl_adapter_link_ok(afu->adapter))) | ||
628 | return in_le64((afu)->afu_desc_mmio + (afu)->crs_offset + | ||
629 | ((cr) * (afu)->crs_len) + (off)); | ||
630 | else | ||
631 | return ~0ULL; | ||
632 | } | ||
633 | |||
634 | static inline u32 cxl_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off) | ||
635 | { | ||
636 | if (likely(cxl_adapter_link_ok(afu->adapter))) | ||
637 | return in_le32((afu)->afu_desc_mmio + (afu)->crs_offset + | ||
638 | ((cr) * (afu)->crs_len) + (off)); | ||
639 | else | ||
640 | return 0xffffffff; | ||
641 | } | ||
642 | u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off); | ||
643 | u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off); | ||
644 | |||
645 | ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf, | ||
646 | loff_t off, size_t count); | 693 | loff_t off, size_t count); |
647 | 694 | ||
648 | 695 | ||
@@ -652,13 +699,14 @@ struct cxl_calls { | |||
652 | }; | 699 | }; |
653 | int register_cxl_calls(struct cxl_calls *calls); | 700 | int register_cxl_calls(struct cxl_calls *calls); |
654 | void unregister_cxl_calls(struct cxl_calls *calls); | 701 | void unregister_cxl_calls(struct cxl_calls *calls); |
702 | int cxl_update_properties(struct device_node *dn, struct property *new_prop); | ||
655 | 703 | ||
656 | int cxl_alloc_adapter_nr(struct cxl *adapter); | ||
657 | void cxl_remove_adapter_nr(struct cxl *adapter); | 704 | void cxl_remove_adapter_nr(struct cxl *adapter); |
658 | 705 | ||
659 | int cxl_alloc_spa(struct cxl_afu *afu); | 706 | int cxl_alloc_spa(struct cxl_afu *afu); |
660 | void cxl_release_spa(struct cxl_afu *afu); | 707 | void cxl_release_spa(struct cxl_afu *afu); |
661 | 708 | ||
709 | dev_t cxl_get_dev(void); | ||
662 | int cxl_file_init(void); | 710 | int cxl_file_init(void); |
663 | void cxl_file_exit(void); | 711 | void cxl_file_exit(void); |
664 | int cxl_register_adapter(struct cxl *adapter); | 712 | int cxl_register_adapter(struct cxl *adapter); |
@@ -679,21 +727,19 @@ void cxl_sysfs_afu_remove(struct cxl_afu *afu); | |||
679 | int cxl_sysfs_afu_m_add(struct cxl_afu *afu); | 727 | int cxl_sysfs_afu_m_add(struct cxl_afu *afu); |
680 | void cxl_sysfs_afu_m_remove(struct cxl_afu *afu); | 728 | void cxl_sysfs_afu_m_remove(struct cxl_afu *afu); |
681 | 729 | ||
682 | int cxl_afu_activate_mode(struct cxl_afu *afu, int mode); | 730 | struct cxl *cxl_alloc_adapter(void); |
683 | int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode); | 731 | struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice); |
684 | int cxl_afu_deactivate_mode(struct cxl_afu *afu); | ||
685 | int cxl_afu_select_best_mode(struct cxl_afu *afu); | 732 | int cxl_afu_select_best_mode(struct cxl_afu *afu); |
686 | 733 | ||
687 | int cxl_register_psl_irq(struct cxl_afu *afu); | 734 | int cxl_native_register_psl_irq(struct cxl_afu *afu); |
688 | void cxl_release_psl_irq(struct cxl_afu *afu); | 735 | void cxl_native_release_psl_irq(struct cxl_afu *afu); |
689 | int cxl_register_psl_err_irq(struct cxl *adapter); | 736 | int cxl_native_register_psl_err_irq(struct cxl *adapter); |
690 | void cxl_release_psl_err_irq(struct cxl *adapter); | 737 | void cxl_native_release_psl_err_irq(struct cxl *adapter); |
691 | int cxl_register_serr_irq(struct cxl_afu *afu); | 738 | int cxl_native_register_serr_irq(struct cxl_afu *afu); |
692 | void cxl_release_serr_irq(struct cxl_afu *afu); | 739 | void cxl_native_release_serr_irq(struct cxl_afu *afu); |
693 | int afu_register_irqs(struct cxl_context *ctx, u32 count); | 740 | int afu_register_irqs(struct cxl_context *ctx, u32 count); |
694 | void afu_release_irqs(struct cxl_context *ctx, void *cookie); | 741 | void afu_release_irqs(struct cxl_context *ctx, void *cookie); |
695 | void afu_irq_name_free(struct cxl_context *ctx); | 742 | void afu_irq_name_free(struct cxl_context *ctx); |
696 | irqreturn_t cxl_slice_irq_err(int irq, void *data); | ||
697 | 743 | ||
698 | int cxl_debugfs_init(void); | 744 | int cxl_debugfs_init(void); |
699 | void cxl_debugfs_exit(void); | 745 | void cxl_debugfs_exit(void); |
@@ -707,6 +753,7 @@ void cxl_prefault(struct cxl_context *ctx, u64 wed); | |||
707 | 753 | ||
708 | struct cxl *get_cxl_adapter(int num); | 754 | struct cxl *get_cxl_adapter(int num); |
709 | int cxl_alloc_sst(struct cxl_context *ctx); | 755 | int cxl_alloc_sst(struct cxl_context *ctx); |
756 | void cxl_dump_debug_buffer(void *addr, size_t size); | ||
710 | 757 | ||
711 | void init_cxl_native(void); | 758 | void init_cxl_native(void); |
712 | 759 | ||
@@ -720,40 +767,54 @@ unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq, | |||
720 | void cxl_unmap_irq(unsigned int virq, void *cookie); | 767 | void cxl_unmap_irq(unsigned int virq, void *cookie); |
721 | int __detach_context(struct cxl_context *ctx); | 768 | int __detach_context(struct cxl_context *ctx); |
722 | 769 | ||
723 | /* This matches the layout of the H_COLLECT_CA_INT_INFO retbuf */ | 770 | /* |
771 | * This must match the layout of the H_COLLECT_CA_INT_INFO retbuf defined | ||
772 | * in PAPR. | ||
773 | * A word about endianness: a pointer to this structure is passed when | ||
774 | * calling the hcall. However, it is not a block of memory filled up by | ||
775 | * the hypervisor. The return values are found in registers, and copied | ||
776 | * one by one when returning from the hcall. See the end of the call to | ||
777 | * plpar_hcall9() in hvCall.S | ||
778 | * As a consequence: | ||
779 | * - we don't need to do any endianness conversion | ||
780 | * - the pid and tid are an exception. They are 32-bit values returned in | ||
781 | * the same 64-bit register. So we do need to worry about byte ordering. | ||
782 | */ | ||
724 | struct cxl_irq_info { | 783 | struct cxl_irq_info { |
725 | u64 dsisr; | 784 | u64 dsisr; |
726 | u64 dar; | 785 | u64 dar; |
727 | u64 dsr; | 786 | u64 dsr; |
787 | #ifndef CONFIG_CPU_LITTLE_ENDIAN | ||
728 | u32 pid; | 788 | u32 pid; |
729 | u32 tid; | 789 | u32 tid; |
790 | #else | ||
791 | u32 tid; | ||
792 | u32 pid; | ||
793 | #endif | ||
730 | u64 afu_err; | 794 | u64 afu_err; |
731 | u64 errstat; | 795 | u64 errstat; |
732 | u64 padding[3]; /* to match the expected retbuf size for plpar_hcall9 */ | 796 | u64 proc_handle; |
797 | u64 padding[2]; /* to match the expected retbuf size for plpar_hcall9 */ | ||
733 | }; | 798 | }; |
734 | 799 | ||
735 | void cxl_assign_psn_space(struct cxl_context *ctx); | 800 | void cxl_assign_psn_space(struct cxl_context *ctx); |
736 | int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, | 801 | irqreturn_t cxl_irq(int irq, struct cxl_context *ctx, struct cxl_irq_info *irq_info); |
737 | u64 amr); | 802 | int cxl_register_one_irq(struct cxl *adapter, irq_handler_t handler, |
738 | int cxl_detach_process(struct cxl_context *ctx); | 803 | void *cookie, irq_hw_number_t *dest_hwirq, |
739 | 804 | unsigned int *dest_virq, const char *name); | |
740 | int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info); | ||
741 | int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask); | ||
742 | 805 | ||
743 | int cxl_check_error(struct cxl_afu *afu); | 806 | int cxl_check_error(struct cxl_afu *afu); |
744 | int cxl_afu_slbia(struct cxl_afu *afu); | 807 | int cxl_afu_slbia(struct cxl_afu *afu); |
745 | int cxl_tlb_slb_invalidate(struct cxl *adapter); | 808 | int cxl_tlb_slb_invalidate(struct cxl *adapter); |
746 | int cxl_afu_disable(struct cxl_afu *afu); | 809 | int cxl_afu_disable(struct cxl_afu *afu); |
747 | int __cxl_afu_reset(struct cxl_afu *afu); | ||
748 | int cxl_afu_check_and_enable(struct cxl_afu *afu); | ||
749 | int cxl_psl_purge(struct cxl_afu *afu); | 810 | int cxl_psl_purge(struct cxl_afu *afu); |
750 | 811 | ||
751 | void cxl_stop_trace(struct cxl *cxl); | 812 | void cxl_stop_trace(struct cxl *cxl); |
752 | int cxl_pci_vphb_add(struct cxl_afu *afu); | 813 | int cxl_pci_vphb_add(struct cxl_afu *afu); |
753 | void cxl_pci_vphb_reconfigure(struct cxl_afu *afu); | ||
754 | void cxl_pci_vphb_remove(struct cxl_afu *afu); | 814 | void cxl_pci_vphb_remove(struct cxl_afu *afu); |
755 | 815 | ||
756 | extern struct pci_driver cxl_pci_driver; | 816 | extern struct pci_driver cxl_pci_driver; |
817 | extern struct platform_driver cxl_of_driver; | ||
757 | int afu_allocate_irqs(struct cxl_context *ctx, u32 count); | 818 | int afu_allocate_irqs(struct cxl_context *ctx, u32 count); |
758 | 819 | ||
759 | int afu_open(struct inode *inode, struct file *file); | 820 | int afu_open(struct inode *inode, struct file *file); |
@@ -764,4 +825,61 @@ unsigned int afu_poll(struct file *file, struct poll_table_struct *poll); | |||
764 | ssize_t afu_read(struct file *file, char __user *buf, size_t count, loff_t *off); | 825 | ssize_t afu_read(struct file *file, char __user *buf, size_t count, loff_t *off); |
765 | extern const struct file_operations afu_fops; | 826 | extern const struct file_operations afu_fops; |
766 | 827 | ||
828 | struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_device *dev); | ||
829 | void cxl_guest_remove_adapter(struct cxl *adapter); | ||
830 | int cxl_of_read_adapter_handle(struct cxl *adapter, struct device_node *np); | ||
831 | int cxl_of_read_adapter_properties(struct cxl *adapter, struct device_node *np); | ||
832 | ssize_t cxl_guest_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len); | ||
833 | ssize_t cxl_guest_read_afu_vpd(struct cxl_afu *afu, void *buf, size_t len); | ||
834 | int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_np); | ||
835 | void cxl_guest_remove_afu(struct cxl_afu *afu); | ||
836 | int cxl_of_read_afu_handle(struct cxl_afu *afu, struct device_node *afu_np); | ||
837 | int cxl_of_read_afu_properties(struct cxl_afu *afu, struct device_node *afu_np); | ||
838 | int cxl_guest_add_chardev(struct cxl *adapter); | ||
839 | void cxl_guest_remove_chardev(struct cxl *adapter); | ||
840 | void cxl_guest_reload_module(struct cxl *adapter); | ||
841 | int cxl_of_probe(struct platform_device *pdev); | ||
842 | |||
843 | struct cxl_backend_ops { | ||
844 | struct module *module; | ||
845 | int (*adapter_reset)(struct cxl *adapter); | ||
846 | int (*alloc_one_irq)(struct cxl *adapter); | ||
847 | void (*release_one_irq)(struct cxl *adapter, int hwirq); | ||
848 | int (*alloc_irq_ranges)(struct cxl_irq_ranges *irqs, | ||
849 | struct cxl *adapter, unsigned int num); | ||
850 | void (*release_irq_ranges)(struct cxl_irq_ranges *irqs, | ||
851 | struct cxl *adapter); | ||
852 | int (*setup_irq)(struct cxl *adapter, unsigned int hwirq, | ||
853 | unsigned int virq); | ||
854 | irqreturn_t (*handle_psl_slice_error)(struct cxl_context *ctx, | ||
855 | u64 dsisr, u64 errstat); | ||
856 | irqreturn_t (*psl_interrupt)(int irq, void *data); | ||
857 | int (*ack_irq)(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask); | ||
858 | int (*attach_process)(struct cxl_context *ctx, bool kernel, | ||
859 | u64 wed, u64 amr); | ||
860 | int (*detach_process)(struct cxl_context *ctx); | ||
861 | bool (*support_attributes)(const char *attr_name, enum cxl_attrs type); | ||
862 | bool (*link_ok)(struct cxl *cxl, struct cxl_afu *afu); | ||
863 | void (*release_afu)(struct device *dev); | ||
864 | ssize_t (*afu_read_err_buffer)(struct cxl_afu *afu, char *buf, | ||
865 | loff_t off, size_t count); | ||
866 | int (*afu_check_and_enable)(struct cxl_afu *afu); | ||
867 | int (*afu_activate_mode)(struct cxl_afu *afu, int mode); | ||
868 | int (*afu_deactivate_mode)(struct cxl_afu *afu, int mode); | ||
869 | int (*afu_reset)(struct cxl_afu *afu); | ||
870 | int (*afu_cr_read8)(struct cxl_afu *afu, int cr_idx, u64 offset, u8 *val); | ||
871 | int (*afu_cr_read16)(struct cxl_afu *afu, int cr_idx, u64 offset, u16 *val); | ||
872 | int (*afu_cr_read32)(struct cxl_afu *afu, int cr_idx, u64 offset, u32 *val); | ||
873 | int (*afu_cr_read64)(struct cxl_afu *afu, int cr_idx, u64 offset, u64 *val); | ||
874 | int (*afu_cr_write8)(struct cxl_afu *afu, int cr_idx, u64 offset, u8 val); | ||
875 | int (*afu_cr_write16)(struct cxl_afu *afu, int cr_idx, u64 offset, u16 val); | ||
876 | int (*afu_cr_write32)(struct cxl_afu *afu, int cr_idx, u64 offset, u32 val); | ||
877 | ssize_t (*read_adapter_vpd)(struct cxl *adapter, void *buf, size_t count); | ||
878 | }; | ||
879 | extern const struct cxl_backend_ops cxl_native_ops; | ||
880 | extern const struct cxl_backend_ops cxl_guest_ops; | ||
881 | extern const struct cxl_backend_ops *cxl_ops; | ||
882 | |||
883 | /* check if the given pci_dev is on the the cxl vphb bus */ | ||
884 | bool cxl_pci_is_vphb_device(struct pci_dev *dev); | ||
767 | #endif | 885 | #endif |
diff --git a/drivers/misc/cxl/debugfs.c b/drivers/misc/cxl/debugfs.c index 18df6f44af2a..5751899e0c17 100644 --- a/drivers/misc/cxl/debugfs.c +++ b/drivers/misc/cxl/debugfs.c | |||
@@ -118,6 +118,10 @@ void cxl_debugfs_afu_remove(struct cxl_afu *afu) | |||
118 | int __init cxl_debugfs_init(void) | 118 | int __init cxl_debugfs_init(void) |
119 | { | 119 | { |
120 | struct dentry *ent; | 120 | struct dentry *ent; |
121 | |||
122 | if (!cpu_has_feature(CPU_FTR_HVMODE)) | ||
123 | return 0; | ||
124 | |||
121 | ent = debugfs_create_dir("cxl", NULL); | 125 | ent = debugfs_create_dir("cxl", NULL); |
122 | if (IS_ERR(ent)) | 126 | if (IS_ERR(ent)) |
123 | return PTR_ERR(ent); | 127 | return PTR_ERR(ent); |
diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c index 81c3f75b7330..9a8650bcb042 100644 --- a/drivers/misc/cxl/fault.c +++ b/drivers/misc/cxl/fault.c | |||
@@ -101,7 +101,7 @@ static void cxl_ack_ae(struct cxl_context *ctx) | |||
101 | { | 101 | { |
102 | unsigned long flags; | 102 | unsigned long flags; |
103 | 103 | ||
104 | cxl_ack_irq(ctx, CXL_PSL_TFC_An_AE, 0); | 104 | cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_AE, 0); |
105 | 105 | ||
106 | spin_lock_irqsave(&ctx->lock, flags); | 106 | spin_lock_irqsave(&ctx->lock, flags); |
107 | ctx->pending_fault = true; | 107 | ctx->pending_fault = true; |
@@ -125,7 +125,7 @@ static int cxl_handle_segment_miss(struct cxl_context *ctx, | |||
125 | else { | 125 | else { |
126 | 126 | ||
127 | mb(); /* Order seg table write to TFC MMIO write */ | 127 | mb(); /* Order seg table write to TFC MMIO write */ |
128 | cxl_ack_irq(ctx, CXL_PSL_TFC_An_R, 0); | 128 | cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0); |
129 | } | 129 | } |
130 | 130 | ||
131 | return IRQ_HANDLED; | 131 | return IRQ_HANDLED; |
@@ -163,7 +163,7 @@ static void cxl_handle_page_fault(struct cxl_context *ctx, | |||
163 | local_irq_restore(flags); | 163 | local_irq_restore(flags); |
164 | 164 | ||
165 | pr_devel("Page fault successfully handled for pe: %i!\n", ctx->pe); | 165 | pr_devel("Page fault successfully handled for pe: %i!\n", ctx->pe); |
166 | cxl_ack_irq(ctx, CXL_PSL_TFC_An_R, 0); | 166 | cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0); |
167 | } | 167 | } |
168 | 168 | ||
169 | /* | 169 | /* |
@@ -254,14 +254,17 @@ void cxl_handle_fault(struct work_struct *fault_work) | |||
254 | u64 dar = ctx->dar; | 254 | u64 dar = ctx->dar; |
255 | struct mm_struct *mm = NULL; | 255 | struct mm_struct *mm = NULL; |
256 | 256 | ||
257 | if (cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An) != dsisr || | 257 | if (cpu_has_feature(CPU_FTR_HVMODE)) { |
258 | cxl_p2n_read(ctx->afu, CXL_PSL_DAR_An) != dar || | 258 | if (cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An) != dsisr || |
259 | cxl_p2n_read(ctx->afu, CXL_PSL_PEHandle_An) != ctx->pe) { | 259 | cxl_p2n_read(ctx->afu, CXL_PSL_DAR_An) != dar || |
260 | /* Most likely explanation is harmless - a dedicated process | 260 | cxl_p2n_read(ctx->afu, CXL_PSL_PEHandle_An) != ctx->pe) { |
261 | * has detached and these were cleared by the PSL purge, but | 261 | /* Most likely explanation is harmless - a dedicated |
262 | * warn about it just in case */ | 262 | * process has detached and these were cleared by the |
263 | dev_notice(&ctx->afu->dev, "cxl_handle_fault: Translation fault regs changed\n"); | 263 | * PSL purge, but warn about it just in case |
264 | return; | 264 | */ |
265 | dev_notice(&ctx->afu->dev, "cxl_handle_fault: Translation fault regs changed\n"); | ||
266 | return; | ||
267 | } | ||
265 | } | 268 | } |
266 | 269 | ||
267 | /* Early return if the context is being / has been detached */ | 270 | /* Early return if the context is being / has been detached */ |
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c index 783337d22f36..eec468f1612f 100644 --- a/drivers/misc/cxl/file.c +++ b/drivers/misc/cxl/file.c | |||
@@ -26,9 +26,7 @@ | |||
26 | #include "trace.h" | 26 | #include "trace.h" |
27 | 27 | ||
28 | #define CXL_NUM_MINORS 256 /* Total to reserve */ | 28 | #define CXL_NUM_MINORS 256 /* Total to reserve */ |
29 | #define CXL_DEV_MINORS 13 /* 1 control + 4 AFUs * 3 (dedicated/master/shared) */ | ||
30 | 29 | ||
31 | #define CXL_CARD_MINOR(adapter) (adapter->adapter_num * CXL_DEV_MINORS) | ||
32 | #define CXL_AFU_MINOR_D(afu) (CXL_CARD_MINOR(afu->adapter) + 1 + (3 * afu->slice)) | 30 | #define CXL_AFU_MINOR_D(afu) (CXL_CARD_MINOR(afu->adapter) + 1 + (3 * afu->slice)) |
33 | #define CXL_AFU_MINOR_M(afu) (CXL_AFU_MINOR_D(afu) + 1) | 31 | #define CXL_AFU_MINOR_M(afu) (CXL_AFU_MINOR_D(afu) + 1) |
34 | #define CXL_AFU_MINOR_S(afu) (CXL_AFU_MINOR_D(afu) + 2) | 32 | #define CXL_AFU_MINOR_S(afu) (CXL_AFU_MINOR_D(afu) + 2) |
@@ -36,7 +34,6 @@ | |||
36 | #define CXL_AFU_MKDEV_M(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_M(afu)) | 34 | #define CXL_AFU_MKDEV_M(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_M(afu)) |
37 | #define CXL_AFU_MKDEV_S(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_S(afu)) | 35 | #define CXL_AFU_MKDEV_S(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_S(afu)) |
38 | 36 | ||
39 | #define CXL_DEVT_ADAPTER(dev) (MINOR(dev) / CXL_DEV_MINORS) | ||
40 | #define CXL_DEVT_AFU(dev) ((MINOR(dev) % CXL_DEV_MINORS - 1) / 3) | 37 | #define CXL_DEVT_AFU(dev) ((MINOR(dev) % CXL_DEV_MINORS - 1) / 3) |
41 | 38 | ||
42 | #define CXL_DEVT_IS_CARD(dev) (MINOR(dev) % CXL_DEV_MINORS == 0) | 39 | #define CXL_DEVT_IS_CARD(dev) (MINOR(dev) % CXL_DEV_MINORS == 0) |
@@ -79,7 +76,7 @@ static int __afu_open(struct inode *inode, struct file *file, bool master) | |||
79 | if (!afu->current_mode) | 76 | if (!afu->current_mode) |
80 | goto err_put_afu; | 77 | goto err_put_afu; |
81 | 78 | ||
82 | if (!cxl_adapter_link_ok(adapter)) { | 79 | if (!cxl_ops->link_ok(adapter, afu)) { |
83 | rc = -EIO; | 80 | rc = -EIO; |
84 | goto err_put_afu; | 81 | goto err_put_afu; |
85 | } | 82 | } |
@@ -210,8 +207,8 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, | |||
210 | 207 | ||
211 | trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr); | 208 | trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr); |
212 | 209 | ||
213 | if ((rc = cxl_attach_process(ctx, false, work.work_element_descriptor, | 210 | if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor, |
214 | amr))) { | 211 | amr))) { |
215 | afu_release_irqs(ctx, ctx); | 212 | afu_release_irqs(ctx, ctx); |
216 | goto out; | 213 | goto out; |
217 | } | 214 | } |
@@ -222,12 +219,13 @@ out: | |||
222 | mutex_unlock(&ctx->status_mutex); | 219 | mutex_unlock(&ctx->status_mutex); |
223 | return rc; | 220 | return rc; |
224 | } | 221 | } |
222 | |||
225 | static long afu_ioctl_process_element(struct cxl_context *ctx, | 223 | static long afu_ioctl_process_element(struct cxl_context *ctx, |
226 | int __user *upe) | 224 | int __user *upe) |
227 | { | 225 | { |
228 | pr_devel("%s: pe: %i\n", __func__, ctx->pe); | 226 | pr_devel("%s: pe: %i\n", __func__, ctx->pe); |
229 | 227 | ||
230 | if (copy_to_user(upe, &ctx->pe, sizeof(__u32))) | 228 | if (copy_to_user(upe, &ctx->external_pe, sizeof(__u32))) |
231 | return -EFAULT; | 229 | return -EFAULT; |
232 | 230 | ||
233 | return 0; | 231 | return 0; |
@@ -259,7 +257,7 @@ long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
259 | if (ctx->status == CLOSED) | 257 | if (ctx->status == CLOSED) |
260 | return -EIO; | 258 | return -EIO; |
261 | 259 | ||
262 | if (!cxl_adapter_link_ok(ctx->afu->adapter)) | 260 | if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) |
263 | return -EIO; | 261 | return -EIO; |
264 | 262 | ||
265 | pr_devel("afu_ioctl\n"); | 263 | pr_devel("afu_ioctl\n"); |
@@ -289,7 +287,7 @@ int afu_mmap(struct file *file, struct vm_area_struct *vm) | |||
289 | if (ctx->status != STARTED) | 287 | if (ctx->status != STARTED) |
290 | return -EIO; | 288 | return -EIO; |
291 | 289 | ||
292 | if (!cxl_adapter_link_ok(ctx->afu->adapter)) | 290 | if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) |
293 | return -EIO; | 291 | return -EIO; |
294 | 292 | ||
295 | return cxl_context_iomap(ctx, vm); | 293 | return cxl_context_iomap(ctx, vm); |
@@ -336,7 +334,7 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count, | |||
336 | int rc; | 334 | int rc; |
337 | DEFINE_WAIT(wait); | 335 | DEFINE_WAIT(wait); |
338 | 336 | ||
339 | if (!cxl_adapter_link_ok(ctx->afu->adapter)) | 337 | if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) |
340 | return -EIO; | 338 | return -EIO; |
341 | 339 | ||
342 | if (count < CXL_READ_MIN_SIZE) | 340 | if (count < CXL_READ_MIN_SIZE) |
@@ -349,7 +347,7 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count, | |||
349 | if (ctx_event_pending(ctx)) | 347 | if (ctx_event_pending(ctx)) |
350 | break; | 348 | break; |
351 | 349 | ||
352 | if (!cxl_adapter_link_ok(ctx->afu->adapter)) { | 350 | if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) { |
353 | rc = -EIO; | 351 | rc = -EIO; |
354 | goto out; | 352 | goto out; |
355 | } | 353 | } |
@@ -445,7 +443,8 @@ static const struct file_operations afu_master_fops = { | |||
445 | 443 | ||
446 | static char *cxl_devnode(struct device *dev, umode_t *mode) | 444 | static char *cxl_devnode(struct device *dev, umode_t *mode) |
447 | { | 445 | { |
448 | if (CXL_DEVT_IS_CARD(dev->devt)) { | 446 | if (cpu_has_feature(CPU_FTR_HVMODE) && |
447 | CXL_DEVT_IS_CARD(dev->devt)) { | ||
449 | /* | 448 | /* |
450 | * These minor numbers will eventually be used to program the | 449 | * These minor numbers will eventually be used to program the |
451 | * PSL and AFUs once we have dynamic reprogramming support | 450 | * PSL and AFUs once we have dynamic reprogramming support |
@@ -546,6 +545,11 @@ int cxl_register_adapter(struct cxl *adapter) | |||
546 | return device_register(&adapter->dev); | 545 | return device_register(&adapter->dev); |
547 | } | 546 | } |
548 | 547 | ||
548 | dev_t cxl_get_dev(void) | ||
549 | { | ||
550 | return cxl_dev; | ||
551 | } | ||
552 | |||
549 | int __init cxl_file_init(void) | 553 | int __init cxl_file_init(void) |
550 | { | 554 | { |
551 | int rc; | 555 | int rc; |
diff --git a/drivers/misc/cxl/flash.c b/drivers/misc/cxl/flash.c new file mode 100644 index 000000000000..68dd0b7da471 --- /dev/null +++ b/drivers/misc/cxl/flash.c | |||
@@ -0,0 +1,538 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/fs.h> | ||
3 | #include <linux/semaphore.h> | ||
4 | #include <linux/slab.h> | ||
5 | #include <linux/uaccess.h> | ||
6 | #include <asm/rtas.h> | ||
7 | |||
8 | #include "cxl.h" | ||
9 | #include "hcalls.h" | ||
10 | |||
11 | #define DOWNLOAD_IMAGE 1 | ||
12 | #define VALIDATE_IMAGE 2 | ||
13 | |||
14 | struct ai_header { | ||
15 | u16 version; | ||
16 | u8 reserved0[6]; | ||
17 | u16 vendor; | ||
18 | u16 device; | ||
19 | u16 subsystem_vendor; | ||
20 | u16 subsystem; | ||
21 | u64 image_offset; | ||
22 | u64 image_length; | ||
23 | u8 reserved1[96]; | ||
24 | }; | ||
25 | |||
26 | static struct semaphore sem; | ||
27 | unsigned long *buffer[CXL_AI_MAX_ENTRIES]; | ||
28 | struct sg_list *le; | ||
29 | static u64 continue_token; | ||
30 | static unsigned int transfer; | ||
31 | |||
32 | struct update_props_workarea { | ||
33 | __be32 phandle; | ||
34 | __be32 state; | ||
35 | __be64 reserved; | ||
36 | __be32 nprops; | ||
37 | } __packed; | ||
38 | |||
39 | struct update_nodes_workarea { | ||
40 | __be32 state; | ||
41 | __be64 unit_address; | ||
42 | __be32 reserved; | ||
43 | } __packed; | ||
44 | |||
45 | #define DEVICE_SCOPE 3 | ||
46 | #define NODE_ACTION_MASK 0xff000000 | ||
47 | #define NODE_COUNT_MASK 0x00ffffff | ||
48 | #define OPCODE_DELETE 0x01000000 | ||
49 | #define OPCODE_UPDATE 0x02000000 | ||
50 | #define OPCODE_ADD 0x03000000 | ||
51 | |||
52 | static int rcall(int token, char *buf, s32 scope) | ||
53 | { | ||
54 | int rc; | ||
55 | |||
56 | spin_lock(&rtas_data_buf_lock); | ||
57 | |||
58 | memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE); | ||
59 | rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, scope); | ||
60 | memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE); | ||
61 | |||
62 | spin_unlock(&rtas_data_buf_lock); | ||
63 | return rc; | ||
64 | } | ||
65 | |||
66 | static int update_property(struct device_node *dn, const char *name, | ||
67 | u32 vd, char *value) | ||
68 | { | ||
69 | struct property *new_prop; | ||
70 | u32 *val; | ||
71 | int rc; | ||
72 | |||
73 | new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL); | ||
74 | if (!new_prop) | ||
75 | return -ENOMEM; | ||
76 | |||
77 | new_prop->name = kstrdup(name, GFP_KERNEL); | ||
78 | if (!new_prop->name) { | ||
79 | kfree(new_prop); | ||
80 | return -ENOMEM; | ||
81 | } | ||
82 | |||
83 | new_prop->length = vd; | ||
84 | new_prop->value = kzalloc(new_prop->length, GFP_KERNEL); | ||
85 | if (!new_prop->value) { | ||
86 | kfree(new_prop->name); | ||
87 | kfree(new_prop); | ||
88 | return -ENOMEM; | ||
89 | } | ||
90 | memcpy(new_prop->value, value, vd); | ||
91 | |||
92 | val = (u32 *)new_prop->value; | ||
93 | rc = cxl_update_properties(dn, new_prop); | ||
94 | pr_devel("%s: update property (%s, length: %i, value: %#x)\n", | ||
95 | dn->name, name, vd, be32_to_cpu(*val)); | ||
96 | |||
97 | if (rc) { | ||
98 | kfree(new_prop->name); | ||
99 | kfree(new_prop->value); | ||
100 | kfree(new_prop); | ||
101 | } | ||
102 | return rc; | ||
103 | } | ||
104 | |||
105 | static int update_node(__be32 phandle, s32 scope) | ||
106 | { | ||
107 | struct update_props_workarea *upwa; | ||
108 | struct device_node *dn; | ||
109 | int i, rc, ret; | ||
110 | char *prop_data; | ||
111 | char *buf; | ||
112 | int token; | ||
113 | u32 nprops; | ||
114 | u32 vd; | ||
115 | |||
116 | token = rtas_token("ibm,update-properties"); | ||
117 | if (token == RTAS_UNKNOWN_SERVICE) | ||
118 | return -EINVAL; | ||
119 | |||
120 | buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); | ||
121 | if (!buf) | ||
122 | return -ENOMEM; | ||
123 | |||
124 | dn = of_find_node_by_phandle(be32_to_cpu(phandle)); | ||
125 | if (!dn) { | ||
126 | kfree(buf); | ||
127 | return -ENOENT; | ||
128 | } | ||
129 | |||
130 | upwa = (struct update_props_workarea *)&buf[0]; | ||
131 | upwa->phandle = phandle; | ||
132 | do { | ||
133 | rc = rcall(token, buf, scope); | ||
134 | if (rc < 0) | ||
135 | break; | ||
136 | |||
137 | prop_data = buf + sizeof(*upwa); | ||
138 | nprops = be32_to_cpu(upwa->nprops); | ||
139 | |||
140 | if (*prop_data == 0) { | ||
141 | prop_data++; | ||
142 | vd = be32_to_cpu(*(__be32 *)prop_data); | ||
143 | prop_data += vd + sizeof(vd); | ||
144 | nprops--; | ||
145 | } | ||
146 | |||
147 | for (i = 0; i < nprops; i++) { | ||
148 | char *prop_name; | ||
149 | |||
150 | prop_name = prop_data; | ||
151 | prop_data += strlen(prop_name) + 1; | ||
152 | vd = be32_to_cpu(*(__be32 *)prop_data); | ||
153 | prop_data += sizeof(vd); | ||
154 | |||
155 | if ((vd != 0x00000000) && (vd != 0x80000000)) { | ||
156 | ret = update_property(dn, prop_name, vd, | ||
157 | prop_data); | ||
158 | if (ret) | ||
159 | pr_err("cxl: Could not update property %s - %i\n", | ||
160 | prop_name, ret); | ||
161 | |||
162 | prop_data += vd; | ||
163 | } | ||
164 | } | ||
165 | } while (rc == 1); | ||
166 | |||
167 | of_node_put(dn); | ||
168 | kfree(buf); | ||
169 | return rc; | ||
170 | } | ||
171 | |||
172 | static int update_devicetree(struct cxl *adapter, s32 scope) | ||
173 | { | ||
174 | struct update_nodes_workarea *unwa; | ||
175 | u32 action, node_count; | ||
176 | int token, rc, i; | ||
177 | __be32 *data, drc_index, phandle; | ||
178 | char *buf; | ||
179 | |||
180 | token = rtas_token("ibm,update-nodes"); | ||
181 | if (token == RTAS_UNKNOWN_SERVICE) | ||
182 | return -EINVAL; | ||
183 | |||
184 | buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); | ||
185 | if (!buf) | ||
186 | return -ENOMEM; | ||
187 | |||
188 | unwa = (struct update_nodes_workarea *)&buf[0]; | ||
189 | unwa->unit_address = cpu_to_be64(adapter->guest->handle); | ||
190 | do { | ||
191 | rc = rcall(token, buf, scope); | ||
192 | if (rc && rc != 1) | ||
193 | break; | ||
194 | |||
195 | data = (__be32 *)buf + 4; | ||
196 | while (be32_to_cpu(*data) & NODE_ACTION_MASK) { | ||
197 | action = be32_to_cpu(*data) & NODE_ACTION_MASK; | ||
198 | node_count = be32_to_cpu(*data) & NODE_COUNT_MASK; | ||
199 | pr_devel("device reconfiguration - action: %#x, nodes: %#x\n", | ||
200 | action, node_count); | ||
201 | data++; | ||
202 | |||
203 | for (i = 0; i < node_count; i++) { | ||
204 | phandle = *data++; | ||
205 | |||
206 | switch (action) { | ||
207 | case OPCODE_DELETE: | ||
208 | /* nothing to do */ | ||
209 | break; | ||
210 | case OPCODE_UPDATE: | ||
211 | update_node(phandle, scope); | ||
212 | break; | ||
213 | case OPCODE_ADD: | ||
214 | /* nothing to do, just move pointer */ | ||
215 | drc_index = *data++; | ||
216 | break; | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | } while (rc == 1); | ||
221 | |||
222 | kfree(buf); | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static int handle_image(struct cxl *adapter, int operation, | ||
227 | long (*fct)(u64, u64, u64, u64 *), | ||
228 | struct cxl_adapter_image *ai) | ||
229 | { | ||
230 | size_t mod, s_copy, len_chunk = 0; | ||
231 | struct ai_header *header = NULL; | ||
232 | unsigned int entries = 0, i; | ||
233 | void *dest, *from; | ||
234 | int rc = 0, need_header; | ||
235 | |||
236 | /* base adapter image header */ | ||
237 | need_header = (ai->flags & CXL_AI_NEED_HEADER); | ||
238 | if (need_header) { | ||
239 | header = kzalloc(sizeof(struct ai_header), GFP_KERNEL); | ||
240 | if (!header) | ||
241 | return -ENOMEM; | ||
242 | header->version = cpu_to_be16(1); | ||
243 | header->vendor = cpu_to_be16(adapter->guest->vendor); | ||
244 | header->device = cpu_to_be16(adapter->guest->device); | ||
245 | header->subsystem_vendor = cpu_to_be16(adapter->guest->subsystem_vendor); | ||
246 | header->subsystem = cpu_to_be16(adapter->guest->subsystem); | ||
247 | header->image_offset = cpu_to_be64(CXL_AI_HEADER_SIZE); | ||
248 | header->image_length = cpu_to_be64(ai->len_image); | ||
249 | } | ||
250 | |||
251 | /* number of entries in the list */ | ||
252 | len_chunk = ai->len_data; | ||
253 | if (need_header) | ||
254 | len_chunk += CXL_AI_HEADER_SIZE; | ||
255 | |||
256 | entries = len_chunk / CXL_AI_BUFFER_SIZE; | ||
257 | mod = len_chunk % CXL_AI_BUFFER_SIZE; | ||
258 | if (mod) | ||
259 | entries++; | ||
260 | |||
261 | if (entries > CXL_AI_MAX_ENTRIES) { | ||
262 | rc = -EINVAL; | ||
263 | goto err; | ||
264 | } | ||
265 | |||
266 | /* < -- MAX_CHUNK_SIZE = 4096 * 256 = 1048576 bytes --> | ||
267 | * chunk 0 ---------------------------------------------------- | ||
268 | * | header | data | | ||
269 | * ---------------------------------------------------- | ||
270 | * chunk 1 ---------------------------------------------------- | ||
271 | * | data | | ||
272 | * ---------------------------------------------------- | ||
273 | * .... | ||
274 | * chunk n ---------------------------------------------------- | ||
275 | * | data | | ||
276 | * ---------------------------------------------------- | ||
277 | */ | ||
278 | from = (void *) ai->data; | ||
279 | for (i = 0; i < entries; i++) { | ||
280 | dest = buffer[i]; | ||
281 | s_copy = CXL_AI_BUFFER_SIZE; | ||
282 | |||
283 | if ((need_header) && (i == 0)) { | ||
284 | /* add adapter image header */ | ||
285 | memcpy(buffer[i], header, sizeof(struct ai_header)); | ||
286 | s_copy = CXL_AI_BUFFER_SIZE - CXL_AI_HEADER_SIZE; | ||
287 | dest += CXL_AI_HEADER_SIZE; /* image offset */ | ||
288 | } | ||
289 | if ((i == (entries - 1)) && mod) | ||
290 | s_copy = mod; | ||
291 | |||
292 | /* copy data */ | ||
293 | if (copy_from_user(dest, from, s_copy)) | ||
294 | goto err; | ||
295 | |||
296 | /* fill in the list */ | ||
297 | le[i].phys_addr = cpu_to_be64(virt_to_phys(buffer[i])); | ||
298 | le[i].len = cpu_to_be64(CXL_AI_BUFFER_SIZE); | ||
299 | if ((i == (entries - 1)) && mod) | ||
300 | le[i].len = cpu_to_be64(mod); | ||
301 | from += s_copy; | ||
302 | } | ||
303 | pr_devel("%s (op: %i, need header: %i, entries: %i, token: %#llx)\n", | ||
304 | __func__, operation, need_header, entries, continue_token); | ||
305 | |||
306 | /* | ||
307 | * download/validate the adapter image to the coherent | ||
308 | * platform facility | ||
309 | */ | ||
310 | rc = fct(adapter->guest->handle, virt_to_phys(le), entries, | ||
311 | &continue_token); | ||
312 | if (rc == 0) /* success of download/validation operation */ | ||
313 | continue_token = 0; | ||
314 | |||
315 | err: | ||
316 | kfree(header); | ||
317 | |||
318 | return rc; | ||
319 | } | ||
320 | |||
321 | static int transfer_image(struct cxl *adapter, int operation, | ||
322 | struct cxl_adapter_image *ai) | ||
323 | { | ||
324 | int rc = 0; | ||
325 | int afu; | ||
326 | |||
327 | switch (operation) { | ||
328 | case DOWNLOAD_IMAGE: | ||
329 | rc = handle_image(adapter, operation, | ||
330 | &cxl_h_download_adapter_image, ai); | ||
331 | if (rc < 0) { | ||
332 | pr_devel("resetting adapter\n"); | ||
333 | cxl_h_reset_adapter(adapter->guest->handle); | ||
334 | } | ||
335 | return rc; | ||
336 | |||
337 | case VALIDATE_IMAGE: | ||
338 | rc = handle_image(adapter, operation, | ||
339 | &cxl_h_validate_adapter_image, ai); | ||
340 | if (rc < 0) { | ||
341 | pr_devel("resetting adapter\n"); | ||
342 | cxl_h_reset_adapter(adapter->guest->handle); | ||
343 | return rc; | ||
344 | } | ||
345 | if (rc == 0) { | ||
346 | pr_devel("remove curent afu\n"); | ||
347 | for (afu = 0; afu < adapter->slices; afu++) | ||
348 | cxl_guest_remove_afu(adapter->afu[afu]); | ||
349 | |||
350 | pr_devel("resetting adapter\n"); | ||
351 | cxl_h_reset_adapter(adapter->guest->handle); | ||
352 | |||
353 | /* The entire image has now been | ||
354 | * downloaded and the validation has | ||
355 | * been successfully performed. | ||
356 | * After that, the partition should call | ||
357 | * ibm,update-nodes and | ||
358 | * ibm,update-properties to receive the | ||
359 | * current configuration | ||
360 | */ | ||
361 | rc = update_devicetree(adapter, DEVICE_SCOPE); | ||
362 | transfer = 1; | ||
363 | } | ||
364 | return rc; | ||
365 | } | ||
366 | |||
367 | return -EINVAL; | ||
368 | } | ||
369 | |||
370 | static long ioctl_transfer_image(struct cxl *adapter, int operation, | ||
371 | struct cxl_adapter_image __user *uai) | ||
372 | { | ||
373 | struct cxl_adapter_image ai; | ||
374 | |||
375 | pr_devel("%s\n", __func__); | ||
376 | |||
377 | if (copy_from_user(&ai, uai, sizeof(struct cxl_adapter_image))) | ||
378 | return -EFAULT; | ||
379 | |||
380 | /* | ||
381 | * Make sure reserved fields and bits are set to 0 | ||
382 | */ | ||
383 | if (ai.reserved1 || ai.reserved2 || ai.reserved3 || ai.reserved4 || | ||
384 | (ai.flags & ~CXL_AI_ALL)) | ||
385 | return -EINVAL; | ||
386 | |||
387 | return transfer_image(adapter, operation, &ai); | ||
388 | } | ||
389 | |||
390 | static int device_open(struct inode *inode, struct file *file) | ||
391 | { | ||
392 | int adapter_num = CXL_DEVT_ADAPTER(inode->i_rdev); | ||
393 | struct cxl *adapter; | ||
394 | int rc = 0, i; | ||
395 | |||
396 | pr_devel("in %s\n", __func__); | ||
397 | |||
398 | BUG_ON(sizeof(struct ai_header) != CXL_AI_HEADER_SIZE); | ||
399 | |||
400 | /* Allows one process to open the device by using a semaphore */ | ||
401 | if (down_interruptible(&sem) != 0) | ||
402 | return -EPERM; | ||
403 | |||
404 | if (!(adapter = get_cxl_adapter(adapter_num))) | ||
405 | return -ENODEV; | ||
406 | |||
407 | file->private_data = adapter; | ||
408 | continue_token = 0; | ||
409 | transfer = 0; | ||
410 | |||
411 | for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) | ||
412 | buffer[i] = NULL; | ||
413 | |||
414 | /* aligned buffer containing list entries which describes up to | ||
415 | * 1 megabyte of data (256 entries of 4096 bytes each) | ||
416 | * Logical real address of buffer 0 - Buffer 0 length in bytes | ||
417 | * Logical real address of buffer 1 - Buffer 1 length in bytes | ||
418 | * Logical real address of buffer 2 - Buffer 2 length in bytes | ||
419 | * .... | ||
420 | * .... | ||
421 | * Logical real address of buffer N - Buffer N length in bytes | ||
422 | */ | ||
423 | le = (struct sg_list *)get_zeroed_page(GFP_KERNEL); | ||
424 | if (!le) { | ||
425 | rc = -ENOMEM; | ||
426 | goto err; | ||
427 | } | ||
428 | |||
429 | for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) { | ||
430 | buffer[i] = (unsigned long *)get_zeroed_page(GFP_KERNEL); | ||
431 | if (!buffer[i]) { | ||
432 | rc = -ENOMEM; | ||
433 | goto err1; | ||
434 | } | ||
435 | } | ||
436 | |||
437 | return 0; | ||
438 | |||
439 | err1: | ||
440 | for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) { | ||
441 | if (buffer[i]) | ||
442 | free_page((unsigned long) buffer[i]); | ||
443 | } | ||
444 | |||
445 | if (le) | ||
446 | free_page((unsigned long) le); | ||
447 | err: | ||
448 | put_device(&adapter->dev); | ||
449 | |||
450 | return rc; | ||
451 | } | ||
452 | |||
453 | static long device_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
454 | { | ||
455 | struct cxl *adapter = file->private_data; | ||
456 | |||
457 | pr_devel("in %s\n", __func__); | ||
458 | |||
459 | if (cmd == CXL_IOCTL_DOWNLOAD_IMAGE) | ||
460 | return ioctl_transfer_image(adapter, | ||
461 | DOWNLOAD_IMAGE, | ||
462 | (struct cxl_adapter_image __user *)arg); | ||
463 | else if (cmd == CXL_IOCTL_VALIDATE_IMAGE) | ||
464 | return ioctl_transfer_image(adapter, | ||
465 | VALIDATE_IMAGE, | ||
466 | (struct cxl_adapter_image __user *)arg); | ||
467 | else | ||
468 | return -EINVAL; | ||
469 | } | ||
470 | |||
471 | static long device_compat_ioctl(struct file *file, unsigned int cmd, | ||
472 | unsigned long arg) | ||
473 | { | ||
474 | return device_ioctl(file, cmd, arg); | ||
475 | } | ||
476 | |||
477 | static int device_close(struct inode *inode, struct file *file) | ||
478 | { | ||
479 | struct cxl *adapter = file->private_data; | ||
480 | int i; | ||
481 | |||
482 | pr_devel("in %s\n", __func__); | ||
483 | |||
484 | for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) { | ||
485 | if (buffer[i]) | ||
486 | free_page((unsigned long) buffer[i]); | ||
487 | } | ||
488 | |||
489 | if (le) | ||
490 | free_page((unsigned long) le); | ||
491 | |||
492 | up(&sem); | ||
493 | put_device(&adapter->dev); | ||
494 | continue_token = 0; | ||
495 | |||
496 | /* reload the module */ | ||
497 | if (transfer) | ||
498 | cxl_guest_reload_module(adapter); | ||
499 | else { | ||
500 | pr_devel("resetting adapter\n"); | ||
501 | cxl_h_reset_adapter(adapter->guest->handle); | ||
502 | } | ||
503 | |||
504 | transfer = 0; | ||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | static const struct file_operations fops = { | ||
509 | .owner = THIS_MODULE, | ||
510 | .open = device_open, | ||
511 | .unlocked_ioctl = device_ioctl, | ||
512 | .compat_ioctl = device_compat_ioctl, | ||
513 | .release = device_close, | ||
514 | }; | ||
515 | |||
516 | void cxl_guest_remove_chardev(struct cxl *adapter) | ||
517 | { | ||
518 | cdev_del(&adapter->guest->cdev); | ||
519 | } | ||
520 | |||
521 | int cxl_guest_add_chardev(struct cxl *adapter) | ||
522 | { | ||
523 | dev_t devt; | ||
524 | int rc; | ||
525 | |||
526 | devt = MKDEV(MAJOR(cxl_get_dev()), CXL_CARD_MINOR(adapter)); | ||
527 | cdev_init(&adapter->guest->cdev, &fops); | ||
528 | if ((rc = cdev_add(&adapter->guest->cdev, devt, 1))) { | ||
529 | dev_err(&adapter->dev, | ||
530 | "Unable to add chardev on adapter (card%i): %i\n", | ||
531 | adapter->adapter_num, rc); | ||
532 | goto err; | ||
533 | } | ||
534 | adapter->dev.devt = devt; | ||
535 | sema_init(&sem, 1); | ||
536 | err: | ||
537 | return rc; | ||
538 | } | ||
diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c new file mode 100644 index 000000000000..8213372de2b7 --- /dev/null +++ b/drivers/misc/cxl/guest.c | |||
@@ -0,0 +1,1177 @@ | |||
1 | /* | ||
2 | * Copyright 2015 IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/spinlock.h> | ||
11 | #include <linux/uaccess.h> | ||
12 | #include <linux/delay.h> | ||
13 | |||
14 | #include "cxl.h" | ||
15 | #include "hcalls.h" | ||
16 | #include "trace.h" | ||
17 | |||
18 | #define CXL_ERROR_DETECTED_EVENT 1 | ||
19 | #define CXL_SLOT_RESET_EVENT 2 | ||
20 | #define CXL_RESUME_EVENT 3 | ||
21 | |||
22 | static void pci_error_handlers(struct cxl_afu *afu, | ||
23 | int bus_error_event, | ||
24 | pci_channel_state_t state) | ||
25 | { | ||
26 | struct pci_dev *afu_dev; | ||
27 | |||
28 | if (afu->phb == NULL) | ||
29 | return; | ||
30 | |||
31 | list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) { | ||
32 | if (!afu_dev->driver) | ||
33 | continue; | ||
34 | |||
35 | switch (bus_error_event) { | ||
36 | case CXL_ERROR_DETECTED_EVENT: | ||
37 | afu_dev->error_state = state; | ||
38 | |||
39 | if (afu_dev->driver->err_handler && | ||
40 | afu_dev->driver->err_handler->error_detected) | ||
41 | afu_dev->driver->err_handler->error_detected(afu_dev, state); | ||
42 | break; | ||
43 | case CXL_SLOT_RESET_EVENT: | ||
44 | afu_dev->error_state = state; | ||
45 | |||
46 | if (afu_dev->driver->err_handler && | ||
47 | afu_dev->driver->err_handler->slot_reset) | ||
48 | afu_dev->driver->err_handler->slot_reset(afu_dev); | ||
49 | break; | ||
50 | case CXL_RESUME_EVENT: | ||
51 | if (afu_dev->driver->err_handler && | ||
52 | afu_dev->driver->err_handler->resume) | ||
53 | afu_dev->driver->err_handler->resume(afu_dev); | ||
54 | break; | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | |||
59 | static irqreturn_t guest_handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr, | ||
60 | u64 errstat) | ||
61 | { | ||
62 | pr_devel("in %s\n", __func__); | ||
63 | dev_crit(&ctx->afu->dev, "PSL ERROR STATUS: 0x%.16llx\n", errstat); | ||
64 | |||
65 | return cxl_ops->ack_irq(ctx, 0, errstat); | ||
66 | } | ||
67 | |||
68 | static ssize_t guest_collect_vpd(struct cxl *adapter, struct cxl_afu *afu, | ||
69 | void *buf, size_t len) | ||
70 | { | ||
71 | unsigned int entries, mod; | ||
72 | unsigned long **vpd_buf = NULL; | ||
73 | struct sg_list *le; | ||
74 | int rc = 0, i, tocopy; | ||
75 | u64 out = 0; | ||
76 | |||
77 | if (buf == NULL) | ||
78 | return -EINVAL; | ||
79 | |||
80 | /* number of entries in the list */ | ||
81 | entries = len / SG_BUFFER_SIZE; | ||
82 | mod = len % SG_BUFFER_SIZE; | ||
83 | if (mod) | ||
84 | entries++; | ||
85 | |||
86 | if (entries > SG_MAX_ENTRIES) { | ||
87 | entries = SG_MAX_ENTRIES; | ||
88 | len = SG_MAX_ENTRIES * SG_BUFFER_SIZE; | ||
89 | mod = 0; | ||
90 | } | ||
91 | |||
92 | vpd_buf = kzalloc(entries * sizeof(unsigned long *), GFP_KERNEL); | ||
93 | if (!vpd_buf) | ||
94 | return -ENOMEM; | ||
95 | |||
96 | le = (struct sg_list *)get_zeroed_page(GFP_KERNEL); | ||
97 | if (!le) { | ||
98 | rc = -ENOMEM; | ||
99 | goto err1; | ||
100 | } | ||
101 | |||
102 | for (i = 0; i < entries; i++) { | ||
103 | vpd_buf[i] = (unsigned long *)get_zeroed_page(GFP_KERNEL); | ||
104 | if (!vpd_buf[i]) { | ||
105 | rc = -ENOMEM; | ||
106 | goto err2; | ||
107 | } | ||
108 | le[i].phys_addr = cpu_to_be64(virt_to_phys(vpd_buf[i])); | ||
109 | le[i].len = cpu_to_be64(SG_BUFFER_SIZE); | ||
110 | if ((i == (entries - 1)) && mod) | ||
111 | le[i].len = cpu_to_be64(mod); | ||
112 | } | ||
113 | |||
114 | if (adapter) | ||
115 | rc = cxl_h_collect_vpd_adapter(adapter->guest->handle, | ||
116 | virt_to_phys(le), entries, &out); | ||
117 | else | ||
118 | rc = cxl_h_collect_vpd(afu->guest->handle, 0, | ||
119 | virt_to_phys(le), entries, &out); | ||
120 | pr_devel("length of available (entries: %i), vpd: %#llx\n", | ||
121 | entries, out); | ||
122 | |||
123 | if (!rc) { | ||
124 | /* | ||
125 | * hcall returns in 'out' the size of available VPDs. | ||
126 | * It fills the buffer with as much data as possible. | ||
127 | */ | ||
128 | if (out < len) | ||
129 | len = out; | ||
130 | rc = len; | ||
131 | if (out) { | ||
132 | for (i = 0; i < entries; i++) { | ||
133 | if (len < SG_BUFFER_SIZE) | ||
134 | tocopy = len; | ||
135 | else | ||
136 | tocopy = SG_BUFFER_SIZE; | ||
137 | memcpy(buf, vpd_buf[i], tocopy); | ||
138 | buf += tocopy; | ||
139 | len -= tocopy; | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | err2: | ||
144 | for (i = 0; i < entries; i++) { | ||
145 | if (vpd_buf[i]) | ||
146 | free_page((unsigned long) vpd_buf[i]); | ||
147 | } | ||
148 | free_page((unsigned long) le); | ||
149 | err1: | ||
150 | kfree(vpd_buf); | ||
151 | return rc; | ||
152 | } | ||
153 | |||
154 | static int guest_get_irq_info(struct cxl_context *ctx, struct cxl_irq_info *info) | ||
155 | { | ||
156 | return cxl_h_collect_int_info(ctx->afu->guest->handle, ctx->process_token, info); | ||
157 | } | ||
158 | |||
159 | static irqreturn_t guest_psl_irq(int irq, void *data) | ||
160 | { | ||
161 | struct cxl_context *ctx = data; | ||
162 | struct cxl_irq_info irq_info; | ||
163 | int rc; | ||
164 | |||
165 | pr_devel("%d: received PSL interrupt %i\n", ctx->pe, irq); | ||
166 | rc = guest_get_irq_info(ctx, &irq_info); | ||
167 | if (rc) { | ||
168 | WARN(1, "Unable to get IRQ info: %i\n", rc); | ||
169 | return IRQ_HANDLED; | ||
170 | } | ||
171 | |||
172 | rc = cxl_irq(irq, ctx, &irq_info); | ||
173 | return rc; | ||
174 | } | ||
175 | |||
176 | static int afu_read_error_state(struct cxl_afu *afu, int *state_out) | ||
177 | { | ||
178 | u64 state; | ||
179 | int rc = 0; | ||
180 | |||
181 | rc = cxl_h_read_error_state(afu->guest->handle, &state); | ||
182 | if (!rc) { | ||
183 | WARN_ON(state != H_STATE_NORMAL && | ||
184 | state != H_STATE_DISABLE && | ||
185 | state != H_STATE_TEMP_UNAVAILABLE && | ||
186 | state != H_STATE_PERM_UNAVAILABLE); | ||
187 | *state_out = state & 0xffffffff; | ||
188 | } | ||
189 | return rc; | ||
190 | } | ||
191 | |||
192 | static irqreturn_t guest_slice_irq_err(int irq, void *data) | ||
193 | { | ||
194 | struct cxl_afu *afu = data; | ||
195 | int rc; | ||
196 | u64 serr; | ||
197 | |||
198 | WARN(irq, "CXL SLICE ERROR interrupt %i\n", irq); | ||
199 | rc = cxl_h_get_fn_error_interrupt(afu->guest->handle, &serr); | ||
200 | if (rc) { | ||
201 | dev_crit(&afu->dev, "Couldn't read PSL_SERR_An: %d\n", rc); | ||
202 | return IRQ_HANDLED; | ||
203 | } | ||
204 | dev_crit(&afu->dev, "PSL_SERR_An: 0x%.16llx\n", serr); | ||
205 | |||
206 | rc = cxl_h_ack_fn_error_interrupt(afu->guest->handle, serr); | ||
207 | if (rc) | ||
208 | dev_crit(&afu->dev, "Couldn't ack slice error interrupt: %d\n", | ||
209 | rc); | ||
210 | |||
211 | return IRQ_HANDLED; | ||
212 | } | ||
213 | |||
214 | |||
215 | static int irq_alloc_range(struct cxl *adapter, int len, int *irq) | ||
216 | { | ||
217 | int i, n; | ||
218 | struct irq_avail *cur; | ||
219 | |||
220 | for (i = 0; i < adapter->guest->irq_nranges; i++) { | ||
221 | cur = &adapter->guest->irq_avail[i]; | ||
222 | n = bitmap_find_next_zero_area(cur->bitmap, cur->range, | ||
223 | 0, len, 0); | ||
224 | if (n < cur->range) { | ||
225 | bitmap_set(cur->bitmap, n, len); | ||
226 | *irq = cur->offset + n; | ||
227 | pr_devel("guest: allocate IRQs %#x->%#x\n", | ||
228 | *irq, *irq + len - 1); | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | } | ||
233 | return -ENOSPC; | ||
234 | } | ||
235 | |||
236 | static int irq_free_range(struct cxl *adapter, int irq, int len) | ||
237 | { | ||
238 | int i, n; | ||
239 | struct irq_avail *cur; | ||
240 | |||
241 | if (len == 0) | ||
242 | return -ENOENT; | ||
243 | |||
244 | for (i = 0; i < adapter->guest->irq_nranges; i++) { | ||
245 | cur = &adapter->guest->irq_avail[i]; | ||
246 | if (irq >= cur->offset && | ||
247 | (irq + len) <= (cur->offset + cur->range)) { | ||
248 | n = irq - cur->offset; | ||
249 | bitmap_clear(cur->bitmap, n, len); | ||
250 | pr_devel("guest: release IRQs %#x->%#x\n", | ||
251 | irq, irq + len - 1); | ||
252 | return 0; | ||
253 | } | ||
254 | } | ||
255 | return -ENOENT; | ||
256 | } | ||
257 | |||
258 | static int guest_reset(struct cxl *adapter) | ||
259 | { | ||
260 | struct cxl_afu *afu = NULL; | ||
261 | int i, rc; | ||
262 | |||
263 | pr_devel("Adapter reset request\n"); | ||
264 | for (i = 0; i < adapter->slices; i++) { | ||
265 | if ((afu = adapter->afu[i])) { | ||
266 | pci_error_handlers(afu, CXL_ERROR_DETECTED_EVENT, | ||
267 | pci_channel_io_frozen); | ||
268 | cxl_context_detach_all(afu); | ||
269 | } | ||
270 | } | ||
271 | |||
272 | rc = cxl_h_reset_adapter(adapter->guest->handle); | ||
273 | for (i = 0; i < adapter->slices; i++) { | ||
274 | if (!rc && (afu = adapter->afu[i])) { | ||
275 | pci_error_handlers(afu, CXL_SLOT_RESET_EVENT, | ||
276 | pci_channel_io_normal); | ||
277 | pci_error_handlers(afu, CXL_RESUME_EVENT, 0); | ||
278 | } | ||
279 | } | ||
280 | return rc; | ||
281 | } | ||
282 | |||
283 | static int guest_alloc_one_irq(struct cxl *adapter) | ||
284 | { | ||
285 | int irq; | ||
286 | |||
287 | spin_lock(&adapter->guest->irq_alloc_lock); | ||
288 | if (irq_alloc_range(adapter, 1, &irq)) | ||
289 | irq = -ENOSPC; | ||
290 | spin_unlock(&adapter->guest->irq_alloc_lock); | ||
291 | return irq; | ||
292 | } | ||
293 | |||
294 | static void guest_release_one_irq(struct cxl *adapter, int irq) | ||
295 | { | ||
296 | spin_lock(&adapter->guest->irq_alloc_lock); | ||
297 | irq_free_range(adapter, irq, 1); | ||
298 | spin_unlock(&adapter->guest->irq_alloc_lock); | ||
299 | } | ||
300 | |||
301 | static int guest_alloc_irq_ranges(struct cxl_irq_ranges *irqs, | ||
302 | struct cxl *adapter, unsigned int num) | ||
303 | { | ||
304 | int i, try, irq; | ||
305 | |||
306 | memset(irqs, 0, sizeof(struct cxl_irq_ranges)); | ||
307 | |||
308 | spin_lock(&adapter->guest->irq_alloc_lock); | ||
309 | for (i = 0; i < CXL_IRQ_RANGES && num; i++) { | ||
310 | try = num; | ||
311 | while (try) { | ||
312 | if (irq_alloc_range(adapter, try, &irq) == 0) | ||
313 | break; | ||
314 | try /= 2; | ||
315 | } | ||
316 | if (!try) | ||
317 | goto error; | ||
318 | irqs->offset[i] = irq; | ||
319 | irqs->range[i] = try; | ||
320 | num -= try; | ||
321 | } | ||
322 | if (num) | ||
323 | goto error; | ||
324 | spin_unlock(&adapter->guest->irq_alloc_lock); | ||
325 | return 0; | ||
326 | |||
327 | error: | ||
328 | for (i = 0; i < CXL_IRQ_RANGES; i++) | ||
329 | irq_free_range(adapter, irqs->offset[i], irqs->range[i]); | ||
330 | spin_unlock(&adapter->guest->irq_alloc_lock); | ||
331 | return -ENOSPC; | ||
332 | } | ||
333 | |||
334 | static void guest_release_irq_ranges(struct cxl_irq_ranges *irqs, | ||
335 | struct cxl *adapter) | ||
336 | { | ||
337 | int i; | ||
338 | |||
339 | spin_lock(&adapter->guest->irq_alloc_lock); | ||
340 | for (i = 0; i < CXL_IRQ_RANGES; i++) | ||
341 | irq_free_range(adapter, irqs->offset[i], irqs->range[i]); | ||
342 | spin_unlock(&adapter->guest->irq_alloc_lock); | ||
343 | } | ||
344 | |||
345 | static int guest_register_serr_irq(struct cxl_afu *afu) | ||
346 | { | ||
347 | afu->err_irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err", | ||
348 | dev_name(&afu->dev)); | ||
349 | if (!afu->err_irq_name) | ||
350 | return -ENOMEM; | ||
351 | |||
352 | if (!(afu->serr_virq = cxl_map_irq(afu->adapter, afu->serr_hwirq, | ||
353 | guest_slice_irq_err, afu, afu->err_irq_name))) { | ||
354 | kfree(afu->err_irq_name); | ||
355 | afu->err_irq_name = NULL; | ||
356 | return -ENOMEM; | ||
357 | } | ||
358 | |||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static void guest_release_serr_irq(struct cxl_afu *afu) | ||
363 | { | ||
364 | cxl_unmap_irq(afu->serr_virq, afu); | ||
365 | cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq); | ||
366 | kfree(afu->err_irq_name); | ||
367 | } | ||
368 | |||
369 | static int guest_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask) | ||
370 | { | ||
371 | return cxl_h_control_faults(ctx->afu->guest->handle, ctx->process_token, | ||
372 | tfc >> 32, (psl_reset_mask != 0)); | ||
373 | } | ||
374 | |||
375 | static void disable_afu_irqs(struct cxl_context *ctx) | ||
376 | { | ||
377 | irq_hw_number_t hwirq; | ||
378 | unsigned int virq; | ||
379 | int r, i; | ||
380 | |||
381 | pr_devel("Disabling AFU(%d) interrupts\n", ctx->afu->slice); | ||
382 | for (r = 0; r < CXL_IRQ_RANGES; r++) { | ||
383 | hwirq = ctx->irqs.offset[r]; | ||
384 | for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) { | ||
385 | virq = irq_find_mapping(NULL, hwirq); | ||
386 | disable_irq(virq); | ||
387 | } | ||
388 | } | ||
389 | } | ||
390 | |||
391 | static void enable_afu_irqs(struct cxl_context *ctx) | ||
392 | { | ||
393 | irq_hw_number_t hwirq; | ||
394 | unsigned int virq; | ||
395 | int r, i; | ||
396 | |||
397 | pr_devel("Enabling AFU(%d) interrupts\n", ctx->afu->slice); | ||
398 | for (r = 0; r < CXL_IRQ_RANGES; r++) { | ||
399 | hwirq = ctx->irqs.offset[r]; | ||
400 | for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) { | ||
401 | virq = irq_find_mapping(NULL, hwirq); | ||
402 | enable_irq(virq); | ||
403 | } | ||
404 | } | ||
405 | } | ||
406 | |||
407 | static int _guest_afu_cr_readXX(int sz, struct cxl_afu *afu, int cr_idx, | ||
408 | u64 offset, u64 *val) | ||
409 | { | ||
410 | unsigned long cr; | ||
411 | char c; | ||
412 | int rc = 0; | ||
413 | |||
414 | if (afu->crs_len < sz) | ||
415 | return -ENOENT; | ||
416 | |||
417 | if (unlikely(offset >= afu->crs_len)) | ||
418 | return -ERANGE; | ||
419 | |||
420 | cr = get_zeroed_page(GFP_KERNEL); | ||
421 | if (!cr) | ||
422 | return -ENOMEM; | ||
423 | |||
424 | rc = cxl_h_get_config(afu->guest->handle, cr_idx, offset, | ||
425 | virt_to_phys((void *)cr), sz); | ||
426 | if (rc) | ||
427 | goto err; | ||
428 | |||
429 | switch (sz) { | ||
430 | case 1: | ||
431 | c = *((char *) cr); | ||
432 | *val = c; | ||
433 | break; | ||
434 | case 2: | ||
435 | *val = in_le16((u16 *)cr); | ||
436 | break; | ||
437 | case 4: | ||
438 | *val = in_le32((unsigned *)cr); | ||
439 | break; | ||
440 | case 8: | ||
441 | *val = in_le64((u64 *)cr); | ||
442 | break; | ||
443 | default: | ||
444 | WARN_ON(1); | ||
445 | } | ||
446 | err: | ||
447 | free_page(cr); | ||
448 | return rc; | ||
449 | } | ||
450 | |||
451 | static int guest_afu_cr_read32(struct cxl_afu *afu, int cr_idx, u64 offset, | ||
452 | u32 *out) | ||
453 | { | ||
454 | int rc; | ||
455 | u64 val; | ||
456 | |||
457 | rc = _guest_afu_cr_readXX(4, afu, cr_idx, offset, &val); | ||
458 | if (!rc) | ||
459 | *out = (u32) val; | ||
460 | return rc; | ||
461 | } | ||
462 | |||
463 | static int guest_afu_cr_read16(struct cxl_afu *afu, int cr_idx, u64 offset, | ||
464 | u16 *out) | ||
465 | { | ||
466 | int rc; | ||
467 | u64 val; | ||
468 | |||
469 | rc = _guest_afu_cr_readXX(2, afu, cr_idx, offset, &val); | ||
470 | if (!rc) | ||
471 | *out = (u16) val; | ||
472 | return rc; | ||
473 | } | ||
474 | |||
475 | static int guest_afu_cr_read8(struct cxl_afu *afu, int cr_idx, u64 offset, | ||
476 | u8 *out) | ||
477 | { | ||
478 | int rc; | ||
479 | u64 val; | ||
480 | |||
481 | rc = _guest_afu_cr_readXX(1, afu, cr_idx, offset, &val); | ||
482 | if (!rc) | ||
483 | *out = (u8) val; | ||
484 | return rc; | ||
485 | } | ||
486 | |||
487 | static int guest_afu_cr_read64(struct cxl_afu *afu, int cr_idx, u64 offset, | ||
488 | u64 *out) | ||
489 | { | ||
490 | return _guest_afu_cr_readXX(8, afu, cr_idx, offset, out); | ||
491 | } | ||
492 | |||
493 | static int guest_afu_cr_write32(struct cxl_afu *afu, int cr, u64 off, u32 in) | ||
494 | { | ||
495 | /* config record is not writable from guest */ | ||
496 | return -EPERM; | ||
497 | } | ||
498 | |||
499 | static int guest_afu_cr_write16(struct cxl_afu *afu, int cr, u64 off, u16 in) | ||
500 | { | ||
501 | /* config record is not writable from guest */ | ||
502 | return -EPERM; | ||
503 | } | ||
504 | |||
505 | static int guest_afu_cr_write8(struct cxl_afu *afu, int cr, u64 off, u8 in) | ||
506 | { | ||
507 | /* config record is not writable from guest */ | ||
508 | return -EPERM; | ||
509 | } | ||
510 | |||
511 | static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr) | ||
512 | { | ||
513 | struct cxl_process_element_hcall *elem; | ||
514 | struct cxl *adapter = ctx->afu->adapter; | ||
515 | const struct cred *cred; | ||
516 | u32 pid, idx; | ||
517 | int rc, r, i; | ||
518 | u64 mmio_addr, mmio_size; | ||
519 | __be64 flags = 0; | ||
520 | |||
521 | /* Must be 8 byte aligned and cannot cross a 4096 byte boundary */ | ||
522 | if (!(elem = (struct cxl_process_element_hcall *) | ||
523 | get_zeroed_page(GFP_KERNEL))) | ||
524 | return -ENOMEM; | ||
525 | |||
526 | elem->version = cpu_to_be64(CXL_PROCESS_ELEMENT_VERSION); | ||
527 | if (ctx->kernel) { | ||
528 | pid = 0; | ||
529 | flags |= CXL_PE_TRANSLATION_ENABLED; | ||
530 | flags |= CXL_PE_PRIVILEGED_PROCESS; | ||
531 | if (mfmsr() & MSR_SF) | ||
532 | flags |= CXL_PE_64_BIT; | ||
533 | } else { | ||
534 | pid = current->pid; | ||
535 | flags |= CXL_PE_PROBLEM_STATE; | ||
536 | flags |= CXL_PE_TRANSLATION_ENABLED; | ||
537 | if (!test_tsk_thread_flag(current, TIF_32BIT)) | ||
538 | flags |= CXL_PE_64_BIT; | ||
539 | cred = get_current_cred(); | ||
540 | if (uid_eq(cred->euid, GLOBAL_ROOT_UID)) | ||
541 | flags |= CXL_PE_PRIVILEGED_PROCESS; | ||
542 | put_cred(cred); | ||
543 | } | ||
544 | elem->flags = cpu_to_be64(flags); | ||
545 | elem->common.tid = cpu_to_be32(0); /* Unused */ | ||
546 | elem->common.pid = cpu_to_be32(pid); | ||
547 | elem->common.csrp = cpu_to_be64(0); /* disable */ | ||
548 | elem->common.aurp0 = cpu_to_be64(0); /* disable */ | ||
549 | elem->common.aurp1 = cpu_to_be64(0); /* disable */ | ||
550 | |||
551 | cxl_prefault(ctx, wed); | ||
552 | |||
553 | elem->common.sstp0 = cpu_to_be64(ctx->sstp0); | ||
554 | elem->common.sstp1 = cpu_to_be64(ctx->sstp1); | ||
555 | for (r = 0; r < CXL_IRQ_RANGES; r++) { | ||
556 | for (i = 0; i < ctx->irqs.range[r]; i++) { | ||
557 | if (r == 0 && i == 0) { | ||
558 | elem->pslVirtualIsn = cpu_to_be32(ctx->irqs.offset[0]); | ||
559 | } else { | ||
560 | idx = ctx->irqs.offset[r] + i - adapter->guest->irq_base_offset; | ||
561 | elem->applicationVirtualIsnBitmap[idx / 8] |= 0x80 >> (idx % 8); | ||
562 | } | ||
563 | } | ||
564 | } | ||
565 | elem->common.amr = cpu_to_be64(amr); | ||
566 | elem->common.wed = cpu_to_be64(wed); | ||
567 | |||
568 | disable_afu_irqs(ctx); | ||
569 | |||
570 | rc = cxl_h_attach_process(ctx->afu->guest->handle, elem, | ||
571 | &ctx->process_token, &mmio_addr, &mmio_size); | ||
572 | if (rc == H_SUCCESS) { | ||
573 | if (ctx->master || !ctx->afu->pp_psa) { | ||
574 | ctx->psn_phys = ctx->afu->psn_phys; | ||
575 | ctx->psn_size = ctx->afu->adapter->ps_size; | ||
576 | } else { | ||
577 | ctx->psn_phys = mmio_addr; | ||
578 | ctx->psn_size = mmio_size; | ||
579 | } | ||
580 | if (ctx->afu->pp_psa && mmio_size && | ||
581 | ctx->afu->pp_size == 0) { | ||
582 | /* | ||
583 | * There's no property in the device tree to read the | ||
584 | * pp_size. We only find out at the 1st attach. | ||
585 | * Compared to bare-metal, it is too late and we | ||
586 | * should really lock here. However, on powerVM, | ||
587 | * pp_size is really only used to display in /sys. | ||
588 | * Being discussed with pHyp for their next release. | ||
589 | */ | ||
590 | ctx->afu->pp_size = mmio_size; | ||
591 | } | ||
592 | /* from PAPR: process element is bytes 4-7 of process token */ | ||
593 | ctx->external_pe = ctx->process_token & 0xFFFFFFFF; | ||
594 | pr_devel("CXL pe=%i is known as %i for pHyp, mmio_size=%#llx", | ||
595 | ctx->pe, ctx->external_pe, ctx->psn_size); | ||
596 | ctx->pe_inserted = true; | ||
597 | enable_afu_irqs(ctx); | ||
598 | } | ||
599 | |||
600 | free_page((u64)elem); | ||
601 | return rc; | ||
602 | } | ||
603 | |||
604 | static int guest_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr) | ||
605 | { | ||
606 | pr_devel("in %s\n", __func__); | ||
607 | |||
608 | ctx->kernel = kernel; | ||
609 | if (ctx->afu->current_mode == CXL_MODE_DIRECTED) | ||
610 | return attach_afu_directed(ctx, wed, amr); | ||
611 | |||
612 | /* dedicated mode not supported on FW840 */ | ||
613 | |||
614 | return -EINVAL; | ||
615 | } | ||
616 | |||
617 | static int detach_afu_directed(struct cxl_context *ctx) | ||
618 | { | ||
619 | if (!ctx->pe_inserted) | ||
620 | return 0; | ||
621 | if (cxl_h_detach_process(ctx->afu->guest->handle, ctx->process_token)) | ||
622 | return -1; | ||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | static int guest_detach_process(struct cxl_context *ctx) | ||
627 | { | ||
628 | pr_devel("in %s\n", __func__); | ||
629 | trace_cxl_detach(ctx); | ||
630 | |||
631 | if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) | ||
632 | return -EIO; | ||
633 | |||
634 | if (ctx->afu->current_mode == CXL_MODE_DIRECTED) | ||
635 | return detach_afu_directed(ctx); | ||
636 | |||
637 | return -EINVAL; | ||
638 | } | ||
639 | |||
640 | static void guest_release_afu(struct device *dev) | ||
641 | { | ||
642 | struct cxl_afu *afu = to_cxl_afu(dev); | ||
643 | |||
644 | pr_devel("%s\n", __func__); | ||
645 | |||
646 | idr_destroy(&afu->contexts_idr); | ||
647 | |||
648 | kfree(afu->guest); | ||
649 | kfree(afu); | ||
650 | } | ||
651 | |||
652 | ssize_t cxl_guest_read_afu_vpd(struct cxl_afu *afu, void *buf, size_t len) | ||
653 | { | ||
654 | return guest_collect_vpd(NULL, afu, buf, len); | ||
655 | } | ||
656 | |||
657 | #define ERR_BUFF_MAX_COPY_SIZE PAGE_SIZE | ||
658 | static ssize_t guest_afu_read_err_buffer(struct cxl_afu *afu, char *buf, | ||
659 | loff_t off, size_t count) | ||
660 | { | ||
661 | void *tbuf = NULL; | ||
662 | int rc = 0; | ||
663 | |||
664 | tbuf = (void *) get_zeroed_page(GFP_KERNEL); | ||
665 | if (!tbuf) | ||
666 | return -ENOMEM; | ||
667 | |||
668 | rc = cxl_h_get_afu_err(afu->guest->handle, | ||
669 | off & 0x7, | ||
670 | virt_to_phys(tbuf), | ||
671 | count); | ||
672 | if (rc) | ||
673 | goto err; | ||
674 | |||
675 | if (count > ERR_BUFF_MAX_COPY_SIZE) | ||
676 | count = ERR_BUFF_MAX_COPY_SIZE - (off & 0x7); | ||
677 | memcpy(buf, tbuf, count); | ||
678 | err: | ||
679 | free_page((u64)tbuf); | ||
680 | |||
681 | return rc; | ||
682 | } | ||
683 | |||
684 | static int guest_afu_check_and_enable(struct cxl_afu *afu) | ||
685 | { | ||
686 | return 0; | ||
687 | } | ||
688 | |||
689 | static bool guest_support_attributes(const char *attr_name, | ||
690 | enum cxl_attrs type) | ||
691 | { | ||
692 | switch (type) { | ||
693 | case CXL_ADAPTER_ATTRS: | ||
694 | if ((strcmp(attr_name, "base_image") == 0) || | ||
695 | (strcmp(attr_name, "load_image_on_perst") == 0) || | ||
696 | (strcmp(attr_name, "perst_reloads_same_image") == 0) || | ||
697 | (strcmp(attr_name, "image_loaded") == 0)) | ||
698 | return false; | ||
699 | break; | ||
700 | case CXL_AFU_MASTER_ATTRS: | ||
701 | if ((strcmp(attr_name, "pp_mmio_off") == 0)) | ||
702 | return false; | ||
703 | break; | ||
704 | case CXL_AFU_ATTRS: | ||
705 | break; | ||
706 | default: | ||
707 | break; | ||
708 | } | ||
709 | |||
710 | return true; | ||
711 | } | ||
712 | |||
713 | static int activate_afu_directed(struct cxl_afu *afu) | ||
714 | { | ||
715 | int rc; | ||
716 | |||
717 | dev_info(&afu->dev, "Activating AFU(%d) directed mode\n", afu->slice); | ||
718 | |||
719 | afu->current_mode = CXL_MODE_DIRECTED; | ||
720 | |||
721 | afu->num_procs = afu->max_procs_virtualised; | ||
722 | |||
723 | if ((rc = cxl_chardev_m_afu_add(afu))) | ||
724 | return rc; | ||
725 | |||
726 | if ((rc = cxl_sysfs_afu_m_add(afu))) | ||
727 | goto err; | ||
728 | |||
729 | if ((rc = cxl_chardev_s_afu_add(afu))) | ||
730 | goto err1; | ||
731 | |||
732 | return 0; | ||
733 | err1: | ||
734 | cxl_sysfs_afu_m_remove(afu); | ||
735 | err: | ||
736 | cxl_chardev_afu_remove(afu); | ||
737 | return rc; | ||
738 | } | ||
739 | |||
740 | static int guest_afu_activate_mode(struct cxl_afu *afu, int mode) | ||
741 | { | ||
742 | if (!mode) | ||
743 | return 0; | ||
744 | if (!(mode & afu->modes_supported)) | ||
745 | return -EINVAL; | ||
746 | |||
747 | if (mode == CXL_MODE_DIRECTED) | ||
748 | return activate_afu_directed(afu); | ||
749 | |||
750 | if (mode == CXL_MODE_DEDICATED) | ||
751 | dev_err(&afu->dev, "Dedicated mode not supported\n"); | ||
752 | |||
753 | return -EINVAL; | ||
754 | } | ||
755 | |||
756 | static int deactivate_afu_directed(struct cxl_afu *afu) | ||
757 | { | ||
758 | dev_info(&afu->dev, "Deactivating AFU(%d) directed mode\n", afu->slice); | ||
759 | |||
760 | afu->current_mode = 0; | ||
761 | afu->num_procs = 0; | ||
762 | |||
763 | cxl_sysfs_afu_m_remove(afu); | ||
764 | cxl_chardev_afu_remove(afu); | ||
765 | |||
766 | cxl_ops->afu_reset(afu); | ||
767 | |||
768 | return 0; | ||
769 | } | ||
770 | |||
771 | static int guest_afu_deactivate_mode(struct cxl_afu *afu, int mode) | ||
772 | { | ||
773 | if (!mode) | ||
774 | return 0; | ||
775 | if (!(mode & afu->modes_supported)) | ||
776 | return -EINVAL; | ||
777 | |||
778 | if (mode == CXL_MODE_DIRECTED) | ||
779 | return deactivate_afu_directed(afu); | ||
780 | return 0; | ||
781 | } | ||
782 | |||
783 | static int guest_afu_reset(struct cxl_afu *afu) | ||
784 | { | ||
785 | pr_devel("AFU(%d) reset request\n", afu->slice); | ||
786 | return cxl_h_reset_afu(afu->guest->handle); | ||
787 | } | ||
788 | |||
789 | static int guest_map_slice_regs(struct cxl_afu *afu) | ||
790 | { | ||
791 | if (!(afu->p2n_mmio = ioremap(afu->guest->p2n_phys, afu->guest->p2n_size))) { | ||
792 | dev_err(&afu->dev, "Error mapping AFU(%d) MMIO regions\n", | ||
793 | afu->slice); | ||
794 | return -ENOMEM; | ||
795 | } | ||
796 | return 0; | ||
797 | } | ||
798 | |||
799 | static void guest_unmap_slice_regs(struct cxl_afu *afu) | ||
800 | { | ||
801 | if (afu->p2n_mmio) | ||
802 | iounmap(afu->p2n_mmio); | ||
803 | } | ||
804 | |||
805 | static int afu_update_state(struct cxl_afu *afu) | ||
806 | { | ||
807 | int rc, cur_state; | ||
808 | |||
809 | rc = afu_read_error_state(afu, &cur_state); | ||
810 | if (rc) | ||
811 | return rc; | ||
812 | |||
813 | if (afu->guest->previous_state == cur_state) | ||
814 | return 0; | ||
815 | |||
816 | pr_devel("AFU(%d) update state to %#x\n", afu->slice, cur_state); | ||
817 | |||
818 | switch (cur_state) { | ||
819 | case H_STATE_NORMAL: | ||
820 | afu->guest->previous_state = cur_state; | ||
821 | rc = 1; | ||
822 | break; | ||
823 | |||
824 | case H_STATE_DISABLE: | ||
825 | pci_error_handlers(afu, CXL_ERROR_DETECTED_EVENT, | ||
826 | pci_channel_io_frozen); | ||
827 | |||
828 | cxl_context_detach_all(afu); | ||
829 | if ((rc = cxl_ops->afu_reset(afu))) | ||
830 | pr_devel("reset hcall failed %d\n", rc); | ||
831 | |||
832 | rc = afu_read_error_state(afu, &cur_state); | ||
833 | if (!rc && cur_state == H_STATE_NORMAL) { | ||
834 | pci_error_handlers(afu, CXL_SLOT_RESET_EVENT, | ||
835 | pci_channel_io_normal); | ||
836 | pci_error_handlers(afu, CXL_RESUME_EVENT, 0); | ||
837 | rc = 1; | ||
838 | } | ||
839 | afu->guest->previous_state = 0; | ||
840 | break; | ||
841 | |||
842 | case H_STATE_TEMP_UNAVAILABLE: | ||
843 | afu->guest->previous_state = cur_state; | ||
844 | break; | ||
845 | |||
846 | case H_STATE_PERM_UNAVAILABLE: | ||
847 | dev_err(&afu->dev, "AFU is in permanent error state\n"); | ||
848 | pci_error_handlers(afu, CXL_ERROR_DETECTED_EVENT, | ||
849 | pci_channel_io_perm_failure); | ||
850 | afu->guest->previous_state = cur_state; | ||
851 | break; | ||
852 | |||
853 | default: | ||
854 | pr_err("Unexpected AFU(%d) error state: %#x\n", | ||
855 | afu->slice, cur_state); | ||
856 | return -EINVAL; | ||
857 | } | ||
858 | |||
859 | return rc; | ||
860 | } | ||
861 | |||
862 | static int afu_do_recovery(struct cxl_afu *afu) | ||
863 | { | ||
864 | int rc; | ||
865 | |||
866 | /* many threads can arrive here, in case of detach_all for example. | ||
867 | * Only one needs to drive the recovery | ||
868 | */ | ||
869 | if (mutex_trylock(&afu->guest->recovery_lock)) { | ||
870 | rc = afu_update_state(afu); | ||
871 | mutex_unlock(&afu->guest->recovery_lock); | ||
872 | return rc; | ||
873 | } | ||
874 | return 0; | ||
875 | } | ||
876 | |||
877 | static bool guest_link_ok(struct cxl *cxl, struct cxl_afu *afu) | ||
878 | { | ||
879 | int state; | ||
880 | |||
881 | if (afu) { | ||
882 | if (afu_read_error_state(afu, &state) || | ||
883 | state != H_STATE_NORMAL) { | ||
884 | if (afu_do_recovery(afu) > 0) { | ||
885 | /* check again in case we've just fixed it */ | ||
886 | if (!afu_read_error_state(afu, &state) && | ||
887 | state == H_STATE_NORMAL) | ||
888 | return true; | ||
889 | } | ||
890 | return false; | ||
891 | } | ||
892 | } | ||
893 | |||
894 | return true; | ||
895 | } | ||
896 | |||
897 | static int afu_properties_look_ok(struct cxl_afu *afu) | ||
898 | { | ||
899 | if (afu->pp_irqs < 0) { | ||
900 | dev_err(&afu->dev, "Unexpected per-process minimum interrupt value\n"); | ||
901 | return -EINVAL; | ||
902 | } | ||
903 | |||
904 | if (afu->max_procs_virtualised < 1) { | ||
905 | dev_err(&afu->dev, "Unexpected max number of processes virtualised value\n"); | ||
906 | return -EINVAL; | ||
907 | } | ||
908 | |||
909 | if (afu->crs_len < 0) { | ||
910 | dev_err(&afu->dev, "Unexpected configuration record size value\n"); | ||
911 | return -EINVAL; | ||
912 | } | ||
913 | |||
914 | return 0; | ||
915 | } | ||
916 | |||
917 | int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_np) | ||
918 | { | ||
919 | struct cxl_afu *afu; | ||
920 | bool free = true; | ||
921 | int rc; | ||
922 | |||
923 | pr_devel("in %s - AFU(%d)\n", __func__, slice); | ||
924 | if (!(afu = cxl_alloc_afu(adapter, slice))) | ||
925 | return -ENOMEM; | ||
926 | |||
927 | if (!(afu->guest = kzalloc(sizeof(struct cxl_afu_guest), GFP_KERNEL))) { | ||
928 | kfree(afu); | ||
929 | return -ENOMEM; | ||
930 | } | ||
931 | |||
932 | mutex_init(&afu->guest->recovery_lock); | ||
933 | |||
934 | if ((rc = dev_set_name(&afu->dev, "afu%i.%i", | ||
935 | adapter->adapter_num, | ||
936 | slice))) | ||
937 | goto err1; | ||
938 | |||
939 | adapter->slices++; | ||
940 | |||
941 | if ((rc = cxl_of_read_afu_handle(afu, afu_np))) | ||
942 | goto err1; | ||
943 | |||
944 | if ((rc = cxl_ops->afu_reset(afu))) | ||
945 | goto err1; | ||
946 | |||
947 | if ((rc = cxl_of_read_afu_properties(afu, afu_np))) | ||
948 | goto err1; | ||
949 | |||
950 | if ((rc = afu_properties_look_ok(afu))) | ||
951 | goto err1; | ||
952 | |||
953 | if ((rc = guest_map_slice_regs(afu))) | ||
954 | goto err1; | ||
955 | |||
956 | if ((rc = guest_register_serr_irq(afu))) | ||
957 | goto err2; | ||
958 | |||
959 | /* | ||
960 | * After we call this function we must not free the afu directly, even | ||
961 | * if it returns an error! | ||
962 | */ | ||
963 | if ((rc = cxl_register_afu(afu))) | ||
964 | goto err_put1; | ||
965 | |||
966 | if ((rc = cxl_sysfs_afu_add(afu))) | ||
967 | goto err_put1; | ||
968 | |||
969 | /* | ||
970 | * pHyp doesn't expose the programming models supported by the | ||
971 | * AFU. pHyp currently only supports directed mode. If it adds | ||
972 | * dedicated mode later, this version of cxl has no way to | ||
973 | * detect it. So we'll initialize the driver, but the first | ||
974 | * attach will fail. | ||
975 | * Being discussed with pHyp to do better (likely new property) | ||
976 | */ | ||
977 | if (afu->max_procs_virtualised == 1) | ||
978 | afu->modes_supported = CXL_MODE_DEDICATED; | ||
979 | else | ||
980 | afu->modes_supported = CXL_MODE_DIRECTED; | ||
981 | |||
982 | if ((rc = cxl_afu_select_best_mode(afu))) | ||
983 | goto err_put2; | ||
984 | |||
985 | adapter->afu[afu->slice] = afu; | ||
986 | |||
987 | afu->enabled = true; | ||
988 | |||
989 | if ((rc = cxl_pci_vphb_add(afu))) | ||
990 | dev_info(&afu->dev, "Can't register vPHB\n"); | ||
991 | |||
992 | return 0; | ||
993 | |||
994 | err_put2: | ||
995 | cxl_sysfs_afu_remove(afu); | ||
996 | err_put1: | ||
997 | device_unregister(&afu->dev); | ||
998 | free = false; | ||
999 | guest_release_serr_irq(afu); | ||
1000 | err2: | ||
1001 | guest_unmap_slice_regs(afu); | ||
1002 | err1: | ||
1003 | if (free) { | ||
1004 | kfree(afu->guest); | ||
1005 | kfree(afu); | ||
1006 | } | ||
1007 | return rc; | ||
1008 | } | ||
1009 | |||
1010 | void cxl_guest_remove_afu(struct cxl_afu *afu) | ||
1011 | { | ||
1012 | pr_devel("in %s - AFU(%d)\n", __func__, afu->slice); | ||
1013 | |||
1014 | if (!afu) | ||
1015 | return; | ||
1016 | |||
1017 | cxl_pci_vphb_remove(afu); | ||
1018 | cxl_sysfs_afu_remove(afu); | ||
1019 | |||
1020 | spin_lock(&afu->adapter->afu_list_lock); | ||
1021 | afu->adapter->afu[afu->slice] = NULL; | ||
1022 | spin_unlock(&afu->adapter->afu_list_lock); | ||
1023 | |||
1024 | cxl_context_detach_all(afu); | ||
1025 | cxl_ops->afu_deactivate_mode(afu, afu->current_mode); | ||
1026 | guest_release_serr_irq(afu); | ||
1027 | guest_unmap_slice_regs(afu); | ||
1028 | |||
1029 | device_unregister(&afu->dev); | ||
1030 | } | ||
1031 | |||
1032 | static void free_adapter(struct cxl *adapter) | ||
1033 | { | ||
1034 | struct irq_avail *cur; | ||
1035 | int i; | ||
1036 | |||
1037 | if (adapter->guest->irq_avail) { | ||
1038 | for (i = 0; i < adapter->guest->irq_nranges; i++) { | ||
1039 | cur = &adapter->guest->irq_avail[i]; | ||
1040 | kfree(cur->bitmap); | ||
1041 | } | ||
1042 | kfree(adapter->guest->irq_avail); | ||
1043 | } | ||
1044 | kfree(adapter->guest->status); | ||
1045 | cxl_remove_adapter_nr(adapter); | ||
1046 | kfree(adapter->guest); | ||
1047 | kfree(adapter); | ||
1048 | } | ||
1049 | |||
1050 | static int properties_look_ok(struct cxl *adapter) | ||
1051 | { | ||
1052 | /* The absence of this property means that the operational | ||
1053 | * status is unknown or okay | ||
1054 | */ | ||
1055 | if (strlen(adapter->guest->status) && | ||
1056 | strcmp(adapter->guest->status, "okay")) { | ||
1057 | pr_err("ABORTING:Bad operational status of the device\n"); | ||
1058 | return -EINVAL; | ||
1059 | } | ||
1060 | |||
1061 | return 0; | ||
1062 | } | ||
1063 | |||
1064 | ssize_t cxl_guest_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len) | ||
1065 | { | ||
1066 | return guest_collect_vpd(adapter, NULL, buf, len); | ||
1067 | } | ||
1068 | |||
1069 | void cxl_guest_remove_adapter(struct cxl *adapter) | ||
1070 | { | ||
1071 | pr_devel("in %s\n", __func__); | ||
1072 | |||
1073 | cxl_sysfs_adapter_remove(adapter); | ||
1074 | |||
1075 | cxl_guest_remove_chardev(adapter); | ||
1076 | device_unregister(&adapter->dev); | ||
1077 | } | ||
1078 | |||
1079 | static void release_adapter(struct device *dev) | ||
1080 | { | ||
1081 | free_adapter(to_cxl_adapter(dev)); | ||
1082 | } | ||
1083 | |||
1084 | struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_device *pdev) | ||
1085 | { | ||
1086 | struct cxl *adapter; | ||
1087 | bool free = true; | ||
1088 | int rc; | ||
1089 | |||
1090 | if (!(adapter = cxl_alloc_adapter())) | ||
1091 | return ERR_PTR(-ENOMEM); | ||
1092 | |||
1093 | if (!(adapter->guest = kzalloc(sizeof(struct cxl_guest), GFP_KERNEL))) { | ||
1094 | free_adapter(adapter); | ||
1095 | return ERR_PTR(-ENOMEM); | ||
1096 | } | ||
1097 | |||
1098 | adapter->slices = 0; | ||
1099 | adapter->guest->pdev = pdev; | ||
1100 | adapter->dev.parent = &pdev->dev; | ||
1101 | adapter->dev.release = release_adapter; | ||
1102 | dev_set_drvdata(&pdev->dev, adapter); | ||
1103 | |||
1104 | if ((rc = cxl_of_read_adapter_handle(adapter, np))) | ||
1105 | goto err1; | ||
1106 | |||
1107 | if ((rc = cxl_of_read_adapter_properties(adapter, np))) | ||
1108 | goto err1; | ||
1109 | |||
1110 | if ((rc = properties_look_ok(adapter))) | ||
1111 | goto err1; | ||
1112 | |||
1113 | if ((rc = cxl_guest_add_chardev(adapter))) | ||
1114 | goto err1; | ||
1115 | |||
1116 | /* | ||
1117 | * After we call this function we must not free the adapter directly, | ||
1118 | * even if it returns an error! | ||
1119 | */ | ||
1120 | if ((rc = cxl_register_adapter(adapter))) | ||
1121 | goto err_put1; | ||
1122 | |||
1123 | if ((rc = cxl_sysfs_adapter_add(adapter))) | ||
1124 | goto err_put1; | ||
1125 | |||
1126 | return adapter; | ||
1127 | |||
1128 | err_put1: | ||
1129 | device_unregister(&adapter->dev); | ||
1130 | free = false; | ||
1131 | cxl_guest_remove_chardev(adapter); | ||
1132 | err1: | ||
1133 | if (free) | ||
1134 | free_adapter(adapter); | ||
1135 | return ERR_PTR(rc); | ||
1136 | } | ||
1137 | |||
1138 | void cxl_guest_reload_module(struct cxl *adapter) | ||
1139 | { | ||
1140 | struct platform_device *pdev; | ||
1141 | |||
1142 | pdev = adapter->guest->pdev; | ||
1143 | cxl_guest_remove_adapter(adapter); | ||
1144 | |||
1145 | cxl_of_probe(pdev); | ||
1146 | } | ||
1147 | |||
1148 | const struct cxl_backend_ops cxl_guest_ops = { | ||
1149 | .module = THIS_MODULE, | ||
1150 | .adapter_reset = guest_reset, | ||
1151 | .alloc_one_irq = guest_alloc_one_irq, | ||
1152 | .release_one_irq = guest_release_one_irq, | ||
1153 | .alloc_irq_ranges = guest_alloc_irq_ranges, | ||
1154 | .release_irq_ranges = guest_release_irq_ranges, | ||
1155 | .setup_irq = NULL, | ||
1156 | .handle_psl_slice_error = guest_handle_psl_slice_error, | ||
1157 | .psl_interrupt = guest_psl_irq, | ||
1158 | .ack_irq = guest_ack_irq, | ||
1159 | .attach_process = guest_attach_process, | ||
1160 | .detach_process = guest_detach_process, | ||
1161 | .support_attributes = guest_support_attributes, | ||
1162 | .link_ok = guest_link_ok, | ||
1163 | .release_afu = guest_release_afu, | ||
1164 | .afu_read_err_buffer = guest_afu_read_err_buffer, | ||
1165 | .afu_check_and_enable = guest_afu_check_and_enable, | ||
1166 | .afu_activate_mode = guest_afu_activate_mode, | ||
1167 | .afu_deactivate_mode = guest_afu_deactivate_mode, | ||
1168 | .afu_reset = guest_afu_reset, | ||
1169 | .afu_cr_read8 = guest_afu_cr_read8, | ||
1170 | .afu_cr_read16 = guest_afu_cr_read16, | ||
1171 | .afu_cr_read32 = guest_afu_cr_read32, | ||
1172 | .afu_cr_read64 = guest_afu_cr_read64, | ||
1173 | .afu_cr_write8 = guest_afu_cr_write8, | ||
1174 | .afu_cr_write16 = guest_afu_cr_write16, | ||
1175 | .afu_cr_write32 = guest_afu_cr_write32, | ||
1176 | .read_adapter_vpd = cxl_guest_read_adapter_vpd, | ||
1177 | }; | ||
diff --git a/drivers/misc/cxl/hcalls.c b/drivers/misc/cxl/hcalls.c new file mode 100644 index 000000000000..d6d11f4056d7 --- /dev/null +++ b/drivers/misc/cxl/hcalls.c | |||
@@ -0,0 +1,647 @@ | |||
1 | /* | ||
2 | * Copyright 2015 IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | |||
11 | #include <linux/compiler.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <asm/byteorder.h> | ||
15 | #include "hcalls.h" | ||
16 | #include "trace.h" | ||
17 | |||
18 | #define CXL_HCALL_TIMEOUT 60000 | ||
19 | #define CXL_HCALL_TIMEOUT_DOWNLOAD 120000 | ||
20 | |||
21 | #define H_ATTACH_CA_PROCESS 0x344 | ||
22 | #define H_CONTROL_CA_FUNCTION 0x348 | ||
23 | #define H_DETACH_CA_PROCESS 0x34C | ||
24 | #define H_COLLECT_CA_INT_INFO 0x350 | ||
25 | #define H_CONTROL_CA_FAULTS 0x354 | ||
26 | #define H_DOWNLOAD_CA_FUNCTION 0x35C | ||
27 | #define H_DOWNLOAD_CA_FACILITY 0x364 | ||
28 | #define H_CONTROL_CA_FACILITY 0x368 | ||
29 | |||
30 | #define H_CONTROL_CA_FUNCTION_RESET 1 /* perform a reset */ | ||
31 | #define H_CONTROL_CA_FUNCTION_SUSPEND_PROCESS 2 /* suspend a process from being executed */ | ||
32 | #define H_CONTROL_CA_FUNCTION_RESUME_PROCESS 3 /* resume a process to be executed */ | ||
33 | #define H_CONTROL_CA_FUNCTION_READ_ERR_STATE 4 /* read the error state */ | ||
34 | #define H_CONTROL_CA_FUNCTION_GET_AFU_ERR 5 /* collect the AFU error buffer */ | ||
35 | #define H_CONTROL_CA_FUNCTION_GET_CONFIG 6 /* collect configuration record */ | ||
36 | #define H_CONTROL_CA_FUNCTION_GET_DOWNLOAD_STATE 7 /* query to return download status */ | ||
37 | #define H_CONTROL_CA_FUNCTION_TERMINATE_PROCESS 8 /* terminate the process before completion */ | ||
38 | #define H_CONTROL_CA_FUNCTION_COLLECT_VPD 9 /* collect VPD */ | ||
39 | #define H_CONTROL_CA_FUNCTION_GET_FUNCTION_ERR_INT 11 /* read the function-wide error data based on an interrupt */ | ||
40 | #define H_CONTROL_CA_FUNCTION_ACK_FUNCTION_ERR_INT 12 /* acknowledge function-wide error data based on an interrupt */ | ||
41 | #define H_CONTROL_CA_FUNCTION_GET_ERROR_LOG 13 /* retrieve the Platform Log ID (PLID) of an error log */ | ||
42 | |||
43 | #define H_CONTROL_CA_FAULTS_RESPOND_PSL 1 | ||
44 | #define H_CONTROL_CA_FAULTS_RESPOND_AFU 2 | ||
45 | |||
46 | #define H_CONTROL_CA_FACILITY_RESET 1 /* perform a reset */ | ||
47 | #define H_CONTROL_CA_FACILITY_COLLECT_VPD 2 /* collect VPD */ | ||
48 | |||
49 | #define H_DOWNLOAD_CA_FACILITY_DOWNLOAD 1 /* download adapter image */ | ||
50 | #define H_DOWNLOAD_CA_FACILITY_VALIDATE 2 /* validate adapter image */ | ||
51 | |||
52 | |||
53 | #define _CXL_LOOP_HCALL(call, rc, retbuf, fn, ...) \ | ||
54 | { \ | ||
55 | unsigned int delay, total_delay = 0; \ | ||
56 | u64 token = 0; \ | ||
57 | \ | ||
58 | memset(retbuf, 0, sizeof(retbuf)); \ | ||
59 | while (1) { \ | ||
60 | rc = call(fn, retbuf, __VA_ARGS__, token); \ | ||
61 | token = retbuf[0]; \ | ||
62 | if (rc != H_BUSY && !H_IS_LONG_BUSY(rc)) \ | ||
63 | break; \ | ||
64 | \ | ||
65 | if (rc == H_BUSY) \ | ||
66 | delay = 10; \ | ||
67 | else \ | ||
68 | delay = get_longbusy_msecs(rc); \ | ||
69 | \ | ||
70 | total_delay += delay; \ | ||
71 | if (total_delay > CXL_HCALL_TIMEOUT) { \ | ||
72 | WARN(1, "Warning: Giving up waiting for CXL hcall " \ | ||
73 | "%#x after %u msec\n", fn, total_delay); \ | ||
74 | rc = H_BUSY; \ | ||
75 | break; \ | ||
76 | } \ | ||
77 | msleep(delay); \ | ||
78 | } \ | ||
79 | } | ||
80 | #define CXL_H_WAIT_UNTIL_DONE(...) _CXL_LOOP_HCALL(plpar_hcall, __VA_ARGS__) | ||
81 | #define CXL_H9_WAIT_UNTIL_DONE(...) _CXL_LOOP_HCALL(plpar_hcall9, __VA_ARGS__) | ||
82 | |||
83 | #define _PRINT_MSG(rc, format, ...) \ | ||
84 | { \ | ||
85 | if ((rc != H_SUCCESS) && (rc != H_CONTINUE)) \ | ||
86 | pr_err(format, __VA_ARGS__); \ | ||
87 | else \ | ||
88 | pr_devel(format, __VA_ARGS__); \ | ||
89 | } \ | ||
90 | |||
91 | |||
92 | static char *afu_op_names[] = { | ||
93 | "UNKNOWN_OP", /* 0 undefined */ | ||
94 | "RESET", /* 1 */ | ||
95 | "SUSPEND_PROCESS", /* 2 */ | ||
96 | "RESUME_PROCESS", /* 3 */ | ||
97 | "READ_ERR_STATE", /* 4 */ | ||
98 | "GET_AFU_ERR", /* 5 */ | ||
99 | "GET_CONFIG", /* 6 */ | ||
100 | "GET_DOWNLOAD_STATE", /* 7 */ | ||
101 | "TERMINATE_PROCESS", /* 8 */ | ||
102 | "COLLECT_VPD", /* 9 */ | ||
103 | "UNKNOWN_OP", /* 10 undefined */ | ||
104 | "GET_FUNCTION_ERR_INT", /* 11 */ | ||
105 | "ACK_FUNCTION_ERR_INT", /* 12 */ | ||
106 | "GET_ERROR_LOG", /* 13 */ | ||
107 | }; | ||
108 | |||
109 | static char *control_adapter_op_names[] = { | ||
110 | "UNKNOWN_OP", /* 0 undefined */ | ||
111 | "RESET", /* 1 */ | ||
112 | "COLLECT_VPD", /* 2 */ | ||
113 | }; | ||
114 | |||
115 | static char *download_op_names[] = { | ||
116 | "UNKNOWN_OP", /* 0 undefined */ | ||
117 | "DOWNLOAD", /* 1 */ | ||
118 | "VALIDATE", /* 2 */ | ||
119 | }; | ||
120 | |||
121 | static char *op_str(unsigned int op, char *name_array[], int array_len) | ||
122 | { | ||
123 | if (op >= array_len) | ||
124 | return "UNKNOWN_OP"; | ||
125 | return name_array[op]; | ||
126 | } | ||
127 | |||
128 | #define OP_STR(op, name_array) op_str(op, name_array, ARRAY_SIZE(name_array)) | ||
129 | |||
130 | #define OP_STR_AFU(op) OP_STR(op, afu_op_names) | ||
131 | #define OP_STR_CONTROL_ADAPTER(op) OP_STR(op, control_adapter_op_names) | ||
132 | #define OP_STR_DOWNLOAD_ADAPTER(op) OP_STR(op, download_op_names) | ||
133 | |||
134 | |||
135 | long cxl_h_attach_process(u64 unit_address, | ||
136 | struct cxl_process_element_hcall *element, | ||
137 | u64 *process_token, u64 *mmio_addr, u64 *mmio_size) | ||
138 | { | ||
139 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; | ||
140 | long rc; | ||
141 | |||
142 | CXL_H_WAIT_UNTIL_DONE(rc, retbuf, H_ATTACH_CA_PROCESS, unit_address, virt_to_phys(element)); | ||
143 | _PRINT_MSG(rc, "cxl_h_attach_process(%#.16llx, %#.16lx): %li\n", | ||
144 | unit_address, virt_to_phys(element), rc); | ||
145 | trace_cxl_hcall_attach(unit_address, virt_to_phys(element), retbuf[0], retbuf[1], retbuf[2], rc); | ||
146 | |||
147 | pr_devel("token: 0x%.8lx mmio_addr: 0x%lx mmio_size: 0x%lx\nProcess Element Structure:\n", | ||
148 | retbuf[0], retbuf[1], retbuf[2]); | ||
149 | cxl_dump_debug_buffer(element, sizeof(*element)); | ||
150 | |||
151 | switch (rc) { | ||
152 | case H_SUCCESS: /* The process info is attached to the coherent platform function */ | ||
153 | *process_token = retbuf[0]; | ||
154 | if (mmio_addr) | ||
155 | *mmio_addr = retbuf[1]; | ||
156 | if (mmio_size) | ||
157 | *mmio_size = retbuf[2]; | ||
158 | return 0; | ||
159 | case H_PARAMETER: /* An incorrect parameter was supplied. */ | ||
160 | case H_FUNCTION: /* The function is not supported. */ | ||
161 | return -EINVAL; | ||
162 | case H_AUTHORITY: /* The partition does not have authority to perform this hcall */ | ||
163 | case H_RESOURCE: /* The coherent platform function does not have enough additional resource to attach the process */ | ||
164 | case H_HARDWARE: /* A hardware event prevented the attach operation */ | ||
165 | case H_STATE: /* The coherent platform function is not in a valid state */ | ||
166 | case H_BUSY: | ||
167 | return -EBUSY; | ||
168 | default: | ||
169 | WARN(1, "Unexpected return code: %lx", rc); | ||
170 | return -EINVAL; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * cxl_h_detach_process - Detach a process element from a coherent | ||
176 | * platform function. | ||
177 | */ | ||
178 | long cxl_h_detach_process(u64 unit_address, u64 process_token) | ||
179 | { | ||
180 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; | ||
181 | long rc; | ||
182 | |||
183 | CXL_H_WAIT_UNTIL_DONE(rc, retbuf, H_DETACH_CA_PROCESS, unit_address, process_token); | ||
184 | _PRINT_MSG(rc, "cxl_h_detach_process(%#.16llx, 0x%.8llx): %li\n", unit_address, process_token, rc); | ||
185 | trace_cxl_hcall_detach(unit_address, process_token, rc); | ||
186 | |||
187 | switch (rc) { | ||
188 | case H_SUCCESS: /* The process was detached from the coherent platform function */ | ||
189 | return 0; | ||
190 | case H_PARAMETER: /* An incorrect parameter was supplied. */ | ||
191 | return -EINVAL; | ||
192 | case H_AUTHORITY: /* The partition does not have authority to perform this hcall */ | ||
193 | case H_RESOURCE: /* The function has page table mappings for MMIO */ | ||
194 | case H_HARDWARE: /* A hardware event prevented the detach operation */ | ||
195 | case H_STATE: /* The coherent platform function is not in a valid state */ | ||
196 | case H_BUSY: | ||
197 | return -EBUSY; | ||
198 | default: | ||
199 | WARN(1, "Unexpected return code: %lx", rc); | ||
200 | return -EINVAL; | ||
201 | } | ||
202 | } | ||
203 | |||
204 | /** | ||
205 | * cxl_h_control_function - This H_CONTROL_CA_FUNCTION hypervisor call allows | ||
206 | * the partition to manipulate or query | ||
207 | * certain coherent platform function behaviors. | ||
208 | */ | ||
209 | static long cxl_h_control_function(u64 unit_address, u64 op, | ||
210 | u64 p1, u64 p2, u64 p3, u64 p4, u64 *out) | ||
211 | { | ||
212 | unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; | ||
213 | long rc; | ||
214 | |||
215 | CXL_H9_WAIT_UNTIL_DONE(rc, retbuf, H_CONTROL_CA_FUNCTION, unit_address, op, p1, p2, p3, p4); | ||
216 | _PRINT_MSG(rc, "cxl_h_control_function(%#.16llx, %s(%#llx, %#llx, %#llx, %#llx, R4: %#lx)): %li\n", | ||
217 | unit_address, OP_STR_AFU(op), p1, p2, p3, p4, retbuf[0], rc); | ||
218 | trace_cxl_hcall_control_function(unit_address, OP_STR_AFU(op), p1, p2, p3, p4, retbuf[0], rc); | ||
219 | |||
220 | switch (rc) { | ||
221 | case H_SUCCESS: /* The operation is completed for the coherent platform function */ | ||
222 | if ((op == H_CONTROL_CA_FUNCTION_GET_FUNCTION_ERR_INT || | ||
223 | op == H_CONTROL_CA_FUNCTION_READ_ERR_STATE || | ||
224 | op == H_CONTROL_CA_FUNCTION_COLLECT_VPD)) | ||
225 | *out = retbuf[0]; | ||
226 | return 0; | ||
227 | case H_PARAMETER: /* An incorrect parameter was supplied. */ | ||
228 | case H_FUNCTION: /* The function is not supported. */ | ||
229 | case H_NOT_FOUND: /* The operation supplied was not valid */ | ||
230 | case H_NOT_AVAILABLE: /* The operation cannot be performed because the AFU has not been downloaded */ | ||
231 | case H_SG_LIST: /* An block list entry was invalid */ | ||
232 | return -EINVAL; | ||
233 | case H_AUTHORITY: /* The partition does not have authority to perform this hcall */ | ||
234 | case H_RESOURCE: /* The function has page table mappings for MMIO */ | ||
235 | case H_HARDWARE: /* A hardware event prevented the attach operation */ | ||
236 | case H_STATE: /* The coherent platform function is not in a valid state */ | ||
237 | case H_BUSY: | ||
238 | return -EBUSY; | ||
239 | default: | ||
240 | WARN(1, "Unexpected return code: %lx", rc); | ||
241 | return -EINVAL; | ||
242 | } | ||
243 | } | ||
244 | |||
245 | /** | ||
246 | * cxl_h_reset_afu - Perform a reset to the coherent platform function. | ||
247 | */ | ||
248 | long cxl_h_reset_afu(u64 unit_address) | ||
249 | { | ||
250 | return cxl_h_control_function(unit_address, | ||
251 | H_CONTROL_CA_FUNCTION_RESET, | ||
252 | 0, 0, 0, 0, | ||
253 | NULL); | ||
254 | } | ||
255 | |||
256 | /** | ||
257 | * cxl_h_suspend_process - Suspend a process from being executed | ||
258 | * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when | ||
259 | * process was attached. | ||
260 | */ | ||
261 | long cxl_h_suspend_process(u64 unit_address, u64 process_token) | ||
262 | { | ||
263 | return cxl_h_control_function(unit_address, | ||
264 | H_CONTROL_CA_FUNCTION_SUSPEND_PROCESS, | ||
265 | process_token, 0, 0, 0, | ||
266 | NULL); | ||
267 | } | ||
268 | |||
269 | /** | ||
270 | * cxl_h_resume_process - Resume a process to be executed | ||
271 | * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when | ||
272 | * process was attached. | ||
273 | */ | ||
274 | long cxl_h_resume_process(u64 unit_address, u64 process_token) | ||
275 | { | ||
276 | return cxl_h_control_function(unit_address, | ||
277 | H_CONTROL_CA_FUNCTION_RESUME_PROCESS, | ||
278 | process_token, 0, 0, 0, | ||
279 | NULL); | ||
280 | } | ||
281 | |||
282 | /** | ||
283 | * cxl_h_read_error_state - Checks the error state of the coherent | ||
284 | * platform function. | ||
285 | * R4 contains the error state | ||
286 | */ | ||
287 | long cxl_h_read_error_state(u64 unit_address, u64 *state) | ||
288 | { | ||
289 | return cxl_h_control_function(unit_address, | ||
290 | H_CONTROL_CA_FUNCTION_READ_ERR_STATE, | ||
291 | 0, 0, 0, 0, | ||
292 | state); | ||
293 | } | ||
294 | |||
295 | /** | ||
296 | * cxl_h_get_afu_err - collect the AFU error buffer | ||
297 | * Parameter1 = byte offset into error buffer to retrieve, valid values | ||
298 | * are between 0 and (ibm,error-buffer-size - 1) | ||
299 | * Parameter2 = 4K aligned real address of error buffer, to be filled in | ||
300 | * Parameter3 = length of error buffer, valid values are 4K or less | ||
301 | */ | ||
302 | long cxl_h_get_afu_err(u64 unit_address, u64 offset, | ||
303 | u64 buf_address, u64 len) | ||
304 | { | ||
305 | return cxl_h_control_function(unit_address, | ||
306 | H_CONTROL_CA_FUNCTION_GET_AFU_ERR, | ||
307 | offset, buf_address, len, 0, | ||
308 | NULL); | ||
309 | } | ||
310 | |||
311 | /** | ||
312 | * cxl_h_get_config - collect configuration record for the | ||
313 | * coherent platform function | ||
314 | * Parameter1 = # of configuration record to retrieve, valid values are | ||
315 | * between 0 and (ibm,#config-records - 1) | ||
316 | * Parameter2 = byte offset into configuration record to retrieve, | ||
317 | * valid values are between 0 and (ibm,config-record-size - 1) | ||
318 | * Parameter3 = 4K aligned real address of configuration record buffer, | ||
319 | * to be filled in | ||
320 | * Parameter4 = length of configuration buffer, valid values are 4K or less | ||
321 | */ | ||
322 | long cxl_h_get_config(u64 unit_address, u64 cr_num, u64 offset, | ||
323 | u64 buf_address, u64 len) | ||
324 | { | ||
325 | return cxl_h_control_function(unit_address, | ||
326 | H_CONTROL_CA_FUNCTION_GET_CONFIG, | ||
327 | cr_num, offset, buf_address, len, | ||
328 | NULL); | ||
329 | } | ||
330 | |||
331 | /** | ||
332 | * cxl_h_terminate_process - Terminate the process before completion | ||
333 | * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when | ||
334 | * process was attached. | ||
335 | */ | ||
336 | long cxl_h_terminate_process(u64 unit_address, u64 process_token) | ||
337 | { | ||
338 | return cxl_h_control_function(unit_address, | ||
339 | H_CONTROL_CA_FUNCTION_TERMINATE_PROCESS, | ||
340 | process_token, 0, 0, 0, | ||
341 | NULL); | ||
342 | } | ||
343 | |||
344 | /** | ||
345 | * cxl_h_collect_vpd - Collect VPD for the coherent platform function. | ||
346 | * Parameter1 = # of VPD record to retrieve, valid values are between 0 | ||
347 | * and (ibm,#config-records - 1). | ||
348 | * Parameter2 = 4K naturally aligned real buffer containing block | ||
349 | * list entries | ||
350 | * Parameter3 = number of block list entries in the block list, valid | ||
351 | * values are between 0 and 256 | ||
352 | */ | ||
353 | long cxl_h_collect_vpd(u64 unit_address, u64 record, u64 list_address, | ||
354 | u64 num, u64 *out) | ||
355 | { | ||
356 | return cxl_h_control_function(unit_address, | ||
357 | H_CONTROL_CA_FUNCTION_COLLECT_VPD, | ||
358 | record, list_address, num, 0, | ||
359 | out); | ||
360 | } | ||
361 | |||
362 | /** | ||
363 | * cxl_h_get_fn_error_interrupt - Read the function-wide error data based on an interrupt | ||
364 | */ | ||
365 | long cxl_h_get_fn_error_interrupt(u64 unit_address, u64 *reg) | ||
366 | { | ||
367 | return cxl_h_control_function(unit_address, | ||
368 | H_CONTROL_CA_FUNCTION_GET_FUNCTION_ERR_INT, | ||
369 | 0, 0, 0, 0, reg); | ||
370 | } | ||
371 | |||
372 | /** | ||
373 | * cxl_h_ack_fn_error_interrupt - Acknowledge function-wide error data | ||
374 | * based on an interrupt | ||
375 | * Parameter1 = value to write to the function-wide error interrupt register | ||
376 | */ | ||
377 | long cxl_h_ack_fn_error_interrupt(u64 unit_address, u64 value) | ||
378 | { | ||
379 | return cxl_h_control_function(unit_address, | ||
380 | H_CONTROL_CA_FUNCTION_ACK_FUNCTION_ERR_INT, | ||
381 | value, 0, 0, 0, | ||
382 | NULL); | ||
383 | } | ||
384 | |||
385 | /** | ||
386 | * cxl_h_get_error_log - Retrieve the Platform Log ID (PLID) of | ||
387 | * an error log | ||
388 | */ | ||
389 | long cxl_h_get_error_log(u64 unit_address, u64 value) | ||
390 | { | ||
391 | return cxl_h_control_function(unit_address, | ||
392 | H_CONTROL_CA_FUNCTION_GET_ERROR_LOG, | ||
393 | 0, 0, 0, 0, | ||
394 | NULL); | ||
395 | } | ||
396 | |||
397 | /** | ||
398 | * cxl_h_collect_int_info - Collect interrupt info about a coherent | ||
399 | * platform function after an interrupt occurred. | ||
400 | */ | ||
401 | long cxl_h_collect_int_info(u64 unit_address, u64 process_token, | ||
402 | struct cxl_irq_info *info) | ||
403 | { | ||
404 | long rc; | ||
405 | |||
406 | BUG_ON(sizeof(*info) != sizeof(unsigned long[PLPAR_HCALL9_BUFSIZE])); | ||
407 | |||
408 | rc = plpar_hcall9(H_COLLECT_CA_INT_INFO, (unsigned long *) info, | ||
409 | unit_address, process_token); | ||
410 | _PRINT_MSG(rc, "cxl_h_collect_int_info(%#.16llx, 0x%llx): %li\n", | ||
411 | unit_address, process_token, rc); | ||
412 | trace_cxl_hcall_collect_int_info(unit_address, process_token, rc); | ||
413 | |||
414 | switch (rc) { | ||
415 | case H_SUCCESS: /* The interrupt info is returned in return registers. */ | ||
416 | pr_devel("dsisr:%#llx, dar:%#llx, dsr:%#llx, pid:%u, tid:%u, afu_err:%#llx, errstat:%#llx\n", | ||
417 | info->dsisr, info->dar, info->dsr, info->pid, | ||
418 | info->tid, info->afu_err, info->errstat); | ||
419 | return 0; | ||
420 | case H_PARAMETER: /* An incorrect parameter was supplied. */ | ||
421 | return -EINVAL; | ||
422 | case H_AUTHORITY: /* The partition does not have authority to perform this hcall. */ | ||
423 | case H_HARDWARE: /* A hardware event prevented the collection of the interrupt info.*/ | ||
424 | case H_STATE: /* The coherent platform function is not in a valid state to collect interrupt info. */ | ||
425 | return -EBUSY; | ||
426 | default: | ||
427 | WARN(1, "Unexpected return code: %lx", rc); | ||
428 | return -EINVAL; | ||
429 | } | ||
430 | } | ||
431 | |||
432 | /** | ||
433 | * cxl_h_control_faults - Control the operation of a coherent platform | ||
434 | * function after a fault occurs. | ||
435 | * | ||
436 | * Parameters | ||
437 | * control-mask: value to control the faults | ||
438 | * looks like PSL_TFC_An shifted >> 32 | ||
439 | * reset-mask: mask to control reset of function faults | ||
440 | * Set reset_mask = 1 to reset PSL errors | ||
441 | */ | ||
442 | long cxl_h_control_faults(u64 unit_address, u64 process_token, | ||
443 | u64 control_mask, u64 reset_mask) | ||
444 | { | ||
445 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; | ||
446 | long rc; | ||
447 | |||
448 | memset(retbuf, 0, sizeof(retbuf)); | ||
449 | |||
450 | rc = plpar_hcall(H_CONTROL_CA_FAULTS, retbuf, unit_address, | ||
451 | H_CONTROL_CA_FAULTS_RESPOND_PSL, process_token, | ||
452 | control_mask, reset_mask); | ||
453 | _PRINT_MSG(rc, "cxl_h_control_faults(%#.16llx, 0x%llx, %#llx, %#llx): %li (%#lx)\n", | ||
454 | unit_address, process_token, control_mask, reset_mask, | ||
455 | rc, retbuf[0]); | ||
456 | trace_cxl_hcall_control_faults(unit_address, process_token, | ||
457 | control_mask, reset_mask, retbuf[0], rc); | ||
458 | |||
459 | switch (rc) { | ||
460 | case H_SUCCESS: /* Faults were successfully controlled for the function. */ | ||
461 | return 0; | ||
462 | case H_PARAMETER: /* An incorrect parameter was supplied. */ | ||
463 | return -EINVAL; | ||
464 | case H_HARDWARE: /* A hardware event prevented the control of faults. */ | ||
465 | case H_STATE: /* The function was in an invalid state. */ | ||
466 | case H_AUTHORITY: /* The partition does not have authority to perform this hcall; the coherent platform facilities may need to be licensed. */ | ||
467 | return -EBUSY; | ||
468 | case H_FUNCTION: /* The function is not supported */ | ||
469 | case H_NOT_FOUND: /* The operation supplied was not valid */ | ||
470 | return -EINVAL; | ||
471 | default: | ||
472 | WARN(1, "Unexpected return code: %lx", rc); | ||
473 | return -EINVAL; | ||
474 | } | ||
475 | } | ||
476 | |||
477 | /** | ||
478 | * cxl_h_control_facility - This H_CONTROL_CA_FACILITY hypervisor call | ||
479 | * allows the partition to manipulate or query | ||
480 | * certain coherent platform facility behaviors. | ||
481 | */ | ||
482 | static long cxl_h_control_facility(u64 unit_address, u64 op, | ||
483 | u64 p1, u64 p2, u64 p3, u64 p4, u64 *out) | ||
484 | { | ||
485 | unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; | ||
486 | long rc; | ||
487 | |||
488 | CXL_H9_WAIT_UNTIL_DONE(rc, retbuf, H_CONTROL_CA_FACILITY, unit_address, op, p1, p2, p3, p4); | ||
489 | _PRINT_MSG(rc, "cxl_h_control_facility(%#.16llx, %s(%#llx, %#llx, %#llx, %#llx, R4: %#lx)): %li\n", | ||
490 | unit_address, OP_STR_CONTROL_ADAPTER(op), p1, p2, p3, p4, retbuf[0], rc); | ||
491 | trace_cxl_hcall_control_facility(unit_address, OP_STR_CONTROL_ADAPTER(op), p1, p2, p3, p4, retbuf[0], rc); | ||
492 | |||
493 | switch (rc) { | ||
494 | case H_SUCCESS: /* The operation is completed for the coherent platform facility */ | ||
495 | if (op == H_CONTROL_CA_FACILITY_COLLECT_VPD) | ||
496 | *out = retbuf[0]; | ||
497 | return 0; | ||
498 | case H_PARAMETER: /* An incorrect parameter was supplied. */ | ||
499 | case H_FUNCTION: /* The function is not supported. */ | ||
500 | case H_NOT_FOUND: /* The operation supplied was not valid */ | ||
501 | case H_NOT_AVAILABLE: /* The operation cannot be performed because the AFU has not been downloaded */ | ||
502 | case H_SG_LIST: /* An block list entry was invalid */ | ||
503 | return -EINVAL; | ||
504 | case H_AUTHORITY: /* The partition does not have authority to perform this hcall */ | ||
505 | case H_RESOURCE: /* The function has page table mappings for MMIO */ | ||
506 | case H_HARDWARE: /* A hardware event prevented the attach operation */ | ||
507 | case H_STATE: /* The coherent platform facility is not in a valid state */ | ||
508 | case H_BUSY: | ||
509 | return -EBUSY; | ||
510 | default: | ||
511 | WARN(1, "Unexpected return code: %lx", rc); | ||
512 | return -EINVAL; | ||
513 | } | ||
514 | } | ||
515 | |||
516 | /** | ||
517 | * cxl_h_reset_adapter - Perform a reset to the coherent platform facility. | ||
518 | */ | ||
519 | long cxl_h_reset_adapter(u64 unit_address) | ||
520 | { | ||
521 | return cxl_h_control_facility(unit_address, | ||
522 | H_CONTROL_CA_FACILITY_RESET, | ||
523 | 0, 0, 0, 0, | ||
524 | NULL); | ||
525 | } | ||
526 | |||
527 | /** | ||
528 | * cxl_h_collect_vpd - Collect VPD for the coherent platform function. | ||
529 | * Parameter1 = 4K naturally aligned real buffer containing block | ||
530 | * list entries | ||
531 | * Parameter2 = number of block list entries in the block list, valid | ||
532 | * values are between 0 and 256 | ||
533 | */ | ||
534 | long cxl_h_collect_vpd_adapter(u64 unit_address, u64 list_address, | ||
535 | u64 num, u64 *out) | ||
536 | { | ||
537 | return cxl_h_control_facility(unit_address, | ||
538 | H_CONTROL_CA_FACILITY_COLLECT_VPD, | ||
539 | list_address, num, 0, 0, | ||
540 | out); | ||
541 | } | ||
542 | |||
543 | /** | ||
544 | * cxl_h_download_facility - This H_DOWNLOAD_CA_FACILITY | ||
545 | * hypervisor call provide platform support for | ||
546 | * downloading a base adapter image to the coherent | ||
547 | * platform facility, and for validating the entire | ||
548 | * image after the download. | ||
549 | * Parameters | ||
550 | * op: operation to perform to the coherent platform function | ||
551 | * Download: operation = 1, the base image in the coherent platform | ||
552 | * facility is first erased, and then | ||
553 | * programmed using the image supplied | ||
554 | * in the scatter/gather list. | ||
555 | * Validate: operation = 2, the base image in the coherent platform | ||
556 | * facility is compared with the image | ||
557 | * supplied in the scatter/gather list. | ||
558 | * list_address: 4K naturally aligned real buffer containing | ||
559 | * scatter/gather list entries. | ||
560 | * num: number of block list entries in the scatter/gather list. | ||
561 | */ | ||
562 | static long cxl_h_download_facility(u64 unit_address, u64 op, | ||
563 | u64 list_address, u64 num, | ||
564 | u64 *out) | ||
565 | { | ||
566 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; | ||
567 | unsigned int delay, total_delay = 0; | ||
568 | u64 token = 0; | ||
569 | long rc; | ||
570 | |||
571 | if (*out != 0) | ||
572 | token = *out; | ||
573 | |||
574 | memset(retbuf, 0, sizeof(retbuf)); | ||
575 | while (1) { | ||
576 | rc = plpar_hcall(H_DOWNLOAD_CA_FACILITY, retbuf, | ||
577 | unit_address, op, list_address, num, | ||
578 | token); | ||
579 | token = retbuf[0]; | ||
580 | if (rc != H_BUSY && !H_IS_LONG_BUSY(rc)) | ||
581 | break; | ||
582 | |||
583 | if (rc != H_BUSY) { | ||
584 | delay = get_longbusy_msecs(rc); | ||
585 | total_delay += delay; | ||
586 | if (total_delay > CXL_HCALL_TIMEOUT_DOWNLOAD) { | ||
587 | WARN(1, "Warning: Giving up waiting for CXL hcall " | ||
588 | "%#x after %u msec\n", | ||
589 | H_DOWNLOAD_CA_FACILITY, total_delay); | ||
590 | rc = H_BUSY; | ||
591 | break; | ||
592 | } | ||
593 | msleep(delay); | ||
594 | } | ||
595 | } | ||
596 | _PRINT_MSG(rc, "cxl_h_download_facility(%#.16llx, %s(%#llx, %#llx), %#lx): %li\n", | ||
597 | unit_address, OP_STR_DOWNLOAD_ADAPTER(op), list_address, num, retbuf[0], rc); | ||
598 | trace_cxl_hcall_download_facility(unit_address, OP_STR_DOWNLOAD_ADAPTER(op), list_address, num, retbuf[0], rc); | ||
599 | |||
600 | switch (rc) { | ||
601 | case H_SUCCESS: /* The operation is completed for the coherent platform facility */ | ||
602 | return 0; | ||
603 | case H_PARAMETER: /* An incorrect parameter was supplied */ | ||
604 | case H_FUNCTION: /* The function is not supported. */ | ||
605 | case H_SG_LIST: /* An block list entry was invalid */ | ||
606 | case H_BAD_DATA: /* Image verification failed */ | ||
607 | return -EINVAL; | ||
608 | case H_AUTHORITY: /* The partition does not have authority to perform this hcall */ | ||
609 | case H_RESOURCE: /* The function has page table mappings for MMIO */ | ||
610 | case H_HARDWARE: /* A hardware event prevented the attach operation */ | ||
611 | case H_STATE: /* The coherent platform facility is not in a valid state */ | ||
612 | case H_BUSY: | ||
613 | return -EBUSY; | ||
614 | case H_CONTINUE: | ||
615 | *out = retbuf[0]; | ||
616 | return 1; /* More data is needed for the complete image */ | ||
617 | default: | ||
618 | WARN(1, "Unexpected return code: %lx", rc); | ||
619 | return -EINVAL; | ||
620 | } | ||
621 | } | ||
622 | |||
623 | /** | ||
624 | * cxl_h_download_adapter_image - Download the base image to the coherent | ||
625 | * platform facility. | ||
626 | */ | ||
627 | long cxl_h_download_adapter_image(u64 unit_address, | ||
628 | u64 list_address, u64 num, | ||
629 | u64 *out) | ||
630 | { | ||
631 | return cxl_h_download_facility(unit_address, | ||
632 | H_DOWNLOAD_CA_FACILITY_DOWNLOAD, | ||
633 | list_address, num, out); | ||
634 | } | ||
635 | |||
636 | /** | ||
637 | * cxl_h_validate_adapter_image - Validate the base image in the coherent | ||
638 | * platform facility. | ||
639 | */ | ||
640 | long cxl_h_validate_adapter_image(u64 unit_address, | ||
641 | u64 list_address, u64 num, | ||
642 | u64 *out) | ||
643 | { | ||
644 | return cxl_h_download_facility(unit_address, | ||
645 | H_DOWNLOAD_CA_FACILITY_VALIDATE, | ||
646 | list_address, num, out); | ||
647 | } | ||
diff --git a/drivers/misc/cxl/hcalls.h b/drivers/misc/cxl/hcalls.h new file mode 100644 index 000000000000..3e25522a5df6 --- /dev/null +++ b/drivers/misc/cxl/hcalls.h | |||
@@ -0,0 +1,204 @@ | |||
1 | /* | ||
2 | * Copyright 2015 IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #ifndef _HCALLS_H | ||
11 | #define _HCALLS_H | ||
12 | |||
13 | #include <linux/types.h> | ||
14 | #include <asm/byteorder.h> | ||
15 | #include <asm/hvcall.h> | ||
16 | #include "cxl.h" | ||
17 | |||
18 | #define SG_BUFFER_SIZE 4096 | ||
19 | #define SG_MAX_ENTRIES 256 | ||
20 | |||
21 | struct sg_list { | ||
22 | u64 phys_addr; | ||
23 | u64 len; | ||
24 | }; | ||
25 | |||
26 | /* | ||
27 | * This is straight out of PAPR, but replacing some of the compound fields with | ||
28 | * a single field, where they were identical to the register layout. | ||
29 | * | ||
30 | * The 'flags' parameter regroups the various bit-fields | ||
31 | */ | ||
32 | #define CXL_PE_CSRP_VALID (1ULL << 63) | ||
33 | #define CXL_PE_PROBLEM_STATE (1ULL << 62) | ||
34 | #define CXL_PE_SECONDARY_SEGMENT_TBL_SRCH (1ULL << 61) | ||
35 | #define CXL_PE_TAGS_ACTIVE (1ULL << 60) | ||
36 | #define CXL_PE_USER_STATE (1ULL << 59) | ||
37 | #define CXL_PE_TRANSLATION_ENABLED (1ULL << 58) | ||
38 | #define CXL_PE_64_BIT (1ULL << 57) | ||
39 | #define CXL_PE_PRIVILEGED_PROCESS (1ULL << 56) | ||
40 | |||
41 | #define CXL_PROCESS_ELEMENT_VERSION 1 | ||
42 | struct cxl_process_element_hcall { | ||
43 | __be64 version; | ||
44 | __be64 flags; | ||
45 | u8 reserved0[12]; | ||
46 | __be32 pslVirtualIsn; | ||
47 | u8 applicationVirtualIsnBitmap[256]; | ||
48 | u8 reserved1[144]; | ||
49 | struct cxl_process_element_common common; | ||
50 | u8 reserved4[12]; | ||
51 | } __packed; | ||
52 | |||
53 | #define H_STATE_NORMAL 1 | ||
54 | #define H_STATE_DISABLE 2 | ||
55 | #define H_STATE_TEMP_UNAVAILABLE 3 | ||
56 | #define H_STATE_PERM_UNAVAILABLE 4 | ||
57 | |||
58 | /* NOTE: element must be a logical real address, and must be pinned */ | ||
59 | long cxl_h_attach_process(u64 unit_address, struct cxl_process_element_hcall *element, | ||
60 | u64 *process_token, u64 *mmio_addr, u64 *mmio_size); | ||
61 | |||
62 | /** | ||
63 | * cxl_h_detach_process - Detach a process element from a coherent | ||
64 | * platform function. | ||
65 | */ | ||
66 | long cxl_h_detach_process(u64 unit_address, u64 process_token); | ||
67 | |||
68 | /** | ||
69 | * cxl_h_reset_afu - Perform a reset to the coherent platform function. | ||
70 | */ | ||
71 | long cxl_h_reset_afu(u64 unit_address); | ||
72 | |||
73 | /** | ||
74 | * cxl_h_suspend_process - Suspend a process from being executed | ||
75 | * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when | ||
76 | * process was attached. | ||
77 | */ | ||
78 | long cxl_h_suspend_process(u64 unit_address, u64 process_token); | ||
79 | |||
80 | /** | ||
81 | * cxl_h_resume_process - Resume a process to be executed | ||
82 | * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when | ||
83 | * process was attached. | ||
84 | */ | ||
85 | long cxl_h_resume_process(u64 unit_address, u64 process_token); | ||
86 | |||
87 | /** | ||
88 | * cxl_h_read_error_state - Reads the error state of the coherent | ||
89 | * platform function. | ||
90 | * R4 contains the error state | ||
91 | */ | ||
92 | long cxl_h_read_error_state(u64 unit_address, u64 *state); | ||
93 | |||
94 | /** | ||
95 | * cxl_h_get_afu_err - collect the AFU error buffer | ||
96 | * Parameter1 = byte offset into error buffer to retrieve, valid values | ||
97 | * are between 0 and (ibm,error-buffer-size - 1) | ||
98 | * Parameter2 = 4K aligned real address of error buffer, to be filled in | ||
99 | * Parameter3 = length of error buffer, valid values are 4K or less | ||
100 | */ | ||
101 | long cxl_h_get_afu_err(u64 unit_address, u64 offset, u64 buf_address, u64 len); | ||
102 | |||
103 | /** | ||
104 | * cxl_h_get_config - collect configuration record for the | ||
105 | * coherent platform function | ||
106 | * Parameter1 = # of configuration record to retrieve, valid values are | ||
107 | * between 0 and (ibm,#config-records - 1) | ||
108 | * Parameter2 = byte offset into configuration record to retrieve, | ||
109 | * valid values are between 0 and (ibm,config-record-size - 1) | ||
110 | * Parameter3 = 4K aligned real address of configuration record buffer, | ||
111 | * to be filled in | ||
112 | * Parameter4 = length of configuration buffer, valid values are 4K or less | ||
113 | */ | ||
114 | long cxl_h_get_config(u64 unit_address, u64 cr_num, u64 offset, | ||
115 | u64 buf_address, u64 len); | ||
116 | |||
117 | /** | ||
118 | * cxl_h_terminate_process - Terminate the process before completion | ||
119 | * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when | ||
120 | * process was attached. | ||
121 | */ | ||
122 | long cxl_h_terminate_process(u64 unit_address, u64 process_token); | ||
123 | |||
124 | /** | ||
125 | * cxl_h_collect_vpd - Collect VPD for the coherent platform function. | ||
126 | * Parameter1 = # of VPD record to retrieve, valid values are between 0 | ||
127 | * and (ibm,#config-records - 1). | ||
128 | * Parameter2 = 4K naturally aligned real buffer containing block | ||
129 | * list entries | ||
130 | * Parameter3 = number of block list entries in the block list, valid | ||
131 | * values are between 0 and 256 | ||
132 | */ | ||
133 | long cxl_h_collect_vpd(u64 unit_address, u64 record, u64 list_address, | ||
134 | u64 num, u64 *out); | ||
135 | |||
136 | /** | ||
137 | * cxl_h_get_fn_error_interrupt - Read the function-wide error data based on an interrupt | ||
138 | */ | ||
139 | long cxl_h_get_fn_error_interrupt(u64 unit_address, u64 *reg); | ||
140 | |||
141 | /** | ||
142 | * cxl_h_ack_fn_error_interrupt - Acknowledge function-wide error data | ||
143 | * based on an interrupt | ||
144 | * Parameter1 = value to write to the function-wide error interrupt register | ||
145 | */ | ||
146 | long cxl_h_ack_fn_error_interrupt(u64 unit_address, u64 value); | ||
147 | |||
148 | /** | ||
149 | * cxl_h_get_error_log - Retrieve the Platform Log ID (PLID) of | ||
150 | * an error log | ||
151 | */ | ||
152 | long cxl_h_get_error_log(u64 unit_address, u64 value); | ||
153 | |||
154 | /** | ||
155 | * cxl_h_collect_int_info - Collect interrupt info about a coherent | ||
156 | * platform function after an interrupt occurred. | ||
157 | */ | ||
158 | long cxl_h_collect_int_info(u64 unit_address, u64 process_token, | ||
159 | struct cxl_irq_info *info); | ||
160 | |||
161 | /** | ||
162 | * cxl_h_control_faults - Control the operation of a coherent platform | ||
163 | * function after a fault occurs. | ||
164 | * | ||
165 | * Parameters | ||
166 | * control-mask: value to control the faults | ||
167 | * looks like PSL_TFC_An shifted >> 32 | ||
168 | * reset-mask: mask to control reset of function faults | ||
169 | * Set reset_mask = 1 to reset PSL errors | ||
170 | */ | ||
171 | long cxl_h_control_faults(u64 unit_address, u64 process_token, | ||
172 | u64 control_mask, u64 reset_mask); | ||
173 | |||
174 | /** | ||
175 | * cxl_h_reset_adapter - Perform a reset to the coherent platform facility. | ||
176 | */ | ||
177 | long cxl_h_reset_adapter(u64 unit_address); | ||
178 | |||
179 | /** | ||
180 | * cxl_h_collect_vpd - Collect VPD for the coherent platform function. | ||
181 | * Parameter1 = 4K naturally aligned real buffer containing block | ||
182 | * list entries | ||
183 | * Parameter2 = number of block list entries in the block list, valid | ||
184 | * values are between 0 and 256 | ||
185 | */ | ||
186 | long cxl_h_collect_vpd_adapter(u64 unit_address, u64 list_address, | ||
187 | u64 num, u64 *out); | ||
188 | |||
189 | /** | ||
190 | * cxl_h_download_adapter_image - Download the base image to the coherent | ||
191 | * platform facility. | ||
192 | */ | ||
193 | long cxl_h_download_adapter_image(u64 unit_address, | ||
194 | u64 list_address, u64 num, | ||
195 | u64 *out); | ||
196 | |||
197 | /** | ||
198 | * cxl_h_validate_adapter_image - Validate the base image in the coherent | ||
199 | * platform facility. | ||
200 | */ | ||
201 | long cxl_h_validate_adapter_image(u64 unit_address, | ||
202 | u64 list_address, u64 num, | ||
203 | u64 *out); | ||
204 | #endif /* _HCALLS_H */ | ||
diff --git a/drivers/misc/cxl/irq.c b/drivers/misc/cxl/irq.c index 09a406058c46..be646dc41a2c 100644 --- a/drivers/misc/cxl/irq.c +++ b/drivers/misc/cxl/irq.c | |||
@@ -19,70 +19,11 @@ | |||
19 | #include "cxl.h" | 19 | #include "cxl.h" |
20 | #include "trace.h" | 20 | #include "trace.h" |
21 | 21 | ||
22 | /* XXX: This is implementation specific */ | 22 | static int afu_irq_range_start(void) |
23 | static irqreturn_t handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr, u64 errstat) | ||
24 | { | 23 | { |
25 | u64 fir1, fir2, fir_slice, serr, afu_debug; | 24 | if (cpu_has_feature(CPU_FTR_HVMODE)) |
26 | 25 | return 1; | |
27 | fir1 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR1); | 26 | return 0; |
28 | fir2 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR2); | ||
29 | fir_slice = cxl_p1n_read(ctx->afu, CXL_PSL_FIR_SLICE_An); | ||
30 | serr = cxl_p1n_read(ctx->afu, CXL_PSL_SERR_An); | ||
31 | afu_debug = cxl_p1n_read(ctx->afu, CXL_AFU_DEBUG_An); | ||
32 | |||
33 | dev_crit(&ctx->afu->dev, "PSL ERROR STATUS: 0x%016llx\n", errstat); | ||
34 | dev_crit(&ctx->afu->dev, "PSL_FIR1: 0x%016llx\n", fir1); | ||
35 | dev_crit(&ctx->afu->dev, "PSL_FIR2: 0x%016llx\n", fir2); | ||
36 | dev_crit(&ctx->afu->dev, "PSL_SERR_An: 0x%016llx\n", serr); | ||
37 | dev_crit(&ctx->afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice); | ||
38 | dev_crit(&ctx->afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug); | ||
39 | |||
40 | dev_crit(&ctx->afu->dev, "STOPPING CXL TRACE\n"); | ||
41 | cxl_stop_trace(ctx->afu->adapter); | ||
42 | |||
43 | return cxl_ack_irq(ctx, 0, errstat); | ||
44 | } | ||
45 | |||
46 | irqreturn_t cxl_slice_irq_err(int irq, void *data) | ||
47 | { | ||
48 | struct cxl_afu *afu = data; | ||
49 | u64 fir_slice, errstat, serr, afu_debug; | ||
50 | |||
51 | WARN(irq, "CXL SLICE ERROR interrupt %i\n", irq); | ||
52 | |||
53 | serr = cxl_p1n_read(afu, CXL_PSL_SERR_An); | ||
54 | fir_slice = cxl_p1n_read(afu, CXL_PSL_FIR_SLICE_An); | ||
55 | errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An); | ||
56 | afu_debug = cxl_p1n_read(afu, CXL_AFU_DEBUG_An); | ||
57 | dev_crit(&afu->dev, "PSL_SERR_An: 0x%016llx\n", serr); | ||
58 | dev_crit(&afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice); | ||
59 | dev_crit(&afu->dev, "CXL_PSL_ErrStat_An: 0x%016llx\n", errstat); | ||
60 | dev_crit(&afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug); | ||
61 | |||
62 | cxl_p1n_write(afu, CXL_PSL_SERR_An, serr); | ||
63 | |||
64 | return IRQ_HANDLED; | ||
65 | } | ||
66 | |||
67 | static irqreturn_t cxl_irq_err(int irq, void *data) | ||
68 | { | ||
69 | struct cxl *adapter = data; | ||
70 | u64 fir1, fir2, err_ivte; | ||
71 | |||
72 | WARN(1, "CXL ERROR interrupt %i\n", irq); | ||
73 | |||
74 | err_ivte = cxl_p1_read(adapter, CXL_PSL_ErrIVTE); | ||
75 | dev_crit(&adapter->dev, "PSL_ErrIVTE: 0x%016llx\n", err_ivte); | ||
76 | |||
77 | dev_crit(&adapter->dev, "STOPPING CXL TRACE\n"); | ||
78 | cxl_stop_trace(adapter); | ||
79 | |||
80 | fir1 = cxl_p1_read(adapter, CXL_PSL_FIR1); | ||
81 | fir2 = cxl_p1_read(adapter, CXL_PSL_FIR2); | ||
82 | |||
83 | dev_crit(&adapter->dev, "PSL_FIR1: 0x%016llx\nPSL_FIR2: 0x%016llx\n", fir1, fir2); | ||
84 | |||
85 | return IRQ_HANDLED; | ||
86 | } | 27 | } |
87 | 28 | ||
88 | static irqreturn_t schedule_cxl_fault(struct cxl_context *ctx, u64 dsisr, u64 dar) | 29 | static irqreturn_t schedule_cxl_fault(struct cxl_context *ctx, u64 dsisr, u64 dar) |
@@ -93,9 +34,8 @@ static irqreturn_t schedule_cxl_fault(struct cxl_context *ctx, u64 dsisr, u64 da | |||
93 | return IRQ_HANDLED; | 34 | return IRQ_HANDLED; |
94 | } | 35 | } |
95 | 36 | ||
96 | static irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info) | 37 | irqreturn_t cxl_irq(int irq, struct cxl_context *ctx, struct cxl_irq_info *irq_info) |
97 | { | 38 | { |
98 | struct cxl_context *ctx = data; | ||
99 | u64 dsisr, dar; | 39 | u64 dsisr, dar; |
100 | 40 | ||
101 | dsisr = irq_info->dsisr; | 41 | dsisr = irq_info->dsisr; |
@@ -145,7 +85,8 @@ static irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info) | |||
145 | if (dsisr & CXL_PSL_DSISR_An_UR) | 85 | if (dsisr & CXL_PSL_DSISR_An_UR) |
146 | pr_devel("CXL interrupt: AURP PTE not found\n"); | 86 | pr_devel("CXL interrupt: AURP PTE not found\n"); |
147 | if (dsisr & CXL_PSL_DSISR_An_PE) | 87 | if (dsisr & CXL_PSL_DSISR_An_PE) |
148 | return handle_psl_slice_error(ctx, dsisr, irq_info->errstat); | 88 | return cxl_ops->handle_psl_slice_error(ctx, dsisr, |
89 | irq_info->errstat); | ||
149 | if (dsisr & CXL_PSL_DSISR_An_AE) { | 90 | if (dsisr & CXL_PSL_DSISR_An_AE) { |
150 | pr_devel("CXL interrupt: AFU Error 0x%016llx\n", irq_info->afu_err); | 91 | pr_devel("CXL interrupt: AFU Error 0x%016llx\n", irq_info->afu_err); |
151 | 92 | ||
@@ -169,7 +110,7 @@ static irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info) | |||
169 | wake_up_all(&ctx->wq); | 110 | wake_up_all(&ctx->wq); |
170 | } | 111 | } |
171 | 112 | ||
172 | cxl_ack_irq(ctx, CXL_PSL_TFC_An_A, 0); | 113 | cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_A, 0); |
173 | return IRQ_HANDLED; | 114 | return IRQ_HANDLED; |
174 | } | 115 | } |
175 | if (dsisr & CXL_PSL_DSISR_An_OC) | 116 | if (dsisr & CXL_PSL_DSISR_An_OC) |
@@ -179,54 +120,27 @@ static irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info) | |||
179 | return IRQ_HANDLED; | 120 | return IRQ_HANDLED; |
180 | } | 121 | } |
181 | 122 | ||
182 | static irqreturn_t fail_psl_irq(struct cxl_afu *afu, struct cxl_irq_info *irq_info) | ||
183 | { | ||
184 | if (irq_info->dsisr & CXL_PSL_DSISR_TRANS) | ||
185 | cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE); | ||
186 | else | ||
187 | cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A); | ||
188 | |||
189 | return IRQ_HANDLED; | ||
190 | } | ||
191 | |||
192 | static irqreturn_t cxl_irq_multiplexed(int irq, void *data) | ||
193 | { | ||
194 | struct cxl_afu *afu = data; | ||
195 | struct cxl_context *ctx; | ||
196 | struct cxl_irq_info irq_info; | ||
197 | int ph = cxl_p2n_read(afu, CXL_PSL_PEHandle_An) & 0xffff; | ||
198 | int ret; | ||
199 | |||
200 | if ((ret = cxl_get_irq(afu, &irq_info))) { | ||
201 | WARN(1, "Unable to get CXL IRQ Info: %i\n", ret); | ||
202 | return fail_psl_irq(afu, &irq_info); | ||
203 | } | ||
204 | |||
205 | rcu_read_lock(); | ||
206 | ctx = idr_find(&afu->contexts_idr, ph); | ||
207 | if (ctx) { | ||
208 | ret = cxl_irq(irq, ctx, &irq_info); | ||
209 | rcu_read_unlock(); | ||
210 | return ret; | ||
211 | } | ||
212 | rcu_read_unlock(); | ||
213 | |||
214 | WARN(1, "Unable to demultiplex CXL PSL IRQ for PE %i DSISR %016llx DAR" | ||
215 | " %016llx\n(Possible AFU HW issue - was a term/remove acked" | ||
216 | " with outstanding transactions?)\n", ph, irq_info.dsisr, | ||
217 | irq_info.dar); | ||
218 | return fail_psl_irq(afu, &irq_info); | ||
219 | } | ||
220 | |||
221 | static irqreturn_t cxl_irq_afu(int irq, void *data) | 123 | static irqreturn_t cxl_irq_afu(int irq, void *data) |
222 | { | 124 | { |
223 | struct cxl_context *ctx = data; | 125 | struct cxl_context *ctx = data; |
224 | irq_hw_number_t hwirq = irqd_to_hwirq(irq_get_irq_data(irq)); | 126 | irq_hw_number_t hwirq = irqd_to_hwirq(irq_get_irq_data(irq)); |
225 | int irq_off, afu_irq = 1; | 127 | int irq_off, afu_irq = 0; |
226 | __u16 range; | 128 | __u16 range; |
227 | int r; | 129 | int r; |
228 | 130 | ||
229 | for (r = 1; r < CXL_IRQ_RANGES; r++) { | 131 | /* |
132 | * Look for the interrupt number. | ||
133 | * On bare-metal, we know range 0 only contains the PSL | ||
134 | * interrupt so we could start counting at range 1 and initialize | ||
135 | * afu_irq at 1. | ||
136 | * In a guest, range 0 also contains AFU interrupts, so it must | ||
137 | * be counted for. Therefore we initialize afu_irq at 0 to take into | ||
138 | * account the PSL interrupt. | ||
139 | * | ||
140 | * For code-readability, it just seems easier to go over all | ||
141 | * the ranges on bare-metal and guest. The end result is the same. | ||
142 | */ | ||
143 | for (r = 0; r < CXL_IRQ_RANGES; r++) { | ||
230 | irq_off = hwirq - ctx->irqs.offset[r]; | 144 | irq_off = hwirq - ctx->irqs.offset[r]; |
231 | range = ctx->irqs.range[r]; | 145 | range = ctx->irqs.range[r]; |
232 | if (irq_off >= 0 && irq_off < range) { | 146 | if (irq_off >= 0 && irq_off < range) { |
@@ -236,7 +150,7 @@ static irqreturn_t cxl_irq_afu(int irq, void *data) | |||
236 | afu_irq += range; | 150 | afu_irq += range; |
237 | } | 151 | } |
238 | if (unlikely(r >= CXL_IRQ_RANGES)) { | 152 | if (unlikely(r >= CXL_IRQ_RANGES)) { |
239 | WARN(1, "Recieved AFU IRQ out of range for pe %i (virq %i hwirq %lx)\n", | 153 | WARN(1, "Received AFU IRQ out of range for pe %i (virq %i hwirq %lx)\n", |
240 | ctx->pe, irq, hwirq); | 154 | ctx->pe, irq, hwirq); |
241 | return IRQ_HANDLED; | 155 | return IRQ_HANDLED; |
242 | } | 156 | } |
@@ -246,7 +160,7 @@ static irqreturn_t cxl_irq_afu(int irq, void *data) | |||
246 | afu_irq, ctx->pe, irq, hwirq); | 160 | afu_irq, ctx->pe, irq, hwirq); |
247 | 161 | ||
248 | if (unlikely(!ctx->irq_bitmap)) { | 162 | if (unlikely(!ctx->irq_bitmap)) { |
249 | WARN(1, "Recieved AFU IRQ for context with no IRQ bitmap\n"); | 163 | WARN(1, "Received AFU IRQ for context with no IRQ bitmap\n"); |
250 | return IRQ_HANDLED; | 164 | return IRQ_HANDLED; |
251 | } | 165 | } |
252 | spin_lock(&ctx->lock); | 166 | spin_lock(&ctx->lock); |
@@ -272,7 +186,8 @@ unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq, | |||
272 | return 0; | 186 | return 0; |
273 | } | 187 | } |
274 | 188 | ||
275 | cxl_setup_irq(adapter, hwirq, virq); | 189 | if (cxl_ops->setup_irq) |
190 | cxl_ops->setup_irq(adapter, hwirq, virq); | ||
276 | 191 | ||
277 | pr_devel("hwirq %#lx mapped to virq %u\n", hwirq, virq); | 192 | pr_devel("hwirq %#lx mapped to virq %u\n", hwirq, virq); |
278 | 193 | ||
@@ -291,16 +206,16 @@ void cxl_unmap_irq(unsigned int virq, void *cookie) | |||
291 | irq_dispose_mapping(virq); | 206 | irq_dispose_mapping(virq); |
292 | } | 207 | } |
293 | 208 | ||
294 | static int cxl_register_one_irq(struct cxl *adapter, | 209 | int cxl_register_one_irq(struct cxl *adapter, |
295 | irq_handler_t handler, | 210 | irq_handler_t handler, |
296 | void *cookie, | 211 | void *cookie, |
297 | irq_hw_number_t *dest_hwirq, | 212 | irq_hw_number_t *dest_hwirq, |
298 | unsigned int *dest_virq, | 213 | unsigned int *dest_virq, |
299 | const char *name) | 214 | const char *name) |
300 | { | 215 | { |
301 | int hwirq, virq; | 216 | int hwirq, virq; |
302 | 217 | ||
303 | if ((hwirq = cxl_alloc_one_irq(adapter)) < 0) | 218 | if ((hwirq = cxl_ops->alloc_one_irq(adapter)) < 0) |
304 | return hwirq; | 219 | return hwirq; |
305 | 220 | ||
306 | if (!(virq = cxl_map_irq(adapter, hwirq, handler, cookie, name))) | 221 | if (!(virq = cxl_map_irq(adapter, hwirq, handler, cookie, name))) |
@@ -312,108 +227,10 @@ static int cxl_register_one_irq(struct cxl *adapter, | |||
312 | return 0; | 227 | return 0; |
313 | 228 | ||
314 | err: | 229 | err: |
315 | cxl_release_one_irq(adapter, hwirq); | 230 | cxl_ops->release_one_irq(adapter, hwirq); |
316 | return -ENOMEM; | 231 | return -ENOMEM; |
317 | } | 232 | } |
318 | 233 | ||
319 | int cxl_register_psl_err_irq(struct cxl *adapter) | ||
320 | { | ||
321 | int rc; | ||
322 | |||
323 | adapter->irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err", | ||
324 | dev_name(&adapter->dev)); | ||
325 | if (!adapter->irq_name) | ||
326 | return -ENOMEM; | ||
327 | |||
328 | if ((rc = cxl_register_one_irq(adapter, cxl_irq_err, adapter, | ||
329 | &adapter->err_hwirq, | ||
330 | &adapter->err_virq, | ||
331 | adapter->irq_name))) { | ||
332 | kfree(adapter->irq_name); | ||
333 | adapter->irq_name = NULL; | ||
334 | return rc; | ||
335 | } | ||
336 | |||
337 | cxl_p1_write(adapter, CXL_PSL_ErrIVTE, adapter->err_hwirq & 0xffff); | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | void cxl_release_psl_err_irq(struct cxl *adapter) | ||
343 | { | ||
344 | if (adapter->err_virq != irq_find_mapping(NULL, adapter->err_hwirq)) | ||
345 | return; | ||
346 | |||
347 | cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000); | ||
348 | cxl_unmap_irq(adapter->err_virq, adapter); | ||
349 | cxl_release_one_irq(adapter, adapter->err_hwirq); | ||
350 | kfree(adapter->irq_name); | ||
351 | } | ||
352 | |||
353 | int cxl_register_serr_irq(struct cxl_afu *afu) | ||
354 | { | ||
355 | u64 serr; | ||
356 | int rc; | ||
357 | |||
358 | afu->err_irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err", | ||
359 | dev_name(&afu->dev)); | ||
360 | if (!afu->err_irq_name) | ||
361 | return -ENOMEM; | ||
362 | |||
363 | if ((rc = cxl_register_one_irq(afu->adapter, cxl_slice_irq_err, afu, | ||
364 | &afu->serr_hwirq, | ||
365 | &afu->serr_virq, afu->err_irq_name))) { | ||
366 | kfree(afu->err_irq_name); | ||
367 | afu->err_irq_name = NULL; | ||
368 | return rc; | ||
369 | } | ||
370 | |||
371 | serr = cxl_p1n_read(afu, CXL_PSL_SERR_An); | ||
372 | serr = (serr & 0x00ffffffffff0000ULL) | (afu->serr_hwirq & 0xffff); | ||
373 | cxl_p1n_write(afu, CXL_PSL_SERR_An, serr); | ||
374 | |||
375 | return 0; | ||
376 | } | ||
377 | |||
378 | void cxl_release_serr_irq(struct cxl_afu *afu) | ||
379 | { | ||
380 | if (afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq)) | ||
381 | return; | ||
382 | |||
383 | cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000); | ||
384 | cxl_unmap_irq(afu->serr_virq, afu); | ||
385 | cxl_release_one_irq(afu->adapter, afu->serr_hwirq); | ||
386 | kfree(afu->err_irq_name); | ||
387 | } | ||
388 | |||
389 | int cxl_register_psl_irq(struct cxl_afu *afu) | ||
390 | { | ||
391 | int rc; | ||
392 | |||
393 | afu->psl_irq_name = kasprintf(GFP_KERNEL, "cxl-%s", | ||
394 | dev_name(&afu->dev)); | ||
395 | if (!afu->psl_irq_name) | ||
396 | return -ENOMEM; | ||
397 | |||
398 | if ((rc = cxl_register_one_irq(afu->adapter, cxl_irq_multiplexed, afu, | ||
399 | &afu->psl_hwirq, &afu->psl_virq, | ||
400 | afu->psl_irq_name))) { | ||
401 | kfree(afu->psl_irq_name); | ||
402 | afu->psl_irq_name = NULL; | ||
403 | } | ||
404 | return rc; | ||
405 | } | ||
406 | |||
407 | void cxl_release_psl_irq(struct cxl_afu *afu) | ||
408 | { | ||
409 | if (afu->psl_virq != irq_find_mapping(NULL, afu->psl_hwirq)) | ||
410 | return; | ||
411 | |||
412 | cxl_unmap_irq(afu->psl_virq, afu); | ||
413 | cxl_release_one_irq(afu->adapter, afu->psl_hwirq); | ||
414 | kfree(afu->psl_irq_name); | ||
415 | } | ||
416 | |||
417 | void afu_irq_name_free(struct cxl_context *ctx) | 234 | void afu_irq_name_free(struct cxl_context *ctx) |
418 | { | 235 | { |
419 | struct cxl_irq_name *irq_name, *tmp; | 236 | struct cxl_irq_name *irq_name, *tmp; |
@@ -429,16 +246,33 @@ int afu_allocate_irqs(struct cxl_context *ctx, u32 count) | |||
429 | { | 246 | { |
430 | int rc, r, i, j = 1; | 247 | int rc, r, i, j = 1; |
431 | struct cxl_irq_name *irq_name; | 248 | struct cxl_irq_name *irq_name; |
249 | int alloc_count; | ||
250 | |||
251 | /* | ||
252 | * In native mode, range 0 is reserved for the multiplexed | ||
253 | * PSL interrupt. It has been allocated when the AFU was initialized. | ||
254 | * | ||
255 | * In a guest, the PSL interrupt is not mutliplexed, but per-context, | ||
256 | * and is the first interrupt from range 0. It still needs to be | ||
257 | * allocated, so bump the count by one. | ||
258 | */ | ||
259 | if (cpu_has_feature(CPU_FTR_HVMODE)) | ||
260 | alloc_count = count; | ||
261 | else | ||
262 | alloc_count = count + 1; | ||
432 | 263 | ||
433 | /* Initialize the list head to hold irq names */ | 264 | /* Initialize the list head to hold irq names */ |
434 | INIT_LIST_HEAD(&ctx->irq_names); | 265 | INIT_LIST_HEAD(&ctx->irq_names); |
435 | 266 | ||
436 | if ((rc = cxl_alloc_irq_ranges(&ctx->irqs, ctx->afu->adapter, count))) | 267 | if ((rc = cxl_ops->alloc_irq_ranges(&ctx->irqs, ctx->afu->adapter, |
268 | alloc_count))) | ||
437 | return rc; | 269 | return rc; |
438 | 270 | ||
439 | /* Multiplexed PSL Interrupt */ | 271 | if (cpu_has_feature(CPU_FTR_HVMODE)) { |
440 | ctx->irqs.offset[0] = ctx->afu->psl_hwirq; | 272 | /* Multiplexed PSL Interrupt */ |
441 | ctx->irqs.range[0] = 1; | 273 | ctx->irqs.offset[0] = ctx->afu->native->psl_hwirq; |
274 | ctx->irqs.range[0] = 1; | ||
275 | } | ||
442 | 276 | ||
443 | ctx->irq_count = count; | 277 | ctx->irq_count = count; |
444 | ctx->irq_bitmap = kcalloc(BITS_TO_LONGS(count), | 278 | ctx->irq_bitmap = kcalloc(BITS_TO_LONGS(count), |
@@ -450,7 +284,7 @@ int afu_allocate_irqs(struct cxl_context *ctx, u32 count) | |||
450 | * Allocate names first. If any fail, bail out before allocating | 284 | * Allocate names first. If any fail, bail out before allocating |
451 | * actual hardware IRQs. | 285 | * actual hardware IRQs. |
452 | */ | 286 | */ |
453 | for (r = 1; r < CXL_IRQ_RANGES; r++) { | 287 | for (r = afu_irq_range_start(); r < CXL_IRQ_RANGES; r++) { |
454 | for (i = 0; i < ctx->irqs.range[r]; i++) { | 288 | for (i = 0; i < ctx->irqs.range[r]; i++) { |
455 | irq_name = kmalloc(sizeof(struct cxl_irq_name), | 289 | irq_name = kmalloc(sizeof(struct cxl_irq_name), |
456 | GFP_KERNEL); | 290 | GFP_KERNEL); |
@@ -471,7 +305,7 @@ int afu_allocate_irqs(struct cxl_context *ctx, u32 count) | |||
471 | return 0; | 305 | return 0; |
472 | 306 | ||
473 | out: | 307 | out: |
474 | cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter); | 308 | cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter); |
475 | afu_irq_name_free(ctx); | 309 | afu_irq_name_free(ctx); |
476 | return -ENOMEM; | 310 | return -ENOMEM; |
477 | } | 311 | } |
@@ -480,15 +314,30 @@ static void afu_register_hwirqs(struct cxl_context *ctx) | |||
480 | { | 314 | { |
481 | irq_hw_number_t hwirq; | 315 | irq_hw_number_t hwirq; |
482 | struct cxl_irq_name *irq_name; | 316 | struct cxl_irq_name *irq_name; |
483 | int r,i; | 317 | int r, i; |
318 | irqreturn_t (*handler)(int irq, void *data); | ||
484 | 319 | ||
485 | /* We've allocated all memory now, so let's do the irq allocations */ | 320 | /* We've allocated all memory now, so let's do the irq allocations */ |
486 | irq_name = list_first_entry(&ctx->irq_names, struct cxl_irq_name, list); | 321 | irq_name = list_first_entry(&ctx->irq_names, struct cxl_irq_name, list); |
487 | for (r = 1; r < CXL_IRQ_RANGES; r++) { | 322 | for (r = afu_irq_range_start(); r < CXL_IRQ_RANGES; r++) { |
488 | hwirq = ctx->irqs.offset[r]; | 323 | hwirq = ctx->irqs.offset[r]; |
489 | for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) { | 324 | for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) { |
490 | cxl_map_irq(ctx->afu->adapter, hwirq, | 325 | if (r == 0 && i == 0) |
491 | cxl_irq_afu, ctx, irq_name->name); | 326 | /* |
327 | * The very first interrupt of range 0 is | ||
328 | * always the PSL interrupt, but we only | ||
329 | * need to connect a handler for guests, | ||
330 | * because there's one PSL interrupt per | ||
331 | * context. | ||
332 | * On bare-metal, the PSL interrupt is | ||
333 | * multiplexed and was setup when the AFU | ||
334 | * was configured. | ||
335 | */ | ||
336 | handler = cxl_ops->psl_interrupt; | ||
337 | else | ||
338 | handler = cxl_irq_afu; | ||
339 | cxl_map_irq(ctx->afu->adapter, hwirq, handler, ctx, | ||
340 | irq_name->name); | ||
492 | irq_name = list_next_entry(irq_name, list); | 341 | irq_name = list_next_entry(irq_name, list); |
493 | } | 342 | } |
494 | } | 343 | } |
@@ -504,7 +353,7 @@ int afu_register_irqs(struct cxl_context *ctx, u32 count) | |||
504 | 353 | ||
505 | afu_register_hwirqs(ctx); | 354 | afu_register_hwirqs(ctx); |
506 | return 0; | 355 | return 0; |
507 | } | 356 | } |
508 | 357 | ||
509 | void afu_release_irqs(struct cxl_context *ctx, void *cookie) | 358 | void afu_release_irqs(struct cxl_context *ctx, void *cookie) |
510 | { | 359 | { |
@@ -512,7 +361,7 @@ void afu_release_irqs(struct cxl_context *ctx, void *cookie) | |||
512 | unsigned int virq; | 361 | unsigned int virq; |
513 | int r, i; | 362 | int r, i; |
514 | 363 | ||
515 | for (r = 1; r < CXL_IRQ_RANGES; r++) { | 364 | for (r = afu_irq_range_start(); r < CXL_IRQ_RANGES; r++) { |
516 | hwirq = ctx->irqs.offset[r]; | 365 | hwirq = ctx->irqs.offset[r]; |
517 | for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) { | 366 | for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) { |
518 | virq = irq_find_mapping(NULL, hwirq); | 367 | virq = irq_find_mapping(NULL, hwirq); |
@@ -522,7 +371,7 @@ void afu_release_irqs(struct cxl_context *ctx, void *cookie) | |||
522 | } | 371 | } |
523 | 372 | ||
524 | afu_irq_name_free(ctx); | 373 | afu_irq_name_free(ctx); |
525 | cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter); | 374 | cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter); |
526 | 375 | ||
527 | ctx->irq_count = 0; | 376 | ctx->irq_count = 0; |
528 | } | 377 | } |
diff --git a/drivers/misc/cxl/main.c b/drivers/misc/cxl/main.c index 9fde75ed4fac..ae68c3201156 100644 --- a/drivers/misc/cxl/main.c +++ b/drivers/misc/cxl/main.c | |||
@@ -32,6 +32,29 @@ uint cxl_verbose; | |||
32 | module_param_named(verbose, cxl_verbose, uint, 0600); | 32 | module_param_named(verbose, cxl_verbose, uint, 0600); |
33 | MODULE_PARM_DESC(verbose, "Enable verbose dmesg output"); | 33 | MODULE_PARM_DESC(verbose, "Enable verbose dmesg output"); |
34 | 34 | ||
35 | const struct cxl_backend_ops *cxl_ops; | ||
36 | |||
37 | int cxl_afu_slbia(struct cxl_afu *afu) | ||
38 | { | ||
39 | unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT); | ||
40 | |||
41 | pr_devel("cxl_afu_slbia issuing SLBIA command\n"); | ||
42 | cxl_p2n_write(afu, CXL_SLBIA_An, CXL_TLB_SLB_IQ_ALL); | ||
43 | while (cxl_p2n_read(afu, CXL_SLBIA_An) & CXL_TLB_SLB_P) { | ||
44 | if (time_after_eq(jiffies, timeout)) { | ||
45 | dev_warn(&afu->dev, "WARNING: CXL AFU SLBIA timed out!\n"); | ||
46 | return -EBUSY; | ||
47 | } | ||
48 | /* If the adapter has gone down, we can assume that we | ||
49 | * will PERST it and that will invalidate everything. | ||
50 | */ | ||
51 | if (!cxl_ops->link_ok(afu->adapter, afu)) | ||
52 | return -EIO; | ||
53 | cpu_relax(); | ||
54 | } | ||
55 | return 0; | ||
56 | } | ||
57 | |||
35 | static inline void _cxl_slbia(struct cxl_context *ctx, struct mm_struct *mm) | 58 | static inline void _cxl_slbia(struct cxl_context *ctx, struct mm_struct *mm) |
36 | { | 59 | { |
37 | struct task_struct *task; | 60 | struct task_struct *task; |
@@ -139,6 +162,32 @@ int cxl_alloc_sst(struct cxl_context *ctx) | |||
139 | return 0; | 162 | return 0; |
140 | } | 163 | } |
141 | 164 | ||
165 | /* print buffer content as integers when debugging */ | ||
166 | void cxl_dump_debug_buffer(void *buf, size_t buf_len) | ||
167 | { | ||
168 | #ifdef DEBUG | ||
169 | int i, *ptr; | ||
170 | |||
171 | /* | ||
172 | * We want to regroup up to 4 integers per line, which means they | ||
173 | * need to be in the same pr_devel() statement | ||
174 | */ | ||
175 | ptr = (int *) buf; | ||
176 | for (i = 0; i * 4 < buf_len; i += 4) { | ||
177 | if ((i + 3) * 4 < buf_len) | ||
178 | pr_devel("%.8x %.8x %.8x %.8x\n", ptr[i], ptr[i + 1], | ||
179 | ptr[i + 2], ptr[i + 3]); | ||
180 | else if ((i + 2) * 4 < buf_len) | ||
181 | pr_devel("%.8x %.8x %.8x\n", ptr[i], ptr[i + 1], | ||
182 | ptr[i + 2]); | ||
183 | else if ((i + 1) * 4 < buf_len) | ||
184 | pr_devel("%.8x %.8x\n", ptr[i], ptr[i + 1]); | ||
185 | else | ||
186 | pr_devel("%.8x\n", ptr[i]); | ||
187 | } | ||
188 | #endif /* DEBUG */ | ||
189 | } | ||
190 | |||
142 | /* Find a CXL adapter by it's number and increase it's refcount */ | 191 | /* Find a CXL adapter by it's number and increase it's refcount */ |
143 | struct cxl *get_cxl_adapter(int num) | 192 | struct cxl *get_cxl_adapter(int num) |
144 | { | 193 | { |
@@ -152,7 +201,7 @@ struct cxl *get_cxl_adapter(int num) | |||
152 | return adapter; | 201 | return adapter; |
153 | } | 202 | } |
154 | 203 | ||
155 | int cxl_alloc_adapter_nr(struct cxl *adapter) | 204 | static int cxl_alloc_adapter_nr(struct cxl *adapter) |
156 | { | 205 | { |
157 | int i; | 206 | int i; |
158 | 207 | ||
@@ -174,13 +223,58 @@ void cxl_remove_adapter_nr(struct cxl *adapter) | |||
174 | idr_remove(&cxl_adapter_idr, adapter->adapter_num); | 223 | idr_remove(&cxl_adapter_idr, adapter->adapter_num); |
175 | } | 224 | } |
176 | 225 | ||
226 | struct cxl *cxl_alloc_adapter(void) | ||
227 | { | ||
228 | struct cxl *adapter; | ||
229 | |||
230 | if (!(adapter = kzalloc(sizeof(struct cxl), GFP_KERNEL))) | ||
231 | return NULL; | ||
232 | |||
233 | spin_lock_init(&adapter->afu_list_lock); | ||
234 | |||
235 | if (cxl_alloc_adapter_nr(adapter)) | ||
236 | goto err1; | ||
237 | |||
238 | if (dev_set_name(&adapter->dev, "card%i", adapter->adapter_num)) | ||
239 | goto err2; | ||
240 | |||
241 | return adapter; | ||
242 | |||
243 | err2: | ||
244 | cxl_remove_adapter_nr(adapter); | ||
245 | err1: | ||
246 | kfree(adapter); | ||
247 | return NULL; | ||
248 | } | ||
249 | |||
250 | struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice) | ||
251 | { | ||
252 | struct cxl_afu *afu; | ||
253 | |||
254 | if (!(afu = kzalloc(sizeof(struct cxl_afu), GFP_KERNEL))) | ||
255 | return NULL; | ||
256 | |||
257 | afu->adapter = adapter; | ||
258 | afu->dev.parent = &adapter->dev; | ||
259 | afu->dev.release = cxl_ops->release_afu; | ||
260 | afu->slice = slice; | ||
261 | idr_init(&afu->contexts_idr); | ||
262 | mutex_init(&afu->contexts_lock); | ||
263 | spin_lock_init(&afu->afu_cntl_lock); | ||
264 | |||
265 | afu->prefault_mode = CXL_PREFAULT_NONE; | ||
266 | afu->irqs_max = afu->adapter->user_irqs; | ||
267 | |||
268 | return afu; | ||
269 | } | ||
270 | |||
177 | int cxl_afu_select_best_mode(struct cxl_afu *afu) | 271 | int cxl_afu_select_best_mode(struct cxl_afu *afu) |
178 | { | 272 | { |
179 | if (afu->modes_supported & CXL_MODE_DIRECTED) | 273 | if (afu->modes_supported & CXL_MODE_DIRECTED) |
180 | return cxl_afu_activate_mode(afu, CXL_MODE_DIRECTED); | 274 | return cxl_ops->afu_activate_mode(afu, CXL_MODE_DIRECTED); |
181 | 275 | ||
182 | if (afu->modes_supported & CXL_MODE_DEDICATED) | 276 | if (afu->modes_supported & CXL_MODE_DEDICATED) |
183 | return cxl_afu_activate_mode(afu, CXL_MODE_DEDICATED); | 277 | return cxl_ops->afu_activate_mode(afu, CXL_MODE_DEDICATED); |
184 | 278 | ||
185 | dev_warn(&afu->dev, "No supported programming modes available\n"); | 279 | dev_warn(&afu->dev, "No supported programming modes available\n"); |
186 | /* We don't fail this so the user can inspect sysfs */ | 280 | /* We don't fail this so the user can inspect sysfs */ |
@@ -191,9 +285,6 @@ static int __init init_cxl(void) | |||
191 | { | 285 | { |
192 | int rc = 0; | 286 | int rc = 0; |
193 | 287 | ||
194 | if (!cpu_has_feature(CPU_FTR_HVMODE)) | ||
195 | return -EPERM; | ||
196 | |||
197 | if ((rc = cxl_file_init())) | 288 | if ((rc = cxl_file_init())) |
198 | return rc; | 289 | return rc; |
199 | 290 | ||
@@ -202,7 +293,17 @@ static int __init init_cxl(void) | |||
202 | if ((rc = register_cxl_calls(&cxl_calls))) | 293 | if ((rc = register_cxl_calls(&cxl_calls))) |
203 | goto err; | 294 | goto err; |
204 | 295 | ||
205 | if ((rc = pci_register_driver(&cxl_pci_driver))) | 296 | if (cpu_has_feature(CPU_FTR_HVMODE)) { |
297 | cxl_ops = &cxl_native_ops; | ||
298 | rc = pci_register_driver(&cxl_pci_driver); | ||
299 | } | ||
300 | #ifdef CONFIG_PPC_PSERIES | ||
301 | else { | ||
302 | cxl_ops = &cxl_guest_ops; | ||
303 | rc = platform_driver_register(&cxl_of_driver); | ||
304 | } | ||
305 | #endif | ||
306 | if (rc) | ||
206 | goto err1; | 307 | goto err1; |
207 | 308 | ||
208 | return 0; | 309 | return 0; |
@@ -217,7 +318,12 @@ err: | |||
217 | 318 | ||
218 | static void exit_cxl(void) | 319 | static void exit_cxl(void) |
219 | { | 320 | { |
220 | pci_unregister_driver(&cxl_pci_driver); | 321 | if (cpu_has_feature(CPU_FTR_HVMODE)) |
322 | pci_unregister_driver(&cxl_pci_driver); | ||
323 | #ifdef CONFIG_PPC_PSERIES | ||
324 | else | ||
325 | platform_driver_unregister(&cxl_of_driver); | ||
326 | #endif | ||
221 | 327 | ||
222 | cxl_debugfs_exit(); | 328 | cxl_debugfs_exit(); |
223 | cxl_file_exit(); | 329 | cxl_file_exit(); |
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index f40909793490..387fcbdf9793 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c | |||
@@ -42,7 +42,7 @@ static int afu_control(struct cxl_afu *afu, u64 command, | |||
42 | goto out; | 42 | goto out; |
43 | } | 43 | } |
44 | 44 | ||
45 | if (!cxl_adapter_link_ok(afu->adapter)) { | 45 | if (!cxl_ops->link_ok(afu->adapter, afu)) { |
46 | afu->enabled = enabled; | 46 | afu->enabled = enabled; |
47 | rc = -EIO; | 47 | rc = -EIO; |
48 | goto out; | 48 | goto out; |
@@ -80,7 +80,7 @@ int cxl_afu_disable(struct cxl_afu *afu) | |||
80 | } | 80 | } |
81 | 81 | ||
82 | /* This will disable as well as reset */ | 82 | /* This will disable as well as reset */ |
83 | int __cxl_afu_reset(struct cxl_afu *afu) | 83 | static int native_afu_reset(struct cxl_afu *afu) |
84 | { | 84 | { |
85 | pr_devel("AFU reset request\n"); | 85 | pr_devel("AFU reset request\n"); |
86 | 86 | ||
@@ -90,9 +90,9 @@ int __cxl_afu_reset(struct cxl_afu *afu) | |||
90 | false); | 90 | false); |
91 | } | 91 | } |
92 | 92 | ||
93 | int cxl_afu_check_and_enable(struct cxl_afu *afu) | 93 | static int native_afu_check_and_enable(struct cxl_afu *afu) |
94 | { | 94 | { |
95 | if (!cxl_adapter_link_ok(afu->adapter)) { | 95 | if (!cxl_ops->link_ok(afu->adapter, afu)) { |
96 | WARN(1, "Refusing to enable afu while link down!\n"); | 96 | WARN(1, "Refusing to enable afu while link down!\n"); |
97 | return -EIO; | 97 | return -EIO; |
98 | } | 98 | } |
@@ -114,7 +114,7 @@ int cxl_psl_purge(struct cxl_afu *afu) | |||
114 | 114 | ||
115 | pr_devel("PSL purge request\n"); | 115 | pr_devel("PSL purge request\n"); |
116 | 116 | ||
117 | if (!cxl_adapter_link_ok(afu->adapter)) { | 117 | if (!cxl_ops->link_ok(afu->adapter, afu)) { |
118 | dev_warn(&afu->dev, "PSL Purge called with link down, ignoring\n"); | 118 | dev_warn(&afu->dev, "PSL Purge called with link down, ignoring\n"); |
119 | rc = -EIO; | 119 | rc = -EIO; |
120 | goto out; | 120 | goto out; |
@@ -136,7 +136,7 @@ int cxl_psl_purge(struct cxl_afu *afu) | |||
136 | rc = -EBUSY; | 136 | rc = -EBUSY; |
137 | goto out; | 137 | goto out; |
138 | } | 138 | } |
139 | if (!cxl_adapter_link_ok(afu->adapter)) { | 139 | if (!cxl_ops->link_ok(afu->adapter, afu)) { |
140 | rc = -EIO; | 140 | rc = -EIO; |
141 | goto out; | 141 | goto out; |
142 | } | 142 | } |
@@ -186,22 +186,22 @@ static int spa_max_procs(int spa_size) | |||
186 | int cxl_alloc_spa(struct cxl_afu *afu) | 186 | int cxl_alloc_spa(struct cxl_afu *afu) |
187 | { | 187 | { |
188 | /* Work out how many pages to allocate */ | 188 | /* Work out how many pages to allocate */ |
189 | afu->spa_order = 0; | 189 | afu->native->spa_order = 0; |
190 | do { | 190 | do { |
191 | afu->spa_order++; | 191 | afu->native->spa_order++; |
192 | afu->spa_size = (1 << afu->spa_order) * PAGE_SIZE; | 192 | afu->native->spa_size = (1 << afu->native->spa_order) * PAGE_SIZE; |
193 | afu->spa_max_procs = spa_max_procs(afu->spa_size); | 193 | afu->native->spa_max_procs = spa_max_procs(afu->native->spa_size); |
194 | } while (afu->spa_max_procs < afu->num_procs); | 194 | } while (afu->native->spa_max_procs < afu->num_procs); |
195 | 195 | ||
196 | WARN_ON(afu->spa_size > 0x100000); /* Max size supported by the hardware */ | 196 | WARN_ON(afu->native->spa_size > 0x100000); /* Max size supported by the hardware */ |
197 | 197 | ||
198 | if (!(afu->spa = (struct cxl_process_element *) | 198 | if (!(afu->native->spa = (struct cxl_process_element *) |
199 | __get_free_pages(GFP_KERNEL | __GFP_ZERO, afu->spa_order))) { | 199 | __get_free_pages(GFP_KERNEL | __GFP_ZERO, afu->native->spa_order))) { |
200 | pr_err("cxl_alloc_spa: Unable to allocate scheduled process area\n"); | 200 | pr_err("cxl_alloc_spa: Unable to allocate scheduled process area\n"); |
201 | return -ENOMEM; | 201 | return -ENOMEM; |
202 | } | 202 | } |
203 | pr_devel("spa pages: %i afu->spa_max_procs: %i afu->num_procs: %i\n", | 203 | pr_devel("spa pages: %i afu->spa_max_procs: %i afu->num_procs: %i\n", |
204 | 1<<afu->spa_order, afu->spa_max_procs, afu->num_procs); | 204 | 1<<afu->native->spa_order, afu->native->spa_max_procs, afu->num_procs); |
205 | 205 | ||
206 | return 0; | 206 | return 0; |
207 | } | 207 | } |
@@ -210,13 +210,15 @@ static void attach_spa(struct cxl_afu *afu) | |||
210 | { | 210 | { |
211 | u64 spap; | 211 | u64 spap; |
212 | 212 | ||
213 | afu->sw_command_status = (__be64 *)((char *)afu->spa + | 213 | afu->native->sw_command_status = (__be64 *)((char *)afu->native->spa + |
214 | ((afu->spa_max_procs + 3) * 128)); | 214 | ((afu->native->spa_max_procs + 3) * 128)); |
215 | 215 | ||
216 | spap = virt_to_phys(afu->spa) & CXL_PSL_SPAP_Addr; | 216 | spap = virt_to_phys(afu->native->spa) & CXL_PSL_SPAP_Addr; |
217 | spap |= ((afu->spa_size >> (12 - CXL_PSL_SPAP_Size_Shift)) - 1) & CXL_PSL_SPAP_Size; | 217 | spap |= ((afu->native->spa_size >> (12 - CXL_PSL_SPAP_Size_Shift)) - 1) & CXL_PSL_SPAP_Size; |
218 | spap |= CXL_PSL_SPAP_V; | 218 | spap |= CXL_PSL_SPAP_V; |
219 | pr_devel("cxl: SPA allocated at 0x%p. Max processes: %i, sw_command_status: 0x%p CXL_PSL_SPAP_An=0x%016llx\n", afu->spa, afu->spa_max_procs, afu->sw_command_status, spap); | 219 | pr_devel("cxl: SPA allocated at 0x%p. Max processes: %i, sw_command_status: 0x%p CXL_PSL_SPAP_An=0x%016llx\n", |
220 | afu->native->spa, afu->native->spa_max_procs, | ||
221 | afu->native->sw_command_status, spap); | ||
220 | cxl_p1n_write(afu, CXL_PSL_SPAP_An, spap); | 222 | cxl_p1n_write(afu, CXL_PSL_SPAP_An, spap); |
221 | } | 223 | } |
222 | 224 | ||
@@ -227,9 +229,10 @@ static inline void detach_spa(struct cxl_afu *afu) | |||
227 | 229 | ||
228 | void cxl_release_spa(struct cxl_afu *afu) | 230 | void cxl_release_spa(struct cxl_afu *afu) |
229 | { | 231 | { |
230 | if (afu->spa) { | 232 | if (afu->native->spa) { |
231 | free_pages((unsigned long) afu->spa, afu->spa_order); | 233 | free_pages((unsigned long) afu->native->spa, |
232 | afu->spa = NULL; | 234 | afu->native->spa_order); |
235 | afu->native->spa = NULL; | ||
233 | } | 236 | } |
234 | } | 237 | } |
235 | 238 | ||
@@ -247,7 +250,7 @@ int cxl_tlb_slb_invalidate(struct cxl *adapter) | |||
247 | dev_warn(&adapter->dev, "WARNING: CXL adapter wide TLBIA timed out!\n"); | 250 | dev_warn(&adapter->dev, "WARNING: CXL adapter wide TLBIA timed out!\n"); |
248 | return -EBUSY; | 251 | return -EBUSY; |
249 | } | 252 | } |
250 | if (!cxl_adapter_link_ok(adapter)) | 253 | if (!cxl_ops->link_ok(adapter, NULL)) |
251 | return -EIO; | 254 | return -EIO; |
252 | cpu_relax(); | 255 | cpu_relax(); |
253 | } | 256 | } |
@@ -258,28 +261,7 @@ int cxl_tlb_slb_invalidate(struct cxl *adapter) | |||
258 | dev_warn(&adapter->dev, "WARNING: CXL adapter wide SLBIA timed out!\n"); | 261 | dev_warn(&adapter->dev, "WARNING: CXL adapter wide SLBIA timed out!\n"); |
259 | return -EBUSY; | 262 | return -EBUSY; |
260 | } | 263 | } |
261 | if (!cxl_adapter_link_ok(adapter)) | 264 | if (!cxl_ops->link_ok(adapter, NULL)) |
262 | return -EIO; | ||
263 | cpu_relax(); | ||
264 | } | ||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | int cxl_afu_slbia(struct cxl_afu *afu) | ||
269 | { | ||
270 | unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT); | ||
271 | |||
272 | pr_devel("cxl_afu_slbia issuing SLBIA command\n"); | ||
273 | cxl_p2n_write(afu, CXL_SLBIA_An, CXL_TLB_SLB_IQ_ALL); | ||
274 | while (cxl_p2n_read(afu, CXL_SLBIA_An) & CXL_TLB_SLB_P) { | ||
275 | if (time_after_eq(jiffies, timeout)) { | ||
276 | dev_warn(&afu->dev, "WARNING: CXL AFU SLBIA timed out!\n"); | ||
277 | return -EBUSY; | ||
278 | } | ||
279 | /* If the adapter has gone down, we can assume that we | ||
280 | * will PERST it and that will invalidate everything. | ||
281 | */ | ||
282 | if (!cxl_adapter_link_ok(afu->adapter)) | ||
283 | return -EIO; | 265 | return -EIO; |
284 | cpu_relax(); | 266 | cpu_relax(); |
285 | } | 267 | } |
@@ -312,7 +294,7 @@ static void slb_invalid(struct cxl_context *ctx) | |||
312 | struct cxl *adapter = ctx->afu->adapter; | 294 | struct cxl *adapter = ctx->afu->adapter; |
313 | u64 slbia; | 295 | u64 slbia; |
314 | 296 | ||
315 | WARN_ON(!mutex_is_locked(&ctx->afu->spa_mutex)); | 297 | WARN_ON(!mutex_is_locked(&ctx->afu->native->spa_mutex)); |
316 | 298 | ||
317 | cxl_p1_write(adapter, CXL_PSL_LBISEL, | 299 | cxl_p1_write(adapter, CXL_PSL_LBISEL, |
318 | ((u64)be32_to_cpu(ctx->elem->common.pid) << 32) | | 300 | ((u64)be32_to_cpu(ctx->elem->common.pid) << 32) | |
@@ -320,7 +302,7 @@ static void slb_invalid(struct cxl_context *ctx) | |||
320 | cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_LPIDPID); | 302 | cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_LPIDPID); |
321 | 303 | ||
322 | while (1) { | 304 | while (1) { |
323 | if (!cxl_adapter_link_ok(adapter)) | 305 | if (!cxl_ops->link_ok(adapter, NULL)) |
324 | break; | 306 | break; |
325 | slbia = cxl_p1_read(adapter, CXL_PSL_SLBIA); | 307 | slbia = cxl_p1_read(adapter, CXL_PSL_SLBIA); |
326 | if (!(slbia & CXL_TLB_SLB_P)) | 308 | if (!(slbia & CXL_TLB_SLB_P)) |
@@ -342,7 +324,7 @@ static int do_process_element_cmd(struct cxl_context *ctx, | |||
342 | 324 | ||
343 | ctx->elem->software_state = cpu_to_be32(pe_state); | 325 | ctx->elem->software_state = cpu_to_be32(pe_state); |
344 | smp_wmb(); | 326 | smp_wmb(); |
345 | *(ctx->afu->sw_command_status) = cpu_to_be64(cmd | 0 | ctx->pe); | 327 | *(ctx->afu->native->sw_command_status) = cpu_to_be64(cmd | 0 | ctx->pe); |
346 | smp_mb(); | 328 | smp_mb(); |
347 | cxl_p1n_write(ctx->afu, CXL_PSL_LLCMD_An, cmd | ctx->pe); | 329 | cxl_p1n_write(ctx->afu, CXL_PSL_LLCMD_An, cmd | ctx->pe); |
348 | while (1) { | 330 | while (1) { |
@@ -351,12 +333,12 @@ static int do_process_element_cmd(struct cxl_context *ctx, | |||
351 | rc = -EBUSY; | 333 | rc = -EBUSY; |
352 | goto out; | 334 | goto out; |
353 | } | 335 | } |
354 | if (!cxl_adapter_link_ok(ctx->afu->adapter)) { | 336 | if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) { |
355 | dev_warn(&ctx->afu->dev, "WARNING: Device link down, aborting Process Element Command!\n"); | 337 | dev_warn(&ctx->afu->dev, "WARNING: Device link down, aborting Process Element Command!\n"); |
356 | rc = -EIO; | 338 | rc = -EIO; |
357 | goto out; | 339 | goto out; |
358 | } | 340 | } |
359 | state = be64_to_cpup(ctx->afu->sw_command_status); | 341 | state = be64_to_cpup(ctx->afu->native->sw_command_status); |
360 | if (state == ~0ULL) { | 342 | if (state == ~0ULL) { |
361 | pr_err("cxl: Error adding process element to AFU\n"); | 343 | pr_err("cxl: Error adding process element to AFU\n"); |
362 | rc = -1; | 344 | rc = -1; |
@@ -384,12 +366,12 @@ static int add_process_element(struct cxl_context *ctx) | |||
384 | { | 366 | { |
385 | int rc = 0; | 367 | int rc = 0; |
386 | 368 | ||
387 | mutex_lock(&ctx->afu->spa_mutex); | 369 | mutex_lock(&ctx->afu->native->spa_mutex); |
388 | pr_devel("%s Adding pe: %i started\n", __func__, ctx->pe); | 370 | pr_devel("%s Adding pe: %i started\n", __func__, ctx->pe); |
389 | if (!(rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_ADD, CXL_PE_SOFTWARE_STATE_V))) | 371 | if (!(rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_ADD, CXL_PE_SOFTWARE_STATE_V))) |
390 | ctx->pe_inserted = true; | 372 | ctx->pe_inserted = true; |
391 | pr_devel("%s Adding pe: %i finished\n", __func__, ctx->pe); | 373 | pr_devel("%s Adding pe: %i finished\n", __func__, ctx->pe); |
392 | mutex_unlock(&ctx->afu->spa_mutex); | 374 | mutex_unlock(&ctx->afu->native->spa_mutex); |
393 | return rc; | 375 | return rc; |
394 | } | 376 | } |
395 | 377 | ||
@@ -401,18 +383,18 @@ static int terminate_process_element(struct cxl_context *ctx) | |||
401 | if (!(ctx->elem->software_state & cpu_to_be32(CXL_PE_SOFTWARE_STATE_V))) | 383 | if (!(ctx->elem->software_state & cpu_to_be32(CXL_PE_SOFTWARE_STATE_V))) |
402 | return rc; | 384 | return rc; |
403 | 385 | ||
404 | mutex_lock(&ctx->afu->spa_mutex); | 386 | mutex_lock(&ctx->afu->native->spa_mutex); |
405 | pr_devel("%s Terminate pe: %i started\n", __func__, ctx->pe); | 387 | pr_devel("%s Terminate pe: %i started\n", __func__, ctx->pe); |
406 | /* We could be asked to terminate when the hw is down. That | 388 | /* We could be asked to terminate when the hw is down. That |
407 | * should always succeed: it's not running if the hw has gone | 389 | * should always succeed: it's not running if the hw has gone |
408 | * away and is being reset. | 390 | * away and is being reset. |
409 | */ | 391 | */ |
410 | if (cxl_adapter_link_ok(ctx->afu->adapter)) | 392 | if (cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) |
411 | rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_TERMINATE, | 393 | rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_TERMINATE, |
412 | CXL_PE_SOFTWARE_STATE_V | CXL_PE_SOFTWARE_STATE_T); | 394 | CXL_PE_SOFTWARE_STATE_V | CXL_PE_SOFTWARE_STATE_T); |
413 | ctx->elem->software_state = 0; /* Remove Valid bit */ | 395 | ctx->elem->software_state = 0; /* Remove Valid bit */ |
414 | pr_devel("%s Terminate pe: %i finished\n", __func__, ctx->pe); | 396 | pr_devel("%s Terminate pe: %i finished\n", __func__, ctx->pe); |
415 | mutex_unlock(&ctx->afu->spa_mutex); | 397 | mutex_unlock(&ctx->afu->native->spa_mutex); |
416 | return rc; | 398 | return rc; |
417 | } | 399 | } |
418 | 400 | ||
@@ -420,20 +402,20 @@ static int remove_process_element(struct cxl_context *ctx) | |||
420 | { | 402 | { |
421 | int rc = 0; | 403 | int rc = 0; |
422 | 404 | ||
423 | mutex_lock(&ctx->afu->spa_mutex); | 405 | mutex_lock(&ctx->afu->native->spa_mutex); |
424 | pr_devel("%s Remove pe: %i started\n", __func__, ctx->pe); | 406 | pr_devel("%s Remove pe: %i started\n", __func__, ctx->pe); |
425 | 407 | ||
426 | /* We could be asked to remove when the hw is down. Again, if | 408 | /* We could be asked to remove when the hw is down. Again, if |
427 | * the hw is down, the PE is gone, so we succeed. | 409 | * the hw is down, the PE is gone, so we succeed. |
428 | */ | 410 | */ |
429 | if (cxl_adapter_link_ok(ctx->afu->adapter)) | 411 | if (cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) |
430 | rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_REMOVE, 0); | 412 | rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_REMOVE, 0); |
431 | 413 | ||
432 | if (!rc) | 414 | if (!rc) |
433 | ctx->pe_inserted = false; | 415 | ctx->pe_inserted = false; |
434 | slb_invalid(ctx); | 416 | slb_invalid(ctx); |
435 | pr_devel("%s Remove pe: %i finished\n", __func__, ctx->pe); | 417 | pr_devel("%s Remove pe: %i finished\n", __func__, ctx->pe); |
436 | mutex_unlock(&ctx->afu->spa_mutex); | 418 | mutex_unlock(&ctx->afu->native->spa_mutex); |
437 | 419 | ||
438 | return rc; | 420 | return rc; |
439 | } | 421 | } |
@@ -446,7 +428,7 @@ void cxl_assign_psn_space(struct cxl_context *ctx) | |||
446 | ctx->psn_size = ctx->afu->adapter->ps_size; | 428 | ctx->psn_size = ctx->afu->adapter->ps_size; |
447 | } else { | 429 | } else { |
448 | ctx->psn_phys = ctx->afu->psn_phys + | 430 | ctx->psn_phys = ctx->afu->psn_phys + |
449 | (ctx->afu->pp_offset + ctx->afu->pp_size * ctx->pe); | 431 | (ctx->afu->native->pp_offset + ctx->afu->pp_size * ctx->pe); |
450 | ctx->psn_size = ctx->afu->pp_size; | 432 | ctx->psn_size = ctx->afu->pp_size; |
451 | } | 433 | } |
452 | } | 434 | } |
@@ -458,7 +440,7 @@ static int activate_afu_directed(struct cxl_afu *afu) | |||
458 | dev_info(&afu->dev, "Activating AFU directed mode\n"); | 440 | dev_info(&afu->dev, "Activating AFU directed mode\n"); |
459 | 441 | ||
460 | afu->num_procs = afu->max_procs_virtualised; | 442 | afu->num_procs = afu->max_procs_virtualised; |
461 | if (afu->spa == NULL) { | 443 | if (afu->native->spa == NULL) { |
462 | if (cxl_alloc_spa(afu)) | 444 | if (cxl_alloc_spa(afu)) |
463 | return -ENOMEM; | 445 | return -ENOMEM; |
464 | } | 446 | } |
@@ -552,7 +534,7 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr) | |||
552 | ctx->elem->common.wed = cpu_to_be64(wed); | 534 | ctx->elem->common.wed = cpu_to_be64(wed); |
553 | 535 | ||
554 | /* first guy needs to enable */ | 536 | /* first guy needs to enable */ |
555 | if ((result = cxl_afu_check_and_enable(ctx->afu))) | 537 | if ((result = cxl_ops->afu_check_and_enable(ctx->afu))) |
556 | return result; | 538 | return result; |
557 | 539 | ||
558 | return add_process_element(ctx); | 540 | return add_process_element(ctx); |
@@ -568,7 +550,7 @@ static int deactivate_afu_directed(struct cxl_afu *afu) | |||
568 | cxl_sysfs_afu_m_remove(afu); | 550 | cxl_sysfs_afu_m_remove(afu); |
569 | cxl_chardev_afu_remove(afu); | 551 | cxl_chardev_afu_remove(afu); |
570 | 552 | ||
571 | __cxl_afu_reset(afu); | 553 | cxl_ops->afu_reset(afu); |
572 | cxl_afu_disable(afu); | 554 | cxl_afu_disable(afu); |
573 | cxl_psl_purge(afu); | 555 | cxl_psl_purge(afu); |
574 | 556 | ||
@@ -632,7 +614,7 @@ static int attach_dedicated(struct cxl_context *ctx, u64 wed, u64 amr) | |||
632 | /* master only context for dedicated */ | 614 | /* master only context for dedicated */ |
633 | cxl_assign_psn_space(ctx); | 615 | cxl_assign_psn_space(ctx); |
634 | 616 | ||
635 | if ((rc = __cxl_afu_reset(afu))) | 617 | if ((rc = cxl_ops->afu_reset(afu))) |
636 | return rc; | 618 | return rc; |
637 | 619 | ||
638 | cxl_p2n_write(afu, CXL_PSL_WED_An, wed); | 620 | cxl_p2n_write(afu, CXL_PSL_WED_An, wed); |
@@ -652,7 +634,7 @@ static int deactivate_dedicated_process(struct cxl_afu *afu) | |||
652 | return 0; | 634 | return 0; |
653 | } | 635 | } |
654 | 636 | ||
655 | int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode) | 637 | static int native_afu_deactivate_mode(struct cxl_afu *afu, int mode) |
656 | { | 638 | { |
657 | if (mode == CXL_MODE_DIRECTED) | 639 | if (mode == CXL_MODE_DIRECTED) |
658 | return deactivate_afu_directed(afu); | 640 | return deactivate_afu_directed(afu); |
@@ -661,19 +643,14 @@ int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode) | |||
661 | return 0; | 643 | return 0; |
662 | } | 644 | } |
663 | 645 | ||
664 | int cxl_afu_deactivate_mode(struct cxl_afu *afu) | 646 | static int native_afu_activate_mode(struct cxl_afu *afu, int mode) |
665 | { | ||
666 | return _cxl_afu_deactivate_mode(afu, afu->current_mode); | ||
667 | } | ||
668 | |||
669 | int cxl_afu_activate_mode(struct cxl_afu *afu, int mode) | ||
670 | { | 647 | { |
671 | if (!mode) | 648 | if (!mode) |
672 | return 0; | 649 | return 0; |
673 | if (!(mode & afu->modes_supported)) | 650 | if (!(mode & afu->modes_supported)) |
674 | return -EINVAL; | 651 | return -EINVAL; |
675 | 652 | ||
676 | if (!cxl_adapter_link_ok(afu->adapter)) { | 653 | if (!cxl_ops->link_ok(afu->adapter, afu)) { |
677 | WARN(1, "Device link is down, refusing to activate!\n"); | 654 | WARN(1, "Device link is down, refusing to activate!\n"); |
678 | return -EIO; | 655 | return -EIO; |
679 | } | 656 | } |
@@ -686,9 +663,10 @@ int cxl_afu_activate_mode(struct cxl_afu *afu, int mode) | |||
686 | return -EINVAL; | 663 | return -EINVAL; |
687 | } | 664 | } |
688 | 665 | ||
689 | int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr) | 666 | static int native_attach_process(struct cxl_context *ctx, bool kernel, |
667 | u64 wed, u64 amr) | ||
690 | { | 668 | { |
691 | if (!cxl_adapter_link_ok(ctx->afu->adapter)) { | 669 | if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) { |
692 | WARN(1, "Device link is down, refusing to attach process!\n"); | 670 | WARN(1, "Device link is down, refusing to attach process!\n"); |
693 | return -EIO; | 671 | return -EIO; |
694 | } | 672 | } |
@@ -705,7 +683,7 @@ int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr) | |||
705 | 683 | ||
706 | static inline int detach_process_native_dedicated(struct cxl_context *ctx) | 684 | static inline int detach_process_native_dedicated(struct cxl_context *ctx) |
707 | { | 685 | { |
708 | __cxl_afu_reset(ctx->afu); | 686 | cxl_ops->afu_reset(ctx->afu); |
709 | cxl_afu_disable(ctx->afu); | 687 | cxl_afu_disable(ctx->afu); |
710 | cxl_psl_purge(ctx->afu); | 688 | cxl_psl_purge(ctx->afu); |
711 | return 0; | 689 | return 0; |
@@ -723,7 +701,7 @@ static inline int detach_process_native_afu_directed(struct cxl_context *ctx) | |||
723 | return 0; | 701 | return 0; |
724 | } | 702 | } |
725 | 703 | ||
726 | int cxl_detach_process(struct cxl_context *ctx) | 704 | static int native_detach_process(struct cxl_context *ctx) |
727 | { | 705 | { |
728 | trace_cxl_detach(ctx); | 706 | trace_cxl_detach(ctx); |
729 | 707 | ||
@@ -733,14 +711,14 @@ int cxl_detach_process(struct cxl_context *ctx) | |||
733 | return detach_process_native_afu_directed(ctx); | 711 | return detach_process_native_afu_directed(ctx); |
734 | } | 712 | } |
735 | 713 | ||
736 | int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info) | 714 | static int native_get_irq_info(struct cxl_afu *afu, struct cxl_irq_info *info) |
737 | { | 715 | { |
738 | u64 pidtid; | 716 | u64 pidtid; |
739 | 717 | ||
740 | /* If the adapter has gone away, we can't get any meaningful | 718 | /* If the adapter has gone away, we can't get any meaningful |
741 | * information. | 719 | * information. |
742 | */ | 720 | */ |
743 | if (!cxl_adapter_link_ok(afu->adapter)) | 721 | if (!cxl_ops->link_ok(afu->adapter, afu)) |
744 | return -EIO; | 722 | return -EIO; |
745 | 723 | ||
746 | info->dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An); | 724 | info->dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An); |
@@ -751,10 +729,214 @@ int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info) | |||
751 | info->tid = pidtid & 0xffffffff; | 729 | info->tid = pidtid & 0xffffffff; |
752 | info->afu_err = cxl_p2n_read(afu, CXL_AFU_ERR_An); | 730 | info->afu_err = cxl_p2n_read(afu, CXL_AFU_ERR_An); |
753 | info->errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An); | 731 | info->errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An); |
732 | info->proc_handle = 0; | ||
733 | |||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | static irqreturn_t native_handle_psl_slice_error(struct cxl_context *ctx, | ||
738 | u64 dsisr, u64 errstat) | ||
739 | { | ||
740 | u64 fir1, fir2, fir_slice, serr, afu_debug; | ||
741 | |||
742 | fir1 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR1); | ||
743 | fir2 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR2); | ||
744 | fir_slice = cxl_p1n_read(ctx->afu, CXL_PSL_FIR_SLICE_An); | ||
745 | serr = cxl_p1n_read(ctx->afu, CXL_PSL_SERR_An); | ||
746 | afu_debug = cxl_p1n_read(ctx->afu, CXL_AFU_DEBUG_An); | ||
747 | |||
748 | dev_crit(&ctx->afu->dev, "PSL ERROR STATUS: 0x%016llx\n", errstat); | ||
749 | dev_crit(&ctx->afu->dev, "PSL_FIR1: 0x%016llx\n", fir1); | ||
750 | dev_crit(&ctx->afu->dev, "PSL_FIR2: 0x%016llx\n", fir2); | ||
751 | dev_crit(&ctx->afu->dev, "PSL_SERR_An: 0x%016llx\n", serr); | ||
752 | dev_crit(&ctx->afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice); | ||
753 | dev_crit(&ctx->afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug); | ||
754 | |||
755 | dev_crit(&ctx->afu->dev, "STOPPING CXL TRACE\n"); | ||
756 | cxl_stop_trace(ctx->afu->adapter); | ||
757 | |||
758 | return cxl_ops->ack_irq(ctx, 0, errstat); | ||
759 | } | ||
760 | |||
761 | static irqreturn_t fail_psl_irq(struct cxl_afu *afu, struct cxl_irq_info *irq_info) | ||
762 | { | ||
763 | if (irq_info->dsisr & CXL_PSL_DSISR_TRANS) | ||
764 | cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE); | ||
765 | else | ||
766 | cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A); | ||
767 | |||
768 | return IRQ_HANDLED; | ||
769 | } | ||
770 | |||
771 | static irqreturn_t native_irq_multiplexed(int irq, void *data) | ||
772 | { | ||
773 | struct cxl_afu *afu = data; | ||
774 | struct cxl_context *ctx; | ||
775 | struct cxl_irq_info irq_info; | ||
776 | int ph = cxl_p2n_read(afu, CXL_PSL_PEHandle_An) & 0xffff; | ||
777 | int ret; | ||
778 | |||
779 | if ((ret = native_get_irq_info(afu, &irq_info))) { | ||
780 | WARN(1, "Unable to get CXL IRQ Info: %i\n", ret); | ||
781 | return fail_psl_irq(afu, &irq_info); | ||
782 | } | ||
783 | |||
784 | rcu_read_lock(); | ||
785 | ctx = idr_find(&afu->contexts_idr, ph); | ||
786 | if (ctx) { | ||
787 | ret = cxl_irq(irq, ctx, &irq_info); | ||
788 | rcu_read_unlock(); | ||
789 | return ret; | ||
790 | } | ||
791 | rcu_read_unlock(); | ||
792 | |||
793 | WARN(1, "Unable to demultiplex CXL PSL IRQ for PE %i DSISR %016llx DAR" | ||
794 | " %016llx\n(Possible AFU HW issue - was a term/remove acked" | ||
795 | " with outstanding transactions?)\n", ph, irq_info.dsisr, | ||
796 | irq_info.dar); | ||
797 | return fail_psl_irq(afu, &irq_info); | ||
798 | } | ||
799 | |||
800 | static irqreturn_t native_slice_irq_err(int irq, void *data) | ||
801 | { | ||
802 | struct cxl_afu *afu = data; | ||
803 | u64 fir_slice, errstat, serr, afu_debug; | ||
804 | |||
805 | WARN(irq, "CXL SLICE ERROR interrupt %i\n", irq); | ||
806 | |||
807 | serr = cxl_p1n_read(afu, CXL_PSL_SERR_An); | ||
808 | fir_slice = cxl_p1n_read(afu, CXL_PSL_FIR_SLICE_An); | ||
809 | errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An); | ||
810 | afu_debug = cxl_p1n_read(afu, CXL_AFU_DEBUG_An); | ||
811 | dev_crit(&afu->dev, "PSL_SERR_An: 0x%016llx\n", serr); | ||
812 | dev_crit(&afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice); | ||
813 | dev_crit(&afu->dev, "CXL_PSL_ErrStat_An: 0x%016llx\n", errstat); | ||
814 | dev_crit(&afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug); | ||
815 | |||
816 | cxl_p1n_write(afu, CXL_PSL_SERR_An, serr); | ||
817 | |||
818 | return IRQ_HANDLED; | ||
819 | } | ||
820 | |||
821 | static irqreturn_t native_irq_err(int irq, void *data) | ||
822 | { | ||
823 | struct cxl *adapter = data; | ||
824 | u64 fir1, fir2, err_ivte; | ||
825 | |||
826 | WARN(1, "CXL ERROR interrupt %i\n", irq); | ||
827 | |||
828 | err_ivte = cxl_p1_read(adapter, CXL_PSL_ErrIVTE); | ||
829 | dev_crit(&adapter->dev, "PSL_ErrIVTE: 0x%016llx\n", err_ivte); | ||
830 | |||
831 | dev_crit(&adapter->dev, "STOPPING CXL TRACE\n"); | ||
832 | cxl_stop_trace(adapter); | ||
833 | |||
834 | fir1 = cxl_p1_read(adapter, CXL_PSL_FIR1); | ||
835 | fir2 = cxl_p1_read(adapter, CXL_PSL_FIR2); | ||
836 | |||
837 | dev_crit(&adapter->dev, "PSL_FIR1: 0x%016llx\nPSL_FIR2: 0x%016llx\n", fir1, fir2); | ||
838 | |||
839 | return IRQ_HANDLED; | ||
840 | } | ||
841 | |||
842 | int cxl_native_register_psl_err_irq(struct cxl *adapter) | ||
843 | { | ||
844 | int rc; | ||
845 | |||
846 | adapter->irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err", | ||
847 | dev_name(&adapter->dev)); | ||
848 | if (!adapter->irq_name) | ||
849 | return -ENOMEM; | ||
850 | |||
851 | if ((rc = cxl_register_one_irq(adapter, native_irq_err, adapter, | ||
852 | &adapter->native->err_hwirq, | ||
853 | &adapter->native->err_virq, | ||
854 | adapter->irq_name))) { | ||
855 | kfree(adapter->irq_name); | ||
856 | adapter->irq_name = NULL; | ||
857 | return rc; | ||
858 | } | ||
859 | |||
860 | cxl_p1_write(adapter, CXL_PSL_ErrIVTE, adapter->native->err_hwirq & 0xffff); | ||
861 | |||
862 | return 0; | ||
863 | } | ||
864 | |||
865 | void cxl_native_release_psl_err_irq(struct cxl *adapter) | ||
866 | { | ||
867 | if (adapter->native->err_virq != irq_find_mapping(NULL, adapter->native->err_hwirq)) | ||
868 | return; | ||
869 | |||
870 | cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000); | ||
871 | cxl_unmap_irq(adapter->native->err_virq, adapter); | ||
872 | cxl_ops->release_one_irq(adapter, adapter->native->err_hwirq); | ||
873 | kfree(adapter->irq_name); | ||
874 | } | ||
875 | |||
876 | int cxl_native_register_serr_irq(struct cxl_afu *afu) | ||
877 | { | ||
878 | u64 serr; | ||
879 | int rc; | ||
880 | |||
881 | afu->err_irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err", | ||
882 | dev_name(&afu->dev)); | ||
883 | if (!afu->err_irq_name) | ||
884 | return -ENOMEM; | ||
885 | |||
886 | if ((rc = cxl_register_one_irq(afu->adapter, native_slice_irq_err, afu, | ||
887 | &afu->serr_hwirq, | ||
888 | &afu->serr_virq, afu->err_irq_name))) { | ||
889 | kfree(afu->err_irq_name); | ||
890 | afu->err_irq_name = NULL; | ||
891 | return rc; | ||
892 | } | ||
893 | |||
894 | serr = cxl_p1n_read(afu, CXL_PSL_SERR_An); | ||
895 | serr = (serr & 0x00ffffffffff0000ULL) | (afu->serr_hwirq & 0xffff); | ||
896 | cxl_p1n_write(afu, CXL_PSL_SERR_An, serr); | ||
754 | 897 | ||
755 | return 0; | 898 | return 0; |
756 | } | 899 | } |
757 | 900 | ||
901 | void cxl_native_release_serr_irq(struct cxl_afu *afu) | ||
902 | { | ||
903 | if (afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq)) | ||
904 | return; | ||
905 | |||
906 | cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000); | ||
907 | cxl_unmap_irq(afu->serr_virq, afu); | ||
908 | cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq); | ||
909 | kfree(afu->err_irq_name); | ||
910 | } | ||
911 | |||
912 | int cxl_native_register_psl_irq(struct cxl_afu *afu) | ||
913 | { | ||
914 | int rc; | ||
915 | |||
916 | afu->psl_irq_name = kasprintf(GFP_KERNEL, "cxl-%s", | ||
917 | dev_name(&afu->dev)); | ||
918 | if (!afu->psl_irq_name) | ||
919 | return -ENOMEM; | ||
920 | |||
921 | if ((rc = cxl_register_one_irq(afu->adapter, native_irq_multiplexed, | ||
922 | afu, &afu->native->psl_hwirq, &afu->native->psl_virq, | ||
923 | afu->psl_irq_name))) { | ||
924 | kfree(afu->psl_irq_name); | ||
925 | afu->psl_irq_name = NULL; | ||
926 | } | ||
927 | return rc; | ||
928 | } | ||
929 | |||
930 | void cxl_native_release_psl_irq(struct cxl_afu *afu) | ||
931 | { | ||
932 | if (afu->native->psl_virq != irq_find_mapping(NULL, afu->native->psl_hwirq)) | ||
933 | return; | ||
934 | |||
935 | cxl_unmap_irq(afu->native->psl_virq, afu); | ||
936 | cxl_ops->release_one_irq(afu->adapter, afu->native->psl_hwirq); | ||
937 | kfree(afu->psl_irq_name); | ||
938 | } | ||
939 | |||
758 | static void recover_psl_err(struct cxl_afu *afu, u64 errstat) | 940 | static void recover_psl_err(struct cxl_afu *afu, u64 errstat) |
759 | { | 941 | { |
760 | u64 dsisr; | 942 | u64 dsisr; |
@@ -769,7 +951,7 @@ static void recover_psl_err(struct cxl_afu *afu, u64 errstat) | |||
769 | cxl_p2n_write(afu, CXL_PSL_ErrStat_An, errstat); | 951 | cxl_p2n_write(afu, CXL_PSL_ErrStat_An, errstat); |
770 | } | 952 | } |
771 | 953 | ||
772 | int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask) | 954 | static int native_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask) |
773 | { | 955 | { |
774 | trace_cxl_psl_irq_ack(ctx, tfc); | 956 | trace_cxl_psl_irq_ack(ctx, tfc); |
775 | if (tfc) | 957 | if (tfc) |
@@ -784,3 +966,132 @@ int cxl_check_error(struct cxl_afu *afu) | |||
784 | { | 966 | { |
785 | return (cxl_p1n_read(afu, CXL_PSL_SCNTL_An) == ~0ULL); | 967 | return (cxl_p1n_read(afu, CXL_PSL_SCNTL_An) == ~0ULL); |
786 | } | 968 | } |
969 | |||
970 | static bool native_support_attributes(const char *attr_name, | ||
971 | enum cxl_attrs type) | ||
972 | { | ||
973 | return true; | ||
974 | } | ||
975 | |||
976 | static int native_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off, u64 *out) | ||
977 | { | ||
978 | if (unlikely(!cxl_ops->link_ok(afu->adapter, afu))) | ||
979 | return -EIO; | ||
980 | if (unlikely(off >= afu->crs_len)) | ||
981 | return -ERANGE; | ||
982 | *out = in_le64(afu->native->afu_desc_mmio + afu->crs_offset + | ||
983 | (cr * afu->crs_len) + off); | ||
984 | return 0; | ||
985 | } | ||
986 | |||
987 | static int native_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off, u32 *out) | ||
988 | { | ||
989 | if (unlikely(!cxl_ops->link_ok(afu->adapter, afu))) | ||
990 | return -EIO; | ||
991 | if (unlikely(off >= afu->crs_len)) | ||
992 | return -ERANGE; | ||
993 | *out = in_le32(afu->native->afu_desc_mmio + afu->crs_offset + | ||
994 | (cr * afu->crs_len) + off); | ||
995 | return 0; | ||
996 | } | ||
997 | |||
998 | static int native_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off, u16 *out) | ||
999 | { | ||
1000 | u64 aligned_off = off & ~0x3L; | ||
1001 | u32 val; | ||
1002 | int rc; | ||
1003 | |||
1004 | rc = native_afu_cr_read32(afu, cr, aligned_off, &val); | ||
1005 | if (!rc) | ||
1006 | *out = (val >> ((off & 0x3) * 8)) & 0xffff; | ||
1007 | return rc; | ||
1008 | } | ||
1009 | |||
1010 | static int native_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off, u8 *out) | ||
1011 | { | ||
1012 | u64 aligned_off = off & ~0x3L; | ||
1013 | u32 val; | ||
1014 | int rc; | ||
1015 | |||
1016 | rc = native_afu_cr_read32(afu, cr, aligned_off, &val); | ||
1017 | if (!rc) | ||
1018 | *out = (val >> ((off & 0x3) * 8)) & 0xff; | ||
1019 | return rc; | ||
1020 | } | ||
1021 | |||
1022 | static int native_afu_cr_write32(struct cxl_afu *afu, int cr, u64 off, u32 in) | ||
1023 | { | ||
1024 | if (unlikely(!cxl_ops->link_ok(afu->adapter, afu))) | ||
1025 | return -EIO; | ||
1026 | if (unlikely(off >= afu->crs_len)) | ||
1027 | return -ERANGE; | ||
1028 | out_le32(afu->native->afu_desc_mmio + afu->crs_offset + | ||
1029 | (cr * afu->crs_len) + off, in); | ||
1030 | return 0; | ||
1031 | } | ||
1032 | |||
1033 | static int native_afu_cr_write16(struct cxl_afu *afu, int cr, u64 off, u16 in) | ||
1034 | { | ||
1035 | u64 aligned_off = off & ~0x3L; | ||
1036 | u32 val32, mask, shift; | ||
1037 | int rc; | ||
1038 | |||
1039 | rc = native_afu_cr_read32(afu, cr, aligned_off, &val32); | ||
1040 | if (rc) | ||
1041 | return rc; | ||
1042 | shift = (off & 0x3) * 8; | ||
1043 | WARN_ON(shift == 24); | ||
1044 | mask = 0xffff << shift; | ||
1045 | val32 = (val32 & ~mask) | (in << shift); | ||
1046 | |||
1047 | rc = native_afu_cr_write32(afu, cr, aligned_off, val32); | ||
1048 | return rc; | ||
1049 | } | ||
1050 | |||
1051 | static int native_afu_cr_write8(struct cxl_afu *afu, int cr, u64 off, u8 in) | ||
1052 | { | ||
1053 | u64 aligned_off = off & ~0x3L; | ||
1054 | u32 val32, mask, shift; | ||
1055 | int rc; | ||
1056 | |||
1057 | rc = native_afu_cr_read32(afu, cr, aligned_off, &val32); | ||
1058 | if (rc) | ||
1059 | return rc; | ||
1060 | shift = (off & 0x3) * 8; | ||
1061 | mask = 0xff << shift; | ||
1062 | val32 = (val32 & ~mask) | (in << shift); | ||
1063 | |||
1064 | rc = native_afu_cr_write32(afu, cr, aligned_off, val32); | ||
1065 | return rc; | ||
1066 | } | ||
1067 | |||
1068 | const struct cxl_backend_ops cxl_native_ops = { | ||
1069 | .module = THIS_MODULE, | ||
1070 | .adapter_reset = cxl_pci_reset, | ||
1071 | .alloc_one_irq = cxl_pci_alloc_one_irq, | ||
1072 | .release_one_irq = cxl_pci_release_one_irq, | ||
1073 | .alloc_irq_ranges = cxl_pci_alloc_irq_ranges, | ||
1074 | .release_irq_ranges = cxl_pci_release_irq_ranges, | ||
1075 | .setup_irq = cxl_pci_setup_irq, | ||
1076 | .handle_psl_slice_error = native_handle_psl_slice_error, | ||
1077 | .psl_interrupt = NULL, | ||
1078 | .ack_irq = native_ack_irq, | ||
1079 | .attach_process = native_attach_process, | ||
1080 | .detach_process = native_detach_process, | ||
1081 | .support_attributes = native_support_attributes, | ||
1082 | .link_ok = cxl_adapter_link_ok, | ||
1083 | .release_afu = cxl_pci_release_afu, | ||
1084 | .afu_read_err_buffer = cxl_pci_afu_read_err_buffer, | ||
1085 | .afu_check_and_enable = native_afu_check_and_enable, | ||
1086 | .afu_activate_mode = native_afu_activate_mode, | ||
1087 | .afu_deactivate_mode = native_afu_deactivate_mode, | ||
1088 | .afu_reset = native_afu_reset, | ||
1089 | .afu_cr_read8 = native_afu_cr_read8, | ||
1090 | .afu_cr_read16 = native_afu_cr_read16, | ||
1091 | .afu_cr_read32 = native_afu_cr_read32, | ||
1092 | .afu_cr_read64 = native_afu_cr_read64, | ||
1093 | .afu_cr_write8 = native_afu_cr_write8, | ||
1094 | .afu_cr_write16 = native_afu_cr_write16, | ||
1095 | .afu_cr_write32 = native_afu_cr_write32, | ||
1096 | .read_adapter_vpd = cxl_pci_read_adapter_vpd, | ||
1097 | }; | ||
diff --git a/drivers/misc/cxl/of.c b/drivers/misc/cxl/of.c new file mode 100644 index 000000000000..edc458395f68 --- /dev/null +++ b/drivers/misc/cxl/of.c | |||
@@ -0,0 +1,513 @@ | |||
1 | /* | ||
2 | * Copyright 2015 IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/of_address.h> | ||
15 | #include <linux/of_platform.h> | ||
16 | |||
17 | #include "cxl.h" | ||
18 | |||
19 | |||
20 | static const __be32 *read_prop_string(const struct device_node *np, | ||
21 | const char *prop_name) | ||
22 | { | ||
23 | const __be32 *prop; | ||
24 | |||
25 | prop = of_get_property(np, prop_name, NULL); | ||
26 | if (cxl_verbose && prop) | ||
27 | pr_info("%s: %s\n", prop_name, (char *) prop); | ||
28 | return prop; | ||
29 | } | ||
30 | |||
31 | static const __be32 *read_prop_dword(const struct device_node *np, | ||
32 | const char *prop_name, u32 *val) | ||
33 | { | ||
34 | const __be32 *prop; | ||
35 | |||
36 | prop = of_get_property(np, prop_name, NULL); | ||
37 | if (prop) | ||
38 | *val = be32_to_cpu(prop[0]); | ||
39 | if (cxl_verbose && prop) | ||
40 | pr_info("%s: %#x (%u)\n", prop_name, *val, *val); | ||
41 | return prop; | ||
42 | } | ||
43 | |||
44 | static const __be64 *read_prop64_dword(const struct device_node *np, | ||
45 | const char *prop_name, u64 *val) | ||
46 | { | ||
47 | const __be64 *prop; | ||
48 | |||
49 | prop = of_get_property(np, prop_name, NULL); | ||
50 | if (prop) | ||
51 | *val = be64_to_cpu(prop[0]); | ||
52 | if (cxl_verbose && prop) | ||
53 | pr_info("%s: %#llx (%llu)\n", prop_name, *val, *val); | ||
54 | return prop; | ||
55 | } | ||
56 | |||
57 | |||
58 | static int read_handle(struct device_node *np, u64 *handle) | ||
59 | { | ||
60 | const __be32 *prop; | ||
61 | u64 size; | ||
62 | |||
63 | /* Get address and size of the node */ | ||
64 | prop = of_get_address(np, 0, &size, NULL); | ||
65 | if (size) | ||
66 | return -EINVAL; | ||
67 | |||
68 | /* Helper to read a big number; size is in cells (not bytes) */ | ||
69 | *handle = of_read_number(prop, of_n_addr_cells(np)); | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static int read_phys_addr(struct device_node *np, char *prop_name, | ||
74 | struct cxl_afu *afu) | ||
75 | { | ||
76 | int i, len, entry_size, naddr, nsize, type; | ||
77 | u64 addr, size; | ||
78 | const __be32 *prop; | ||
79 | |||
80 | naddr = of_n_addr_cells(np); | ||
81 | nsize = of_n_size_cells(np); | ||
82 | |||
83 | prop = of_get_property(np, prop_name, &len); | ||
84 | if (prop) { | ||
85 | entry_size = naddr + nsize; | ||
86 | for (i = 0; i < (len / 4); i += entry_size, prop += entry_size) { | ||
87 | type = be32_to_cpu(prop[0]); | ||
88 | addr = of_read_number(prop, naddr); | ||
89 | size = of_read_number(&prop[naddr], nsize); | ||
90 | switch (type) { | ||
91 | case 0: /* unit address */ | ||
92 | afu->guest->handle = addr; | ||
93 | break; | ||
94 | case 1: /* p2 area */ | ||
95 | afu->guest->p2n_phys += addr; | ||
96 | afu->guest->p2n_size = size; | ||
97 | break; | ||
98 | case 2: /* problem state area */ | ||
99 | afu->psn_phys += addr; | ||
100 | afu->adapter->ps_size = size; | ||
101 | break; | ||
102 | default: | ||
103 | pr_err("Invalid address type %d found in %s property of AFU\n", | ||
104 | type, prop_name); | ||
105 | return -EINVAL; | ||
106 | } | ||
107 | if (cxl_verbose) | ||
108 | pr_info("%s: %#x %#llx (size %#llx)\n", | ||
109 | prop_name, type, addr, size); | ||
110 | } | ||
111 | } | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static int read_vpd(struct cxl *adapter, struct cxl_afu *afu) | ||
116 | { | ||
117 | char vpd[256]; | ||
118 | int rc; | ||
119 | size_t len = sizeof(vpd); | ||
120 | |||
121 | memset(vpd, 0, len); | ||
122 | |||
123 | if (adapter) | ||
124 | rc = cxl_guest_read_adapter_vpd(adapter, vpd, len); | ||
125 | else | ||
126 | rc = cxl_guest_read_afu_vpd(afu, vpd, len); | ||
127 | |||
128 | if (rc > 0) { | ||
129 | cxl_dump_debug_buffer(vpd, rc); | ||
130 | rc = 0; | ||
131 | } | ||
132 | return rc; | ||
133 | } | ||
134 | |||
135 | int cxl_of_read_afu_handle(struct cxl_afu *afu, struct device_node *afu_np) | ||
136 | { | ||
137 | if (read_handle(afu_np, &afu->guest->handle)) | ||
138 | return -EINVAL; | ||
139 | pr_devel("AFU handle: 0x%.16llx\n", afu->guest->handle); | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | int cxl_of_read_afu_properties(struct cxl_afu *afu, struct device_node *np) | ||
145 | { | ||
146 | int i, len, rc; | ||
147 | char *p; | ||
148 | const __be32 *prop; | ||
149 | u16 device_id, vendor_id; | ||
150 | u32 val = 0, class_code; | ||
151 | |||
152 | /* Properties are read in the same order as listed in PAPR */ | ||
153 | |||
154 | if (cxl_verbose) { | ||
155 | pr_info("Dump of the 'ibm,coherent-platform-function' node properties:\n"); | ||
156 | |||
157 | prop = of_get_property(np, "compatible", &len); | ||
158 | i = 0; | ||
159 | while (i < len) { | ||
160 | p = (char *) prop + i; | ||
161 | pr_info("compatible: %s\n", p); | ||
162 | i += strlen(p) + 1; | ||
163 | } | ||
164 | read_prop_string(np, "name"); | ||
165 | } | ||
166 | |||
167 | rc = read_phys_addr(np, "reg", afu); | ||
168 | if (rc) | ||
169 | return rc; | ||
170 | |||
171 | rc = read_phys_addr(np, "assigned-addresses", afu); | ||
172 | if (rc) | ||
173 | return rc; | ||
174 | |||
175 | if (afu->psn_phys == 0) | ||
176 | afu->psa = false; | ||
177 | else | ||
178 | afu->psa = true; | ||
179 | |||
180 | if (cxl_verbose) { | ||
181 | read_prop_string(np, "ibm,loc-code"); | ||
182 | read_prop_string(np, "device_type"); | ||
183 | } | ||
184 | |||
185 | read_prop_dword(np, "ibm,#processes", &afu->max_procs_virtualised); | ||
186 | |||
187 | if (cxl_verbose) { | ||
188 | read_prop_dword(np, "ibm,scratchpad-size", &val); | ||
189 | read_prop_dword(np, "ibm,programmable", &val); | ||
190 | read_prop_string(np, "ibm,phandle"); | ||
191 | read_vpd(NULL, afu); | ||
192 | } | ||
193 | |||
194 | read_prop_dword(np, "ibm,max-ints-per-process", &afu->guest->max_ints); | ||
195 | afu->irqs_max = afu->guest->max_ints; | ||
196 | |||
197 | prop = read_prop_dword(np, "ibm,min-ints-per-process", &afu->pp_irqs); | ||
198 | if (prop) { | ||
199 | /* One extra interrupt for the PSL interrupt is already | ||
200 | * included. Remove it now to keep only AFU interrupts and | ||
201 | * match the native case. | ||
202 | */ | ||
203 | afu->pp_irqs--; | ||
204 | } | ||
205 | |||
206 | if (cxl_verbose) { | ||
207 | read_prop_dword(np, "ibm,max-ints", &val); | ||
208 | read_prop_dword(np, "ibm,vpd-size", &val); | ||
209 | } | ||
210 | |||
211 | read_prop64_dword(np, "ibm,error-buffer-size", &afu->eb_len); | ||
212 | afu->eb_offset = 0; | ||
213 | |||
214 | if (cxl_verbose) | ||
215 | read_prop_dword(np, "ibm,config-record-type", &val); | ||
216 | |||
217 | read_prop64_dword(np, "ibm,config-record-size", &afu->crs_len); | ||
218 | afu->crs_offset = 0; | ||
219 | |||
220 | read_prop_dword(np, "ibm,#config-records", &afu->crs_num); | ||
221 | |||
222 | if (cxl_verbose) { | ||
223 | for (i = 0; i < afu->crs_num; i++) { | ||
224 | rc = cxl_ops->afu_cr_read16(afu, i, PCI_DEVICE_ID, | ||
225 | &device_id); | ||
226 | if (!rc) | ||
227 | pr_info("record %d - device-id: %#x\n", | ||
228 | i, device_id); | ||
229 | rc = cxl_ops->afu_cr_read16(afu, i, PCI_VENDOR_ID, | ||
230 | &vendor_id); | ||
231 | if (!rc) | ||
232 | pr_info("record %d - vendor-id: %#x\n", | ||
233 | i, vendor_id); | ||
234 | rc = cxl_ops->afu_cr_read32(afu, i, PCI_CLASS_REVISION, | ||
235 | &class_code); | ||
236 | if (!rc) { | ||
237 | class_code >>= 8; | ||
238 | pr_info("record %d - class-code: %#x\n", | ||
239 | i, class_code); | ||
240 | } | ||
241 | } | ||
242 | |||
243 | read_prop_dword(np, "ibm,function-number", &val); | ||
244 | read_prop_dword(np, "ibm,privileged-function", &val); | ||
245 | read_prop_dword(np, "vendor-id", &val); | ||
246 | read_prop_dword(np, "device-id", &val); | ||
247 | read_prop_dword(np, "revision-id", &val); | ||
248 | read_prop_dword(np, "class-code", &val); | ||
249 | read_prop_dword(np, "subsystem-vendor-id", &val); | ||
250 | read_prop_dword(np, "subsystem-id", &val); | ||
251 | } | ||
252 | /* | ||
253 | * if "ibm,process-mmio" doesn't exist then per-process mmio is | ||
254 | * not supported | ||
255 | */ | ||
256 | val = 0; | ||
257 | prop = read_prop_dword(np, "ibm,process-mmio", &val); | ||
258 | if (prop && val == 1) | ||
259 | afu->pp_psa = true; | ||
260 | else | ||
261 | afu->pp_psa = false; | ||
262 | |||
263 | if (cxl_verbose) { | ||
264 | read_prop_dword(np, "ibm,supports-aur", &val); | ||
265 | read_prop_dword(np, "ibm,supports-csrp", &val); | ||
266 | read_prop_dword(np, "ibm,supports-prr", &val); | ||
267 | } | ||
268 | |||
269 | prop = read_prop_dword(np, "ibm,function-error-interrupt", &val); | ||
270 | if (prop) | ||
271 | afu->serr_hwirq = val; | ||
272 | |||
273 | pr_devel("AFU handle: %#llx\n", afu->guest->handle); | ||
274 | pr_devel("p2n_phys: %#llx (size %#llx)\n", | ||
275 | afu->guest->p2n_phys, afu->guest->p2n_size); | ||
276 | pr_devel("psn_phys: %#llx (size %#llx)\n", | ||
277 | afu->psn_phys, afu->adapter->ps_size); | ||
278 | pr_devel("Max number of processes virtualised=%i\n", | ||
279 | afu->max_procs_virtualised); | ||
280 | pr_devel("Per-process irqs min=%i, max=%i\n", afu->pp_irqs, | ||
281 | afu->irqs_max); | ||
282 | pr_devel("Slice error interrupt=%#lx\n", afu->serr_hwirq); | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static int read_adapter_irq_config(struct cxl *adapter, struct device_node *np) | ||
288 | { | ||
289 | const __be32 *ranges; | ||
290 | int len, nranges, i; | ||
291 | struct irq_avail *cur; | ||
292 | |||
293 | ranges = of_get_property(np, "interrupt-ranges", &len); | ||
294 | if (ranges == NULL || len < (2 * sizeof(int))) | ||
295 | return -EINVAL; | ||
296 | |||
297 | /* | ||
298 | * encoded array of two cells per entry, each cell encoded as | ||
299 | * with encode-int | ||
300 | */ | ||
301 | nranges = len / (2 * sizeof(int)); | ||
302 | if (nranges == 0 || (nranges * 2 * sizeof(int)) != len) | ||
303 | return -EINVAL; | ||
304 | |||
305 | adapter->guest->irq_avail = kzalloc(nranges * sizeof(struct irq_avail), | ||
306 | GFP_KERNEL); | ||
307 | if (adapter->guest->irq_avail == NULL) | ||
308 | return -ENOMEM; | ||
309 | |||
310 | adapter->guest->irq_base_offset = be32_to_cpu(ranges[0]); | ||
311 | for (i = 0; i < nranges; i++) { | ||
312 | cur = &adapter->guest->irq_avail[i]; | ||
313 | cur->offset = be32_to_cpu(ranges[i * 2]); | ||
314 | cur->range = be32_to_cpu(ranges[i * 2 + 1]); | ||
315 | cur->bitmap = kcalloc(BITS_TO_LONGS(cur->range), | ||
316 | sizeof(*cur->bitmap), GFP_KERNEL); | ||
317 | if (cur->bitmap == NULL) | ||
318 | goto err; | ||
319 | if (cur->offset < adapter->guest->irq_base_offset) | ||
320 | adapter->guest->irq_base_offset = cur->offset; | ||
321 | if (cxl_verbose) | ||
322 | pr_info("available IRQ range: %#lx-%#lx (%lu)\n", | ||
323 | cur->offset, cur->offset + cur->range - 1, | ||
324 | cur->range); | ||
325 | } | ||
326 | adapter->guest->irq_nranges = nranges; | ||
327 | spin_lock_init(&adapter->guest->irq_alloc_lock); | ||
328 | |||
329 | return 0; | ||
330 | err: | ||
331 | for (i--; i >= 0; i--) { | ||
332 | cur = &adapter->guest->irq_avail[i]; | ||
333 | kfree(cur->bitmap); | ||
334 | } | ||
335 | kfree(adapter->guest->irq_avail); | ||
336 | adapter->guest->irq_avail = NULL; | ||
337 | return -ENOMEM; | ||
338 | } | ||
339 | |||
340 | int cxl_of_read_adapter_handle(struct cxl *adapter, struct device_node *np) | ||
341 | { | ||
342 | if (read_handle(np, &adapter->guest->handle)) | ||
343 | return -EINVAL; | ||
344 | pr_devel("Adapter handle: 0x%.16llx\n", adapter->guest->handle); | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | int cxl_of_read_adapter_properties(struct cxl *adapter, struct device_node *np) | ||
350 | { | ||
351 | int rc, len, naddr, i; | ||
352 | char *p; | ||
353 | const __be32 *prop; | ||
354 | u32 val = 0; | ||
355 | |||
356 | /* Properties are read in the same order as listed in PAPR */ | ||
357 | |||
358 | naddr = of_n_addr_cells(np); | ||
359 | |||
360 | if (cxl_verbose) { | ||
361 | pr_info("Dump of the 'ibm,coherent-platform-facility' node properties:\n"); | ||
362 | |||
363 | read_prop_dword(np, "#address-cells", &val); | ||
364 | read_prop_dword(np, "#size-cells", &val); | ||
365 | |||
366 | prop = of_get_property(np, "compatible", &len); | ||
367 | i = 0; | ||
368 | while (i < len) { | ||
369 | p = (char *) prop + i; | ||
370 | pr_info("compatible: %s\n", p); | ||
371 | i += strlen(p) + 1; | ||
372 | } | ||
373 | read_prop_string(np, "name"); | ||
374 | read_prop_string(np, "model"); | ||
375 | |||
376 | prop = of_get_property(np, "reg", NULL); | ||
377 | if (prop) { | ||
378 | pr_info("reg: addr:%#llx size:%#x\n", | ||
379 | of_read_number(prop, naddr), | ||
380 | be32_to_cpu(prop[naddr])); | ||
381 | } | ||
382 | |||
383 | read_prop_string(np, "ibm,loc-code"); | ||
384 | } | ||
385 | |||
386 | if ((rc = read_adapter_irq_config(adapter, np))) | ||
387 | return rc; | ||
388 | |||
389 | if (cxl_verbose) { | ||
390 | read_prop_string(np, "device_type"); | ||
391 | read_prop_string(np, "ibm,phandle"); | ||
392 | } | ||
393 | |||
394 | prop = read_prop_dword(np, "ibm,caia-version", &val); | ||
395 | if (prop) { | ||
396 | adapter->caia_major = (val & 0xFF00) >> 8; | ||
397 | adapter->caia_minor = val & 0xFF; | ||
398 | } | ||
399 | |||
400 | prop = read_prop_dword(np, "ibm,psl-revision", &val); | ||
401 | if (prop) | ||
402 | adapter->psl_rev = val; | ||
403 | |||
404 | prop = read_prop_string(np, "status"); | ||
405 | if (prop) { | ||
406 | adapter->guest->status = kasprintf(GFP_KERNEL, "%s", (char *) prop); | ||
407 | if (adapter->guest->status == NULL) | ||
408 | return -ENOMEM; | ||
409 | } | ||
410 | |||
411 | prop = read_prop_dword(np, "vendor-id", &val); | ||
412 | if (prop) | ||
413 | adapter->guest->vendor = val; | ||
414 | |||
415 | prop = read_prop_dword(np, "device-id", &val); | ||
416 | if (prop) | ||
417 | adapter->guest->device = val; | ||
418 | |||
419 | if (cxl_verbose) { | ||
420 | read_prop_dword(np, "ibm,privileged-facility", &val); | ||
421 | read_prop_dword(np, "revision-id", &val); | ||
422 | read_prop_dword(np, "class-code", &val); | ||
423 | } | ||
424 | |||
425 | prop = read_prop_dword(np, "subsystem-vendor-id", &val); | ||
426 | if (prop) | ||
427 | adapter->guest->subsystem_vendor = val; | ||
428 | |||
429 | prop = read_prop_dword(np, "subsystem-id", &val); | ||
430 | if (prop) | ||
431 | adapter->guest->subsystem = val; | ||
432 | |||
433 | if (cxl_verbose) | ||
434 | read_vpd(adapter, NULL); | ||
435 | |||
436 | return 0; | ||
437 | } | ||
438 | |||
439 | static int cxl_of_remove(struct platform_device *pdev) | ||
440 | { | ||
441 | struct cxl *adapter; | ||
442 | int afu; | ||
443 | |||
444 | adapter = dev_get_drvdata(&pdev->dev); | ||
445 | for (afu = 0; afu < adapter->slices; afu++) | ||
446 | cxl_guest_remove_afu(adapter->afu[afu]); | ||
447 | |||
448 | cxl_guest_remove_adapter(adapter); | ||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | static void cxl_of_shutdown(struct platform_device *pdev) | ||
453 | { | ||
454 | cxl_of_remove(pdev); | ||
455 | } | ||
456 | |||
457 | int cxl_of_probe(struct platform_device *pdev) | ||
458 | { | ||
459 | struct device_node *np = NULL; | ||
460 | struct device_node *afu_np = NULL; | ||
461 | struct cxl *adapter = NULL; | ||
462 | int ret; | ||
463 | int slice, slice_ok; | ||
464 | |||
465 | pr_devel("in %s\n", __func__); | ||
466 | |||
467 | np = pdev->dev.of_node; | ||
468 | if (np == NULL) | ||
469 | return -ENODEV; | ||
470 | |||
471 | /* init adapter */ | ||
472 | adapter = cxl_guest_init_adapter(np, pdev); | ||
473 | if (IS_ERR(adapter)) { | ||
474 | dev_err(&pdev->dev, "guest_init_adapter failed: %li\n", PTR_ERR(adapter)); | ||
475 | return PTR_ERR(adapter); | ||
476 | } | ||
477 | |||
478 | /* init afu */ | ||
479 | slice_ok = 0; | ||
480 | for (afu_np = NULL, slice = 0; (afu_np = of_get_next_child(np, afu_np)); slice++) { | ||
481 | if ((ret = cxl_guest_init_afu(adapter, slice, afu_np))) | ||
482 | dev_err(&pdev->dev, "AFU %i failed to initialise: %i\n", | ||
483 | slice, ret); | ||
484 | else | ||
485 | slice_ok++; | ||
486 | } | ||
487 | |||
488 | if (slice_ok == 0) { | ||
489 | dev_info(&pdev->dev, "No active AFU"); | ||
490 | adapter->slices = 0; | ||
491 | } | ||
492 | |||
493 | if (afu_np) | ||
494 | of_node_put(afu_np); | ||
495 | return 0; | ||
496 | } | ||
497 | |||
498 | static const struct of_device_id cxl_of_match[] = { | ||
499 | { .compatible = "ibm,coherent-platform-facility",}, | ||
500 | {}, | ||
501 | }; | ||
502 | MODULE_DEVICE_TABLE(of, cxl_of_match); | ||
503 | |||
504 | struct platform_driver cxl_of_driver = { | ||
505 | .driver = { | ||
506 | .name = "cxl_of", | ||
507 | .of_match_table = cxl_of_match, | ||
508 | .owner = THIS_MODULE | ||
509 | }, | ||
510 | .probe = cxl_of_probe, | ||
511 | .remove = cxl_of_remove, | ||
512 | .shutdown = cxl_of_shutdown, | ||
513 | }; | ||
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index a89608334ed5..2844e975bf79 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c | |||
@@ -89,8 +89,8 @@ | |||
89 | 89 | ||
90 | /* This works a little different than the p1/p2 register accesses to make it | 90 | /* This works a little different than the p1/p2 register accesses to make it |
91 | * easier to pull out individual fields */ | 91 | * easier to pull out individual fields */ |
92 | #define AFUD_READ(afu, off) in_be64(afu->afu_desc_mmio + off) | 92 | #define AFUD_READ(afu, off) in_be64(afu->native->afu_desc_mmio + off) |
93 | #define AFUD_READ_LE(afu, off) in_le64(afu->afu_desc_mmio + off) | 93 | #define AFUD_READ_LE(afu, off) in_le64(afu->native->afu_desc_mmio + off) |
94 | #define EXTRACT_PPC_BIT(val, bit) (!!(val & PPC_BIT(bit))) | 94 | #define EXTRACT_PPC_BIT(val, bit) (!!(val & PPC_BIT(bit))) |
95 | #define EXTRACT_PPC_BITS(val, bs, be) ((val & PPC_BITMASK(bs, be)) >> PPC_BITLSHIFT(be)) | 95 | #define EXTRACT_PPC_BITS(val, bs, be) ((val & PPC_BITMASK(bs, be)) >> PPC_BITLSHIFT(be)) |
96 | 96 | ||
@@ -115,24 +115,6 @@ | |||
115 | #define AFUD_EB_LEN(val) EXTRACT_PPC_BITS(val, 8, 63) | 115 | #define AFUD_EB_LEN(val) EXTRACT_PPC_BITS(val, 8, 63) |
116 | #define AFUD_READ_EB_OFF(afu) AFUD_READ(afu, 0x48) | 116 | #define AFUD_READ_EB_OFF(afu) AFUD_READ(afu, 0x48) |
117 | 117 | ||
118 | u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off) | ||
119 | { | ||
120 | u64 aligned_off = off & ~0x3L; | ||
121 | u32 val; | ||
122 | |||
123 | val = cxl_afu_cr_read32(afu, cr, aligned_off); | ||
124 | return (val >> ((off & 0x2) * 8)) & 0xffff; | ||
125 | } | ||
126 | |||
127 | u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off) | ||
128 | { | ||
129 | u64 aligned_off = off & ~0x3L; | ||
130 | u32 val; | ||
131 | |||
132 | val = cxl_afu_cr_read32(afu, cr, aligned_off); | ||
133 | return (val >> ((off & 0x3) * 8)) & 0xff; | ||
134 | } | ||
135 | |||
136 | static const struct pci_device_id cxl_pci_tbl[] = { | 118 | static const struct pci_device_id cxl_pci_tbl[] = { |
137 | { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0477), }, | 119 | { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0477), }, |
138 | { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x044b), }, | 120 | { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x044b), }, |
@@ -432,8 +414,8 @@ static int init_implementation_afu_regs(struct cxl_afu *afu) | |||
432 | return 0; | 414 | return 0; |
433 | } | 415 | } |
434 | 416 | ||
435 | int cxl_setup_irq(struct cxl *adapter, unsigned int hwirq, | 417 | int cxl_pci_setup_irq(struct cxl *adapter, unsigned int hwirq, |
436 | unsigned int virq) | 418 | unsigned int virq) |
437 | { | 419 | { |
438 | struct pci_dev *dev = to_pci_dev(adapter->dev.parent); | 420 | struct pci_dev *dev = to_pci_dev(adapter->dev.parent); |
439 | 421 | ||
@@ -475,28 +457,30 @@ int cxl_update_image_control(struct cxl *adapter) | |||
475 | return 0; | 457 | return 0; |
476 | } | 458 | } |
477 | 459 | ||
478 | int cxl_alloc_one_irq(struct cxl *adapter) | 460 | int cxl_pci_alloc_one_irq(struct cxl *adapter) |
479 | { | 461 | { |
480 | struct pci_dev *dev = to_pci_dev(adapter->dev.parent); | 462 | struct pci_dev *dev = to_pci_dev(adapter->dev.parent); |
481 | 463 | ||
482 | return pnv_cxl_alloc_hwirqs(dev, 1); | 464 | return pnv_cxl_alloc_hwirqs(dev, 1); |
483 | } | 465 | } |
484 | 466 | ||
485 | void cxl_release_one_irq(struct cxl *adapter, int hwirq) | 467 | void cxl_pci_release_one_irq(struct cxl *adapter, int hwirq) |
486 | { | 468 | { |
487 | struct pci_dev *dev = to_pci_dev(adapter->dev.parent); | 469 | struct pci_dev *dev = to_pci_dev(adapter->dev.parent); |
488 | 470 | ||
489 | return pnv_cxl_release_hwirqs(dev, hwirq, 1); | 471 | return pnv_cxl_release_hwirqs(dev, hwirq, 1); |
490 | } | 472 | } |
491 | 473 | ||
492 | int cxl_alloc_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter, unsigned int num) | 474 | int cxl_pci_alloc_irq_ranges(struct cxl_irq_ranges *irqs, |
475 | struct cxl *adapter, unsigned int num) | ||
493 | { | 476 | { |
494 | struct pci_dev *dev = to_pci_dev(adapter->dev.parent); | 477 | struct pci_dev *dev = to_pci_dev(adapter->dev.parent); |
495 | 478 | ||
496 | return pnv_cxl_alloc_hwirq_ranges(irqs, dev, num); | 479 | return pnv_cxl_alloc_hwirq_ranges(irqs, dev, num); |
497 | } | 480 | } |
498 | 481 | ||
499 | void cxl_release_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter) | 482 | void cxl_pci_release_irq_ranges(struct cxl_irq_ranges *irqs, |
483 | struct cxl *adapter) | ||
500 | { | 484 | { |
501 | struct pci_dev *dev = to_pci_dev(adapter->dev.parent); | 485 | struct pci_dev *dev = to_pci_dev(adapter->dev.parent); |
502 | 486 | ||
@@ -557,7 +541,7 @@ static int switch_card_to_cxl(struct pci_dev *dev) | |||
557 | return 0; | 541 | return 0; |
558 | } | 542 | } |
559 | 543 | ||
560 | static int cxl_map_slice_regs(struct cxl_afu *afu, struct cxl *adapter, struct pci_dev *dev) | 544 | static int pci_map_slice_regs(struct cxl_afu *afu, struct cxl *adapter, struct pci_dev *dev) |
561 | { | 545 | { |
562 | u64 p1n_base, p2n_base, afu_desc; | 546 | u64 p1n_base, p2n_base, afu_desc; |
563 | const u64 p1n_size = 0x100; | 547 | const u64 p1n_size = 0x100; |
@@ -565,15 +549,15 @@ static int cxl_map_slice_regs(struct cxl_afu *afu, struct cxl *adapter, struct p | |||
565 | 549 | ||
566 | p1n_base = p1_base(dev) + 0x10000 + (afu->slice * p1n_size); | 550 | p1n_base = p1_base(dev) + 0x10000 + (afu->slice * p1n_size); |
567 | p2n_base = p2_base(dev) + (afu->slice * p2n_size); | 551 | p2n_base = p2_base(dev) + (afu->slice * p2n_size); |
568 | afu->psn_phys = p2_base(dev) + (adapter->ps_off + (afu->slice * adapter->ps_size)); | 552 | afu->psn_phys = p2_base(dev) + (adapter->native->ps_off + (afu->slice * adapter->ps_size)); |
569 | afu_desc = p2_base(dev) + adapter->afu_desc_off + (afu->slice * adapter->afu_desc_size); | 553 | afu_desc = p2_base(dev) + adapter->native->afu_desc_off + (afu->slice * adapter->native->afu_desc_size); |
570 | 554 | ||
571 | if (!(afu->p1n_mmio = ioremap(p1n_base, p1n_size))) | 555 | if (!(afu->native->p1n_mmio = ioremap(p1n_base, p1n_size))) |
572 | goto err; | 556 | goto err; |
573 | if (!(afu->p2n_mmio = ioremap(p2n_base, p2n_size))) | 557 | if (!(afu->p2n_mmio = ioremap(p2n_base, p2n_size))) |
574 | goto err1; | 558 | goto err1; |
575 | if (afu_desc) { | 559 | if (afu_desc) { |
576 | if (!(afu->afu_desc_mmio = ioremap(afu_desc, adapter->afu_desc_size))) | 560 | if (!(afu->native->afu_desc_mmio = ioremap(afu_desc, adapter->native->afu_desc_size))) |
577 | goto err2; | 561 | goto err2; |
578 | } | 562 | } |
579 | 563 | ||
@@ -581,62 +565,41 @@ static int cxl_map_slice_regs(struct cxl_afu *afu, struct cxl *adapter, struct p | |||
581 | err2: | 565 | err2: |
582 | iounmap(afu->p2n_mmio); | 566 | iounmap(afu->p2n_mmio); |
583 | err1: | 567 | err1: |
584 | iounmap(afu->p1n_mmio); | 568 | iounmap(afu->native->p1n_mmio); |
585 | err: | 569 | err: |
586 | dev_err(&afu->dev, "Error mapping AFU MMIO regions\n"); | 570 | dev_err(&afu->dev, "Error mapping AFU MMIO regions\n"); |
587 | return -ENOMEM; | 571 | return -ENOMEM; |
588 | } | 572 | } |
589 | 573 | ||
590 | static void cxl_unmap_slice_regs(struct cxl_afu *afu) | 574 | static void pci_unmap_slice_regs(struct cxl_afu *afu) |
591 | { | 575 | { |
592 | if (afu->p2n_mmio) { | 576 | if (afu->p2n_mmio) { |
593 | iounmap(afu->p2n_mmio); | 577 | iounmap(afu->p2n_mmio); |
594 | afu->p2n_mmio = NULL; | 578 | afu->p2n_mmio = NULL; |
595 | } | 579 | } |
596 | if (afu->p1n_mmio) { | 580 | if (afu->native->p1n_mmio) { |
597 | iounmap(afu->p1n_mmio); | 581 | iounmap(afu->native->p1n_mmio); |
598 | afu->p1n_mmio = NULL; | 582 | afu->native->p1n_mmio = NULL; |
599 | } | 583 | } |
600 | if (afu->afu_desc_mmio) { | 584 | if (afu->native->afu_desc_mmio) { |
601 | iounmap(afu->afu_desc_mmio); | 585 | iounmap(afu->native->afu_desc_mmio); |
602 | afu->afu_desc_mmio = NULL; | 586 | afu->native->afu_desc_mmio = NULL; |
603 | } | 587 | } |
604 | } | 588 | } |
605 | 589 | ||
606 | static void cxl_release_afu(struct device *dev) | 590 | void cxl_pci_release_afu(struct device *dev) |
607 | { | 591 | { |
608 | struct cxl_afu *afu = to_cxl_afu(dev); | 592 | struct cxl_afu *afu = to_cxl_afu(dev); |
609 | 593 | ||
610 | pr_devel("cxl_release_afu\n"); | 594 | pr_devel("%s\n", __func__); |
611 | 595 | ||
612 | idr_destroy(&afu->contexts_idr); | 596 | idr_destroy(&afu->contexts_idr); |
613 | cxl_release_spa(afu); | 597 | cxl_release_spa(afu); |
614 | 598 | ||
599 | kfree(afu->native); | ||
615 | kfree(afu); | 600 | kfree(afu); |
616 | } | 601 | } |
617 | 602 | ||
618 | static struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice) | ||
619 | { | ||
620 | struct cxl_afu *afu; | ||
621 | |||
622 | if (!(afu = kzalloc(sizeof(struct cxl_afu), GFP_KERNEL))) | ||
623 | return NULL; | ||
624 | |||
625 | afu->adapter = adapter; | ||
626 | afu->dev.parent = &adapter->dev; | ||
627 | afu->dev.release = cxl_release_afu; | ||
628 | afu->slice = slice; | ||
629 | idr_init(&afu->contexts_idr); | ||
630 | mutex_init(&afu->contexts_lock); | ||
631 | spin_lock_init(&afu->afu_cntl_lock); | ||
632 | mutex_init(&afu->spa_mutex); | ||
633 | |||
634 | afu->prefault_mode = CXL_PREFAULT_NONE; | ||
635 | afu->irqs_max = afu->adapter->user_irqs; | ||
636 | |||
637 | return afu; | ||
638 | } | ||
639 | |||
640 | /* Expects AFU struct to have recently been zeroed out */ | 603 | /* Expects AFU struct to have recently been zeroed out */ |
641 | static int cxl_read_afu_descriptor(struct cxl_afu *afu) | 604 | static int cxl_read_afu_descriptor(struct cxl_afu *afu) |
642 | { | 605 | { |
@@ -658,7 +621,7 @@ static int cxl_read_afu_descriptor(struct cxl_afu *afu) | |||
658 | afu->pp_size = AFUD_PPPSA_LEN(val) * 4096; | 621 | afu->pp_size = AFUD_PPPSA_LEN(val) * 4096; |
659 | afu->psa = AFUD_PPPSA_PSA(val); | 622 | afu->psa = AFUD_PPPSA_PSA(val); |
660 | if ((afu->pp_psa = AFUD_PPPSA_PP(val))) | 623 | if ((afu->pp_psa = AFUD_PPPSA_PP(val))) |
661 | afu->pp_offset = AFUD_READ_PPPSA_OFF(afu); | 624 | afu->native->pp_offset = AFUD_READ_PPPSA_OFF(afu); |
662 | 625 | ||
663 | val = AFUD_READ_CR(afu); | 626 | val = AFUD_READ_CR(afu); |
664 | afu->crs_len = AFUD_CR_LEN(val) * 256; | 627 | afu->crs_len = AFUD_CR_LEN(val) * 256; |
@@ -685,10 +648,11 @@ static int cxl_read_afu_descriptor(struct cxl_afu *afu) | |||
685 | 648 | ||
686 | static int cxl_afu_descriptor_looks_ok(struct cxl_afu *afu) | 649 | static int cxl_afu_descriptor_looks_ok(struct cxl_afu *afu) |
687 | { | 650 | { |
688 | int i; | 651 | int i, rc; |
652 | u32 val; | ||
689 | 653 | ||
690 | if (afu->psa && afu->adapter->ps_size < | 654 | if (afu->psa && afu->adapter->ps_size < |
691 | (afu->pp_offset + afu->pp_size*afu->max_procs_virtualised)) { | 655 | (afu->native->pp_offset + afu->pp_size*afu->max_procs_virtualised)) { |
692 | dev_err(&afu->dev, "per-process PSA can't fit inside the PSA!\n"); | 656 | dev_err(&afu->dev, "per-process PSA can't fit inside the PSA!\n"); |
693 | return -ENODEV; | 657 | return -ENODEV; |
694 | } | 658 | } |
@@ -697,7 +661,8 @@ static int cxl_afu_descriptor_looks_ok(struct cxl_afu *afu) | |||
697 | dev_warn(&afu->dev, "AFU uses < PAGE_SIZE per-process PSA!"); | 661 | dev_warn(&afu->dev, "AFU uses < PAGE_SIZE per-process PSA!"); |
698 | 662 | ||
699 | for (i = 0; i < afu->crs_num; i++) { | 663 | for (i = 0; i < afu->crs_num; i++) { |
700 | if ((cxl_afu_cr_read32(afu, i, 0) == 0)) { | 664 | rc = cxl_ops->afu_cr_read32(afu, i, 0, &val); |
665 | if (rc || val == 0) { | ||
701 | dev_err(&afu->dev, "ABORTING: AFU configuration record %i is invalid\n", i); | 666 | dev_err(&afu->dev, "ABORTING: AFU configuration record %i is invalid\n", i); |
702 | return -EINVAL; | 667 | return -EINVAL; |
703 | } | 668 | } |
@@ -718,7 +683,7 @@ static int sanitise_afu_regs(struct cxl_afu *afu) | |||
718 | reg = cxl_p2n_read(afu, CXL_AFU_Cntl_An); | 683 | reg = cxl_p2n_read(afu, CXL_AFU_Cntl_An); |
719 | if ((reg & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) { | 684 | if ((reg & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) { |
720 | dev_warn(&afu->dev, "WARNING: AFU was not disabled: %#016llx\n", reg); | 685 | dev_warn(&afu->dev, "WARNING: AFU was not disabled: %#016llx\n", reg); |
721 | if (__cxl_afu_reset(afu)) | 686 | if (cxl_ops->afu_reset(afu)) |
722 | return -EIO; | 687 | return -EIO; |
723 | if (cxl_afu_disable(afu)) | 688 | if (cxl_afu_disable(afu)) |
724 | return -EIO; | 689 | return -EIO; |
@@ -766,13 +731,13 @@ static int sanitise_afu_regs(struct cxl_afu *afu) | |||
766 | * 4/8 bytes aligned access. So in case the requested offset/count arent 8 byte | 731 | * 4/8 bytes aligned access. So in case the requested offset/count arent 8 byte |
767 | * aligned the function uses a bounce buffer which can be max PAGE_SIZE. | 732 | * aligned the function uses a bounce buffer which can be max PAGE_SIZE. |
768 | */ | 733 | */ |
769 | ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf, | 734 | ssize_t cxl_pci_afu_read_err_buffer(struct cxl_afu *afu, char *buf, |
770 | loff_t off, size_t count) | 735 | loff_t off, size_t count) |
771 | { | 736 | { |
772 | loff_t aligned_start, aligned_end; | 737 | loff_t aligned_start, aligned_end; |
773 | size_t aligned_length; | 738 | size_t aligned_length; |
774 | void *tbuf; | 739 | void *tbuf; |
775 | const void __iomem *ebuf = afu->afu_desc_mmio + afu->eb_offset; | 740 | const void __iomem *ebuf = afu->native->afu_desc_mmio + afu->eb_offset; |
776 | 741 | ||
777 | if (count == 0 || off < 0 || (size_t)off >= afu->eb_len) | 742 | if (count == 0 || off < 0 || (size_t)off >= afu->eb_len) |
778 | return 0; | 743 | return 0; |
@@ -803,18 +768,18 @@ ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf, | |||
803 | return count; | 768 | return count; |
804 | } | 769 | } |
805 | 770 | ||
806 | static int cxl_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pci_dev *dev) | 771 | static int pci_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pci_dev *dev) |
807 | { | 772 | { |
808 | int rc; | 773 | int rc; |
809 | 774 | ||
810 | if ((rc = cxl_map_slice_regs(afu, adapter, dev))) | 775 | if ((rc = pci_map_slice_regs(afu, adapter, dev))) |
811 | return rc; | 776 | return rc; |
812 | 777 | ||
813 | if ((rc = sanitise_afu_regs(afu))) | 778 | if ((rc = sanitise_afu_regs(afu))) |
814 | goto err1; | 779 | goto err1; |
815 | 780 | ||
816 | /* We need to reset the AFU before we can read the AFU descriptor */ | 781 | /* We need to reset the AFU before we can read the AFU descriptor */ |
817 | if ((rc = __cxl_afu_reset(afu))) | 782 | if ((rc = cxl_ops->afu_reset(afu))) |
818 | goto err1; | 783 | goto err1; |
819 | 784 | ||
820 | if (cxl_verbose) | 785 | if (cxl_verbose) |
@@ -829,44 +794,50 @@ static int cxl_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pc | |||
829 | if ((rc = init_implementation_afu_regs(afu))) | 794 | if ((rc = init_implementation_afu_regs(afu))) |
830 | goto err1; | 795 | goto err1; |
831 | 796 | ||
832 | if ((rc = cxl_register_serr_irq(afu))) | 797 | if ((rc = cxl_native_register_serr_irq(afu))) |
833 | goto err1; | 798 | goto err1; |
834 | 799 | ||
835 | if ((rc = cxl_register_psl_irq(afu))) | 800 | if ((rc = cxl_native_register_psl_irq(afu))) |
836 | goto err2; | 801 | goto err2; |
837 | 802 | ||
838 | return 0; | 803 | return 0; |
839 | 804 | ||
840 | err2: | 805 | err2: |
841 | cxl_release_serr_irq(afu); | 806 | cxl_native_release_serr_irq(afu); |
842 | err1: | 807 | err1: |
843 | cxl_unmap_slice_regs(afu); | 808 | pci_unmap_slice_regs(afu); |
844 | return rc; | 809 | return rc; |
845 | } | 810 | } |
846 | 811 | ||
847 | static void cxl_deconfigure_afu(struct cxl_afu *afu) | 812 | static void pci_deconfigure_afu(struct cxl_afu *afu) |
848 | { | 813 | { |
849 | cxl_release_psl_irq(afu); | 814 | cxl_native_release_psl_irq(afu); |
850 | cxl_release_serr_irq(afu); | 815 | cxl_native_release_serr_irq(afu); |
851 | cxl_unmap_slice_regs(afu); | 816 | pci_unmap_slice_regs(afu); |
852 | } | 817 | } |
853 | 818 | ||
854 | static int cxl_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev) | 819 | static int pci_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev) |
855 | { | 820 | { |
856 | struct cxl_afu *afu; | 821 | struct cxl_afu *afu; |
857 | int rc; | 822 | int rc = -ENOMEM; |
858 | 823 | ||
859 | afu = cxl_alloc_afu(adapter, slice); | 824 | afu = cxl_alloc_afu(adapter, slice); |
860 | if (!afu) | 825 | if (!afu) |
861 | return -ENOMEM; | 826 | return -ENOMEM; |
862 | 827 | ||
828 | afu->native = kzalloc(sizeof(struct cxl_afu_native), GFP_KERNEL); | ||
829 | if (!afu->native) | ||
830 | goto err_free_afu; | ||
831 | |||
832 | mutex_init(&afu->native->spa_mutex); | ||
833 | |||
863 | rc = dev_set_name(&afu->dev, "afu%i.%i", adapter->adapter_num, slice); | 834 | rc = dev_set_name(&afu->dev, "afu%i.%i", adapter->adapter_num, slice); |
864 | if (rc) | 835 | if (rc) |
865 | goto err_free; | 836 | goto err_free_native; |
866 | 837 | ||
867 | rc = cxl_configure_afu(afu, adapter, dev); | 838 | rc = pci_configure_afu(afu, adapter, dev); |
868 | if (rc) | 839 | if (rc) |
869 | goto err_free; | 840 | goto err_free_native; |
870 | 841 | ||
871 | /* Don't care if this fails */ | 842 | /* Don't care if this fails */ |
872 | cxl_debugfs_afu_add(afu); | 843 | cxl_debugfs_afu_add(afu); |
@@ -889,24 +860,27 @@ static int cxl_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev) | |||
889 | return 0; | 860 | return 0; |
890 | 861 | ||
891 | err_put1: | 862 | err_put1: |
892 | cxl_deconfigure_afu(afu); | 863 | pci_deconfigure_afu(afu); |
893 | cxl_debugfs_afu_remove(afu); | 864 | cxl_debugfs_afu_remove(afu); |
894 | device_unregister(&afu->dev); | 865 | device_unregister(&afu->dev); |
895 | return rc; | 866 | return rc; |
896 | 867 | ||
897 | err_free: | 868 | err_free_native: |
869 | kfree(afu->native); | ||
870 | err_free_afu: | ||
898 | kfree(afu); | 871 | kfree(afu); |
899 | return rc; | 872 | return rc; |
900 | 873 | ||
901 | } | 874 | } |
902 | 875 | ||
903 | static void cxl_remove_afu(struct cxl_afu *afu) | 876 | static void cxl_pci_remove_afu(struct cxl_afu *afu) |
904 | { | 877 | { |
905 | pr_devel("cxl_remove_afu\n"); | 878 | pr_devel("%s\n", __func__); |
906 | 879 | ||
907 | if (!afu) | 880 | if (!afu) |
908 | return; | 881 | return; |
909 | 882 | ||
883 | cxl_pci_vphb_remove(afu); | ||
910 | cxl_sysfs_afu_remove(afu); | 884 | cxl_sysfs_afu_remove(afu); |
911 | cxl_debugfs_afu_remove(afu); | 885 | cxl_debugfs_afu_remove(afu); |
912 | 886 | ||
@@ -915,13 +889,13 @@ static void cxl_remove_afu(struct cxl_afu *afu) | |||
915 | spin_unlock(&afu->adapter->afu_list_lock); | 889 | spin_unlock(&afu->adapter->afu_list_lock); |
916 | 890 | ||
917 | cxl_context_detach_all(afu); | 891 | cxl_context_detach_all(afu); |
918 | cxl_afu_deactivate_mode(afu); | 892 | cxl_ops->afu_deactivate_mode(afu, afu->current_mode); |
919 | 893 | ||
920 | cxl_deconfigure_afu(afu); | 894 | pci_deconfigure_afu(afu); |
921 | device_unregister(&afu->dev); | 895 | device_unregister(&afu->dev); |
922 | } | 896 | } |
923 | 897 | ||
924 | int cxl_reset(struct cxl *adapter) | 898 | int cxl_pci_reset(struct cxl *adapter) |
925 | { | 899 | { |
926 | struct pci_dev *dev = to_pci_dev(adapter->dev.parent); | 900 | struct pci_dev *dev = to_pci_dev(adapter->dev.parent); |
927 | int rc; | 901 | int rc; |
@@ -955,17 +929,17 @@ static int cxl_map_adapter_regs(struct cxl *adapter, struct pci_dev *dev) | |||
955 | pr_devel("cxl_map_adapter_regs: p1: %#016llx %#llx, p2: %#016llx %#llx", | 929 | pr_devel("cxl_map_adapter_regs: p1: %#016llx %#llx, p2: %#016llx %#llx", |
956 | p1_base(dev), p1_size(dev), p2_base(dev), p2_size(dev)); | 930 | p1_base(dev), p1_size(dev), p2_base(dev), p2_size(dev)); |
957 | 931 | ||
958 | if (!(adapter->p1_mmio = ioremap(p1_base(dev), p1_size(dev)))) | 932 | if (!(adapter->native->p1_mmio = ioremap(p1_base(dev), p1_size(dev)))) |
959 | goto err3; | 933 | goto err3; |
960 | 934 | ||
961 | if (!(adapter->p2_mmio = ioremap(p2_base(dev), p2_size(dev)))) | 935 | if (!(adapter->native->p2_mmio = ioremap(p2_base(dev), p2_size(dev)))) |
962 | goto err4; | 936 | goto err4; |
963 | 937 | ||
964 | return 0; | 938 | return 0; |
965 | 939 | ||
966 | err4: | 940 | err4: |
967 | iounmap(adapter->p1_mmio); | 941 | iounmap(adapter->native->p1_mmio); |
968 | adapter->p1_mmio = NULL; | 942 | adapter->native->p1_mmio = NULL; |
969 | err3: | 943 | err3: |
970 | pci_release_region(dev, 0); | 944 | pci_release_region(dev, 0); |
971 | err2: | 945 | err2: |
@@ -976,14 +950,14 @@ err1: | |||
976 | 950 | ||
977 | static void cxl_unmap_adapter_regs(struct cxl *adapter) | 951 | static void cxl_unmap_adapter_regs(struct cxl *adapter) |
978 | { | 952 | { |
979 | if (adapter->p1_mmio) { | 953 | if (adapter->native->p1_mmio) { |
980 | iounmap(adapter->p1_mmio); | 954 | iounmap(adapter->native->p1_mmio); |
981 | adapter->p1_mmio = NULL; | 955 | adapter->native->p1_mmio = NULL; |
982 | pci_release_region(to_pci_dev(adapter->dev.parent), 2); | 956 | pci_release_region(to_pci_dev(adapter->dev.parent), 2); |
983 | } | 957 | } |
984 | if (adapter->p2_mmio) { | 958 | if (adapter->native->p2_mmio) { |
985 | iounmap(adapter->p2_mmio); | 959 | iounmap(adapter->native->p2_mmio); |
986 | adapter->p2_mmio = NULL; | 960 | adapter->native->p2_mmio = NULL; |
987 | pci_release_region(to_pci_dev(adapter->dev.parent), 0); | 961 | pci_release_region(to_pci_dev(adapter->dev.parent), 0); |
988 | } | 962 | } |
989 | } | 963 | } |
@@ -1024,10 +998,10 @@ static int cxl_read_vsec(struct cxl *adapter, struct pci_dev *dev) | |||
1024 | 998 | ||
1025 | /* Convert everything to bytes, because there is NO WAY I'd look at the | 999 | /* Convert everything to bytes, because there is NO WAY I'd look at the |
1026 | * code a month later and forget what units these are in ;-) */ | 1000 | * code a month later and forget what units these are in ;-) */ |
1027 | adapter->ps_off = ps_off * 64 * 1024; | 1001 | adapter->native->ps_off = ps_off * 64 * 1024; |
1028 | adapter->ps_size = ps_size * 64 * 1024; | 1002 | adapter->ps_size = ps_size * 64 * 1024; |
1029 | adapter->afu_desc_off = afu_desc_off * 64 * 1024; | 1003 | adapter->native->afu_desc_off = afu_desc_off * 64 * 1024; |
1030 | adapter->afu_desc_size = afu_desc_size *64 * 1024; | 1004 | adapter->native->afu_desc_size = afu_desc_size * 64 * 1024; |
1031 | 1005 | ||
1032 | /* Total IRQs - 1 PSL ERROR - #AFU*(1 slice error + 1 DSI) */ | 1006 | /* Total IRQs - 1 PSL ERROR - #AFU*(1 slice error + 1 DSI) */ |
1033 | adapter->user_irqs = pnv_cxl_get_irq_count(dev) - 1 - 2*adapter->slices; | 1007 | adapter->user_irqs = pnv_cxl_get_irq_count(dev) - 1 - 2*adapter->slices; |
@@ -1078,21 +1052,26 @@ static int cxl_vsec_looks_ok(struct cxl *adapter, struct pci_dev *dev) | |||
1078 | return -EINVAL; | 1052 | return -EINVAL; |
1079 | } | 1053 | } |
1080 | 1054 | ||
1081 | if (!adapter->afu_desc_off || !adapter->afu_desc_size) { | 1055 | if (!adapter->native->afu_desc_off || !adapter->native->afu_desc_size) { |
1082 | dev_err(&dev->dev, "ABORTING: VSEC shows no AFU descriptors\n"); | 1056 | dev_err(&dev->dev, "ABORTING: VSEC shows no AFU descriptors\n"); |
1083 | return -EINVAL; | 1057 | return -EINVAL; |
1084 | } | 1058 | } |
1085 | 1059 | ||
1086 | if (adapter->ps_size > p2_size(dev) - adapter->ps_off) { | 1060 | if (adapter->ps_size > p2_size(dev) - adapter->native->ps_off) { |
1087 | dev_err(&dev->dev, "ABORTING: Problem state size larger than " | 1061 | dev_err(&dev->dev, "ABORTING: Problem state size larger than " |
1088 | "available in BAR2: 0x%llx > 0x%llx\n", | 1062 | "available in BAR2: 0x%llx > 0x%llx\n", |
1089 | adapter->ps_size, p2_size(dev) - adapter->ps_off); | 1063 | adapter->ps_size, p2_size(dev) - adapter->native->ps_off); |
1090 | return -EINVAL; | 1064 | return -EINVAL; |
1091 | } | 1065 | } |
1092 | 1066 | ||
1093 | return 0; | 1067 | return 0; |
1094 | } | 1068 | } |
1095 | 1069 | ||
1070 | ssize_t cxl_pci_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len) | ||
1071 | { | ||
1072 | return pci_read_vpd(to_pci_dev(adapter->dev.parent), 0, len, buf); | ||
1073 | } | ||
1074 | |||
1096 | static void cxl_release_adapter(struct device *dev) | 1075 | static void cxl_release_adapter(struct device *dev) |
1097 | { | 1076 | { |
1098 | struct cxl *adapter = to_cxl_adapter(dev); | 1077 | struct cxl *adapter = to_cxl_adapter(dev); |
@@ -1101,33 +1080,10 @@ static void cxl_release_adapter(struct device *dev) | |||
1101 | 1080 | ||
1102 | cxl_remove_adapter_nr(adapter); | 1081 | cxl_remove_adapter_nr(adapter); |
1103 | 1082 | ||
1083 | kfree(adapter->native); | ||
1104 | kfree(adapter); | 1084 | kfree(adapter); |
1105 | } | 1085 | } |
1106 | 1086 | ||
1107 | static struct cxl *cxl_alloc_adapter(void) | ||
1108 | { | ||
1109 | struct cxl *adapter; | ||
1110 | |||
1111 | if (!(adapter = kzalloc(sizeof(struct cxl), GFP_KERNEL))) | ||
1112 | return NULL; | ||
1113 | |||
1114 | spin_lock_init(&adapter->afu_list_lock); | ||
1115 | |||
1116 | if (cxl_alloc_adapter_nr(adapter)) | ||
1117 | goto err1; | ||
1118 | |||
1119 | if (dev_set_name(&adapter->dev, "card%i", adapter->adapter_num)) | ||
1120 | goto err2; | ||
1121 | |||
1122 | return adapter; | ||
1123 | |||
1124 | err2: | ||
1125 | cxl_remove_adapter_nr(adapter); | ||
1126 | err1: | ||
1127 | kfree(adapter); | ||
1128 | return NULL; | ||
1129 | } | ||
1130 | |||
1131 | #define CXL_PSL_ErrIVTE_tberror (0x1ull << (63-31)) | 1087 | #define CXL_PSL_ErrIVTE_tberror (0x1ull << (63-31)) |
1132 | 1088 | ||
1133 | static int sanitise_adapter_regs(struct cxl *adapter) | 1089 | static int sanitise_adapter_regs(struct cxl *adapter) |
@@ -1191,7 +1147,7 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev) | |||
1191 | if ((rc = cxl_setup_psl_timebase(adapter, dev))) | 1147 | if ((rc = cxl_setup_psl_timebase(adapter, dev))) |
1192 | goto err; | 1148 | goto err; |
1193 | 1149 | ||
1194 | if ((rc = cxl_register_psl_err_irq(adapter))) | 1150 | if ((rc = cxl_native_register_psl_err_irq(adapter))) |
1195 | goto err; | 1151 | goto err; |
1196 | 1152 | ||
1197 | return 0; | 1153 | return 0; |
@@ -1206,13 +1162,13 @@ static void cxl_deconfigure_adapter(struct cxl *adapter) | |||
1206 | { | 1162 | { |
1207 | struct pci_dev *pdev = to_pci_dev(adapter->dev.parent); | 1163 | struct pci_dev *pdev = to_pci_dev(adapter->dev.parent); |
1208 | 1164 | ||
1209 | cxl_release_psl_err_irq(adapter); | 1165 | cxl_native_release_psl_err_irq(adapter); |
1210 | cxl_unmap_adapter_regs(adapter); | 1166 | cxl_unmap_adapter_regs(adapter); |
1211 | 1167 | ||
1212 | pci_disable_device(pdev); | 1168 | pci_disable_device(pdev); |
1213 | } | 1169 | } |
1214 | 1170 | ||
1215 | static struct cxl *cxl_init_adapter(struct pci_dev *dev) | 1171 | static struct cxl *cxl_pci_init_adapter(struct pci_dev *dev) |
1216 | { | 1172 | { |
1217 | struct cxl *adapter; | 1173 | struct cxl *adapter; |
1218 | int rc; | 1174 | int rc; |
@@ -1221,6 +1177,12 @@ static struct cxl *cxl_init_adapter(struct pci_dev *dev) | |||
1221 | if (!adapter) | 1177 | if (!adapter) |
1222 | return ERR_PTR(-ENOMEM); | 1178 | return ERR_PTR(-ENOMEM); |
1223 | 1179 | ||
1180 | adapter->native = kzalloc(sizeof(struct cxl_native), GFP_KERNEL); | ||
1181 | if (!adapter->native) { | ||
1182 | rc = -ENOMEM; | ||
1183 | goto err_release; | ||
1184 | } | ||
1185 | |||
1224 | /* Set defaults for parameters which need to persist over | 1186 | /* Set defaults for parameters which need to persist over |
1225 | * configure/reconfigure | 1187 | * configure/reconfigure |
1226 | */ | 1188 | */ |
@@ -1230,8 +1192,7 @@ static struct cxl *cxl_init_adapter(struct pci_dev *dev) | |||
1230 | rc = cxl_configure_adapter(adapter, dev); | 1192 | rc = cxl_configure_adapter(adapter, dev); |
1231 | if (rc) { | 1193 | if (rc) { |
1232 | pci_disable_device(dev); | 1194 | pci_disable_device(dev); |
1233 | cxl_release_adapter(&adapter->dev); | 1195 | goto err_release; |
1234 | return ERR_PTR(rc); | ||
1235 | } | 1196 | } |
1236 | 1197 | ||
1237 | /* Don't care if this one fails: */ | 1198 | /* Don't care if this one fails: */ |
@@ -1257,9 +1218,13 @@ err_put1: | |||
1257 | cxl_deconfigure_adapter(adapter); | 1218 | cxl_deconfigure_adapter(adapter); |
1258 | device_unregister(&adapter->dev); | 1219 | device_unregister(&adapter->dev); |
1259 | return ERR_PTR(rc); | 1220 | return ERR_PTR(rc); |
1221 | |||
1222 | err_release: | ||
1223 | cxl_release_adapter(&adapter->dev); | ||
1224 | return ERR_PTR(rc); | ||
1260 | } | 1225 | } |
1261 | 1226 | ||
1262 | static void cxl_remove_adapter(struct cxl *adapter) | 1227 | static void cxl_pci_remove_adapter(struct cxl *adapter) |
1263 | { | 1228 | { |
1264 | pr_devel("cxl_remove_adapter\n"); | 1229 | pr_devel("cxl_remove_adapter\n"); |
1265 | 1230 | ||
@@ -1277,17 +1242,22 @@ static int cxl_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1277 | int slice; | 1242 | int slice; |
1278 | int rc; | 1243 | int rc; |
1279 | 1244 | ||
1245 | if (cxl_pci_is_vphb_device(dev)) { | ||
1246 | dev_dbg(&dev->dev, "cxl_init_adapter: Ignoring cxl vphb device\n"); | ||
1247 | return -ENODEV; | ||
1248 | } | ||
1249 | |||
1280 | if (cxl_verbose) | 1250 | if (cxl_verbose) |
1281 | dump_cxl_config_space(dev); | 1251 | dump_cxl_config_space(dev); |
1282 | 1252 | ||
1283 | adapter = cxl_init_adapter(dev); | 1253 | adapter = cxl_pci_init_adapter(dev); |
1284 | if (IS_ERR(adapter)) { | 1254 | if (IS_ERR(adapter)) { |
1285 | dev_err(&dev->dev, "cxl_init_adapter failed: %li\n", PTR_ERR(adapter)); | 1255 | dev_err(&dev->dev, "cxl_init_adapter failed: %li\n", PTR_ERR(adapter)); |
1286 | return PTR_ERR(adapter); | 1256 | return PTR_ERR(adapter); |
1287 | } | 1257 | } |
1288 | 1258 | ||
1289 | for (slice = 0; slice < adapter->slices; slice++) { | 1259 | for (slice = 0; slice < adapter->slices; slice++) { |
1290 | if ((rc = cxl_init_afu(adapter, slice, dev))) { | 1260 | if ((rc = pci_init_afu(adapter, slice, dev))) { |
1291 | dev_err(&dev->dev, "AFU %i failed to initialise: %i\n", slice, rc); | 1261 | dev_err(&dev->dev, "AFU %i failed to initialise: %i\n", slice, rc); |
1292 | continue; | 1262 | continue; |
1293 | } | 1263 | } |
@@ -1312,10 +1282,9 @@ static void cxl_remove(struct pci_dev *dev) | |||
1312 | */ | 1282 | */ |
1313 | for (i = 0; i < adapter->slices; i++) { | 1283 | for (i = 0; i < adapter->slices; i++) { |
1314 | afu = adapter->afu[i]; | 1284 | afu = adapter->afu[i]; |
1315 | cxl_pci_vphb_remove(afu); | 1285 | cxl_pci_remove_afu(afu); |
1316 | cxl_remove_afu(afu); | ||
1317 | } | 1286 | } |
1318 | cxl_remove_adapter(adapter); | 1287 | cxl_pci_remove_adapter(adapter); |
1319 | } | 1288 | } |
1320 | 1289 | ||
1321 | static pci_ers_result_t cxl_vphb_error_detected(struct cxl_afu *afu, | 1290 | static pci_ers_result_t cxl_vphb_error_detected(struct cxl_afu *afu, |
@@ -1461,8 +1430,8 @@ static pci_ers_result_t cxl_pci_error_detected(struct pci_dev *pdev, | |||
1461 | return result; | 1430 | return result; |
1462 | 1431 | ||
1463 | cxl_context_detach_all(afu); | 1432 | cxl_context_detach_all(afu); |
1464 | cxl_afu_deactivate_mode(afu); | 1433 | cxl_ops->afu_deactivate_mode(afu, afu->current_mode); |
1465 | cxl_deconfigure_afu(afu); | 1434 | pci_deconfigure_afu(afu); |
1466 | } | 1435 | } |
1467 | cxl_deconfigure_adapter(adapter); | 1436 | cxl_deconfigure_adapter(adapter); |
1468 | 1437 | ||
@@ -1485,14 +1454,12 @@ static pci_ers_result_t cxl_pci_slot_reset(struct pci_dev *pdev) | |||
1485 | for (i = 0; i < adapter->slices; i++) { | 1454 | for (i = 0; i < adapter->slices; i++) { |
1486 | afu = adapter->afu[i]; | 1455 | afu = adapter->afu[i]; |
1487 | 1456 | ||
1488 | if (cxl_configure_afu(afu, adapter, pdev)) | 1457 | if (pci_configure_afu(afu, adapter, pdev)) |
1489 | goto err; | 1458 | goto err; |
1490 | 1459 | ||
1491 | if (cxl_afu_select_best_mode(afu)) | 1460 | if (cxl_afu_select_best_mode(afu)) |
1492 | goto err; | 1461 | goto err; |
1493 | 1462 | ||
1494 | cxl_pci_vphb_reconfigure(afu); | ||
1495 | |||
1496 | list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) { | 1463 | list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) { |
1497 | /* Reset the device context. | 1464 | /* Reset the device context. |
1498 | * TODO: make this less disruptive | 1465 | * TODO: make this less disruptive |
@@ -1508,7 +1475,7 @@ static pci_ers_result_t cxl_pci_slot_reset(struct pci_dev *pdev) | |||
1508 | 1475 | ||
1509 | afu_dev->dev.archdata.cxl_ctx = ctx; | 1476 | afu_dev->dev.archdata.cxl_ctx = ctx; |
1510 | 1477 | ||
1511 | if (cxl_afu_check_and_enable(afu)) | 1478 | if (cxl_ops->afu_check_and_enable(afu)) |
1512 | goto err; | 1479 | goto err; |
1513 | 1480 | ||
1514 | afu_dev->error_state = pci_channel_io_normal; | 1481 | afu_dev->error_state = pci_channel_io_normal; |
diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c index 038af5d45145..25913c08794c 100644 --- a/drivers/misc/cxl/sysfs.c +++ b/drivers/misc/cxl/sysfs.c | |||
@@ -69,7 +69,7 @@ static ssize_t reset_adapter_store(struct device *device, | |||
69 | if ((rc != 1) || (val != 1)) | 69 | if ((rc != 1) || (val != 1)) |
70 | return -EINVAL; | 70 | return -EINVAL; |
71 | 71 | ||
72 | if ((rc = cxl_reset(adapter))) | 72 | if ((rc = cxl_ops->adapter_reset(adapter))) |
73 | return rc; | 73 | return rc; |
74 | return count; | 74 | return count; |
75 | } | 75 | } |
@@ -165,7 +165,7 @@ static ssize_t pp_mmio_off_show(struct device *device, | |||
165 | { | 165 | { |
166 | struct cxl_afu *afu = to_afu_chardev_m(device); | 166 | struct cxl_afu *afu = to_afu_chardev_m(device); |
167 | 167 | ||
168 | return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->pp_offset); | 168 | return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->native->pp_offset); |
169 | } | 169 | } |
170 | 170 | ||
171 | static ssize_t pp_mmio_len_show(struct device *device, | 171 | static ssize_t pp_mmio_len_show(struct device *device, |
@@ -211,7 +211,7 @@ static ssize_t reset_store_afu(struct device *device, | |||
211 | goto err; | 211 | goto err; |
212 | } | 212 | } |
213 | 213 | ||
214 | if ((rc = __cxl_afu_reset(afu))) | 214 | if ((rc = cxl_ops->afu_reset(afu))) |
215 | goto err; | 215 | goto err; |
216 | 216 | ||
217 | rc = count; | 217 | rc = count; |
@@ -253,8 +253,14 @@ static ssize_t irqs_max_store(struct device *device, | |||
253 | if (irqs_max < afu->pp_irqs) | 253 | if (irqs_max < afu->pp_irqs) |
254 | return -EINVAL; | 254 | return -EINVAL; |
255 | 255 | ||
256 | if (irqs_max > afu->adapter->user_irqs) | 256 | if (cpu_has_feature(CPU_FTR_HVMODE)) { |
257 | return -EINVAL; | 257 | if (irqs_max > afu->adapter->user_irqs) |
258 | return -EINVAL; | ||
259 | } else { | ||
260 | /* pHyp sets a per-AFU limit */ | ||
261 | if (irqs_max > afu->guest->max_ints) | ||
262 | return -EINVAL; | ||
263 | } | ||
258 | 264 | ||
259 | afu->irqs_max = irqs_max; | 265 | afu->irqs_max = irqs_max; |
260 | return count; | 266 | return count; |
@@ -348,7 +354,7 @@ static ssize_t mode_store(struct device *device, struct device_attribute *attr, | |||
348 | } | 354 | } |
349 | 355 | ||
350 | /* | 356 | /* |
351 | * cxl_afu_deactivate_mode needs to be done outside the lock, prevent | 357 | * afu_deactivate_mode needs to be done outside the lock, prevent |
352 | * other contexts coming in before we are ready: | 358 | * other contexts coming in before we are ready: |
353 | */ | 359 | */ |
354 | old_mode = afu->current_mode; | 360 | old_mode = afu->current_mode; |
@@ -357,9 +363,9 @@ static ssize_t mode_store(struct device *device, struct device_attribute *attr, | |||
357 | 363 | ||
358 | mutex_unlock(&afu->contexts_lock); | 364 | mutex_unlock(&afu->contexts_lock); |
359 | 365 | ||
360 | if ((rc = _cxl_afu_deactivate_mode(afu, old_mode))) | 366 | if ((rc = cxl_ops->afu_deactivate_mode(afu, old_mode))) |
361 | return rc; | 367 | return rc; |
362 | if ((rc = cxl_afu_activate_mode(afu, mode))) | 368 | if ((rc = cxl_ops->afu_activate_mode(afu, mode))) |
363 | return rc; | 369 | return rc; |
364 | 370 | ||
365 | return count; | 371 | return count; |
@@ -388,7 +394,7 @@ static ssize_t afu_eb_read(struct file *filp, struct kobject *kobj, | |||
388 | { | 394 | { |
389 | struct cxl_afu *afu = to_cxl_afu(kobj_to_dev(kobj)); | 395 | struct cxl_afu *afu = to_cxl_afu(kobj_to_dev(kobj)); |
390 | 396 | ||
391 | return cxl_afu_read_err_buffer(afu, buf, off, count); | 397 | return cxl_ops->afu_read_err_buffer(afu, buf, off, count); |
392 | } | 398 | } |
393 | 399 | ||
394 | static struct device_attribute afu_attrs[] = { | 400 | static struct device_attribute afu_attrs[] = { |
@@ -405,24 +411,39 @@ static struct device_attribute afu_attrs[] = { | |||
405 | 411 | ||
406 | int cxl_sysfs_adapter_add(struct cxl *adapter) | 412 | int cxl_sysfs_adapter_add(struct cxl *adapter) |
407 | { | 413 | { |
414 | struct device_attribute *dev_attr; | ||
408 | int i, rc; | 415 | int i, rc; |
409 | 416 | ||
410 | for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) { | 417 | for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) { |
411 | if ((rc = device_create_file(&adapter->dev, &adapter_attrs[i]))) | 418 | dev_attr = &adapter_attrs[i]; |
412 | goto err; | 419 | if (cxl_ops->support_attributes(dev_attr->attr.name, |
420 | CXL_ADAPTER_ATTRS)) { | ||
421 | if ((rc = device_create_file(&adapter->dev, dev_attr))) | ||
422 | goto err; | ||
423 | } | ||
413 | } | 424 | } |
414 | return 0; | 425 | return 0; |
415 | err: | 426 | err: |
416 | for (i--; i >= 0; i--) | 427 | for (i--; i >= 0; i--) { |
417 | device_remove_file(&adapter->dev, &adapter_attrs[i]); | 428 | dev_attr = &adapter_attrs[i]; |
429 | if (cxl_ops->support_attributes(dev_attr->attr.name, | ||
430 | CXL_ADAPTER_ATTRS)) | ||
431 | device_remove_file(&adapter->dev, dev_attr); | ||
432 | } | ||
418 | return rc; | 433 | return rc; |
419 | } | 434 | } |
435 | |||
420 | void cxl_sysfs_adapter_remove(struct cxl *adapter) | 436 | void cxl_sysfs_adapter_remove(struct cxl *adapter) |
421 | { | 437 | { |
438 | struct device_attribute *dev_attr; | ||
422 | int i; | 439 | int i; |
423 | 440 | ||
424 | for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) | 441 | for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) { |
425 | device_remove_file(&adapter->dev, &adapter_attrs[i]); | 442 | dev_attr = &adapter_attrs[i]; |
443 | if (cxl_ops->support_attributes(dev_attr->attr.name, | ||
444 | CXL_ADAPTER_ATTRS)) | ||
445 | device_remove_file(&adapter->dev, dev_attr); | ||
446 | } | ||
426 | } | 447 | } |
427 | 448 | ||
428 | struct afu_config_record { | 449 | struct afu_config_record { |
@@ -468,10 +489,12 @@ static ssize_t afu_read_config(struct file *filp, struct kobject *kobj, | |||
468 | struct afu_config_record *cr = to_cr(kobj); | 489 | struct afu_config_record *cr = to_cr(kobj); |
469 | struct cxl_afu *afu = to_cxl_afu(kobj_to_dev(kobj->parent)); | 490 | struct cxl_afu *afu = to_cxl_afu(kobj_to_dev(kobj->parent)); |
470 | 491 | ||
471 | u64 i, j, val; | 492 | u64 i, j, val, rc; |
472 | 493 | ||
473 | for (i = 0; i < count;) { | 494 | for (i = 0; i < count;) { |
474 | val = cxl_afu_cr_read64(afu, cr->cr, off & ~0x7); | 495 | rc = cxl_ops->afu_cr_read64(afu, cr->cr, off & ~0x7, &val); |
496 | if (rc) | ||
497 | val = ~0ULL; | ||
475 | for (j = off & 0x7; j < 8 && i < count; i++, j++, off++) | 498 | for (j = off & 0x7; j < 8 && i < count; i++, j++, off++) |
476 | buf[i] = (val >> (j * 8)) & 0xff; | 499 | buf[i] = (val >> (j * 8)) & 0xff; |
477 | } | 500 | } |
@@ -516,14 +539,22 @@ static struct afu_config_record *cxl_sysfs_afu_new_cr(struct cxl_afu *afu, int c | |||
516 | return ERR_PTR(-ENOMEM); | 539 | return ERR_PTR(-ENOMEM); |
517 | 540 | ||
518 | cr->cr = cr_idx; | 541 | cr->cr = cr_idx; |
519 | cr->device = cxl_afu_cr_read16(afu, cr_idx, PCI_DEVICE_ID); | 542 | |
520 | cr->vendor = cxl_afu_cr_read16(afu, cr_idx, PCI_VENDOR_ID); | 543 | rc = cxl_ops->afu_cr_read16(afu, cr_idx, PCI_DEVICE_ID, &cr->device); |
521 | cr->class = cxl_afu_cr_read32(afu, cr_idx, PCI_CLASS_REVISION) >> 8; | 544 | if (rc) |
545 | goto err; | ||
546 | rc = cxl_ops->afu_cr_read16(afu, cr_idx, PCI_VENDOR_ID, &cr->vendor); | ||
547 | if (rc) | ||
548 | goto err; | ||
549 | rc = cxl_ops->afu_cr_read32(afu, cr_idx, PCI_CLASS_REVISION, &cr->class); | ||
550 | if (rc) | ||
551 | goto err; | ||
552 | cr->class >>= 8; | ||
522 | 553 | ||
523 | /* | 554 | /* |
524 | * Export raw AFU PCIe like config record. For now this is read only by | 555 | * Export raw AFU PCIe like config record. For now this is read only by |
525 | * root - we can expand that later to be readable by non-root and maybe | 556 | * root - we can expand that later to be readable by non-root and maybe |
526 | * even writable provided we have a good use-case. Once we suport | 557 | * even writable provided we have a good use-case. Once we support |
527 | * exposing AFUs through a virtual PHB they will get that for free from | 558 | * exposing AFUs through a virtual PHB they will get that for free from |
528 | * Linux' PCI infrastructure, but until then it's not clear that we | 559 | * Linux' PCI infrastructure, but until then it's not clear that we |
529 | * need it for anything since the main use case is just identifying | 560 | * need it for anything since the main use case is just identifying |
@@ -561,6 +592,7 @@ err: | |||
561 | 592 | ||
562 | void cxl_sysfs_afu_remove(struct cxl_afu *afu) | 593 | void cxl_sysfs_afu_remove(struct cxl_afu *afu) |
563 | { | 594 | { |
595 | struct device_attribute *dev_attr; | ||
564 | struct afu_config_record *cr, *tmp; | 596 | struct afu_config_record *cr, *tmp; |
565 | int i; | 597 | int i; |
566 | 598 | ||
@@ -568,8 +600,12 @@ void cxl_sysfs_afu_remove(struct cxl_afu *afu) | |||
568 | if (afu->eb_len) | 600 | if (afu->eb_len) |
569 | device_remove_bin_file(&afu->dev, &afu->attr_eb); | 601 | device_remove_bin_file(&afu->dev, &afu->attr_eb); |
570 | 602 | ||
571 | for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) | 603 | for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) { |
572 | device_remove_file(&afu->dev, &afu_attrs[i]); | 604 | dev_attr = &afu_attrs[i]; |
605 | if (cxl_ops->support_attributes(dev_attr->attr.name, | ||
606 | CXL_AFU_ATTRS)) | ||
607 | device_remove_file(&afu->dev, &afu_attrs[i]); | ||
608 | } | ||
573 | 609 | ||
574 | list_for_each_entry_safe(cr, tmp, &afu->crs, list) { | 610 | list_for_each_entry_safe(cr, tmp, &afu->crs, list) { |
575 | sysfs_remove_bin_file(&cr->kobj, &cr->config_attr); | 611 | sysfs_remove_bin_file(&cr->kobj, &cr->config_attr); |
@@ -579,14 +615,19 @@ void cxl_sysfs_afu_remove(struct cxl_afu *afu) | |||
579 | 615 | ||
580 | int cxl_sysfs_afu_add(struct cxl_afu *afu) | 616 | int cxl_sysfs_afu_add(struct cxl_afu *afu) |
581 | { | 617 | { |
618 | struct device_attribute *dev_attr; | ||
582 | struct afu_config_record *cr; | 619 | struct afu_config_record *cr; |
583 | int i, rc; | 620 | int i, rc; |
584 | 621 | ||
585 | INIT_LIST_HEAD(&afu->crs); | 622 | INIT_LIST_HEAD(&afu->crs); |
586 | 623 | ||
587 | for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) { | 624 | for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) { |
588 | if ((rc = device_create_file(&afu->dev, &afu_attrs[i]))) | 625 | dev_attr = &afu_attrs[i]; |
589 | goto err; | 626 | if (cxl_ops->support_attributes(dev_attr->attr.name, |
627 | CXL_AFU_ATTRS)) { | ||
628 | if ((rc = device_create_file(&afu->dev, &afu_attrs[i]))) | ||
629 | goto err; | ||
630 | } | ||
590 | } | 631 | } |
591 | 632 | ||
592 | /* conditionally create the add the binary file for error info buffer */ | 633 | /* conditionally create the add the binary file for error info buffer */ |
@@ -625,32 +666,50 @@ err: | |||
625 | /* reset the eb_len as we havent created the bin attr */ | 666 | /* reset the eb_len as we havent created the bin attr */ |
626 | afu->eb_len = 0; | 667 | afu->eb_len = 0; |
627 | 668 | ||
628 | for (i--; i >= 0; i--) | 669 | for (i--; i >= 0; i--) { |
670 | dev_attr = &afu_attrs[i]; | ||
671 | if (cxl_ops->support_attributes(dev_attr->attr.name, | ||
672 | CXL_AFU_ATTRS)) | ||
629 | device_remove_file(&afu->dev, &afu_attrs[i]); | 673 | device_remove_file(&afu->dev, &afu_attrs[i]); |
674 | } | ||
630 | return rc; | 675 | return rc; |
631 | } | 676 | } |
632 | 677 | ||
633 | int cxl_sysfs_afu_m_add(struct cxl_afu *afu) | 678 | int cxl_sysfs_afu_m_add(struct cxl_afu *afu) |
634 | { | 679 | { |
680 | struct device_attribute *dev_attr; | ||
635 | int i, rc; | 681 | int i, rc; |
636 | 682 | ||
637 | for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) { | 683 | for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) { |
638 | if ((rc = device_create_file(afu->chardev_m, &afu_master_attrs[i]))) | 684 | dev_attr = &afu_master_attrs[i]; |
639 | goto err; | 685 | if (cxl_ops->support_attributes(dev_attr->attr.name, |
686 | CXL_AFU_MASTER_ATTRS)) { | ||
687 | if ((rc = device_create_file(afu->chardev_m, &afu_master_attrs[i]))) | ||
688 | goto err; | ||
689 | } | ||
640 | } | 690 | } |
641 | 691 | ||
642 | return 0; | 692 | return 0; |
643 | 693 | ||
644 | err: | 694 | err: |
645 | for (i--; i >= 0; i--) | 695 | for (i--; i >= 0; i--) { |
646 | device_remove_file(afu->chardev_m, &afu_master_attrs[i]); | 696 | dev_attr = &afu_master_attrs[i]; |
697 | if (cxl_ops->support_attributes(dev_attr->attr.name, | ||
698 | CXL_AFU_MASTER_ATTRS)) | ||
699 | device_remove_file(afu->chardev_m, &afu_master_attrs[i]); | ||
700 | } | ||
647 | return rc; | 701 | return rc; |
648 | } | 702 | } |
649 | 703 | ||
650 | void cxl_sysfs_afu_m_remove(struct cxl_afu *afu) | 704 | void cxl_sysfs_afu_m_remove(struct cxl_afu *afu) |
651 | { | 705 | { |
706 | struct device_attribute *dev_attr; | ||
652 | int i; | 707 | int i; |
653 | 708 | ||
654 | for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) | 709 | for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) { |
655 | device_remove_file(afu->chardev_m, &afu_master_attrs[i]); | 710 | dev_attr = &afu_master_attrs[i]; |
711 | if (cxl_ops->support_attributes(dev_attr->attr.name, | ||
712 | CXL_AFU_MASTER_ATTRS)) | ||
713 | device_remove_file(afu->chardev_m, &afu_master_attrs[i]); | ||
714 | } | ||
656 | } | 715 | } |
diff --git a/drivers/misc/cxl/trace.h b/drivers/misc/cxl/trace.h index 6e1e2adfba8e..751d6119683e 100644 --- a/drivers/misc/cxl/trace.h +++ b/drivers/misc/cxl/trace.h | |||
@@ -450,6 +450,199 @@ DEFINE_EVENT(cxl_pe_class, cxl_slbia, | |||
450 | TP_ARGS(ctx) | 450 | TP_ARGS(ctx) |
451 | ); | 451 | ); |
452 | 452 | ||
453 | TRACE_EVENT(cxl_hcall, | ||
454 | TP_PROTO(u64 unit_address, u64 process_token, long rc), | ||
455 | |||
456 | TP_ARGS(unit_address, process_token, rc), | ||
457 | |||
458 | TP_STRUCT__entry( | ||
459 | __field(u64, unit_address) | ||
460 | __field(u64, process_token) | ||
461 | __field(long, rc) | ||
462 | ), | ||
463 | |||
464 | TP_fast_assign( | ||
465 | __entry->unit_address = unit_address; | ||
466 | __entry->process_token = process_token; | ||
467 | __entry->rc = rc; | ||
468 | ), | ||
469 | |||
470 | TP_printk("unit_address=0x%016llx process_token=0x%016llx rc=%li", | ||
471 | __entry->unit_address, | ||
472 | __entry->process_token, | ||
473 | __entry->rc | ||
474 | ) | ||
475 | ); | ||
476 | |||
477 | TRACE_EVENT(cxl_hcall_control, | ||
478 | TP_PROTO(u64 unit_address, char *fct, u64 p1, u64 p2, u64 p3, | ||
479 | u64 p4, unsigned long r4, long rc), | ||
480 | |||
481 | TP_ARGS(unit_address, fct, p1, p2, p3, p4, r4, rc), | ||
482 | |||
483 | TP_STRUCT__entry( | ||
484 | __field(u64, unit_address) | ||
485 | __field(char *, fct) | ||
486 | __field(u64, p1) | ||
487 | __field(u64, p2) | ||
488 | __field(u64, p3) | ||
489 | __field(u64, p4) | ||
490 | __field(unsigned long, r4) | ||
491 | __field(long, rc) | ||
492 | ), | ||
493 | |||
494 | TP_fast_assign( | ||
495 | __entry->unit_address = unit_address; | ||
496 | __entry->fct = fct; | ||
497 | __entry->p1 = p1; | ||
498 | __entry->p2 = p2; | ||
499 | __entry->p3 = p3; | ||
500 | __entry->p4 = p4; | ||
501 | __entry->r4 = r4; | ||
502 | __entry->rc = rc; | ||
503 | ), | ||
504 | |||
505 | TP_printk("unit_address=%#.16llx %s(%#llx, %#llx, %#llx, %#llx, R4: %#lx)): %li", | ||
506 | __entry->unit_address, | ||
507 | __entry->fct, | ||
508 | __entry->p1, | ||
509 | __entry->p2, | ||
510 | __entry->p3, | ||
511 | __entry->p4, | ||
512 | __entry->r4, | ||
513 | __entry->rc | ||
514 | ) | ||
515 | ); | ||
516 | |||
517 | TRACE_EVENT(cxl_hcall_attach, | ||
518 | TP_PROTO(u64 unit_address, u64 phys_addr, unsigned long process_token, | ||
519 | unsigned long mmio_addr, unsigned long mmio_size, long rc), | ||
520 | |||
521 | TP_ARGS(unit_address, phys_addr, process_token, | ||
522 | mmio_addr, mmio_size, rc), | ||
523 | |||
524 | TP_STRUCT__entry( | ||
525 | __field(u64, unit_address) | ||
526 | __field(u64, phys_addr) | ||
527 | __field(unsigned long, process_token) | ||
528 | __field(unsigned long, mmio_addr) | ||
529 | __field(unsigned long, mmio_size) | ||
530 | __field(long, rc) | ||
531 | ), | ||
532 | |||
533 | TP_fast_assign( | ||
534 | __entry->unit_address = unit_address; | ||
535 | __entry->phys_addr = phys_addr; | ||
536 | __entry->process_token = process_token; | ||
537 | __entry->mmio_addr = mmio_addr; | ||
538 | __entry->mmio_size = mmio_size; | ||
539 | __entry->rc = rc; | ||
540 | ), | ||
541 | |||
542 | TP_printk("unit_address=0x%016llx phys_addr=0x%016llx " | ||
543 | "token=0x%.8lx mmio_addr=0x%lx mmio_size=0x%lx rc=%li", | ||
544 | __entry->unit_address, | ||
545 | __entry->phys_addr, | ||
546 | __entry->process_token, | ||
547 | __entry->mmio_addr, | ||
548 | __entry->mmio_size, | ||
549 | __entry->rc | ||
550 | ) | ||
551 | ); | ||
552 | |||
553 | DEFINE_EVENT(cxl_hcall, cxl_hcall_detach, | ||
554 | TP_PROTO(u64 unit_address, u64 process_token, long rc), | ||
555 | TP_ARGS(unit_address, process_token, rc) | ||
556 | ); | ||
557 | |||
558 | DEFINE_EVENT(cxl_hcall_control, cxl_hcall_control_function, | ||
559 | TP_PROTO(u64 unit_address, char *fct, u64 p1, u64 p2, u64 p3, | ||
560 | u64 p4, unsigned long r4, long rc), | ||
561 | TP_ARGS(unit_address, fct, p1, p2, p3, p4, r4, rc) | ||
562 | ); | ||
563 | |||
564 | DEFINE_EVENT(cxl_hcall, cxl_hcall_collect_int_info, | ||
565 | TP_PROTO(u64 unit_address, u64 process_token, long rc), | ||
566 | TP_ARGS(unit_address, process_token, rc) | ||
567 | ); | ||
568 | |||
569 | TRACE_EVENT(cxl_hcall_control_faults, | ||
570 | TP_PROTO(u64 unit_address, u64 process_token, | ||
571 | u64 control_mask, u64 reset_mask, unsigned long r4, | ||
572 | long rc), | ||
573 | |||
574 | TP_ARGS(unit_address, process_token, | ||
575 | control_mask, reset_mask, r4, rc), | ||
576 | |||
577 | TP_STRUCT__entry( | ||
578 | __field(u64, unit_address) | ||
579 | __field(u64, process_token) | ||
580 | __field(u64, control_mask) | ||
581 | __field(u64, reset_mask) | ||
582 | __field(unsigned long, r4) | ||
583 | __field(long, rc) | ||
584 | ), | ||
585 | |||
586 | TP_fast_assign( | ||
587 | __entry->unit_address = unit_address; | ||
588 | __entry->process_token = process_token; | ||
589 | __entry->control_mask = control_mask; | ||
590 | __entry->reset_mask = reset_mask; | ||
591 | __entry->r4 = r4; | ||
592 | __entry->rc = rc; | ||
593 | ), | ||
594 | |||
595 | TP_printk("unit_address=0x%016llx process_token=0x%llx " | ||
596 | "control_mask=%#llx reset_mask=%#llx r4=%#lx rc=%li", | ||
597 | __entry->unit_address, | ||
598 | __entry->process_token, | ||
599 | __entry->control_mask, | ||
600 | __entry->reset_mask, | ||
601 | __entry->r4, | ||
602 | __entry->rc | ||
603 | ) | ||
604 | ); | ||
605 | |||
606 | DEFINE_EVENT(cxl_hcall_control, cxl_hcall_control_facility, | ||
607 | TP_PROTO(u64 unit_address, char *fct, u64 p1, u64 p2, u64 p3, | ||
608 | u64 p4, unsigned long r4, long rc), | ||
609 | TP_ARGS(unit_address, fct, p1, p2, p3, p4, r4, rc) | ||
610 | ); | ||
611 | |||
612 | TRACE_EVENT(cxl_hcall_download_facility, | ||
613 | TP_PROTO(u64 unit_address, char *fct, u64 list_address, u64 num, | ||
614 | unsigned long r4, long rc), | ||
615 | |||
616 | TP_ARGS(unit_address, fct, list_address, num, r4, rc), | ||
617 | |||
618 | TP_STRUCT__entry( | ||
619 | __field(u64, unit_address) | ||
620 | __field(char *, fct) | ||
621 | __field(u64, list_address) | ||
622 | __field(u64, num) | ||
623 | __field(unsigned long, r4) | ||
624 | __field(long, rc) | ||
625 | ), | ||
626 | |||
627 | TP_fast_assign( | ||
628 | __entry->unit_address = unit_address; | ||
629 | __entry->fct = fct; | ||
630 | __entry->list_address = list_address; | ||
631 | __entry->num = num; | ||
632 | __entry->r4 = r4; | ||
633 | __entry->rc = rc; | ||
634 | ), | ||
635 | |||
636 | TP_printk("%#.16llx, %s(%#llx, %#llx), %#lx): %li", | ||
637 | __entry->unit_address, | ||
638 | __entry->fct, | ||
639 | __entry->list_address, | ||
640 | __entry->num, | ||
641 | __entry->r4, | ||
642 | __entry->rc | ||
643 | ) | ||
644 | ); | ||
645 | |||
453 | #endif /* _CXL_TRACE_H */ | 646 | #endif /* _CXL_TRACE_H */ |
454 | 647 | ||
455 | /* This part must be outside protection */ | 648 | /* This part must be outside protection */ |
diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c index cbd4331fb45c..cdc7723b845d 100644 --- a/drivers/misc/cxl/vphb.c +++ b/drivers/misc/cxl/vphb.c | |||
@@ -49,7 +49,7 @@ static bool cxl_pci_enable_device_hook(struct pci_dev *dev) | |||
49 | phb = pci_bus_to_host(dev->bus); | 49 | phb = pci_bus_to_host(dev->bus); |
50 | afu = (struct cxl_afu *)phb->private_data; | 50 | afu = (struct cxl_afu *)phb->private_data; |
51 | 51 | ||
52 | if (!cxl_adapter_link_ok(afu->adapter)) { | 52 | if (!cxl_ops->link_ok(afu->adapter, afu)) { |
53 | dev_warn(&dev->dev, "%s: Device link is down, refusing to enable AFU\n", __func__); | 53 | dev_warn(&dev->dev, "%s: Device link is down, refusing to enable AFU\n", __func__); |
54 | return false; | 54 | return false; |
55 | } | 55 | } |
@@ -66,7 +66,7 @@ static bool cxl_pci_enable_device_hook(struct pci_dev *dev) | |||
66 | return false; | 66 | return false; |
67 | dev->dev.archdata.cxl_ctx = ctx; | 67 | dev->dev.archdata.cxl_ctx = ctx; |
68 | 68 | ||
69 | return (cxl_afu_check_and_enable(afu) == 0); | 69 | return (cxl_ops->afu_check_and_enable(afu) == 0); |
70 | } | 70 | } |
71 | 71 | ||
72 | static void cxl_pci_disable_device(struct pci_dev *dev) | 72 | static void cxl_pci_disable_device(struct pci_dev *dev) |
@@ -99,113 +99,90 @@ static int cxl_pcie_cfg_record(u8 bus, u8 devfn) | |||
99 | return (bus << 8) + devfn; | 99 | return (bus << 8) + devfn; |
100 | } | 100 | } |
101 | 101 | ||
102 | static unsigned long cxl_pcie_cfg_addr(struct pci_controller* phb, | ||
103 | u8 bus, u8 devfn, int offset) | ||
104 | { | ||
105 | int record = cxl_pcie_cfg_record(bus, devfn); | ||
106 | |||
107 | return (unsigned long)phb->cfg_addr + ((unsigned long)phb->cfg_data * record) + offset; | ||
108 | } | ||
109 | |||
110 | |||
111 | static int cxl_pcie_config_info(struct pci_bus *bus, unsigned int devfn, | 102 | static int cxl_pcie_config_info(struct pci_bus *bus, unsigned int devfn, |
112 | int offset, int len, | 103 | struct cxl_afu **_afu, int *_record) |
113 | volatile void __iomem **ioaddr, | ||
114 | u32 *mask, int *shift) | ||
115 | { | 104 | { |
116 | struct pci_controller *phb; | 105 | struct pci_controller *phb; |
117 | struct cxl_afu *afu; | 106 | struct cxl_afu *afu; |
118 | unsigned long addr; | 107 | int record; |
119 | 108 | ||
120 | phb = pci_bus_to_host(bus); | 109 | phb = pci_bus_to_host(bus); |
121 | if (phb == NULL) | 110 | if (phb == NULL) |
122 | return PCIBIOS_DEVICE_NOT_FOUND; | 111 | return PCIBIOS_DEVICE_NOT_FOUND; |
123 | afu = (struct cxl_afu *)phb->private_data; | ||
124 | 112 | ||
125 | if (cxl_pcie_cfg_record(bus->number, devfn) > afu->crs_num) | 113 | afu = (struct cxl_afu *)phb->private_data; |
114 | record = cxl_pcie_cfg_record(bus->number, devfn); | ||
115 | if (record > afu->crs_num) | ||
126 | return PCIBIOS_DEVICE_NOT_FOUND; | 116 | return PCIBIOS_DEVICE_NOT_FOUND; |
127 | if (offset >= (unsigned long)phb->cfg_data) | ||
128 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
129 | addr = cxl_pcie_cfg_addr(phb, bus->number, devfn, offset); | ||
130 | 117 | ||
131 | *ioaddr = (void *)(addr & ~0x3ULL); | 118 | *_afu = afu; |
132 | *shift = ((addr & 0x3) * 8); | 119 | *_record = record; |
133 | switch (len) { | ||
134 | case 1: | ||
135 | *mask = 0xff; | ||
136 | break; | ||
137 | case 2: | ||
138 | *mask = 0xffff; | ||
139 | break; | ||
140 | default: | ||
141 | *mask = 0xffffffff; | ||
142 | break; | ||
143 | } | ||
144 | return 0; | 120 | return 0; |
145 | } | 121 | } |
146 | 122 | ||
147 | |||
148 | static inline bool cxl_config_link_ok(struct pci_bus *bus) | ||
149 | { | ||
150 | struct pci_controller *phb; | ||
151 | struct cxl_afu *afu; | ||
152 | |||
153 | /* Config space IO is based on phb->cfg_addr, which is based on | ||
154 | * afu_desc_mmio. This isn't safe to read/write when the link | ||
155 | * goes down, as EEH tears down MMIO space. | ||
156 | * | ||
157 | * Check if the link is OK before proceeding. | ||
158 | */ | ||
159 | |||
160 | phb = pci_bus_to_host(bus); | ||
161 | if (phb == NULL) | ||
162 | return false; | ||
163 | afu = (struct cxl_afu *)phb->private_data; | ||
164 | return cxl_adapter_link_ok(afu->adapter); | ||
165 | } | ||
166 | |||
167 | static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn, | 123 | static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn, |
168 | int offset, int len, u32 *val) | 124 | int offset, int len, u32 *val) |
169 | { | 125 | { |
170 | volatile void __iomem *ioaddr; | 126 | int rc, record; |
171 | int shift, rc; | 127 | struct cxl_afu *afu; |
172 | u32 mask; | 128 | u8 val8; |
129 | u16 val16; | ||
130 | u32 val32; | ||
173 | 131 | ||
174 | rc = cxl_pcie_config_info(bus, devfn, offset, len, &ioaddr, | 132 | rc = cxl_pcie_config_info(bus, devfn, &afu, &record); |
175 | &mask, &shift); | ||
176 | if (rc) | 133 | if (rc) |
177 | return rc; | 134 | return rc; |
178 | 135 | ||
179 | if (!cxl_config_link_ok(bus)) | 136 | switch (len) { |
137 | case 1: | ||
138 | rc = cxl_ops->afu_cr_read8(afu, record, offset, &val8); | ||
139 | *val = val8; | ||
140 | break; | ||
141 | case 2: | ||
142 | rc = cxl_ops->afu_cr_read16(afu, record, offset, &val16); | ||
143 | *val = val16; | ||
144 | break; | ||
145 | case 4: | ||
146 | rc = cxl_ops->afu_cr_read32(afu, record, offset, &val32); | ||
147 | *val = val32; | ||
148 | break; | ||
149 | default: | ||
150 | WARN_ON(1); | ||
151 | } | ||
152 | |||
153 | if (rc) | ||
180 | return PCIBIOS_DEVICE_NOT_FOUND; | 154 | return PCIBIOS_DEVICE_NOT_FOUND; |
181 | 155 | ||
182 | /* Can only read 32 bits */ | ||
183 | *val = (in_le32(ioaddr) >> shift) & mask; | ||
184 | return PCIBIOS_SUCCESSFUL; | 156 | return PCIBIOS_SUCCESSFUL; |
185 | } | 157 | } |
186 | 158 | ||
187 | static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn, | 159 | static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn, |
188 | int offset, int len, u32 val) | 160 | int offset, int len, u32 val) |
189 | { | 161 | { |
190 | volatile void __iomem *ioaddr; | 162 | int rc, record; |
191 | u32 v, mask; | 163 | struct cxl_afu *afu; |
192 | int shift, rc; | ||
193 | 164 | ||
194 | rc = cxl_pcie_config_info(bus, devfn, offset, len, &ioaddr, | 165 | rc = cxl_pcie_config_info(bus, devfn, &afu, &record); |
195 | &mask, &shift); | ||
196 | if (rc) | 166 | if (rc) |
197 | return rc; | 167 | return rc; |
198 | 168 | ||
199 | if (!cxl_config_link_ok(bus)) | 169 | switch (len) { |
200 | return PCIBIOS_DEVICE_NOT_FOUND; | 170 | case 1: |
201 | 171 | rc = cxl_ops->afu_cr_write8(afu, record, offset, val & 0xff); | |
202 | /* Can only write 32 bits so do read-modify-write */ | 172 | break; |
203 | mask <<= shift; | 173 | case 2: |
204 | val <<= shift; | 174 | rc = cxl_ops->afu_cr_write16(afu, record, offset, val & 0xffff); |
175 | break; | ||
176 | case 4: | ||
177 | rc = cxl_ops->afu_cr_write32(afu, record, offset, val); | ||
178 | break; | ||
179 | default: | ||
180 | WARN_ON(1); | ||
181 | } | ||
205 | 182 | ||
206 | v = (in_le32(ioaddr) & ~mask) | (val & mask); | 183 | if (rc) |
184 | return PCIBIOS_SET_FAILED; | ||
207 | 185 | ||
208 | out_le32(ioaddr, v); | ||
209 | return PCIBIOS_SUCCESSFUL; | 186 | return PCIBIOS_SUCCESSFUL; |
210 | } | 187 | } |
211 | 188 | ||
@@ -233,23 +210,31 @@ int cxl_pci_vphb_add(struct cxl_afu *afu) | |||
233 | { | 210 | { |
234 | struct pci_dev *phys_dev; | 211 | struct pci_dev *phys_dev; |
235 | struct pci_controller *phb, *phys_phb; | 212 | struct pci_controller *phb, *phys_phb; |
236 | 213 | struct device_node *vphb_dn; | |
237 | phys_dev = to_pci_dev(afu->adapter->dev.parent); | 214 | struct device *parent; |
238 | phys_phb = pci_bus_to_host(phys_dev->bus); | 215 | |
216 | if (cpu_has_feature(CPU_FTR_HVMODE)) { | ||
217 | phys_dev = to_pci_dev(afu->adapter->dev.parent); | ||
218 | phys_phb = pci_bus_to_host(phys_dev->bus); | ||
219 | vphb_dn = phys_phb->dn; | ||
220 | parent = &phys_dev->dev; | ||
221 | } else { | ||
222 | vphb_dn = afu->adapter->dev.parent->of_node; | ||
223 | parent = afu->adapter->dev.parent; | ||
224 | } | ||
239 | 225 | ||
240 | /* Alloc and setup PHB data structure */ | 226 | /* Alloc and setup PHB data structure */ |
241 | phb = pcibios_alloc_controller(phys_phb->dn); | 227 | phb = pcibios_alloc_controller(vphb_dn); |
242 | |||
243 | if (!phb) | 228 | if (!phb) |
244 | return -ENODEV; | 229 | return -ENODEV; |
245 | 230 | ||
246 | /* Setup parent in sysfs */ | 231 | /* Setup parent in sysfs */ |
247 | phb->parent = &phys_dev->dev; | 232 | phb->parent = parent; |
248 | 233 | ||
249 | /* Setup the PHB using arch provided callback */ | 234 | /* Setup the PHB using arch provided callback */ |
250 | phb->ops = &cxl_pcie_pci_ops; | 235 | phb->ops = &cxl_pcie_pci_ops; |
251 | phb->cfg_addr = afu->afu_desc_mmio + afu->crs_offset; | 236 | phb->cfg_addr = NULL; |
252 | phb->cfg_data = (void *)(u64)afu->crs_len; | 237 | phb->cfg_data = 0; |
253 | phb->private_data = afu; | 238 | phb->private_data = afu; |
254 | phb->controller_ops = cxl_pci_controller_ops; | 239 | phb->controller_ops = cxl_pci_controller_ops; |
255 | 240 | ||
@@ -272,15 +257,6 @@ int cxl_pci_vphb_add(struct cxl_afu *afu) | |||
272 | return 0; | 257 | return 0; |
273 | } | 258 | } |
274 | 259 | ||
275 | void cxl_pci_vphb_reconfigure(struct cxl_afu *afu) | ||
276 | { | ||
277 | /* When we are reconfigured, the AFU's MMIO space is unmapped | ||
278 | * and remapped. We need to reflect this in the PHB's view of | ||
279 | * the world. | ||
280 | */ | ||
281 | afu->phb->cfg_addr = afu->afu_desc_mmio + afu->crs_offset; | ||
282 | } | ||
283 | |||
284 | void cxl_pci_vphb_remove(struct cxl_afu *afu) | 260 | void cxl_pci_vphb_remove(struct cxl_afu *afu) |
285 | { | 261 | { |
286 | struct pci_controller *phb; | 262 | struct pci_controller *phb; |
@@ -296,6 +272,15 @@ void cxl_pci_vphb_remove(struct cxl_afu *afu) | |||
296 | pcibios_free_controller(phb); | 272 | pcibios_free_controller(phb); |
297 | } | 273 | } |
298 | 274 | ||
275 | bool cxl_pci_is_vphb_device(struct pci_dev *dev) | ||
276 | { | ||
277 | struct pci_controller *phb; | ||
278 | |||
279 | phb = pci_bus_to_host(dev->bus); | ||
280 | |||
281 | return (phb->ops == &cxl_pcie_pci_ops); | ||
282 | } | ||
283 | |||
299 | struct cxl_afu *cxl_pci_to_afu(struct pci_dev *dev) | 284 | struct cxl_afu *cxl_pci_to_afu(struct pci_dev *dev) |
300 | { | 285 | { |
301 | struct pci_controller *phb; | 286 | struct pci_controller *phb; |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index f2187d491475..6c9f5467bc5f 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -271,6 +271,8 @@ bool pci_bus_clip_resource(struct pci_dev *dev, int idx) | |||
271 | 271 | ||
272 | void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { } | 272 | void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { } |
273 | 273 | ||
274 | void __weak pcibios_bus_add_device(struct pci_dev *pdev) { } | ||
275 | |||
274 | /** | 276 | /** |
275 | * pci_bus_add_device - start driver for a single device | 277 | * pci_bus_add_device - start driver for a single device |
276 | * @dev: device to add | 278 | * @dev: device to add |
@@ -285,6 +287,7 @@ void pci_bus_add_device(struct pci_dev *dev) | |||
285 | * Can not put in pci_device_add yet because resources | 287 | * Can not put in pci_device_add yet because resources |
286 | * are not assigned yet for some devices. | 288 | * are not assigned yet for some devices. |
287 | */ | 289 | */ |
290 | pcibios_bus_add_device(dev); | ||
288 | pci_fixup_device(pci_fixup_final, dev); | 291 | pci_fixup_device(pci_fixup_final, dev); |
289 | pci_create_sysfs_dev_files(dev); | 292 | pci_create_sysfs_dev_files(dev); |
290 | pci_proc_attach_device(dev); | 293 | pci_proc_attach_device(dev); |
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index fe4bd0aa91a6..2194b447201d 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -113,7 +113,7 @@ resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno) | |||
113 | return dev->sriov->barsz[resno - PCI_IOV_RESOURCES]; | 113 | return dev->sriov->barsz[resno - PCI_IOV_RESOURCES]; |
114 | } | 114 | } |
115 | 115 | ||
116 | static int virtfn_add(struct pci_dev *dev, int id, int reset) | 116 | int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) |
117 | { | 117 | { |
118 | int i; | 118 | int i; |
119 | int rc = -ENOMEM; | 119 | int rc = -ENOMEM; |
@@ -188,7 +188,7 @@ failed: | |||
188 | return rc; | 188 | return rc; |
189 | } | 189 | } |
190 | 190 | ||
191 | static void virtfn_remove(struct pci_dev *dev, int id, int reset) | 191 | void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset) |
192 | { | 192 | { |
193 | char buf[VIRTFN_ID_LEN]; | 193 | char buf[VIRTFN_ID_LEN]; |
194 | struct pci_dev *virtfn; | 194 | struct pci_dev *virtfn; |
@@ -321,7 +321,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | |||
321 | } | 321 | } |
322 | 322 | ||
323 | for (i = 0; i < initial; i++) { | 323 | for (i = 0; i < initial; i++) { |
324 | rc = virtfn_add(dev, i, 0); | 324 | rc = pci_iov_add_virtfn(dev, i, 0); |
325 | if (rc) | 325 | if (rc) |
326 | goto failed; | 326 | goto failed; |
327 | } | 327 | } |
@@ -333,7 +333,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | |||
333 | 333 | ||
334 | failed: | 334 | failed: |
335 | while (i--) | 335 | while (i--) |
336 | virtfn_remove(dev, i, 0); | 336 | pci_iov_remove_virtfn(dev, i, 0); |
337 | 337 | ||
338 | pcibios_sriov_disable(dev); | 338 | pcibios_sriov_disable(dev); |
339 | err_pcibios: | 339 | err_pcibios: |
@@ -359,7 +359,7 @@ static void sriov_disable(struct pci_dev *dev) | |||
359 | return; | 359 | return; |
360 | 360 | ||
361 | for (i = 0; i < iov->num_VFs; i++) | 361 | for (i = 0; i < iov->num_VFs; i++) |
362 | virtfn_remove(dev, i, 0); | 362 | pci_iov_remove_virtfn(dev, i, 0); |
363 | 363 | ||
364 | pcibios_sriov_disable(dev); | 364 | pcibios_sriov_disable(dev); |
365 | 365 | ||
diff --git a/drivers/scsi/cxlflash/common.h b/drivers/scsi/cxlflash/common.h index a8ac4c0a1493..6e6815545a71 100644 --- a/drivers/scsi/cxlflash/common.h +++ b/drivers/scsi/cxlflash/common.h | |||
@@ -108,7 +108,6 @@ struct cxlflash_cfg { | |||
108 | atomic_t scan_host_needed; | 108 | atomic_t scan_host_needed; |
109 | 109 | ||
110 | struct cxl_afu *cxl_afu; | 110 | struct cxl_afu *cxl_afu; |
111 | struct pci_dev *parent_dev; | ||
112 | 111 | ||
113 | atomic_t recovery_threads; | 112 | atomic_t recovery_threads; |
114 | struct mutex ctx_recovery_mutex; | 113 | struct mutex ctx_recovery_mutex; |
diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 3879b46d79e1..35968bdb4866 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c | |||
@@ -1355,7 +1355,7 @@ static int start_context(struct cxlflash_cfg *cfg) | |||
1355 | */ | 1355 | */ |
1356 | static int read_vpd(struct cxlflash_cfg *cfg, u64 wwpn[]) | 1356 | static int read_vpd(struct cxlflash_cfg *cfg, u64 wwpn[]) |
1357 | { | 1357 | { |
1358 | struct pci_dev *dev = cfg->parent_dev; | 1358 | struct pci_dev *dev = cfg->dev; |
1359 | int rc = 0; | 1359 | int rc = 0; |
1360 | int ro_start, ro_size, i, j, k; | 1360 | int ro_start, ro_size, i, j, k; |
1361 | ssize_t vpd_size; | 1361 | ssize_t vpd_size; |
@@ -1364,7 +1364,7 @@ static int read_vpd(struct cxlflash_cfg *cfg, u64 wwpn[]) | |||
1364 | char *wwpn_vpd_tags[NUM_FC_PORTS] = { "V5", "V6" }; | 1364 | char *wwpn_vpd_tags[NUM_FC_PORTS] = { "V5", "V6" }; |
1365 | 1365 | ||
1366 | /* Get the VPD data from the device */ | 1366 | /* Get the VPD data from the device */ |
1367 | vpd_size = pci_read_vpd(dev, 0, sizeof(vpd_data), vpd_data); | 1367 | vpd_size = cxl_read_adapter_vpd(dev, vpd_data, sizeof(vpd_data)); |
1368 | if (unlikely(vpd_size <= 0)) { | 1368 | if (unlikely(vpd_size <= 0)) { |
1369 | dev_err(&dev->dev, "%s: Unable to read VPD (size = %ld)\n", | 1369 | dev_err(&dev->dev, "%s: Unable to read VPD (size = %ld)\n", |
1370 | __func__, vpd_size); | 1370 | __func__, vpd_size); |
@@ -2350,7 +2350,6 @@ static int cxlflash_probe(struct pci_dev *pdev, | |||
2350 | { | 2350 | { |
2351 | struct Scsi_Host *host; | 2351 | struct Scsi_Host *host; |
2352 | struct cxlflash_cfg *cfg = NULL; | 2352 | struct cxlflash_cfg *cfg = NULL; |
2353 | struct device *phys_dev; | ||
2354 | struct dev_dependent_vals *ddv; | 2353 | struct dev_dependent_vals *ddv; |
2355 | int rc = 0; | 2354 | int rc = 0; |
2356 | 2355 | ||
@@ -2416,19 +2415,6 @@ static int cxlflash_probe(struct pci_dev *pdev, | |||
2416 | 2415 | ||
2417 | pci_set_drvdata(pdev, cfg); | 2416 | pci_set_drvdata(pdev, cfg); |
2418 | 2417 | ||
2419 | /* | ||
2420 | * Use the special service provided to look up the physical | ||
2421 | * PCI device, since we are called on the probe of the virtual | ||
2422 | * PCI host bus (vphb) | ||
2423 | */ | ||
2424 | phys_dev = cxl_get_phys_dev(pdev); | ||
2425 | if (!dev_is_pci(phys_dev)) { | ||
2426 | dev_err(&pdev->dev, "%s: not a pci dev\n", __func__); | ||
2427 | rc = -ENODEV; | ||
2428 | goto out_remove; | ||
2429 | } | ||
2430 | cfg->parent_dev = to_pci_dev(phys_dev); | ||
2431 | |||
2432 | cfg->cxl_afu = cxl_pci_to_afu(pdev); | 2418 | cfg->cxl_afu = cxl_pci_to_afu(pdev); |
2433 | 2419 | ||
2434 | rc = init_pci(cfg); | 2420 | rc = init_pci(cfg); |
diff --git a/drivers/soc/fsl/qe/qe_common.c b/drivers/soc/fsl/qe/qe_common.c index 419fa5b7be4d..41eff805a904 100644 --- a/drivers/soc/fsl/qe/qe_common.c +++ b/drivers/soc/fsl/qe/qe_common.c | |||
@@ -103,6 +103,39 @@ out_muram: | |||
103 | } | 103 | } |
104 | 104 | ||
105 | /* | 105 | /* |
106 | * cpm_muram_alloc_common - cpm_muram_alloc common code | ||
107 | * @size: number of bytes to allocate | ||
108 | * @algo: algorithm for alloc. | ||
109 | * @data: data for genalloc's algorithm. | ||
110 | * | ||
111 | * This function returns an offset into the muram area. | ||
112 | */ | ||
113 | static unsigned long cpm_muram_alloc_common(unsigned long size, | ||
114 | genpool_algo_t algo, void *data) | ||
115 | { | ||
116 | struct muram_block *entry; | ||
117 | unsigned long start; | ||
118 | |||
119 | start = gen_pool_alloc_algo(muram_pool, size, algo, data); | ||
120 | if (!start) | ||
121 | goto out2; | ||
122 | start = start - GENPOOL_OFFSET; | ||
123 | memset_io(cpm_muram_addr(start), 0, size); | ||
124 | entry = kmalloc(sizeof(*entry), GFP_ATOMIC); | ||
125 | if (!entry) | ||
126 | goto out1; | ||
127 | entry->start = start; | ||
128 | entry->size = size; | ||
129 | list_add(&entry->head, &muram_block_list); | ||
130 | |||
131 | return start; | ||
132 | out1: | ||
133 | gen_pool_free(muram_pool, start, size); | ||
134 | out2: | ||
135 | return (unsigned long)-ENOMEM; | ||
136 | } | ||
137 | |||
138 | /* | ||
106 | * cpm_muram_alloc - allocate the requested size worth of multi-user ram | 139 | * cpm_muram_alloc - allocate the requested size worth of multi-user ram |
107 | * @size: number of bytes to allocate | 140 | * @size: number of bytes to allocate |
108 | * @align: requested alignment, in bytes | 141 | * @align: requested alignment, in bytes |
@@ -175,39 +208,6 @@ unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size) | |||
175 | } | 208 | } |
176 | EXPORT_SYMBOL(cpm_muram_alloc_fixed); | 209 | EXPORT_SYMBOL(cpm_muram_alloc_fixed); |
177 | 210 | ||
178 | /* | ||
179 | * cpm_muram_alloc_common - cpm_muram_alloc common code | ||
180 | * @size: number of bytes to allocate | ||
181 | * @algo: algorithm for alloc. | ||
182 | * @data: data for genalloc's algorithm. | ||
183 | * | ||
184 | * This function returns an offset into the muram area. | ||
185 | */ | ||
186 | unsigned long cpm_muram_alloc_common(unsigned long size, genpool_algo_t algo, | ||
187 | void *data) | ||
188 | { | ||
189 | struct muram_block *entry; | ||
190 | unsigned long start; | ||
191 | |||
192 | start = gen_pool_alloc_algo(muram_pool, size, algo, data); | ||
193 | if (!start) | ||
194 | goto out2; | ||
195 | start = start - GENPOOL_OFFSET; | ||
196 | memset_io(cpm_muram_addr(start), 0, size); | ||
197 | entry = kmalloc(sizeof(*entry), GFP_KERNEL); | ||
198 | if (!entry) | ||
199 | goto out1; | ||
200 | entry->start = start; | ||
201 | entry->size = size; | ||
202 | list_add(&entry->head, &muram_block_list); | ||
203 | |||
204 | return start; | ||
205 | out1: | ||
206 | gen_pool_free(muram_pool, start, size); | ||
207 | out2: | ||
208 | return (unsigned long)-ENOMEM; | ||
209 | } | ||
210 | |||
211 | /** | 211 | /** |
212 | * cpm_muram_addr - turn a muram offset into a virtual address | 212 | * cpm_muram_addr - turn a muram offset into a virtual address |
213 | * @offset: muram offset to convert | 213 | * @offset: muram offset to convert |
diff --git a/drivers/soc/fsl/qe/qe_ic.c b/drivers/soc/fsl/qe/qe_ic.c index b77d01ff8330..ec2ca864b0c5 100644 --- a/drivers/soc/fsl/qe/qe_ic.c +++ b/drivers/soc/fsl/qe/qe_ic.c | |||
@@ -259,6 +259,11 @@ static int qe_ic_host_map(struct irq_domain *h, unsigned int virq, | |||
259 | struct qe_ic *qe_ic = h->host_data; | 259 | struct qe_ic *qe_ic = h->host_data; |
260 | struct irq_chip *chip; | 260 | struct irq_chip *chip; |
261 | 261 | ||
262 | if (hw >= ARRAY_SIZE(qe_ic_info)) { | ||
263 | pr_err("%s: Invalid hw irq number for QEIC\n", __func__); | ||
264 | return -EINVAL; | ||
265 | } | ||
266 | |||
262 | if (qe_ic_info[hw].mask == 0) { | 267 | if (qe_ic_info[hw].mask == 0) { |
263 | printk(KERN_ERR "Can't map reserved IRQ\n"); | 268 | printk(KERN_ERR "Can't map reserved IRQ\n"); |
264 | return -EINVAL; | 269 | return -EINVAL; |
@@ -407,7 +412,8 @@ int qe_ic_set_priority(unsigned int virq, unsigned int priority) | |||
407 | 412 | ||
408 | if (priority > 8 || priority == 0) | 413 | if (priority > 8 || priority == 0) |
409 | return -EINVAL; | 414 | return -EINVAL; |
410 | if (src > 127) | 415 | if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info), |
416 | "%s: Invalid hw irq number for QEIC\n", __func__)) | ||
411 | return -EINVAL; | 417 | return -EINVAL; |
412 | if (qe_ic_info[src].pri_reg == 0) | 418 | if (qe_ic_info[src].pri_reg == 0) |
413 | return -EINVAL; | 419 | return -EINVAL; |
@@ -436,6 +442,9 @@ int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high) | |||
436 | 442 | ||
437 | if (priority > 2 || priority == 0) | 443 | if (priority > 2 || priority == 0) |
438 | return -EINVAL; | 444 | return -EINVAL; |
445 | if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info), | ||
446 | "%s: Invalid hw irq number for QEIC\n", __func__)) | ||
447 | return -EINVAL; | ||
439 | 448 | ||
440 | switch (qe_ic_info[src].pri_reg) { | 449 | switch (qe_ic_info[src].pri_reg) { |
441 | case QEIC_CIPZCC: | 450 | case QEIC_CIPZCC: |
diff --git a/include/linux/atomic.h b/include/linux/atomic.h index 6c502cb13c95..df4f369254c0 100644 --- a/include/linux/atomic.h +++ b/include/linux/atomic.h | |||
@@ -34,20 +34,29 @@ | |||
34 | * The idea here is to build acquire/release variants by adding explicit | 34 | * The idea here is to build acquire/release variants by adding explicit |
35 | * barriers on top of the relaxed variant. In the case where the relaxed | 35 | * barriers on top of the relaxed variant. In the case where the relaxed |
36 | * variant is already fully ordered, no additional barriers are needed. | 36 | * variant is already fully ordered, no additional barriers are needed. |
37 | * | ||
38 | * Besides, if an arch has a special barrier for acquire/release, it could | ||
39 | * implement its own __atomic_op_* and use the same framework for building | ||
40 | * variants | ||
37 | */ | 41 | */ |
42 | #ifndef __atomic_op_acquire | ||
38 | #define __atomic_op_acquire(op, args...) \ | 43 | #define __atomic_op_acquire(op, args...) \ |
39 | ({ \ | 44 | ({ \ |
40 | typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \ | 45 | typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \ |
41 | smp_mb__after_atomic(); \ | 46 | smp_mb__after_atomic(); \ |
42 | __ret; \ | 47 | __ret; \ |
43 | }) | 48 | }) |
49 | #endif | ||
44 | 50 | ||
51 | #ifndef __atomic_op_release | ||
45 | #define __atomic_op_release(op, args...) \ | 52 | #define __atomic_op_release(op, args...) \ |
46 | ({ \ | 53 | ({ \ |
47 | smp_mb__before_atomic(); \ | 54 | smp_mb__before_atomic(); \ |
48 | op##_relaxed(args); \ | 55 | op##_relaxed(args); \ |
49 | }) | 56 | }) |
57 | #endif | ||
50 | 58 | ||
59 | #ifndef __atomic_op_fence | ||
51 | #define __atomic_op_fence(op, args...) \ | 60 | #define __atomic_op_fence(op, args...) \ |
52 | ({ \ | 61 | ({ \ |
53 | typeof(op##_relaxed(args)) __ret; \ | 62 | typeof(op##_relaxed(args)) __ret; \ |
@@ -56,6 +65,7 @@ | |||
56 | smp_mb__after_atomic(); \ | 65 | smp_mb__after_atomic(); \ |
57 | __ret; \ | 66 | __ret; \ |
58 | }) | 67 | }) |
68 | #endif | ||
59 | 69 | ||
60 | /* atomic_add_return_relaxed */ | 70 | /* atomic_add_return_relaxed */ |
61 | #ifndef atomic_add_return_relaxed | 71 | #ifndef atomic_add_return_relaxed |
diff --git a/include/linux/bug.h b/include/linux/bug.h index 7f4818673c41..e51b0709e78d 100644 --- a/include/linux/bug.h +++ b/include/linux/bug.h | |||
@@ -20,6 +20,7 @@ struct pt_regs; | |||
20 | #define BUILD_BUG_ON_MSG(cond, msg) (0) | 20 | #define BUILD_BUG_ON_MSG(cond, msg) (0) |
21 | #define BUILD_BUG_ON(condition) (0) | 21 | #define BUILD_BUG_ON(condition) (0) |
22 | #define BUILD_BUG() (0) | 22 | #define BUILD_BUG() (0) |
23 | #define MAYBE_BUILD_BUG_ON(cond) (0) | ||
23 | #else /* __CHECKER__ */ | 24 | #else /* __CHECKER__ */ |
24 | 25 | ||
25 | /* Force a compilation error if a constant expression is not a power of 2 */ | 26 | /* Force a compilation error if a constant expression is not a power of 2 */ |
@@ -83,6 +84,14 @@ struct pt_regs; | |||
83 | */ | 84 | */ |
84 | #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed") | 85 | #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed") |
85 | 86 | ||
87 | #define MAYBE_BUILD_BUG_ON(cond) \ | ||
88 | do { \ | ||
89 | if (__builtin_constant_p((cond))) \ | ||
90 | BUILD_BUG_ON(cond); \ | ||
91 | else \ | ||
92 | BUG_ON(cond); \ | ||
93 | } while (0) | ||
94 | |||
86 | #endif /* __CHECKER__ */ | 95 | #endif /* __CHECKER__ */ |
87 | 96 | ||
88 | #ifdef CONFIG_GENERIC_BUG | 97 | #ifdef CONFIG_GENERIC_BUG |
diff --git a/include/linux/fsl/guts.h b/include/linux/fsl/guts.h index 84d971ff3fba..649e9171a9b3 100644 --- a/include/linux/fsl/guts.h +++ b/include/linux/fsl/guts.h | |||
@@ -189,4 +189,109 @@ static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts, | |||
189 | 189 | ||
190 | #endif | 190 | #endif |
191 | 191 | ||
192 | struct ccsr_rcpm_v1 { | ||
193 | u8 res0000[4]; | ||
194 | __be32 cdozsr; /* 0x0004 Core Doze Status Register */ | ||
195 | u8 res0008[4]; | ||
196 | __be32 cdozcr; /* 0x000c Core Doze Control Register */ | ||
197 | u8 res0010[4]; | ||
198 | __be32 cnapsr; /* 0x0014 Core Nap Status Register */ | ||
199 | u8 res0018[4]; | ||
200 | __be32 cnapcr; /* 0x001c Core Nap Control Register */ | ||
201 | u8 res0020[4]; | ||
202 | __be32 cdozpsr; /* 0x0024 Core Doze Previous Status Register */ | ||
203 | u8 res0028[4]; | ||
204 | __be32 cnappsr; /* 0x002c Core Nap Previous Status Register */ | ||
205 | u8 res0030[4]; | ||
206 | __be32 cwaitsr; /* 0x0034 Core Wait Status Register */ | ||
207 | u8 res0038[4]; | ||
208 | __be32 cwdtdsr; /* 0x003c Core Watchdog Detect Status Register */ | ||
209 | __be32 powmgtcsr; /* 0x0040 PM Control&Status Register */ | ||
210 | #define RCPM_POWMGTCSR_SLP 0x00020000 | ||
211 | u8 res0044[12]; | ||
212 | __be32 ippdexpcr; /* 0x0050 IP Powerdown Exception Control Register */ | ||
213 | u8 res0054[16]; | ||
214 | __be32 cpmimr; /* 0x0064 Core PM IRQ Mask Register */ | ||
215 | u8 res0068[4]; | ||
216 | __be32 cpmcimr; /* 0x006c Core PM Critical IRQ Mask Register */ | ||
217 | u8 res0070[4]; | ||
218 | __be32 cpmmcmr; /* 0x0074 Core PM Machine Check Mask Register */ | ||
219 | u8 res0078[4]; | ||
220 | __be32 cpmnmimr; /* 0x007c Core PM NMI Mask Register */ | ||
221 | u8 res0080[4]; | ||
222 | __be32 ctbenr; /* 0x0084 Core Time Base Enable Register */ | ||
223 | u8 res0088[4]; | ||
224 | __be32 ctbckselr; /* 0x008c Core Time Base Clock Select Register */ | ||
225 | u8 res0090[4]; | ||
226 | __be32 ctbhltcr; /* 0x0094 Core Time Base Halt Control Register */ | ||
227 | u8 res0098[4]; | ||
228 | __be32 cmcpmaskcr; /* 0x00a4 Core Machine Check Mask Register */ | ||
229 | }; | ||
230 | |||
231 | struct ccsr_rcpm_v2 { | ||
232 | u8 res_00[12]; | ||
233 | __be32 tph10sr0; /* Thread PH10 Status Register */ | ||
234 | u8 res_10[12]; | ||
235 | __be32 tph10setr0; /* Thread PH10 Set Control Register */ | ||
236 | u8 res_20[12]; | ||
237 | __be32 tph10clrr0; /* Thread PH10 Clear Control Register */ | ||
238 | u8 res_30[12]; | ||
239 | __be32 tph10psr0; /* Thread PH10 Previous Status Register */ | ||
240 | u8 res_40[12]; | ||
241 | __be32 twaitsr0; /* Thread Wait Status Register */ | ||
242 | u8 res_50[96]; | ||
243 | __be32 pcph15sr; /* Physical Core PH15 Status Register */ | ||
244 | __be32 pcph15setr; /* Physical Core PH15 Set Control Register */ | ||
245 | __be32 pcph15clrr; /* Physical Core PH15 Clear Control Register */ | ||
246 | __be32 pcph15psr; /* Physical Core PH15 Prev Status Register */ | ||
247 | u8 res_c0[16]; | ||
248 | __be32 pcph20sr; /* Physical Core PH20 Status Register */ | ||
249 | __be32 pcph20setr; /* Physical Core PH20 Set Control Register */ | ||
250 | __be32 pcph20clrr; /* Physical Core PH20 Clear Control Register */ | ||
251 | __be32 pcph20psr; /* Physical Core PH20 Prev Status Register */ | ||
252 | __be32 pcpw20sr; /* Physical Core PW20 Status Register */ | ||
253 | u8 res_e0[12]; | ||
254 | __be32 pcph30sr; /* Physical Core PH30 Status Register */ | ||
255 | __be32 pcph30setr; /* Physical Core PH30 Set Control Register */ | ||
256 | __be32 pcph30clrr; /* Physical Core PH30 Clear Control Register */ | ||
257 | __be32 pcph30psr; /* Physical Core PH30 Prev Status Register */ | ||
258 | u8 res_100[32]; | ||
259 | __be32 ippwrgatecr; /* IP Power Gating Control Register */ | ||
260 | u8 res_124[12]; | ||
261 | __be32 powmgtcsr; /* Power Management Control & Status Reg */ | ||
262 | #define RCPM_POWMGTCSR_LPM20_RQ 0x00100000 | ||
263 | #define RCPM_POWMGTCSR_LPM20_ST 0x00000200 | ||
264 | #define RCPM_POWMGTCSR_P_LPM20_ST 0x00000100 | ||
265 | u8 res_134[12]; | ||
266 | __be32 ippdexpcr[4]; /* IP Powerdown Exception Control Reg */ | ||
267 | u8 res_150[12]; | ||
268 | __be32 tpmimr0; /* Thread PM Interrupt Mask Reg */ | ||
269 | u8 res_160[12]; | ||
270 | __be32 tpmcimr0; /* Thread PM Crit Interrupt Mask Reg */ | ||
271 | u8 res_170[12]; | ||
272 | __be32 tpmmcmr0; /* Thread PM Machine Check Interrupt Mask Reg */ | ||
273 | u8 res_180[12]; | ||
274 | __be32 tpmnmimr0; /* Thread PM NMI Mask Reg */ | ||
275 | u8 res_190[12]; | ||
276 | __be32 tmcpmaskcr0; /* Thread Machine Check Mask Control Reg */ | ||
277 | __be32 pctbenr; /* Physical Core Time Base Enable Reg */ | ||
278 | __be32 pctbclkselr; /* Physical Core Time Base Clock Select */ | ||
279 | __be32 tbclkdivr; /* Time Base Clock Divider Register */ | ||
280 | u8 res_1ac[4]; | ||
281 | __be32 ttbhltcr[4]; /* Thread Time Base Halt Control Register */ | ||
282 | __be32 clpcl10sr; /* Cluster PCL10 Status Register */ | ||
283 | __be32 clpcl10setr; /* Cluster PCL30 Set Control Register */ | ||
284 | __be32 clpcl10clrr; /* Cluster PCL30 Clear Control Register */ | ||
285 | __be32 clpcl10psr; /* Cluster PCL30 Prev Status Register */ | ||
286 | __be32 cddslpsetr; /* Core Domain Deep Sleep Set Register */ | ||
287 | __be32 cddslpclrr; /* Core Domain Deep Sleep Clear Register */ | ||
288 | __be32 cdpwroksetr; /* Core Domain Power OK Set Register */ | ||
289 | __be32 cdpwrokclrr; /* Core Domain Power OK Clear Register */ | ||
290 | __be32 cdpwrensr; /* Core Domain Power Enable Status Register */ | ||
291 | __be32 cddslsr; /* Core Domain Deep Sleep Status Register */ | ||
292 | u8 res_1e8[8]; | ||
293 | __be32 dslpcntcr[8]; /* Deep Sleep Counter Cfg Register */ | ||
294 | u8 res_300[3568]; | ||
295 | }; | ||
296 | |||
192 | #endif | 297 | #endif |
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index 5307dfb3f8ec..79b0ef6aaa14 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h | |||
@@ -111,9 +111,6 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, | |||
111 | void split_huge_pmd_address(struct vm_area_struct *vma, unsigned long address, | 111 | void split_huge_pmd_address(struct vm_area_struct *vma, unsigned long address, |
112 | bool freeze, struct page *page); | 112 | bool freeze, struct page *page); |
113 | 113 | ||
114 | #if HPAGE_PMD_ORDER >= MAX_ORDER | ||
115 | #error "hugepages can't be allocated by the buddy allocator" | ||
116 | #endif | ||
117 | extern int hugepage_madvise(struct vm_area_struct *vma, | 114 | extern int hugepage_madvise(struct vm_area_struct *vma, |
118 | unsigned long *vm_flags, int advice); | 115 | unsigned long *vm_flags, int advice); |
119 | extern void vma_adjust_trans_huge(struct vm_area_struct *vma, | 116 | extern void vma_adjust_trans_huge(struct vm_area_struct *vma, |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 17e17c2ee1e6..004b8133417d 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -784,6 +784,7 @@ extern struct list_head pci_root_buses; /* list of all known PCI buses */ | |||
784 | int no_pci_devices(void); | 784 | int no_pci_devices(void); |
785 | 785 | ||
786 | void pcibios_resource_survey_bus(struct pci_bus *bus); | 786 | void pcibios_resource_survey_bus(struct pci_bus *bus); |
787 | void pcibios_bus_add_device(struct pci_dev *pdev); | ||
787 | void pcibios_add_bus(struct pci_bus *bus); | 788 | void pcibios_add_bus(struct pci_bus *bus); |
788 | void pcibios_remove_bus(struct pci_bus *bus); | 789 | void pcibios_remove_bus(struct pci_bus *bus); |
789 | void pcibios_fixup_bus(struct pci_bus *); | 790 | void pcibios_fixup_bus(struct pci_bus *); |
@@ -1733,6 +1734,8 @@ int pci_iov_virtfn_devfn(struct pci_dev *dev, int id); | |||
1733 | 1734 | ||
1734 | int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); | 1735 | int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); |
1735 | void pci_disable_sriov(struct pci_dev *dev); | 1736 | void pci_disable_sriov(struct pci_dev *dev); |
1737 | int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset); | ||
1738 | void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset); | ||
1736 | int pci_num_vf(struct pci_dev *dev); | 1739 | int pci_num_vf(struct pci_dev *dev); |
1737 | int pci_vfs_assigned(struct pci_dev *dev); | 1740 | int pci_vfs_assigned(struct pci_dev *dev); |
1738 | int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); | 1741 | int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); |
@@ -1749,6 +1752,12 @@ static inline int pci_iov_virtfn_devfn(struct pci_dev *dev, int id) | |||
1749 | } | 1752 | } |
1750 | static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) | 1753 | static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) |
1751 | { return -ENODEV; } | 1754 | { return -ENODEV; } |
1755 | static inline int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) | ||
1756 | { | ||
1757 | return -ENOSYS; | ||
1758 | } | ||
1759 | static inline void pci_iov_remove_virtfn(struct pci_dev *dev, | ||
1760 | int id, int reset) { } | ||
1752 | static inline void pci_disable_sriov(struct pci_dev *dev) { } | 1761 | static inline void pci_disable_sriov(struct pci_dev *dev) { } |
1753 | static inline int pci_num_vf(struct pci_dev *dev) { return 0; } | 1762 | static inline int pci_num_vf(struct pci_dev *dev) { return 0; } |
1754 | static inline int pci_vfs_assigned(struct pci_dev *dev) | 1763 | static inline int pci_vfs_assigned(struct pci_dev *dev) |
diff --git a/include/misc/cxl.h b/include/misc/cxl.h index f2ffe5bd720d..7d5e2613c7b8 100644 --- a/include/misc/cxl.h +++ b/include/misc/cxl.h | |||
@@ -30,9 +30,6 @@ struct cxl_afu *cxl_pci_to_afu(struct pci_dev *dev); | |||
30 | /* Get the AFU conf record number associated with a pci_dev */ | 30 | /* Get the AFU conf record number associated with a pci_dev */ |
31 | unsigned int cxl_pci_to_cfg_record(struct pci_dev *dev); | 31 | unsigned int cxl_pci_to_cfg_record(struct pci_dev *dev); |
32 | 32 | ||
33 | /* Get the physical device (ie. the PCIe card) which the AFU is attached */ | ||
34 | struct device *cxl_get_phys_dev(struct pci_dev *dev); | ||
35 | |||
36 | 33 | ||
37 | /* | 34 | /* |
38 | * Context lifetime overview: | 35 | * Context lifetime overview: |
@@ -210,4 +207,9 @@ ssize_t cxl_fd_read(struct file *file, char __user *buf, size_t count, | |||
210 | void cxl_perst_reloads_same_image(struct cxl_afu *afu, | 207 | void cxl_perst_reloads_same_image(struct cxl_afu *afu, |
211 | bool perst_reloads_same_image); | 208 | bool perst_reloads_same_image); |
212 | 209 | ||
210 | /* | ||
211 | * Read the VPD for the card where the AFU resides | ||
212 | */ | ||
213 | ssize_t cxl_read_adapter_vpd(struct pci_dev *dev, void *buf, size_t count); | ||
214 | |||
213 | #endif /* _MISC_CXL_H */ | 215 | #endif /* _MISC_CXL_H */ |
diff --git a/include/soc/fsl/qe/qe.h b/include/soc/fsl/qe/qe.h index c7fa36c335c9..33b29ead3d55 100644 --- a/include/soc/fsl/qe/qe.h +++ b/include/soc/fsl/qe/qe.h | |||
@@ -103,8 +103,6 @@ int cpm_muram_init(void); | |||
103 | unsigned long cpm_muram_alloc(unsigned long size, unsigned long align); | 103 | unsigned long cpm_muram_alloc(unsigned long size, unsigned long align); |
104 | int cpm_muram_free(unsigned long offset); | 104 | int cpm_muram_free(unsigned long offset); |
105 | unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size); | 105 | unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size); |
106 | unsigned long cpm_muram_alloc_common(unsigned long size, genpool_algo_t algo, | ||
107 | void *data); | ||
108 | void __iomem *cpm_muram_addr(unsigned long offset); | 106 | void __iomem *cpm_muram_addr(unsigned long offset); |
109 | unsigned long cpm_muram_offset(void __iomem *addr); | 107 | unsigned long cpm_muram_offset(void __iomem *addr); |
110 | dma_addr_t cpm_muram_dma(void __iomem *addr); | 108 | dma_addr_t cpm_muram_dma(void __iomem *addr); |
diff --git a/include/uapi/misc/cxl.h b/include/uapi/misc/cxl.h index 1e889aa8a36e..8cd334f99ddc 100644 --- a/include/uapi/misc/cxl.h +++ b/include/uapi/misc/cxl.h | |||
@@ -55,11 +55,35 @@ struct cxl_afu_id { | |||
55 | __u64 reserved6; | 55 | __u64 reserved6; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | /* base adapter image header is included in the image */ | ||
59 | #define CXL_AI_NEED_HEADER 0x0000000000000001ULL | ||
60 | #define CXL_AI_ALL CXL_AI_NEED_HEADER | ||
61 | |||
62 | #define CXL_AI_HEADER_SIZE 128 | ||
63 | #define CXL_AI_BUFFER_SIZE 4096 | ||
64 | #define CXL_AI_MAX_ENTRIES 256 | ||
65 | #define CXL_AI_MAX_CHUNK_SIZE (CXL_AI_BUFFER_SIZE * CXL_AI_MAX_ENTRIES) | ||
66 | |||
67 | struct cxl_adapter_image { | ||
68 | __u64 flags; | ||
69 | __u64 data; | ||
70 | __u64 len_data; | ||
71 | __u64 len_image; | ||
72 | __u64 reserved1; | ||
73 | __u64 reserved2; | ||
74 | __u64 reserved3; | ||
75 | __u64 reserved4; | ||
76 | }; | ||
77 | |||
58 | /* ioctl numbers */ | 78 | /* ioctl numbers */ |
59 | #define CXL_MAGIC 0xCA | 79 | #define CXL_MAGIC 0xCA |
80 | /* AFU devices */ | ||
60 | #define CXL_IOCTL_START_WORK _IOW(CXL_MAGIC, 0x00, struct cxl_ioctl_start_work) | 81 | #define CXL_IOCTL_START_WORK _IOW(CXL_MAGIC, 0x00, struct cxl_ioctl_start_work) |
61 | #define CXL_IOCTL_GET_PROCESS_ELEMENT _IOR(CXL_MAGIC, 0x01, __u32) | 82 | #define CXL_IOCTL_GET_PROCESS_ELEMENT _IOR(CXL_MAGIC, 0x01, __u32) |
62 | #define CXL_IOCTL_GET_AFU_ID _IOR(CXL_MAGIC, 0x02, struct cxl_afu_id) | 83 | #define CXL_IOCTL_GET_AFU_ID _IOR(CXL_MAGIC, 0x02, struct cxl_afu_id) |
84 | /* adapter devices */ | ||
85 | #define CXL_IOCTL_DOWNLOAD_IMAGE _IOW(CXL_MAGIC, 0x0A, struct cxl_adapter_image) | ||
86 | #define CXL_IOCTL_VALIDATE_IMAGE _IOW(CXL_MAGIC, 0x0B, struct cxl_adapter_image) | ||
63 | 87 | ||
64 | #define CXL_READ_MIN_SIZE 0x1000 /* 4K */ | 88 | #define CXL_READ_MIN_SIZE 0x1000 /* 4K */ |
65 | 89 | ||
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 021db1781872..fbfb1b8d6726 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
@@ -83,7 +83,7 @@ unsigned long transparent_hugepage_flags __read_mostly = | |||
83 | (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG); | 83 | (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG); |
84 | 84 | ||
85 | /* default scan 8*512 pte (or vmas) every 30 second */ | 85 | /* default scan 8*512 pte (or vmas) every 30 second */ |
86 | static unsigned int khugepaged_pages_to_scan __read_mostly = HPAGE_PMD_NR*8; | 86 | static unsigned int khugepaged_pages_to_scan __read_mostly; |
87 | static unsigned int khugepaged_pages_collapsed; | 87 | static unsigned int khugepaged_pages_collapsed; |
88 | static unsigned int khugepaged_full_scans; | 88 | static unsigned int khugepaged_full_scans; |
89 | static unsigned int khugepaged_scan_sleep_millisecs __read_mostly = 10000; | 89 | static unsigned int khugepaged_scan_sleep_millisecs __read_mostly = 10000; |
@@ -98,7 +98,7 @@ static DECLARE_WAIT_QUEUE_HEAD(khugepaged_wait); | |||
98 | * it would have happened if the vma was large enough during page | 98 | * it would have happened if the vma was large enough during page |
99 | * fault. | 99 | * fault. |
100 | */ | 100 | */ |
101 | static unsigned int khugepaged_max_ptes_none __read_mostly = HPAGE_PMD_NR-1; | 101 | static unsigned int khugepaged_max_ptes_none __read_mostly; |
102 | 102 | ||
103 | static int khugepaged(void *none); | 103 | static int khugepaged(void *none); |
104 | static int khugepaged_slab_init(void); | 104 | static int khugepaged_slab_init(void); |
@@ -669,6 +669,18 @@ static int __init hugepage_init(void) | |||
669 | return -EINVAL; | 669 | return -EINVAL; |
670 | } | 670 | } |
671 | 671 | ||
672 | khugepaged_pages_to_scan = HPAGE_PMD_NR * 8; | ||
673 | khugepaged_max_ptes_none = HPAGE_PMD_NR - 1; | ||
674 | /* | ||
675 | * hugepages can't be allocated by the buddy allocator | ||
676 | */ | ||
677 | MAYBE_BUILD_BUG_ON(HPAGE_PMD_ORDER >= MAX_ORDER); | ||
678 | /* | ||
679 | * we use page->mapping and page->index in second tail page | ||
680 | * as list_head: assuming THP order >= 2 | ||
681 | */ | ||
682 | MAYBE_BUILD_BUG_ON(HPAGE_PMD_ORDER < 2); | ||
683 | |||
672 | err = hugepage_init_sysfs(&hugepage_kobj); | 684 | err = hugepage_init_sysfs(&hugepage_kobj); |
673 | if (err) | 685 | if (err) |
674 | goto err_sysfs; | 686 | goto err_sysfs; |
@@ -773,7 +785,6 @@ void prep_transhuge_page(struct page *page) | |||
773 | * we use page->mapping and page->indexlru in second tail page | 785 | * we use page->mapping and page->indexlru in second tail page |
774 | * as list_head: assuming THP order >= 2 | 786 | * as list_head: assuming THP order >= 2 |
775 | */ | 787 | */ |
776 | BUILD_BUG_ON(HPAGE_PMD_ORDER < 2); | ||
777 | 788 | ||
778 | INIT_LIST_HEAD(page_deferred_list(page)); | 789 | INIT_LIST_HEAD(page_deferred_list(page)); |
779 | set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); | 790 | set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); |
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile index 0c2706bda330..b08f77cbe31b 100644 --- a/tools/testing/selftests/powerpc/Makefile +++ b/tools/testing/selftests/powerpc/Makefile | |||
@@ -8,7 +8,7 @@ ifeq ($(ARCH),powerpc) | |||
8 | 8 | ||
9 | GIT_VERSION = $(shell git describe --always --long --dirty || echo "unknown") | 9 | GIT_VERSION = $(shell git describe --always --long --dirty || echo "unknown") |
10 | 10 | ||
11 | CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CURDIR) $(CFLAGS) | 11 | CFLAGS := -Wall -O2 -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CURDIR) $(CFLAGS) |
12 | 12 | ||
13 | export CFLAGS | 13 | export CFLAGS |
14 | 14 | ||
@@ -22,7 +22,8 @@ SUB_DIRS = benchmarks \ | |||
22 | switch_endian \ | 22 | switch_endian \ |
23 | syscalls \ | 23 | syscalls \ |
24 | tm \ | 24 | tm \ |
25 | vphn | 25 | vphn \ |
26 | math | ||
26 | 27 | ||
27 | endif | 28 | endif |
28 | 29 | ||
diff --git a/tools/testing/selftests/powerpc/basic_asm.h b/tools/testing/selftests/powerpc/basic_asm.h new file mode 100644 index 000000000000..3349a0704d1a --- /dev/null +++ b/tools/testing/selftests/powerpc/basic_asm.h | |||
@@ -0,0 +1,70 @@ | |||
1 | #ifndef _SELFTESTS_POWERPC_BASIC_ASM_H | ||
2 | #define _SELFTESTS_POWERPC_BASIC_ASM_H | ||
3 | |||
4 | #include <ppc-asm.h> | ||
5 | #include <asm/unistd.h> | ||
6 | |||
7 | #define LOAD_REG_IMMEDIATE(reg,expr) \ | ||
8 | lis reg,(expr)@highest; \ | ||
9 | ori reg,reg,(expr)@higher; \ | ||
10 | rldicr reg,reg,32,31; \ | ||
11 | oris reg,reg,(expr)@high; \ | ||
12 | ori reg,reg,(expr)@l; | ||
13 | |||
14 | /* | ||
15 | * Note: These macros assume that variables being stored on the stack are | ||
16 | * doublewords, while this is usually the case it may not always be the | ||
17 | * case for each use case. | ||
18 | */ | ||
19 | #if defined(_CALL_ELF) && _CALL_ELF == 2 | ||
20 | #define STACK_FRAME_MIN_SIZE 32 | ||
21 | #define STACK_FRAME_TOC_POS 24 | ||
22 | #define __STACK_FRAME_PARAM(_param) (32 + ((_param)*8)) | ||
23 | #define __STACK_FRAME_LOCAL(_num_params,_var_num) ((STACK_FRAME_PARAM(_num_params)) + ((_var_num)*8)) | ||
24 | #else | ||
25 | #define STACK_FRAME_MIN_SIZE 112 | ||
26 | #define STACK_FRAME_TOC_POS 40 | ||
27 | #define __STACK_FRAME_PARAM(i) (48 + ((i)*8)) | ||
28 | |||
29 | /* | ||
30 | * Caveat: if a function passed more than 8 doublewords, the caller will have | ||
31 | * made more space... which would render the 112 incorrect. | ||
32 | */ | ||
33 | #define __STACK_FRAME_LOCAL(_num_params,_var_num) (112 + ((_var_num)*8)) | ||
34 | #endif | ||
35 | |||
36 | /* Parameter x saved to the stack */ | ||
37 | #define STACK_FRAME_PARAM(var) __STACK_FRAME_PARAM(var) | ||
38 | |||
39 | /* Local variable x saved to the stack after x parameters */ | ||
40 | #define STACK_FRAME_LOCAL(num_params,var) __STACK_FRAME_LOCAL(num_params,var) | ||
41 | #define STACK_FRAME_LR_POS 16 | ||
42 | #define STACK_FRAME_CR_POS 8 | ||
43 | |||
44 | /* | ||
45 | * It is very important to note here that _extra is the extra amount of | ||
46 | * stack space needed. This space can be accessed using STACK_FRAME_PARAM() | ||
47 | * or STACK_FRAME_LOCAL() macros. | ||
48 | * | ||
49 | * r1 and r2 are not defined in ppc-asm.h (instead they are defined as sp | ||
50 | * and toc). Kernel programmers tend to prefer rX even for r1 and r2, hence | ||
51 | * %1 and %r2. r0 is defined in ppc-asm.h and therefore %r0 gets | ||
52 | * preprocessed incorrectly, hence r0. | ||
53 | */ | ||
54 | #define PUSH_BASIC_STACK(_extra) \ | ||
55 | mflr r0; \ | ||
56 | std r0,STACK_FRAME_LR_POS(%r1); \ | ||
57 | stdu %r1,-(_extra + STACK_FRAME_MIN_SIZE)(%r1); \ | ||
58 | mfcr r0; \ | ||
59 | stw r0,STACK_FRAME_CR_POS(%r1); \ | ||
60 | std %r2,STACK_FRAME_TOC_POS(%r1); | ||
61 | |||
62 | #define POP_BASIC_STACK(_extra) \ | ||
63 | ld %r2,STACK_FRAME_TOC_POS(%r1); \ | ||
64 | lwz r0,STACK_FRAME_CR_POS(%r1); \ | ||
65 | mtcr r0; \ | ||
66 | addi %r1,%r1,(_extra + STACK_FRAME_MIN_SIZE); \ | ||
67 | ld r0,STACK_FRAME_LR_POS(%r1); \ | ||
68 | mtlr r0; | ||
69 | |||
70 | #endif /* _SELFTESTS_POWERPC_BASIC_ASM_H */ | ||
diff --git a/tools/testing/selftests/powerpc/math/.gitignore b/tools/testing/selftests/powerpc/math/.gitignore new file mode 100644 index 000000000000..4fe13a439fd7 --- /dev/null +++ b/tools/testing/selftests/powerpc/math/.gitignore | |||
@@ -0,0 +1,6 @@ | |||
1 | fpu_syscall | ||
2 | vmx_syscall | ||
3 | fpu_preempt | ||
4 | vmx_preempt | ||
5 | fpu_signal | ||
6 | vmx_signal | ||
diff --git a/tools/testing/selftests/powerpc/math/Makefile b/tools/testing/selftests/powerpc/math/Makefile new file mode 100644 index 000000000000..5b88875d5955 --- /dev/null +++ b/tools/testing/selftests/powerpc/math/Makefile | |||
@@ -0,0 +1,19 @@ | |||
1 | TEST_PROGS := fpu_syscall fpu_preempt fpu_signal vmx_syscall vmx_preempt vmx_signal | ||
2 | |||
3 | all: $(TEST_PROGS) | ||
4 | |||
5 | $(TEST_PROGS): ../harness.c | ||
6 | $(TEST_PROGS): CFLAGS += -O2 -g -pthread -m64 -maltivec | ||
7 | |||
8 | fpu_syscall: fpu_asm.S | ||
9 | fpu_preempt: fpu_asm.S | ||
10 | fpu_signal: fpu_asm.S | ||
11 | |||
12 | vmx_syscall: vmx_asm.S | ||
13 | vmx_preempt: vmx_asm.S | ||
14 | vmx_signal: vmx_asm.S | ||
15 | |||
16 | include ../../lib.mk | ||
17 | |||
18 | clean: | ||
19 | rm -f $(TEST_PROGS) *.o | ||
diff --git a/tools/testing/selftests/powerpc/math/fpu_asm.S b/tools/testing/selftests/powerpc/math/fpu_asm.S new file mode 100644 index 000000000000..f3711d80e709 --- /dev/null +++ b/tools/testing/selftests/powerpc/math/fpu_asm.S | |||
@@ -0,0 +1,198 @@ | |||
1 | /* | ||
2 | * Copyright 2015, Cyril Bur, IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include "../basic_asm.h" | ||
11 | |||
12 | #define PUSH_FPU(pos) \ | ||
13 | stfd f14,pos(sp); \ | ||
14 | stfd f15,pos+8(sp); \ | ||
15 | stfd f16,pos+16(sp); \ | ||
16 | stfd f17,pos+24(sp); \ | ||
17 | stfd f18,pos+32(sp); \ | ||
18 | stfd f19,pos+40(sp); \ | ||
19 | stfd f20,pos+48(sp); \ | ||
20 | stfd f21,pos+56(sp); \ | ||
21 | stfd f22,pos+64(sp); \ | ||
22 | stfd f23,pos+72(sp); \ | ||
23 | stfd f24,pos+80(sp); \ | ||
24 | stfd f25,pos+88(sp); \ | ||
25 | stfd f26,pos+96(sp); \ | ||
26 | stfd f27,pos+104(sp); \ | ||
27 | stfd f28,pos+112(sp); \ | ||
28 | stfd f29,pos+120(sp); \ | ||
29 | stfd f30,pos+128(sp); \ | ||
30 | stfd f31,pos+136(sp); | ||
31 | |||
32 | #define POP_FPU(pos) \ | ||
33 | lfd f14,pos(sp); \ | ||
34 | lfd f15,pos+8(sp); \ | ||
35 | lfd f16,pos+16(sp); \ | ||
36 | lfd f17,pos+24(sp); \ | ||
37 | lfd f18,pos+32(sp); \ | ||
38 | lfd f19,pos+40(sp); \ | ||
39 | lfd f20,pos+48(sp); \ | ||
40 | lfd f21,pos+56(sp); \ | ||
41 | lfd f22,pos+64(sp); \ | ||
42 | lfd f23,pos+72(sp); \ | ||
43 | lfd f24,pos+80(sp); \ | ||
44 | lfd f25,pos+88(sp); \ | ||
45 | lfd f26,pos+96(sp); \ | ||
46 | lfd f27,pos+104(sp); \ | ||
47 | lfd f28,pos+112(sp); \ | ||
48 | lfd f29,pos+120(sp); \ | ||
49 | lfd f30,pos+128(sp); \ | ||
50 | lfd f31,pos+136(sp); | ||
51 | |||
52 | # Careful calling this, it will 'clobber' fpu (by design) | ||
53 | # Don't call this from C | ||
54 | FUNC_START(load_fpu) | ||
55 | lfd f14,0(r3) | ||
56 | lfd f15,8(r3) | ||
57 | lfd f16,16(r3) | ||
58 | lfd f17,24(r3) | ||
59 | lfd f18,32(r3) | ||
60 | lfd f19,40(r3) | ||
61 | lfd f20,48(r3) | ||
62 | lfd f21,56(r3) | ||
63 | lfd f22,64(r3) | ||
64 | lfd f23,72(r3) | ||
65 | lfd f24,80(r3) | ||
66 | lfd f25,88(r3) | ||
67 | lfd f26,96(r3) | ||
68 | lfd f27,104(r3) | ||
69 | lfd f28,112(r3) | ||
70 | lfd f29,120(r3) | ||
71 | lfd f30,128(r3) | ||
72 | lfd f31,136(r3) | ||
73 | blr | ||
74 | FUNC_END(load_fpu) | ||
75 | |||
76 | FUNC_START(check_fpu) | ||
77 | mr r4,r3 | ||
78 | li r3,1 # assume a bad result | ||
79 | lfd f0,0(r4) | ||
80 | fcmpu cr1,f0,f14 | ||
81 | bne cr1,1f | ||
82 | lfd f0,8(r4) | ||
83 | fcmpu cr1,f0,f15 | ||
84 | bne cr1,1f | ||
85 | lfd f0,16(r4) | ||
86 | fcmpu cr1,f0,f16 | ||
87 | bne cr1,1f | ||
88 | lfd f0,24(r4) | ||
89 | fcmpu cr1,f0,f17 | ||
90 | bne cr1,1f | ||
91 | lfd f0,32(r4) | ||
92 | fcmpu cr1,f0,f18 | ||
93 | bne cr1,1f | ||
94 | lfd f0,40(r4) | ||
95 | fcmpu cr1,f0,f19 | ||
96 | bne cr1,1f | ||
97 | lfd f0,48(r4) | ||
98 | fcmpu cr1,f0,f20 | ||
99 | bne cr1,1f | ||
100 | lfd f0,56(r4) | ||
101 | fcmpu cr1,f0,f21 | ||
102 | bne cr1,1f | ||
103 | lfd f0,64(r4) | ||
104 | fcmpu cr1,f0,f22 | ||
105 | bne cr1,1f | ||
106 | lfd f0,72(r4) | ||
107 | fcmpu cr1,f0,f23 | ||
108 | bne cr1,1f | ||
109 | lfd f0,80(r4) | ||
110 | fcmpu cr1,f0,f24 | ||
111 | bne cr1,1f | ||
112 | lfd f0,88(r4) | ||
113 | fcmpu cr1,f0,f25 | ||
114 | bne cr1,1f | ||
115 | lfd f0,96(r4) | ||
116 | fcmpu cr1,f0,f26 | ||
117 | bne cr1,1f | ||
118 | lfd f0,104(r4) | ||
119 | fcmpu cr1,f0,f27 | ||
120 | bne cr1,1f | ||
121 | lfd f0,112(r4) | ||
122 | fcmpu cr1,f0,f28 | ||
123 | bne cr1,1f | ||
124 | lfd f0,120(r4) | ||
125 | fcmpu cr1,f0,f29 | ||
126 | bne cr1,1f | ||
127 | lfd f0,128(r4) | ||
128 | fcmpu cr1,f0,f30 | ||
129 | bne cr1,1f | ||
130 | lfd f0,136(r4) | ||
131 | fcmpu cr1,f0,f31 | ||
132 | bne cr1,1f | ||
133 | li r3,0 # Success!!! | ||
134 | 1: blr | ||
135 | |||
136 | FUNC_START(test_fpu) | ||
137 | # r3 holds pointer to where to put the result of fork | ||
138 | # r4 holds pointer to the pid | ||
139 | # f14-f31 are non volatiles | ||
140 | PUSH_BASIC_STACK(256) | ||
141 | std r3,STACK_FRAME_PARAM(0)(sp) # Address of darray | ||
142 | std r4,STACK_FRAME_PARAM(1)(sp) # Address of pid | ||
143 | PUSH_FPU(STACK_FRAME_LOCAL(2,0)) | ||
144 | |||
145 | bl load_fpu | ||
146 | nop | ||
147 | li r0,__NR_fork | ||
148 | sc | ||
149 | |||
150 | # pass the result of the fork to the caller | ||
151 | ld r9,STACK_FRAME_PARAM(1)(sp) | ||
152 | std r3,0(r9) | ||
153 | |||
154 | ld r3,STACK_FRAME_PARAM(0)(sp) | ||
155 | bl check_fpu | ||
156 | nop | ||
157 | |||
158 | POP_FPU(STACK_FRAME_LOCAL(2,0)) | ||
159 | POP_BASIC_STACK(256) | ||
160 | blr | ||
161 | FUNC_END(test_fpu) | ||
162 | |||
163 | # int preempt_fpu(double *darray, int *threads_running, int *running) | ||
164 | # On starting will (atomically) decrement not_ready as a signal that the FPU | ||
165 | # has been loaded with darray. Will proceed to check the validity of the FPU | ||
166 | # registers while running is not zero. | ||
167 | FUNC_START(preempt_fpu) | ||
168 | PUSH_BASIC_STACK(256) | ||
169 | std r3,STACK_FRAME_PARAM(0)(sp) # double *darray | ||
170 | std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting | ||
171 | std r5,STACK_FRAME_PARAM(2)(sp) # int *running | ||
172 | PUSH_FPU(STACK_FRAME_LOCAL(3,0)) | ||
173 | |||
174 | bl load_fpu | ||
175 | nop | ||
176 | |||
177 | sync | ||
178 | # Atomic DEC | ||
179 | ld r3,STACK_FRAME_PARAM(1)(sp) | ||
180 | 1: lwarx r4,0,r3 | ||
181 | addi r4,r4,-1 | ||
182 | stwcx. r4,0,r3 | ||
183 | bne- 1b | ||
184 | |||
185 | 2: ld r3,STACK_FRAME_PARAM(0)(sp) | ||
186 | bl check_fpu | ||
187 | nop | ||
188 | cmpdi r3,0 | ||
189 | bne 3f | ||
190 | ld r4,STACK_FRAME_PARAM(2)(sp) | ||
191 | ld r5,0(r4) | ||
192 | cmpwi r5,0 | ||
193 | bne 2b | ||
194 | |||
195 | 3: POP_FPU(STACK_FRAME_LOCAL(3,0)) | ||
196 | POP_BASIC_STACK(256) | ||
197 | blr | ||
198 | FUNC_END(preempt_fpu) | ||
diff --git a/tools/testing/selftests/powerpc/math/fpu_preempt.c b/tools/testing/selftests/powerpc/math/fpu_preempt.c new file mode 100644 index 000000000000..0f85b79d883d --- /dev/null +++ b/tools/testing/selftests/powerpc/math/fpu_preempt.c | |||
@@ -0,0 +1,113 @@ | |||
1 | /* | ||
2 | * Copyright 2015, Cyril Bur, IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This test attempts to see if the FPU registers change across preemption. | ||
10 | * Two things should be noted here a) The check_fpu function in asm only checks | ||
11 | * the non volatile registers as it is reused from the syscall test b) There is | ||
12 | * no way to be sure preemption happened so this test just uses many threads | ||
13 | * and a long wait. As such, a successful test doesn't mean much but a failure | ||
14 | * is bad. | ||
15 | */ | ||
16 | |||
17 | #include <stdio.h> | ||
18 | #include <unistd.h> | ||
19 | #include <sys/syscall.h> | ||
20 | #include <sys/time.h> | ||
21 | #include <sys/types.h> | ||
22 | #include <sys/wait.h> | ||
23 | #include <stdlib.h> | ||
24 | #include <pthread.h> | ||
25 | |||
26 | #include "utils.h" | ||
27 | |||
28 | /* Time to wait for workers to get preempted (seconds) */ | ||
29 | #define PREEMPT_TIME 20 | ||
30 | /* | ||
31 | * Factor by which to multiply number of online CPUs for total number of | ||
32 | * worker threads | ||
33 | */ | ||
34 | #define THREAD_FACTOR 8 | ||
35 | |||
36 | |||
37 | __thread double darray[] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, | ||
38 | 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, | ||
39 | 2.1}; | ||
40 | |||
41 | int threads_starting; | ||
42 | int running; | ||
43 | |||
44 | extern void preempt_fpu(double *darray, int *threads_starting, int *running); | ||
45 | |||
46 | void *preempt_fpu_c(void *p) | ||
47 | { | ||
48 | int i; | ||
49 | srand(pthread_self()); | ||
50 | for (i = 0; i < 21; i++) | ||
51 | darray[i] = rand(); | ||
52 | |||
53 | /* Test failed if it ever returns */ | ||
54 | preempt_fpu(darray, &threads_starting, &running); | ||
55 | |||
56 | return p; | ||
57 | } | ||
58 | |||
59 | int test_preempt_fpu(void) | ||
60 | { | ||
61 | int i, rc, threads; | ||
62 | pthread_t *tids; | ||
63 | |||
64 | threads = sysconf(_SC_NPROCESSORS_ONLN) * THREAD_FACTOR; | ||
65 | tids = malloc((threads) * sizeof(pthread_t)); | ||
66 | FAIL_IF(!tids); | ||
67 | |||
68 | running = true; | ||
69 | threads_starting = threads; | ||
70 | for (i = 0; i < threads; i++) { | ||
71 | rc = pthread_create(&tids[i], NULL, preempt_fpu_c, NULL); | ||
72 | FAIL_IF(rc); | ||
73 | } | ||
74 | |||
75 | setbuf(stdout, NULL); | ||
76 | /* Not really necessary but nice to wait for every thread to start */ | ||
77 | printf("\tWaiting for all workers to start..."); | ||
78 | while(threads_starting) | ||
79 | asm volatile("": : :"memory"); | ||
80 | printf("done\n"); | ||
81 | |||
82 | printf("\tWaiting for %d seconds to let some workers get preempted...", PREEMPT_TIME); | ||
83 | sleep(PREEMPT_TIME); | ||
84 | printf("done\n"); | ||
85 | |||
86 | printf("\tStopping workers..."); | ||
87 | /* | ||
88 | * Working are checking this value every loop. In preempt_fpu 'cmpwi r5,0; bne 2b'. | ||
89 | * r5 will have loaded the value of running. | ||
90 | */ | ||
91 | running = 0; | ||
92 | for (i = 0; i < threads; i++) { | ||
93 | void *rc_p; | ||
94 | pthread_join(tids[i], &rc_p); | ||
95 | |||
96 | /* | ||
97 | * Harness will say the fail was here, look at why preempt_fpu | ||
98 | * returned | ||
99 | */ | ||
100 | if ((long) rc_p) | ||
101 | printf("oops\n"); | ||
102 | FAIL_IF((long) rc_p); | ||
103 | } | ||
104 | printf("done\n"); | ||
105 | |||
106 | free(tids); | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | int main(int argc, char *argv[]) | ||
111 | { | ||
112 | return test_harness(test_preempt_fpu, "fpu_preempt"); | ||
113 | } | ||
diff --git a/tools/testing/selftests/powerpc/math/fpu_signal.c b/tools/testing/selftests/powerpc/math/fpu_signal.c new file mode 100644 index 000000000000..888aa51b4204 --- /dev/null +++ b/tools/testing/selftests/powerpc/math/fpu_signal.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * Copyright 2015, Cyril Bur, IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This test attempts to see if the FPU registers are correctly reported in a | ||
10 | * signal context. Each worker just spins checking its FPU registers, at some | ||
11 | * point a signal will interrupt it and C code will check the signal context | ||
12 | * ensuring it is also the same. | ||
13 | */ | ||
14 | |||
15 | #include <stdio.h> | ||
16 | #include <unistd.h> | ||
17 | #include <sys/syscall.h> | ||
18 | #include <sys/time.h> | ||
19 | #include <sys/types.h> | ||
20 | #include <sys/wait.h> | ||
21 | #include <stdlib.h> | ||
22 | #include <pthread.h> | ||
23 | |||
24 | #include "utils.h" | ||
25 | |||
26 | /* Number of times each thread should receive the signal */ | ||
27 | #define ITERATIONS 10 | ||
28 | /* | ||
29 | * Factor by which to multiply number of online CPUs for total number of | ||
30 | * worker threads | ||
31 | */ | ||
32 | #define THREAD_FACTOR 8 | ||
33 | |||
34 | __thread double darray[] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, | ||
35 | 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, | ||
36 | 2.1}; | ||
37 | |||
38 | bool bad_context; | ||
39 | int threads_starting; | ||
40 | int running; | ||
41 | |||
42 | extern long preempt_fpu(double *darray, int *threads_starting, int *running); | ||
43 | |||
44 | void signal_fpu_sig(int sig, siginfo_t *info, void *context) | ||
45 | { | ||
46 | int i; | ||
47 | ucontext_t *uc = context; | ||
48 | mcontext_t *mc = &uc->uc_mcontext; | ||
49 | |||
50 | /* Only the non volatiles were loaded up */ | ||
51 | for (i = 14; i < 32; i++) { | ||
52 | if (mc->fp_regs[i] != darray[i - 14]) { | ||
53 | bad_context = true; | ||
54 | break; | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | |||
59 | void *signal_fpu_c(void *p) | ||
60 | { | ||
61 | int i; | ||
62 | long rc; | ||
63 | struct sigaction act; | ||
64 | act.sa_sigaction = signal_fpu_sig; | ||
65 | act.sa_flags = SA_SIGINFO; | ||
66 | rc = sigaction(SIGUSR1, &act, NULL); | ||
67 | if (rc) | ||
68 | return p; | ||
69 | |||
70 | srand(pthread_self()); | ||
71 | for (i = 0; i < 21; i++) | ||
72 | darray[i] = rand(); | ||
73 | |||
74 | rc = preempt_fpu(darray, &threads_starting, &running); | ||
75 | |||
76 | return (void *) rc; | ||
77 | } | ||
78 | |||
79 | int test_signal_fpu(void) | ||
80 | { | ||
81 | int i, j, rc, threads; | ||
82 | void *rc_p; | ||
83 | pthread_t *tids; | ||
84 | |||
85 | threads = sysconf(_SC_NPROCESSORS_ONLN) * THREAD_FACTOR; | ||
86 | tids = malloc(threads * sizeof(pthread_t)); | ||
87 | FAIL_IF(!tids); | ||
88 | |||
89 | running = true; | ||
90 | threads_starting = threads; | ||
91 | for (i = 0; i < threads; i++) { | ||
92 | rc = pthread_create(&tids[i], NULL, signal_fpu_c, NULL); | ||
93 | FAIL_IF(rc); | ||
94 | } | ||
95 | |||
96 | setbuf(stdout, NULL); | ||
97 | printf("\tWaiting for all workers to start..."); | ||
98 | while (threads_starting) | ||
99 | asm volatile("": : :"memory"); | ||
100 | printf("done\n"); | ||
101 | |||
102 | printf("\tSending signals to all threads %d times...", ITERATIONS); | ||
103 | for (i = 0; i < ITERATIONS; i++) { | ||
104 | for (j = 0; j < threads; j++) { | ||
105 | pthread_kill(tids[j], SIGUSR1); | ||
106 | } | ||
107 | sleep(1); | ||
108 | } | ||
109 | printf("done\n"); | ||
110 | |||
111 | printf("\tStopping workers..."); | ||
112 | running = 0; | ||
113 | for (i = 0; i < threads; i++) { | ||
114 | pthread_join(tids[i], &rc_p); | ||
115 | |||
116 | /* | ||
117 | * Harness will say the fail was here, look at why signal_fpu | ||
118 | * returned | ||
119 | */ | ||
120 | if ((long) rc_p || bad_context) | ||
121 | printf("oops\n"); | ||
122 | if (bad_context) | ||
123 | fprintf(stderr, "\t!! bad_context is true\n"); | ||
124 | FAIL_IF((long) rc_p || bad_context); | ||
125 | } | ||
126 | printf("done\n"); | ||
127 | |||
128 | free(tids); | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | int main(int argc, char *argv[]) | ||
133 | { | ||
134 | return test_harness(test_signal_fpu, "fpu_signal"); | ||
135 | } | ||
diff --git a/tools/testing/selftests/powerpc/math/fpu_syscall.c b/tools/testing/selftests/powerpc/math/fpu_syscall.c new file mode 100644 index 000000000000..949e6721256d --- /dev/null +++ b/tools/testing/selftests/powerpc/math/fpu_syscall.c | |||
@@ -0,0 +1,90 @@ | |||
1 | /* | ||
2 | * Copyright 2015, Cyril Bur, IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This test attempts to see if the FPU registers change across a syscall (fork). | ||
10 | */ | ||
11 | |||
12 | #include <stdio.h> | ||
13 | #include <unistd.h> | ||
14 | #include <sys/syscall.h> | ||
15 | #include <sys/time.h> | ||
16 | #include <sys/types.h> | ||
17 | #include <sys/wait.h> | ||
18 | #include <stdlib.h> | ||
19 | |||
20 | #include "utils.h" | ||
21 | |||
22 | extern int test_fpu(double *darray, pid_t *pid); | ||
23 | |||
24 | double darray[] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, | ||
25 | 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, | ||
26 | 2.1}; | ||
27 | |||
28 | int syscall_fpu(void) | ||
29 | { | ||
30 | pid_t fork_pid; | ||
31 | int i; | ||
32 | int ret; | ||
33 | int child_ret; | ||
34 | for (i = 0; i < 1000; i++) { | ||
35 | /* test_fpu will fork() */ | ||
36 | ret = test_fpu(darray, &fork_pid); | ||
37 | if (fork_pid == -1) | ||
38 | return -1; | ||
39 | if (fork_pid == 0) | ||
40 | exit(ret); | ||
41 | waitpid(fork_pid, &child_ret, 0); | ||
42 | if (ret || child_ret) | ||
43 | return 1; | ||
44 | } | ||
45 | |||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | int test_syscall_fpu(void) | ||
50 | { | ||
51 | /* | ||
52 | * Setup an environment with much context switching | ||
53 | */ | ||
54 | pid_t pid2; | ||
55 | pid_t pid = fork(); | ||
56 | int ret; | ||
57 | int child_ret; | ||
58 | FAIL_IF(pid == -1); | ||
59 | |||
60 | pid2 = fork(); | ||
61 | /* Can't FAIL_IF(pid2 == -1); because already forked once */ | ||
62 | if (pid2 == -1) { | ||
63 | /* | ||
64 | * Couldn't fork, ensure test is a fail | ||
65 | */ | ||
66 | child_ret = ret = 1; | ||
67 | } else { | ||
68 | ret = syscall_fpu(); | ||
69 | if (pid2) | ||
70 | waitpid(pid2, &child_ret, 0); | ||
71 | else | ||
72 | exit(ret); | ||
73 | } | ||
74 | |||
75 | ret |= child_ret; | ||
76 | |||
77 | if (pid) | ||
78 | waitpid(pid, &child_ret, 0); | ||
79 | else | ||
80 | exit(ret); | ||
81 | |||
82 | FAIL_IF(ret || child_ret); | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | int main(int argc, char *argv[]) | ||
87 | { | ||
88 | return test_harness(test_syscall_fpu, "syscall_fpu"); | ||
89 | |||
90 | } | ||
diff --git a/tools/testing/selftests/powerpc/math/vmx_asm.S b/tools/testing/selftests/powerpc/math/vmx_asm.S new file mode 100644 index 000000000000..1b8c248b3ac1 --- /dev/null +++ b/tools/testing/selftests/powerpc/math/vmx_asm.S | |||
@@ -0,0 +1,235 @@ | |||
1 | /* | ||
2 | * Copyright 2015, Cyril Bur, IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include "../basic_asm.h" | ||
11 | |||
12 | # POS MUST BE 16 ALIGNED! | ||
13 | #define PUSH_VMX(pos,reg) \ | ||
14 | li reg,pos; \ | ||
15 | stvx v20,reg,sp; \ | ||
16 | addi reg,reg,16; \ | ||
17 | stvx v21,reg,sp; \ | ||
18 | addi reg,reg,16; \ | ||
19 | stvx v22,reg,sp; \ | ||
20 | addi reg,reg,16; \ | ||
21 | stvx v23,reg,sp; \ | ||
22 | addi reg,reg,16; \ | ||
23 | stvx v24,reg,sp; \ | ||
24 | addi reg,reg,16; \ | ||
25 | stvx v25,reg,sp; \ | ||
26 | addi reg,reg,16; \ | ||
27 | stvx v26,reg,sp; \ | ||
28 | addi reg,reg,16; \ | ||
29 | stvx v27,reg,sp; \ | ||
30 | addi reg,reg,16; \ | ||
31 | stvx v28,reg,sp; \ | ||
32 | addi reg,reg,16; \ | ||
33 | stvx v29,reg,sp; \ | ||
34 | addi reg,reg,16; \ | ||
35 | stvx v30,reg,sp; \ | ||
36 | addi reg,reg,16; \ | ||
37 | stvx v31,reg,sp; | ||
38 | |||
39 | # POS MUST BE 16 ALIGNED! | ||
40 | #define POP_VMX(pos,reg) \ | ||
41 | li reg,pos; \ | ||
42 | lvx v20,reg,sp; \ | ||
43 | addi reg,reg,16; \ | ||
44 | lvx v21,reg,sp; \ | ||
45 | addi reg,reg,16; \ | ||
46 | lvx v22,reg,sp; \ | ||
47 | addi reg,reg,16; \ | ||
48 | lvx v23,reg,sp; \ | ||
49 | addi reg,reg,16; \ | ||
50 | lvx v24,reg,sp; \ | ||
51 | addi reg,reg,16; \ | ||
52 | lvx v25,reg,sp; \ | ||
53 | addi reg,reg,16; \ | ||
54 | lvx v26,reg,sp; \ | ||
55 | addi reg,reg,16; \ | ||
56 | lvx v27,reg,sp; \ | ||
57 | addi reg,reg,16; \ | ||
58 | lvx v28,reg,sp; \ | ||
59 | addi reg,reg,16; \ | ||
60 | lvx v29,reg,sp; \ | ||
61 | addi reg,reg,16; \ | ||
62 | lvx v30,reg,sp; \ | ||
63 | addi reg,reg,16; \ | ||
64 | lvx v31,reg,sp; | ||
65 | |||
66 | # Carefull this will 'clobber' vmx (by design) | ||
67 | # Don't call this from C | ||
68 | FUNC_START(load_vmx) | ||
69 | li r5,0 | ||
70 | lvx v20,r5,r3 | ||
71 | addi r5,r5,16 | ||
72 | lvx v21,r5,r3 | ||
73 | addi r5,r5,16 | ||
74 | lvx v22,r5,r3 | ||
75 | addi r5,r5,16 | ||
76 | lvx v23,r5,r3 | ||
77 | addi r5,r5,16 | ||
78 | lvx v24,r5,r3 | ||
79 | addi r5,r5,16 | ||
80 | lvx v25,r5,r3 | ||
81 | addi r5,r5,16 | ||
82 | lvx v26,r5,r3 | ||
83 | addi r5,r5,16 | ||
84 | lvx v27,r5,r3 | ||
85 | addi r5,r5,16 | ||
86 | lvx v28,r5,r3 | ||
87 | addi r5,r5,16 | ||
88 | lvx v29,r5,r3 | ||
89 | addi r5,r5,16 | ||
90 | lvx v30,r5,r3 | ||
91 | addi r5,r5,16 | ||
92 | lvx v31,r5,r3 | ||
93 | blr | ||
94 | FUNC_END(load_vmx) | ||
95 | |||
96 | # Should be safe from C, only touches r4, r5 and v0,v1,v2 | ||
97 | FUNC_START(check_vmx) | ||
98 | PUSH_BASIC_STACK(32) | ||
99 | mr r4,r3 | ||
100 | li r3,1 # assume a bad result | ||
101 | li r5,0 | ||
102 | lvx v0,r5,r4 | ||
103 | vcmpequd. v1,v0,v20 | ||
104 | vmr v2,v1 | ||
105 | |||
106 | addi r5,r5,16 | ||
107 | lvx v0,r5,r4 | ||
108 | vcmpequd. v1,v0,v21 | ||
109 | vand v2,v2,v1 | ||
110 | |||
111 | addi r5,r5,16 | ||
112 | lvx v0,r5,r4 | ||
113 | vcmpequd. v1,v0,v22 | ||
114 | vand v2,v2,v1 | ||
115 | |||
116 | addi r5,r5,16 | ||
117 | lvx v0,r5,r4 | ||
118 | vcmpequd. v1,v0,v23 | ||
119 | vand v2,v2,v1 | ||
120 | |||
121 | addi r5,r5,16 | ||
122 | lvx v0,r5,r4 | ||
123 | vcmpequd. v1,v0,v24 | ||
124 | vand v2,v2,v1 | ||
125 | |||
126 | addi r5,r5,16 | ||
127 | lvx v0,r5,r4 | ||
128 | vcmpequd. v1,v0,v25 | ||
129 | vand v2,v2,v1 | ||
130 | |||
131 | addi r5,r5,16 | ||
132 | lvx v0,r5,r4 | ||
133 | vcmpequd. v1,v0,v26 | ||
134 | vand v2,v2,v1 | ||
135 | |||
136 | addi r5,r5,16 | ||
137 | lvx v0,r5,r4 | ||
138 | vcmpequd. v1,v0,v27 | ||
139 | vand v2,v2,v1 | ||
140 | |||
141 | addi r5,r5,16 | ||
142 | lvx v0,r5,r4 | ||
143 | vcmpequd. v1,v0,v28 | ||
144 | vand v2,v2,v1 | ||
145 | |||
146 | addi r5,r5,16 | ||
147 | lvx v0,r5,r4 | ||
148 | vcmpequd. v1,v0,v29 | ||
149 | vand v2,v2,v1 | ||
150 | |||
151 | addi r5,r5,16 | ||
152 | lvx v0,r5,r4 | ||
153 | vcmpequd. v1,v0,v30 | ||
154 | vand v2,v2,v1 | ||
155 | |||
156 | addi r5,r5,16 | ||
157 | lvx v0,r5,r4 | ||
158 | vcmpequd. v1,v0,v31 | ||
159 | vand v2,v2,v1 | ||
160 | |||
161 | li r5,STACK_FRAME_LOCAL(0,0) | ||
162 | stvx v2,r5,sp | ||
163 | ldx r0,r5,sp | ||
164 | cmpdi r0,0xffffffffffffffff | ||
165 | bne 1f | ||
166 | li r3,0 | ||
167 | 1: POP_BASIC_STACK(32) | ||
168 | blr | ||
169 | FUNC_END(check_vmx) | ||
170 | |||
171 | # Safe from C | ||
172 | FUNC_START(test_vmx) | ||
173 | # r3 holds pointer to where to put the result of fork | ||
174 | # r4 holds pointer to the pid | ||
175 | # v20-v31 are non-volatile | ||
176 | PUSH_BASIC_STACK(512) | ||
177 | std r3,STACK_FRAME_PARAM(0)(sp) # Address of varray | ||
178 | std r4,STACK_FRAME_PARAM(1)(sp) # address of pid | ||
179 | PUSH_VMX(STACK_FRAME_LOCAL(2,0),r4) | ||
180 | |||
181 | bl load_vmx | ||
182 | nop | ||
183 | |||
184 | li r0,__NR_fork | ||
185 | sc | ||
186 | # Pass the result of fork back to the caller | ||
187 | ld r9,STACK_FRAME_PARAM(1)(sp) | ||
188 | std r3,0(r9) | ||
189 | |||
190 | ld r3,STACK_FRAME_PARAM(0)(sp) | ||
191 | bl check_vmx | ||
192 | nop | ||
193 | |||
194 | POP_VMX(STACK_FRAME_LOCAL(2,0),r4) | ||
195 | POP_BASIC_STACK(512) | ||
196 | blr | ||
197 | FUNC_END(test_vmx) | ||
198 | |||
199 | # int preempt_vmx(vector int *varray, int *threads_starting, int *running) | ||
200 | # On starting will (atomically) decrement threads_starting as a signal that | ||
201 | # the VMX have been loaded with varray. Will proceed to check the validity of | ||
202 | # the VMX registers while running is not zero. | ||
203 | FUNC_START(preempt_vmx) | ||
204 | PUSH_BASIC_STACK(512) | ||
205 | std r3,STACK_FRAME_PARAM(0)(sp) # vector int *varray | ||
206 | std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting | ||
207 | std r5,STACK_FRAME_PARAM(2)(sp) # int *running | ||
208 | # VMX need to write to 16 byte aligned addresses, skip STACK_FRAME_LOCAL(3,0) | ||
209 | PUSH_VMX(STACK_FRAME_LOCAL(4,0),r4) | ||
210 | |||
211 | bl load_vmx | ||
212 | nop | ||
213 | |||
214 | sync | ||
215 | # Atomic DEC | ||
216 | ld r3,STACK_FRAME_PARAM(1)(sp) | ||
217 | 1: lwarx r4,0,r3 | ||
218 | addi r4,r4,-1 | ||
219 | stwcx. r4,0,r3 | ||
220 | bne- 1b | ||
221 | |||
222 | 2: ld r3,STACK_FRAME_PARAM(0)(sp) | ||
223 | bl check_vmx | ||
224 | nop | ||
225 | cmpdi r3,0 | ||
226 | bne 3f | ||
227 | ld r4,STACK_FRAME_PARAM(2)(sp) | ||
228 | ld r5,0(r4) | ||
229 | cmpwi r5,0 | ||
230 | bne 2b | ||
231 | |||
232 | 3: POP_VMX(STACK_FRAME_LOCAL(4,0),r4) | ||
233 | POP_BASIC_STACK(512) | ||
234 | blr | ||
235 | FUNC_END(preempt_vmx) | ||
diff --git a/tools/testing/selftests/powerpc/math/vmx_preempt.c b/tools/testing/selftests/powerpc/math/vmx_preempt.c new file mode 100644 index 000000000000..9ef376c55b13 --- /dev/null +++ b/tools/testing/selftests/powerpc/math/vmx_preempt.c | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * Copyright 2015, Cyril Bur, IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This test attempts to see if the VMX registers change across preemption. | ||
10 | * Two things should be noted here a) The check_vmx function in asm only checks | ||
11 | * the non volatile registers as it is reused from the syscall test b) There is | ||
12 | * no way to be sure preemption happened so this test just uses many threads | ||
13 | * and a long wait. As such, a successful test doesn't mean much but a failure | ||
14 | * is bad. | ||
15 | */ | ||
16 | |||
17 | #include <stdio.h> | ||
18 | #include <unistd.h> | ||
19 | #include <sys/syscall.h> | ||
20 | #include <sys/time.h> | ||
21 | #include <sys/types.h> | ||
22 | #include <sys/wait.h> | ||
23 | #include <stdlib.h> | ||
24 | #include <pthread.h> | ||
25 | |||
26 | #include "utils.h" | ||
27 | |||
28 | /* Time to wait for workers to get preempted (seconds) */ | ||
29 | #define PREEMPT_TIME 20 | ||
30 | /* | ||
31 | * Factor by which to multiply number of online CPUs for total number of | ||
32 | * worker threads | ||
33 | */ | ||
34 | #define THREAD_FACTOR 8 | ||
35 | |||
36 | __thread vector int varray[] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10,11,12}, | ||
37 | {13,14,15,16},{17,18,19,20},{21,22,23,24}, | ||
38 | {25,26,27,28},{29,30,31,32},{33,34,35,36}, | ||
39 | {37,38,39,40},{41,42,43,44},{45,46,47,48}}; | ||
40 | |||
41 | int threads_starting; | ||
42 | int running; | ||
43 | |||
44 | extern void preempt_vmx(vector int *varray, int *threads_starting, int *running); | ||
45 | |||
46 | void *preempt_vmx_c(void *p) | ||
47 | { | ||
48 | int i, j; | ||
49 | srand(pthread_self()); | ||
50 | for (i = 0; i < 12; i++) | ||
51 | for (j = 0; j < 4; j++) | ||
52 | varray[i][j] = rand(); | ||
53 | |||
54 | /* Test fails if it ever returns */ | ||
55 | preempt_vmx(varray, &threads_starting, &running); | ||
56 | return p; | ||
57 | } | ||
58 | |||
59 | int test_preempt_vmx(void) | ||
60 | { | ||
61 | int i, rc, threads; | ||
62 | pthread_t *tids; | ||
63 | |||
64 | threads = sysconf(_SC_NPROCESSORS_ONLN) * THREAD_FACTOR; | ||
65 | tids = malloc(threads * sizeof(pthread_t)); | ||
66 | FAIL_IF(!tids); | ||
67 | |||
68 | running = true; | ||
69 | threads_starting = threads; | ||
70 | for (i = 0; i < threads; i++) { | ||
71 | rc = pthread_create(&tids[i], NULL, preempt_vmx_c, NULL); | ||
72 | FAIL_IF(rc); | ||
73 | } | ||
74 | |||
75 | setbuf(stdout, NULL); | ||
76 | /* Not really nessesary but nice to wait for every thread to start */ | ||
77 | printf("\tWaiting for all workers to start..."); | ||
78 | while(threads_starting) | ||
79 | asm volatile("": : :"memory"); | ||
80 | printf("done\n"); | ||
81 | |||
82 | printf("\tWaiting for %d seconds to let some workers get preempted...", PREEMPT_TIME); | ||
83 | sleep(PREEMPT_TIME); | ||
84 | printf("done\n"); | ||
85 | |||
86 | printf("\tStopping workers..."); | ||
87 | /* | ||
88 | * Working are checking this value every loop. In preempt_vmx 'cmpwi r5,0; bne 2b'. | ||
89 | * r5 will have loaded the value of running. | ||
90 | */ | ||
91 | running = 0; | ||
92 | for (i = 0; i < threads; i++) { | ||
93 | void *rc_p; | ||
94 | pthread_join(tids[i], &rc_p); | ||
95 | |||
96 | /* | ||
97 | * Harness will say the fail was here, look at why preempt_vmx | ||
98 | * returned | ||
99 | */ | ||
100 | if ((long) rc_p) | ||
101 | printf("oops\n"); | ||
102 | FAIL_IF((long) rc_p); | ||
103 | } | ||
104 | printf("done\n"); | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | int main(int argc, char *argv[]) | ||
110 | { | ||
111 | return test_harness(test_preempt_vmx, "vmx_preempt"); | ||
112 | } | ||
diff --git a/tools/testing/selftests/powerpc/math/vmx_signal.c b/tools/testing/selftests/powerpc/math/vmx_signal.c new file mode 100644 index 000000000000..671d7533a557 --- /dev/null +++ b/tools/testing/selftests/powerpc/math/vmx_signal.c | |||
@@ -0,0 +1,156 @@ | |||
1 | /* | ||
2 | * Copyright 2015, Cyril Bur, IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This test attempts to see if the VMX registers are correctly reported in a | ||
10 | * signal context. Each worker just spins checking its VMX registers, at some | ||
11 | * point a signal will interrupt it and C code will check the signal context | ||
12 | * ensuring it is also the same. | ||
13 | */ | ||
14 | |||
15 | #include <stdio.h> | ||
16 | #include <unistd.h> | ||
17 | #include <sys/syscall.h> | ||
18 | #include <sys/time.h> | ||
19 | #include <sys/types.h> | ||
20 | #include <sys/wait.h> | ||
21 | #include <stdlib.h> | ||
22 | #include <string.h> | ||
23 | #include <pthread.h> | ||
24 | #include <altivec.h> | ||
25 | |||
26 | #include "utils.h" | ||
27 | |||
28 | /* Number of times each thread should receive the signal */ | ||
29 | #define ITERATIONS 10 | ||
30 | /* | ||
31 | * Factor by which to multiply number of online CPUs for total number of | ||
32 | * worker threads | ||
33 | */ | ||
34 | #define THREAD_FACTOR 8 | ||
35 | |||
36 | __thread vector int varray[] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10,11,12}, | ||
37 | {13,14,15,16},{17,18,19,20},{21,22,23,24}, | ||
38 | {25,26,27,28},{29,30,31,32},{33,34,35,36}, | ||
39 | {37,38,39,40},{41,42,43,44},{45,46,47,48}}; | ||
40 | |||
41 | bool bad_context; | ||
42 | int running; | ||
43 | int threads_starting; | ||
44 | |||
45 | extern int preempt_vmx(vector int *varray, int *threads_starting, int *sentinal); | ||
46 | |||
47 | void signal_vmx_sig(int sig, siginfo_t *info, void *context) | ||
48 | { | ||
49 | int i; | ||
50 | ucontext_t *uc = context; | ||
51 | mcontext_t *mc = &uc->uc_mcontext; | ||
52 | |||
53 | /* Only the non volatiles were loaded up */ | ||
54 | for (i = 20; i < 32; i++) { | ||
55 | if (memcmp(mc->v_regs->vrregs[i], &varray[i - 20], 16)) { | ||
56 | int j; | ||
57 | /* | ||
58 | * Shouldn't printf() in a signal handler, however, this is a | ||
59 | * test and we've detected failure. Understanding what failed | ||
60 | * is paramount. All that happens after this is tests exit with | ||
61 | * failure. | ||
62 | */ | ||
63 | printf("VMX mismatch at reg %d!\n", i); | ||
64 | printf("Reg | Actual | Expected\n"); | ||
65 | for (j = 20; j < 32; j++) { | ||
66 | printf("%d | 0x%04x%04x%04x%04x | 0x%04x%04x%04x%04x\n", j, mc->v_regs->vrregs[j][0], | ||
67 | mc->v_regs->vrregs[j][1], mc->v_regs->vrregs[j][2], mc->v_regs->vrregs[j][3], | ||
68 | varray[j - 20][0], varray[j - 20][1], varray[j - 20][2], varray[j - 20][3]); | ||
69 | } | ||
70 | bad_context = true; | ||
71 | break; | ||
72 | } | ||
73 | } | ||
74 | } | ||
75 | |||
76 | void *signal_vmx_c(void *p) | ||
77 | { | ||
78 | int i, j; | ||
79 | long rc; | ||
80 | struct sigaction act; | ||
81 | act.sa_sigaction = signal_vmx_sig; | ||
82 | act.sa_flags = SA_SIGINFO; | ||
83 | rc = sigaction(SIGUSR1, &act, NULL); | ||
84 | if (rc) | ||
85 | return p; | ||
86 | |||
87 | srand(pthread_self()); | ||
88 | for (i = 0; i < 12; i++) | ||
89 | for (j = 0; j < 4; j++) | ||
90 | varray[i][j] = rand(); | ||
91 | |||
92 | rc = preempt_vmx(varray, &threads_starting, &running); | ||
93 | |||
94 | return (void *) rc; | ||
95 | } | ||
96 | |||
97 | int test_signal_vmx(void) | ||
98 | { | ||
99 | int i, j, rc, threads; | ||
100 | void *rc_p; | ||
101 | pthread_t *tids; | ||
102 | |||
103 | threads = sysconf(_SC_NPROCESSORS_ONLN) * THREAD_FACTOR; | ||
104 | tids = malloc(threads * sizeof(pthread_t)); | ||
105 | FAIL_IF(!tids); | ||
106 | |||
107 | running = true; | ||
108 | threads_starting = threads; | ||
109 | for (i = 0; i < threads; i++) { | ||
110 | rc = pthread_create(&tids[i], NULL, signal_vmx_c, NULL); | ||
111 | FAIL_IF(rc); | ||
112 | } | ||
113 | |||
114 | setbuf(stdout, NULL); | ||
115 | printf("\tWaiting for %d workers to start... %d", threads, threads_starting); | ||
116 | while (threads_starting) { | ||
117 | asm volatile("": : :"memory"); | ||
118 | usleep(1000); | ||
119 | printf(", %d", threads_starting); | ||
120 | } | ||
121 | printf(" ...done\n"); | ||
122 | |||
123 | printf("\tSending signals to all threads %d times...", ITERATIONS); | ||
124 | for (i = 0; i < ITERATIONS; i++) { | ||
125 | for (j = 0; j < threads; j++) { | ||
126 | pthread_kill(tids[j], SIGUSR1); | ||
127 | } | ||
128 | sleep(1); | ||
129 | } | ||
130 | printf("done\n"); | ||
131 | |||
132 | printf("\tKilling workers..."); | ||
133 | running = 0; | ||
134 | for (i = 0; i < threads; i++) { | ||
135 | pthread_join(tids[i], &rc_p); | ||
136 | |||
137 | /* | ||
138 | * Harness will say the fail was here, look at why signal_vmx | ||
139 | * returned | ||
140 | */ | ||
141 | if ((long) rc_p || bad_context) | ||
142 | printf("oops\n"); | ||
143 | if (bad_context) | ||
144 | fprintf(stderr, "\t!! bad_context is true\n"); | ||
145 | FAIL_IF((long) rc_p || bad_context); | ||
146 | } | ||
147 | printf("done\n"); | ||
148 | |||
149 | free(tids); | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | int main(int argc, char *argv[]) | ||
154 | { | ||
155 | return test_harness(test_signal_vmx, "vmx_signal"); | ||
156 | } | ||
diff --git a/tools/testing/selftests/powerpc/math/vmx_syscall.c b/tools/testing/selftests/powerpc/math/vmx_syscall.c new file mode 100644 index 000000000000..a017918ee1ca --- /dev/null +++ b/tools/testing/selftests/powerpc/math/vmx_syscall.c | |||
@@ -0,0 +1,91 @@ | |||
1 | /* | ||
2 | * Copyright 2015, Cyril Bur, IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This test attempts to see if the VMX registers change across a syscall (fork). | ||
10 | */ | ||
11 | |||
12 | #include <altivec.h> | ||
13 | #include <stdio.h> | ||
14 | #include <unistd.h> | ||
15 | #include <sys/syscall.h> | ||
16 | #include <sys/time.h> | ||
17 | #include <stdlib.h> | ||
18 | #include <sys/types.h> | ||
19 | #include <sys/wait.h> | ||
20 | #include "utils.h" | ||
21 | |||
22 | vector int varray[] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10,11,12}, | ||
23 | {13,14,15,16},{17,18,19,20},{21,22,23,24}, | ||
24 | {25,26,27,28},{29,30,31,32},{33,34,35,36}, | ||
25 | {37,38,39,40},{41,42,43,44},{45,46,47,48}}; | ||
26 | |||
27 | extern int test_vmx(vector int *varray, pid_t *pid); | ||
28 | |||
29 | int vmx_syscall(void) | ||
30 | { | ||
31 | pid_t fork_pid; | ||
32 | int i; | ||
33 | int ret; | ||
34 | int child_ret; | ||
35 | for (i = 0; i < 1000; i++) { | ||
36 | /* test_vmx will fork() */ | ||
37 | ret = test_vmx(varray, &fork_pid); | ||
38 | if (fork_pid == -1) | ||
39 | return -1; | ||
40 | if (fork_pid == 0) | ||
41 | exit(ret); | ||
42 | waitpid(fork_pid, &child_ret, 0); | ||
43 | if (ret || child_ret) | ||
44 | return 1; | ||
45 | } | ||
46 | |||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | int test_vmx_syscall(void) | ||
51 | { | ||
52 | /* | ||
53 | * Setup an environment with much context switching | ||
54 | */ | ||
55 | pid_t pid2; | ||
56 | pid_t pid = fork(); | ||
57 | int ret; | ||
58 | int child_ret; | ||
59 | FAIL_IF(pid == -1); | ||
60 | |||
61 | pid2 = fork(); | ||
62 | ret = vmx_syscall(); | ||
63 | /* Can't FAIL_IF(pid2 == -1); because we've already forked */ | ||
64 | if (pid2 == -1) { | ||
65 | /* | ||
66 | * Couldn't fork, ensure child_ret is set and is a fail | ||
67 | */ | ||
68 | ret = child_ret = 1; | ||
69 | } else { | ||
70 | if (pid2) | ||
71 | waitpid(pid2, &child_ret, 0); | ||
72 | else | ||
73 | exit(ret); | ||
74 | } | ||
75 | |||
76 | ret |= child_ret; | ||
77 | |||
78 | if (pid) | ||
79 | waitpid(pid, &child_ret, 0); | ||
80 | else | ||
81 | exit(ret); | ||
82 | |||
83 | FAIL_IF(ret || child_ret); | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | int main(int argc, char *argv[]) | ||
88 | { | ||
89 | return test_harness(test_vmx_syscall, "vmx_syscall"); | ||
90 | |||
91 | } | ||
diff --git a/tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c b/tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c index d86653f282b1..8c54d18b3e9a 100644 --- a/tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c +++ b/tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c | |||
@@ -40,7 +40,7 @@ void signal_usr1(int signum, siginfo_t *info, void *uc) | |||
40 | #ifdef __powerpc64__ | 40 | #ifdef __powerpc64__ |
41 | ucp->uc_mcontext.gp_regs[PT_MSR] |= (7ULL << 32); | 41 | ucp->uc_mcontext.gp_regs[PT_MSR] |= (7ULL << 32); |
42 | #else | 42 | #else |
43 | ucp->uc_mcontext.regs->gpr[PT_MSR] |= (7ULL); | 43 | ucp->uc_mcontext.uc_regs->gregs[PT_MSR] |= (7ULL); |
44 | #endif | 44 | #endif |
45 | /* Should segv on return becuase of invalid context */ | 45 | /* Should segv on return becuase of invalid context */ |
46 | segv_expected = 1; | 46 | segv_expected = 1; |