aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-07 11:50:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-07 11:50:34 -0400
commitf536b3cae84eb7c9f3495285ad048d13a397ed0b (patch)
treeb53eee1c45eb080168786e2f103e76d6706cbbb0
parente669830526a0abaf301bf408df69cde33901ac63 (diff)
parent537e5400a0a05c4efe70e7b372c19cfcd0179362 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull powerpc updates from Ben Herrenschmidt: "This is the powerpc new goodies for 3.17. The short story: The biggest bit is Michael removing all of pre-POWER4 processor support from the 64-bit kernel. POWER3 and rs64. This gets rid of a ton of old cruft that has been bitrotting in a long while. It was broken for quite a few versions already and nobody noticed. Nobody uses those machines anymore. While at it, he cleaned up a bunch of old dusty cabinets, getting rid of a skeletton or two. Then, we have some base VFIO support for KVM, which allows assigning of PCI devices to KVM guests, support for large 64-bit BARs on "powernv" platforms, support for HMI (Hardware Management Interrupts) on those same platforms, some sparse-vmemmap improvements (for memory hotplug), There is the usual batch of Freescale embedded updates (summary in the merge commit) and fixes here or there, I think that's it for the highlights" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (102 commits) powerpc/eeh: Export eeh_iommu_group_to_pe() powerpc/eeh: Add missing #ifdef CONFIG_IOMMU_API powerpc: Reduce scariness of interrupt frames in stack traces powerpc: start loop at section start of start in vmemmap_populated() powerpc: implement vmemmap_free() powerpc: implement vmemmap_remove_mapping() for BOOK3S powerpc: implement vmemmap_list_free() powerpc: Fail remap_4k_pfn() if PFN doesn't fit inside PTE powerpc/book3s: Fix endianess issue for HMI handling on napping cpus. powerpc/book3s: handle HMIs for cpus in nap mode. powerpc/powernv: Invoke opal call to handle hmi. powerpc/book3s: Add basic infrastructure to handle HMI in Linux. powerpc/iommu: Fix comments with it_page_shift powerpc/powernv: Handle compound PE in config accessors powerpc/powernv: Handle compound PE for EEH powerpc/powernv: Handle compound PE powerpc/powernv: Split ioda_eeh_get_state() powerpc/powernv: Allow to freeze PE powerpc/powernv: Enable M64 aperatus for PHB3 powerpc/eeh: Aux PE data for error log ...
-rw-r--r--Documentation/devicetree/bindings/powerpc/fsl/board.txt16
-rw-r--r--Documentation/vfio.txt87
-rw-r--r--MAINTAINERS4
-rw-r--r--arch/powerpc/boot/dts/fsl/p2041si-post.dtsi1
-rw-r--r--arch/powerpc/boot/dts/fsl/t2080si-post.dtsi69
-rw-r--r--arch/powerpc/boot/dts/fsl/t2081si-post.dtsi435
-rw-r--r--arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi99
-rw-r--r--arch/powerpc/boot/dts/fsl/t4240si-post.dtsi1
-rw-r--r--arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi1
-rw-r--r--arch/powerpc/boot/dts/t2080qds.dts57
-rw-r--r--arch/powerpc/boot/dts/t2080rdb.dts57
-rw-r--r--arch/powerpc/boot/dts/t2081qds.dts46
-rw-r--r--arch/powerpc/boot/dts/t208xqds.dtsi239
-rw-r--r--arch/powerpc/boot/dts/t208xrdb.dtsi184
-rw-r--r--arch/powerpc/boot/dts/t4240rdb.dts186
-rw-r--r--arch/powerpc/boot/io.h2
-rw-r--r--arch/powerpc/configs/corenet32_smp_defconfig4
-rw-r--r--arch/powerpc/configs/corenet64_smp_defconfig5
-rw-r--r--arch/powerpc/configs/mpc85xx_defconfig3
-rw-r--r--arch/powerpc/configs/mpc85xx_smp_defconfig3
-rw-r--r--arch/powerpc/include/asm/cputable.h31
-rw-r--r--arch/powerpc/include/asm/eeh.h62
-rw-r--r--arch/powerpc/include/asm/exception-64s.h14
-rw-r--r--arch/powerpc/include/asm/fs_pd.h1
-rw-r--r--arch/powerpc/include/asm/hardirq.h1
-rw-r--r--arch/powerpc/include/asm/hw_irq.h1
-rw-r--r--arch/powerpc/include/asm/irqflags.h8
-rw-r--r--arch/powerpc/include/asm/jump_label.h9
-rw-r--r--arch/powerpc/include/asm/kvm_asm.h1
-rw-r--r--arch/powerpc/include/asm/machdep.h5
-rw-r--r--arch/powerpc/include/asm/mmu-hash64.h22
-rw-r--r--arch/powerpc/include/asm/mmu.h8
-rw-r--r--arch/powerpc/include/asm/mmu_context.h6
-rw-r--r--arch/powerpc/include/asm/mpc85xx.h2
-rw-r--r--arch/powerpc/include/asm/mpc8xx.h12
-rw-r--r--arch/powerpc/include/asm/opal.h194
-rw-r--r--arch/powerpc/include/asm/oprofile_impl.h1
-rw-r--r--arch/powerpc/include/asm/paca.h5
-rw-r--r--arch/powerpc/include/asm/perf_event_server.h5
-rw-r--r--arch/powerpc/include/asm/ppc-opcode.h9
-rw-r--r--arch/powerpc/include/asm/pte-fsl-booke.h2
-rw-r--r--arch/powerpc/include/asm/pte-hash64-64k.h5
-rw-r--r--arch/powerpc/include/asm/reg.h2
-rw-r--r--arch/powerpc/include/asm/reg_booke.h57
-rw-r--r--arch/powerpc/include/asm/systbl.h4
-rw-r--r--arch/powerpc/include/asm/trace.h45
-rw-r--r--arch/powerpc/kernel/asm-offsets.c2
-rw-r--r--arch/powerpc/kernel/cputable.c94
-rw-r--r--arch/powerpc/kernel/eeh.c366
-rw-r--r--arch/powerpc/kernel/eeh_cache.c9
-rw-r--r--arch/powerpc/kernel/eeh_dev.c3
-rw-r--r--arch/powerpc/kernel/eeh_driver.c16
-rw-r--r--arch/powerpc/kernel/eeh_pe.c86
-rw-r--r--arch/powerpc/kernel/entry_64.S13
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S361
-rw-r--r--arch/powerpc/kernel/head_64.S30
-rw-r--r--arch/powerpc/kernel/idle_power7.S69
-rw-r--r--arch/powerpc/kernel/iommu.c4
-rw-r--r--arch/powerpc/kernel/irq.c14
-rw-r--r--arch/powerpc/kernel/process.c34
-rw-r--r--arch/powerpc/kernel/prom.c11
-rw-r--r--arch/powerpc/kernel/setup-common.c6
-rw-r--r--arch/powerpc/kernel/setup_64.c15
-rw-r--r--arch/powerpc/kernel/systbl.S3
-rw-r--r--arch/powerpc/kernel/traps.c26
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S6
-rw-r--r--arch/powerpc/lib/copyuser_64.S3
-rw-r--r--arch/powerpc/mm/Makefile4
-rw-r--r--arch/powerpc/mm/hash_utils_64.c26
-rw-r--r--arch/powerpc/mm/init_64.c132
-rw-r--r--arch/powerpc/mm/mmu_context_hash32.c2
-rw-r--r--arch/powerpc/mm/numa.c2
-rw-r--r--arch/powerpc/mm/pgtable_32.c2
-rw-r--r--arch/powerpc/mm/pgtable_64.c2
-rw-r--r--arch/powerpc/mm/ppc_mmu_32.c2
-rw-r--r--arch/powerpc/mm/stab.c286
-rw-r--r--arch/powerpc/mm/tlb_low_64e.S69
-rw-r--r--arch/powerpc/oprofile/Makefile2
-rw-r--r--arch/powerpc/oprofile/common.c3
-rw-r--r--arch/powerpc/oprofile/op_model_rs64.c222
-rw-r--r--arch/powerpc/perf/core-book3s.c73
-rw-r--r--arch/powerpc/perf/mpc7450-pmu.c5
-rw-r--r--arch/powerpc/perf/power4-pmu.c2
-rw-r--r--arch/powerpc/perf/power5+-pmu.c2
-rw-r--r--arch/powerpc/perf/power5-pmu.c2
-rw-r--r--arch/powerpc/perf/power6-pmu.c2
-rw-r--r--arch/powerpc/perf/power7-pmu.c2
-rw-r--r--arch/powerpc/perf/power8-pmu.c27
-rw-r--r--arch/powerpc/perf/ppc970-pmu.c2
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig2
-rw-r--r--arch/powerpc/platforms/85xx/corenet_generic.c53
-rw-r--r--arch/powerpc/platforms/85xx/smp.c44
-rw-r--r--arch/powerpc/platforms/8xx/m8xx_setup.c3
-rw-r--r--arch/powerpc/platforms/8xx/mpc885ads_setup.c62
-rw-r--r--arch/powerpc/platforms/8xx/tqm8xx_setup.c1
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype18
-rw-r--r--arch/powerpc/platforms/powermac/Kconfig2
-rw-r--r--arch/powerpc/platforms/powermac/feature.c42
-rw-r--r--arch/powerpc/platforms/powernv/Makefile3
-rw-r--r--arch/powerpc/platforms/powernv/eeh-ioda.c393
-rw-r--r--arch/powerpc/platforms/powernv/eeh-powernv.c55
-rw-r--r--arch/powerpc/platforms/powernv/opal-async.c3
-rw-r--r--arch/powerpc/platforms/powernv/opal-hmi.c188
-rw-r--r--arch/powerpc/platforms/powernv/opal-lpc.c2
-rw-r--r--arch/powerpc/platforms/powernv/opal-memory-errors.c3
-rw-r--r--arch/powerpc/platforms/powernv/opal-tracepoints.c84
-rw-r--r--arch/powerpc/platforms/powernv/opal-wrappers.S117
-rw-r--r--arch/powerpc/platforms/powernv/opal-xscom.c2
-rw-r--r--arch/powerpc/platforms/powernv/opal.c52
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c499
-rw-r--r--arch/powerpc/platforms/powernv/pci-p5ioc2.c3
-rw-r--r--arch/powerpc/platforms/powernv/pci.c169
-rw-r--r--arch/powerpc/platforms/powernv/pci.h25
-rw-r--r--arch/powerpc/platforms/powernv/rng.c2
-rw-r--r--arch/powerpc/platforms/powernv/setup.c2
-rw-r--r--arch/powerpc/platforms/pseries/dtl.c3
-rw-r--r--arch/powerpc/platforms/pseries/eeh_pseries.c40
-rw-r--r--arch/powerpc/platforms/pseries/hvCall.S172
-rw-r--r--arch/powerpc/platforms/pseries/hvCall_inst.c3
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c30
-rw-r--r--arch/powerpc/platforms/pseries/mobility.c3
-rw-r--r--arch/powerpc/platforms/pseries/msi.c4
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c4
-rw-r--r--arch/powerpc/platforms/pseries/power.c5
-rw-r--r--arch/powerpc/platforms/pseries/ras.c2
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c5
-rw-r--r--arch/powerpc/platforms/pseries/rng.c2
-rw-r--r--arch/powerpc/platforms/pseries/setup.c2
-rw-r--r--arch/powerpc/platforms/pseries/suspend.c5
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c4
-rw-r--r--arch/powerpc/sysdev/micropatch.c1
-rw-r--r--arch/powerpc/sysdev/mpic_msgr.c2
-rw-r--r--arch/powerpc/xmon/xmon.c34
-rw-r--r--drivers/cpufreq/powernv-cpufreq.c18
-rw-r--r--drivers/cpuidle/cpuidle-powernv.c16
-rw-r--r--drivers/memory/Kconfig10
-rw-r--r--drivers/memory/Makefile1
-rw-r--r--drivers/memory/fsl-corenet-cf.c251
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/mac-fec.c1
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/mac-scc.c1
-rw-r--r--drivers/pcmcia/Kconfig10
-rw-r--r--drivers/pcmcia/Makefile1
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c1168
-rw-r--r--drivers/vfio/Makefile1
-rw-r--r--drivers/vfio/pci/vfio_pci.c18
-rw-r--r--drivers/vfio/vfio_iommu_spapr_tce.c17
-rw-r--r--drivers/vfio/vfio_spapr_eeh.c87
-rw-r--r--include/linux/vfio.h23
-rw-r--r--include/uapi/linux/vfio.h34
-rw-r--r--tools/testing/selftests/powerpc/Makefile10
-rw-r--r--tools/testing/selftests/powerpc/pmu/Makefile19
-rw-r--r--tools/testing/selftests/powerpc/pmu/count_instructions.c30
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/Makefile5
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/busy_loop.S271
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c91
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/ebb.c261
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/ebb.h1
-rw-r--r--tools/testing/selftests/powerpc/pmu/l3_bank_test.c48
-rw-r--r--tools/testing/selftests/powerpc/pmu/lib.c50
-rw-r--r--tools/testing/selftests/powerpc/pmu/lib.h1
-rw-r--r--tools/testing/selftests/powerpc/pmu/per_event_excludes.c114
161 files changed, 5477 insertions, 3284 deletions
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/board.txt b/Documentation/devicetree/bindings/powerpc/fsl/board.txt
index 700dec4774fa..cff38bdbc0e4 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/board.txt
+++ b/Documentation/devicetree/bindings/powerpc/fsl/board.txt
@@ -84,3 +84,19 @@ Example:
84 compatible = "fsl,bsc9132qds-fpga", "fsl,fpga-qixis-i2c"; 84 compatible = "fsl,bsc9132qds-fpga", "fsl,fpga-qixis-i2c";
85 reg = <0x66>; 85 reg = <0x66>;
86 }; 86 };
87
88* Freescale on-board CPLD
89
90Some Freescale boards like T1040RDB have an on board CPLD connected.
91
92Required properties:
93- compatible: Should be a board-specific string like "fsl,<board>-cpld"
94 Example:
95 "fsl,t1040rdb-cpld", "fsl,t1042rdb-cpld", "fsl,t1042rdb_pi-cpld"
96- reg: should describe CPLD registers
97
98Example:
99 cpld@3,0 {
100 compatible = "fsl,t1040rdb-cpld";
101 reg = <3 0 0x300>;
102 };
diff --git a/Documentation/vfio.txt b/Documentation/vfio.txt
index b9ca02370d46..96978eced341 100644
--- a/Documentation/vfio.txt
+++ b/Documentation/vfio.txt
@@ -305,7 +305,15 @@ faster, the map/unmap handling has been implemented in real mode which provides
305an excellent performance which has limitations such as inability to do 305an excellent performance which has limitations such as inability to do
306locked pages accounting in real time. 306locked pages accounting in real time.
307 307
308So 3 additional ioctls have been added: 3084) According to sPAPR specification, A Partitionable Endpoint (PE) is an I/O
309subtree that can be treated as a unit for the purposes of partitioning and
310error recovery. A PE may be a single or multi-function IOA (IO Adapter), a
311function of a multi-function IOA, or multiple IOAs (possibly including switch
312and bridge structures above the multiple IOAs). PPC64 guests detect PCI errors
313and recover from them via EEH RTAS services, which works on the basis of
314additional ioctl commands.
315
316So 4 additional ioctls have been added:
309 317
310 VFIO_IOMMU_SPAPR_TCE_GET_INFO - returns the size and the start 318 VFIO_IOMMU_SPAPR_TCE_GET_INFO - returns the size and the start
311 of the DMA window on the PCI bus. 319 of the DMA window on the PCI bus.
@@ -316,9 +324,12 @@ So 3 additional ioctls have been added:
316 324
317 VFIO_IOMMU_DISABLE - disables the container. 325 VFIO_IOMMU_DISABLE - disables the container.
318 326
327 VFIO_EEH_PE_OP - provides an API for EEH setup, error detection and recovery.
319 328
320The code flow from the example above should be slightly changed: 329The code flow from the example above should be slightly changed:
321 330
331 struct vfio_eeh_pe_op pe_op = { .argsz = sizeof(pe_op), .flags = 0 };
332
322 ..... 333 .....
323 /* Add the group to the container */ 334 /* Add the group to the container */
324 ioctl(group, VFIO_GROUP_SET_CONTAINER, &container); 335 ioctl(group, VFIO_GROUP_SET_CONTAINER, &container);
@@ -342,9 +353,79 @@ The code flow from the example above should be slightly changed:
342 dma_map.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE; 353 dma_map.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;
343 354
344 /* Check here is .iova/.size are within DMA window from spapr_iommu_info */ 355 /* Check here is .iova/.size are within DMA window from spapr_iommu_info */
345
346 ioctl(container, VFIO_IOMMU_MAP_DMA, &dma_map); 356 ioctl(container, VFIO_IOMMU_MAP_DMA, &dma_map);
347 ..... 357
358 /* Get a file descriptor for the device */
359 device = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "0000:06:0d.0");
360
361 ....
362
363 /* Gratuitous device reset and go... */
364 ioctl(device, VFIO_DEVICE_RESET);
365
366 /* Make sure EEH is supported */
367 ioctl(container, VFIO_CHECK_EXTENSION, VFIO_EEH);
368
369 /* Enable the EEH functionality on the device */
370 pe_op.op = VFIO_EEH_PE_ENABLE;
371 ioctl(container, VFIO_EEH_PE_OP, &pe_op);
372
373 /* You're suggested to create additional data struct to represent
374 * PE, and put child devices belonging to same IOMMU group to the
375 * PE instance for later reference.
376 */
377
378 /* Check the PE's state and make sure it's in functional state */
379 pe_op.op = VFIO_EEH_PE_GET_STATE;
380 ioctl(container, VFIO_EEH_PE_OP, &pe_op);
381
382 /* Save device state using pci_save_state().
383 * EEH should be enabled on the specified device.
384 */
385
386 ....
387
388 /* When 0xFF's returned from reading PCI config space or IO BARs
389 * of the PCI device. Check the PE's state to see if that has been
390 * frozen.
391 */
392 ioctl(container, VFIO_EEH_PE_OP, &pe_op);
393
394 /* Waiting for pending PCI transactions to be completed and don't
395 * produce any more PCI traffic from/to the affected PE until
396 * recovery is finished.
397 */
398
399 /* Enable IO for the affected PE and collect logs. Usually, the
400 * standard part of PCI config space, AER registers are dumped
401 * as logs for further analysis.
402 */
403 pe_op.op = VFIO_EEH_PE_UNFREEZE_IO;
404 ioctl(container, VFIO_EEH_PE_OP, &pe_op);
405
406 /*
407 * Issue PE reset: hot or fundamental reset. Usually, hot reset
408 * is enough. However, the firmware of some PCI adapters would
409 * require fundamental reset.
410 */
411 pe_op.op = VFIO_EEH_PE_RESET_HOT;
412 ioctl(container, VFIO_EEH_PE_OP, &pe_op);
413 pe_op.op = VFIO_EEH_PE_RESET_DEACTIVATE;
414 ioctl(container, VFIO_EEH_PE_OP, &pe_op);
415
416 /* Configure the PCI bridges for the affected PE */
417 pe_op.op = VFIO_EEH_PE_CONFIGURE;
418 ioctl(container, VFIO_EEH_PE_OP, &pe_op);
419
420 /* Restored state we saved at initialization time. pci_restore_state()
421 * is good enough as an example.
422 */
423
424 /* Hopefully, error is recovered successfully. Now, you can resume to
425 * start PCI traffic to/from the affected PE.
426 */
427
428 ....
348 429
349------------------------------------------------------------------------------- 430-------------------------------------------------------------------------------
350 431
diff --git a/MAINTAINERS b/MAINTAINERS
index 05e545096100..946a67e6c4ea 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5424,6 +5424,7 @@ F: arch/powerpc/boot/rs6000.h
5424LINUX FOR POWERPC (32-BIT AND 64-BIT) 5424LINUX FOR POWERPC (32-BIT AND 64-BIT)
5425M: Benjamin Herrenschmidt <benh@kernel.crashing.org> 5425M: Benjamin Herrenschmidt <benh@kernel.crashing.org>
5426M: Paul Mackerras <paulus@samba.org> 5426M: Paul Mackerras <paulus@samba.org>
5427M: Michael Ellerman <mpe@ellerman.id.au>
5427W: http://www.penguinppc.org/ 5428W: http://www.penguinppc.org/
5428L: linuxppc-dev@lists.ozlabs.org 5429L: linuxppc-dev@lists.ozlabs.org
5429Q: http://patchwork.ozlabs.org/project/linuxppc-dev/list/ 5430Q: http://patchwork.ozlabs.org/project/linuxppc-dev/list/
@@ -5465,16 +5466,17 @@ F: arch/powerpc/*/*/*virtex*
5465 5466
5466LINUX FOR POWERPC EMBEDDED PPC8XX 5467LINUX FOR POWERPC EMBEDDED PPC8XX
5467M: Vitaly Bordug <vitb@kernel.crashing.org> 5468M: Vitaly Bordug <vitb@kernel.crashing.org>
5468M: Marcelo Tosatti <marcelo@kvack.org>
5469W: http://www.penguinppc.org/ 5469W: http://www.penguinppc.org/
5470L: linuxppc-dev@lists.ozlabs.org 5470L: linuxppc-dev@lists.ozlabs.org
5471S: Maintained 5471S: Maintained
5472F: arch/powerpc/platforms/8xx/ 5472F: arch/powerpc/platforms/8xx/
5473 5473
5474LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX 5474LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX
5475M: Scott Wood <scottwood@freescale.com>
5475M: Kumar Gala <galak@kernel.crashing.org> 5476M: Kumar Gala <galak@kernel.crashing.org>
5476W: http://www.penguinppc.org/ 5477W: http://www.penguinppc.org/
5477L: linuxppc-dev@lists.ozlabs.org 5478L: linuxppc-dev@lists.ozlabs.org
5479T: git git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux.git
5478S: Maintained 5480S: Maintained
5479F: arch/powerpc/platforms/83xx/ 5481F: arch/powerpc/platforms/83xx/
5480F: arch/powerpc/platforms/85xx/ 5482F: arch/powerpc/platforms/85xx/
diff --git a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi
index 5290df83ff30..69ce1026c948 100644
--- a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi
@@ -359,6 +359,7 @@
359 compatible = "fsl,qoriq-core-mux-1.0"; 359 compatible = "fsl,qoriq-core-mux-1.0";
360 clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>; 360 clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
361 clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2"; 361 clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
362 clock-output-names = "cmux2";
362 }; 363 };
363 364
364 mux3: mux3@60 { 365 mux3: mux3@60 {
diff --git a/arch/powerpc/boot/dts/fsl/t2080si-post.dtsi b/arch/powerpc/boot/dts/fsl/t2080si-post.dtsi
new file mode 100644
index 000000000000..082ec2044060
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t2080si-post.dtsi
@@ -0,0 +1,69 @@
1/*
2 * T2080 Silicon/SoC Device Tree Source (post include)
3 *
4 * Copyright 2013 Freescale Semiconductor Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Freescale Semiconductor nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 *
18 * ALTERNATIVELY, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") as published by the Free Software
20 * Foundation, either version 2 of that License or (at your option) any
21 * later version.
22 *
23 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/include/ "t2081si-post.dtsi"
36
37&soc {
38/include/ "qoriq-sata2-0.dtsi"
39 sata@220000 {
40 fsl,iommu-parent = <&pamu1>;
41 fsl,liodn-reg = <&guts 0x550>; /* SATA1LIODNR */
42 };
43
44/include/ "qoriq-sata2-1.dtsi"
45 sata@221000 {
46 fsl,iommu-parent = <&pamu1>;
47 fsl,liodn-reg = <&guts 0x554>; /* SATA2LIODNR */
48 };
49};
50
51&rio {
52 compatible = "fsl,srio";
53 interrupts = <16 2 1 11>;
54 #address-cells = <2>;
55 #size-cells = <2>;
56 ranges;
57
58 port1 {
59 #address-cells = <2>;
60 #size-cells = <2>;
61 cell-index = <1>;
62 };
63
64 port2 {
65 #address-cells = <2>;
66 #size-cells = <2>;
67 cell-index = <2>;
68 };
69};
diff --git a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
new file mode 100644
index 000000000000..97479f0ce630
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
@@ -0,0 +1,435 @@
1/*
2 * T2081 Silicon/SoC Device Tree Source (post include)
3 *
4 * Copyright 2013 Freescale Semiconductor Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Freescale Semiconductor nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 *
18 * ALTERNATIVELY, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") as published by the Free Software
20 * Foundation, either version 2 of that License or (at your option) any
21 * later version.
22 *
23 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35&ifc {
36 #address-cells = <2>;
37 #size-cells = <1>;
38 compatible = "fsl,ifc", "simple-bus";
39 interrupts = <25 2 0 0>;
40};
41
42/* controller at 0x240000 */
43&pci0 {
44 compatible = "fsl,t2080-pcie", "fsl,qoriq-pcie-v3.0", "fsl,qoriq-pcie";
45 device_type = "pci";
46 #size-cells = <2>;
47 #address-cells = <3>;
48 bus-range = <0x0 0xff>;
49 interrupts = <20 2 0 0>;
50 fsl,iommu-parent = <&pamu0>;
51 pcie@0 {
52 reg = <0 0 0 0 0>;
53 #interrupt-cells = <1>;
54 #size-cells = <2>;
55 #address-cells = <3>;
56 device_type = "pci";
57 interrupts = <20 2 0 0>;
58 interrupt-map-mask = <0xf800 0 0 7>;
59 interrupt-map = <
60 /* IDSEL 0x0 */
61 0000 0 0 1 &mpic 40 1 0 0
62 0000 0 0 2 &mpic 1 1 0 0
63 0000 0 0 3 &mpic 2 1 0 0
64 0000 0 0 4 &mpic 3 1 0 0
65 >;
66 };
67};
68
69/* controller at 0x250000 */
70&pci1 {
71 compatible = "fsl,t2080-pcie", "fsl,qoriq-pcie-v3.0", "fsl,qoriq-pcie";
72 device_type = "pci";
73 #size-cells = <2>;
74 #address-cells = <3>;
75 bus-range = <0 0xff>;
76 interrupts = <21 2 0 0>;
77 fsl,iommu-parent = <&pamu0>;
78 pcie@0 {
79 reg = <0 0 0 0 0>;
80 #interrupt-cells = <1>;
81 #size-cells = <2>;
82 #address-cells = <3>;
83 device_type = "pci";
84 interrupts = <21 2 0 0>;
85 interrupt-map-mask = <0xf800 0 0 7>;
86 interrupt-map = <
87 /* IDSEL 0x0 */
88 0000 0 0 1 &mpic 41 1 0 0
89 0000 0 0 2 &mpic 5 1 0 0
90 0000 0 0 3 &mpic 6 1 0 0
91 0000 0 0 4 &mpic 7 1 0 0
92 >;
93 };
94};
95
96/* controller at 0x260000 */
97&pci2 {
98 compatible = "fsl,t2080-pcie", "fsl,qoriq-pcie-v3.0", "fsl,qoriq-pcie";
99 device_type = "pci";
100 #size-cells = <2>;
101 #address-cells = <3>;
102 bus-range = <0x0 0xff>;
103 interrupts = <22 2 0 0>;
104 fsl,iommu-parent = <&pamu0>;
105 pcie@0 {
106 reg = <0 0 0 0 0>;
107 #interrupt-cells = <1>;
108 #size-cells = <2>;
109 #address-cells = <3>;
110 device_type = "pci";
111 interrupts = <22 2 0 0>;
112 interrupt-map-mask = <0xf800 0 0 7>;
113 interrupt-map = <
114 /* IDSEL 0x0 */
115 0000 0 0 1 &mpic 42 1 0 0
116 0000 0 0 2 &mpic 9 1 0 0
117 0000 0 0 3 &mpic 10 1 0 0
118 0000 0 0 4 &mpic 11 1 0 0
119 >;
120 };
121};
122
123/* controller at 0x270000 */
124&pci3 {
125 compatible = "fsl,t2080-pcie", "fsl,qoriq-pcie-v3.0", "fsl,qoriq-pcie";
126 device_type = "pci";
127 #size-cells = <2>;
128 #address-cells = <3>;
129 bus-range = <0x0 0xff>;
130 interrupts = <23 2 0 0>;
131 fsl,iommu-parent = <&pamu0>;
132 pcie@0 {
133 reg = <0 0 0 0 0>;
134 #interrupt-cells = <1>;
135 #size-cells = <2>;
136 #address-cells = <3>;
137 device_type = "pci";
138 interrupts = <23 2 0 0>;
139 interrupt-map-mask = <0xf800 0 0 7>;
140 interrupt-map = <
141 /* IDSEL 0x0 */
142 0000 0 0 1 &mpic 43 1 0 0
143 0000 0 0 2 &mpic 0 1 0 0
144 0000 0 0 3 &mpic 4 1 0 0
145 0000 0 0 4 &mpic 8 1 0 0
146 >;
147 };
148};
149
150&dcsr {
151 #address-cells = <1>;
152 #size-cells = <1>;
153 compatible = "fsl,dcsr", "simple-bus";
154
155 dcsr-epu@0 {
156 compatible = "fsl,t2080-dcsr-epu", "fsl,dcsr-epu";
157 interrupts = <52 2 0 0
158 84 2 0 0
159 85 2 0 0
160 94 2 0 0
161 95 2 0 0>;
162 reg = <0x0 0x1000>;
163 };
164 dcsr-npc {
165 compatible = "fsl,t2080-dcsr-cnpc", "fsl,dcsr-cnpc";
166 reg = <0x1000 0x1000 0x1002000 0x10000>;
167 };
168 dcsr-nxc@2000 {
169 compatible = "fsl,dcsr-nxc";
170 reg = <0x2000 0x1000>;
171 };
172 dcsr-corenet {
173 compatible = "fsl,dcsr-corenet";
174 reg = <0x8000 0x1000 0x1A000 0x1000>;
175 };
176 dcsr-ocn@11000 {
177 compatible = "fsl,t2080-dcsr-ocn", "fsl,dcsr-ocn";
178 reg = <0x11000 0x1000>;
179 };
180 dcsr-ddr@12000 {
181 compatible = "fsl,dcsr-ddr";
182 dev-handle = <&ddr1>;
183 reg = <0x12000 0x1000>;
184 };
185 dcsr-nal@18000 {
186 compatible = "fsl,t2080-dcsr-nal", "fsl,dcsr-nal";
187 reg = <0x18000 0x1000>;
188 };
189 dcsr-rcpm@22000 {
190 compatible = "fsl,t2080-dcsr-rcpm", "fsl,dcsr-rcpm";
191 reg = <0x22000 0x1000>;
192 };
193 dcsr-snpc@30000 {
194 compatible = "fsl,t2080-dcsr-snpc", "fsl,dcsr-snpc";
195 reg = <0x30000 0x1000 0x1022000 0x10000>;
196 };
197 dcsr-snpc@31000 {
198 compatible = "fsl,t2080-dcsr-snpc", "fsl,dcsr-snpc";
199 reg = <0x31000 0x1000 0x1042000 0x10000>;
200 };
201 dcsr-snpc@32000 {
202 compatible = "fsl,t2080-dcsr-snpc", "fsl,dcsr-snpc";
203 reg = <0x32000 0x1000 0x1062000 0x10000>;
204 };
205 dcsr-cpu-sb-proxy@100000 {
206 compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
207 cpu-handle = <&cpu0>;
208 reg = <0x100000 0x1000 0x101000 0x1000>;
209 };
210 dcsr-cpu-sb-proxy@108000 {
211 compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
212 cpu-handle = <&cpu1>;
213 reg = <0x108000 0x1000 0x109000 0x1000>;
214 };
215 dcsr-cpu-sb-proxy@110000 {
216 compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
217 cpu-handle = <&cpu2>;
218 reg = <0x110000 0x1000 0x111000 0x1000>;
219 };
220 dcsr-cpu-sb-proxy@118000 {
221 compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
222 cpu-handle = <&cpu3>;
223 reg = <0x118000 0x1000 0x119000 0x1000>;
224 };
225};
226
227&soc {
228 #address-cells = <1>;
229 #size-cells = <1>;
230 device_type = "soc";
231 compatible = "simple-bus";
232
233 soc-sram-error {
234 compatible = "fsl,soc-sram-error";
235 interrupts = <16 2 1 29>;
236 };
237
238 corenet-law@0 {
239 compatible = "fsl,corenet-law";
240 reg = <0x0 0x1000>;
241 fsl,num-laws = <32>;
242 };
243
244 ddr1: memory-controller@8000 {
245 compatible = "fsl,qoriq-memory-controller-v4.7",
246 "fsl,qoriq-memory-controller";
247 reg = <0x8000 0x1000>;
248 interrupts = <16 2 1 23>;
249 };
250
251 cpc: l3-cache-controller@10000 {
252 compatible = "fsl,t2080-l3-cache-controller", "cache";
253 reg = <0x10000 0x1000
254 0x11000 0x1000
255 0x12000 0x1000>;
256 interrupts = <16 2 1 27
257 16 2 1 26
258 16 2 1 25>;
259 };
260
261 corenet-cf@18000 {
262 compatible = "fsl,corenet2-cf", "fsl,corenet-cf";
263 reg = <0x18000 0x1000>;
264 interrupts = <16 2 1 31>;
265 fsl,ccf-num-csdids = <32>;
266 fsl,ccf-num-snoopids = <32>;
267 };
268
269 iommu@20000 {
270 compatible = "fsl,pamu-v1.0", "fsl,pamu";
271 reg = <0x20000 0x3000>;
272 fsl,portid-mapping = <0x8000>;
273 ranges = <0 0x20000 0x3000>;
274 #address-cells = <1>;
275 #size-cells = <1>;
276 interrupts = <
277 24 2 0 0
278 16 2 1 30>;
279
280 pamu0: pamu@0 {
281 reg = <0 0x1000>;
282 fsl,primary-cache-geometry = <32 1>;
283 fsl,secondary-cache-geometry = <128 2>;
284 };
285
286 pamu1: pamu@1000 {
287 reg = <0x1000 0x1000>;
288 fsl,primary-cache-geometry = <32 1>;
289 fsl,secondary-cache-geometry = <128 2>;
290 };
291
292 pamu2: pamu@2000 {
293 reg = <0x2000 0x1000>;
294 fsl,primary-cache-geometry = <32 1>;
295 fsl,secondary-cache-geometry = <128 2>;
296 };
297 };
298
299/include/ "qoriq-mpic4.3.dtsi"
300
301 guts: global-utilities@e0000 {
302 compatible = "fsl,t2080-device-config", "fsl,qoriq-device-config-2.0";
303 reg = <0xe0000 0xe00>;
304 fsl,has-rstcr;
305 fsl,liodn-bits = <12>;
306 };
307
308 clockgen: global-utilities@e1000 {
309 compatible = "fsl,t2080-clockgen", "fsl,qoriq-clockgen-2.0";
310 ranges = <0x0 0xe1000 0x1000>;
311 reg = <0xe1000 0x1000>;
312 #address-cells = <1>;
313 #size-cells = <1>;
314
315 sysclk: sysclk {
316 #clock-cells = <0>;
317 compatible = "fsl,qoriq-sysclk-2.0";
318 clock-output-names = "sysclk", "fixed-clock";
319 };
320
321 pll0: pll0@800 {
322 #clock-cells = <1>;
323 reg = <0x800 4>;
324 compatible = "fsl,qoriq-core-pll-2.0";
325 clocks = <&sysclk>;
326 clock-output-names = "pll0", "pll0-div2", "pll0-div4";
327 };
328
329 pll1: pll1@820 {
330 #clock-cells = <1>;
331 reg = <0x820 4>;
332 compatible = "fsl,qoriq-core-pll-2.0";
333 clocks = <&sysclk>;
334 clock-output-names = "pll1", "pll1-div2", "pll1-div4";
335 };
336
337 mux0: mux0@0 {
338 #clock-cells = <0>;
339 reg = <0x0 4>;
340 compatible = "fsl,qoriq-core-mux-2.0";
341 clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>,
342 <&pll1 0>, <&pll1 1>, <&pll1 2>;
343 clock-names = "pll0", "pll0-div2", "pll1-div4",
344 "pll1", "pll1-div2", "pll1-div4";
345 clock-output-names = "cmux0";
346 };
347
348 mux1: mux1@20 {
349 #clock-cells = <0>;
350 reg = <0x20 4>;
351 compatible = "fsl,qoriq-core-mux-2.0";
352 clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>,
353 <&pll1 0>, <&pll1 1>, <&pll1 2>;
354 clock-names = "pll0", "pll0-div2", "pll1-div4",
355 "pll1", "pll1-div2", "pll1-div4";
356 clock-output-names = "cmux1";
357 };
358 };
359
360 rcpm: global-utilities@e2000 {
361 compatible = "fsl,t2080-rcpm", "fsl,qoriq-rcpm-2.0";
362 reg = <0xe2000 0x1000>;
363 };
364
365 sfp: sfp@e8000 {
366 compatible = "fsl,t2080-sfp";
367 reg = <0xe8000 0x1000>;
368 };
369
370 serdes: serdes@ea000 {
371 compatible = "fsl,t2080-serdes";
372 reg = <0xea000 0x4000>;
373 };
374
375/include/ "elo3-dma-0.dtsi"
376 dma@100300 {
377 fsl,iommu-parent = <&pamu0>;
378 fsl,liodn-reg = <&guts 0x580>; /* DMA1LIODNR */
379 };
380/include/ "elo3-dma-1.dtsi"
381 dma@101300 {
382 fsl,iommu-parent = <&pamu0>;
383 fsl,liodn-reg = <&guts 0x584>; /* DMA2LIODNR */
384 };
385/include/ "elo3-dma-2.dtsi"
386 dma@102300 {
387 fsl,iommu-parent = <&pamu0>;
388 fsl,liodn-reg = <&guts 0x588>; /* DMA3LIODNR */
389 };
390
391/include/ "qoriq-espi-0.dtsi"
392 spi@110000 {
393 fsl,espi-num-chipselects = <4>;
394 };
395
396/include/ "qoriq-esdhc-0.dtsi"
397 sdhc@114000 {
398 compatible = "fsl,t2080-esdhc", "fsl,esdhc";
399 fsl,iommu-parent = <&pamu1>;
400 fsl,liodn-reg = <&guts 0x530>; /* SDMMCLIODNR */
401 sdhci,auto-cmd12;
402 };
403/include/ "qoriq-i2c-0.dtsi"
404/include/ "qoriq-i2c-1.dtsi"
405/include/ "qoriq-duart-0.dtsi"
406/include/ "qoriq-duart-1.dtsi"
407/include/ "qoriq-gpio-0.dtsi"
408/include/ "qoriq-gpio-1.dtsi"
409/include/ "qoriq-gpio-2.dtsi"
410/include/ "qoriq-gpio-3.dtsi"
411/include/ "qoriq-usb2-mph-0.dtsi"
412 usb0: usb@210000 {
413 compatible = "fsl-usb2-mph-v2.4", "fsl-usb2-mph";
414 fsl,iommu-parent = <&pamu1>;
415 fsl,liodn-reg = <&guts 0x520>; /* USB1LIODNR */
416 phy_type = "utmi";
417 port0;
418 };
419/include/ "qoriq-usb2-dr-0.dtsi"
420 usb1: usb@211000 {
421 compatible = "fsl-usb2-dr-v2.4", "fsl-usb2-dr";
422 fsl,iommu-parent = <&pamu1>;
423 fsl,liodn-reg = <&guts 0x524>; /* USB1LIODNR */
424 dr_mode = "host";
425 phy_type = "utmi";
426 };
427/include/ "qoriq-sec5.2-0.dtsi"
428
429 L2_1: l2-cache-controller@c20000 {
430 /* Cluster 0 L2 cache */
431 compatible = "fsl,t2080-l2-cache-controller";
432 reg = <0xc20000 0x40000>;
433 next-level-cache = <&cpc>;
434 };
435};
diff --git a/arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi b/arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi
new file mode 100644
index 000000000000..e71ceb0e1100
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi
@@ -0,0 +1,99 @@
1/*
2 * T2080/T2081 Silicon/SoC Device Tree Source (pre include)
3 *
4 * Copyright 2013 Freescale Semiconductor Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Freescale Semiconductor nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 *
18 * ALTERNATIVELY, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") as published by the Free Software
20 * Foundation, either version 2 of that License or (at your option) any
21 * later version.
22 *
23 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/dts-v1/;
36
37/include/ "e6500_power_isa.dtsi"
38
39/ {
40 #address-cells = <2>;
41 #size-cells = <2>;
42 interrupt-parent = <&mpic>;
43
44 aliases {
45 ccsr = &soc;
46 dcsr = &dcsr;
47
48 serial0 = &serial0;
49 serial1 = &serial1;
50 serial2 = &serial2;
51 serial3 = &serial3;
52
53 crypto = &crypto;
54 pci0 = &pci0;
55 pci1 = &pci1;
56 pci2 = &pci2;
57 pci3 = &pci3;
58 usb0 = &usb0;
59 usb1 = &usb1;
60 dma0 = &dma0;
61 dma1 = &dma1;
62 dma2 = &dma2;
63 sdhc = &sdhc;
64 };
65
66 cpus {
67 #address-cells = <1>;
68 #size-cells = <0>;
69
70 cpu0: PowerPC,e6500@0 {
71 device_type = "cpu";
72 reg = <0 1>;
73 clocks = <&mux0>;
74 next-level-cache = <&L2_1>;
75 fsl,portid-mapping = <0x80000000>;
76 };
77 cpu1: PowerPC,e6500@2 {
78 device_type = "cpu";
79 reg = <2 3>;
80 clocks = <&mux0>;
81 next-level-cache = <&L2_1>;
82 fsl,portid-mapping = <0x80000000>;
83 };
84 cpu2: PowerPC,e6500@4 {
85 device_type = "cpu";
86 reg = <4 5>;
87 clocks = <&mux0>;
88 next-level-cache = <&L2_1>;
89 fsl,portid-mapping = <0x80000000>;
90 };
91 cpu3: PowerPC,e6500@6 {
92 device_type = "cpu";
93 reg = <6 7>;
94 clocks = <&mux0>;
95 next-level-cache = <&L2_1>;
96 fsl,portid-mapping = <0x80000000>;
97 };
98 };
99};
diff --git a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
index 793669baa13e..a3d582e0361a 100644
--- a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
@@ -476,6 +476,7 @@
476 476
477/include/ "elo3-dma-0.dtsi" 477/include/ "elo3-dma-0.dtsi"
478/include/ "elo3-dma-1.dtsi" 478/include/ "elo3-dma-1.dtsi"
479/include/ "elo3-dma-2.dtsi"
479 480
480/include/ "qoriq-espi-0.dtsi" 481/include/ "qoriq-espi-0.dtsi"
481 spi@110000 { 482 spi@110000 {
diff --git a/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi
index d2f157edbe81..261a3abb1a55 100644
--- a/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi
@@ -57,6 +57,7 @@
57 pci3 = &pci3; 57 pci3 = &pci3;
58 dma0 = &dma0; 58 dma0 = &dma0;
59 dma1 = &dma1; 59 dma1 = &dma1;
60 dma2 = &dma2;
60 sdhc = &sdhc; 61 sdhc = &sdhc;
61 }; 62 };
62 63
diff --git a/arch/powerpc/boot/dts/t2080qds.dts b/arch/powerpc/boot/dts/t2080qds.dts
new file mode 100644
index 000000000000..aa1d6d8c169b
--- /dev/null
+++ b/arch/powerpc/boot/dts/t2080qds.dts
@@ -0,0 +1,57 @@
1/*
2 * T2080QDS Device Tree Source
3 *
4 * Copyright 2013 Freescale Semiconductor Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Freescale Semiconductor nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 *
18 * ALTERNATIVELY, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") as published by the Free Software
20 * Foundation, either version 2 of that License or (at your option) any
21 * later version.
22 *
23 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/include/ "fsl/t208xsi-pre.dtsi"
36/include/ "t208xqds.dtsi"
37
38/ {
39 model = "fsl,T2080QDS";
40 compatible = "fsl,T2080QDS";
41 #address-cells = <2>;
42 #size-cells = <2>;
43 interrupt-parent = <&mpic>;
44
45 rio: rapidio@ffe0c0000 {
46 reg = <0xf 0xfe0c0000 0 0x11000>;
47
48 port1 {
49 ranges = <0 0 0xc 0x20000000 0 0x10000000>;
50 };
51 port2 {
52 ranges = <0 0 0xc 0x30000000 0 0x10000000>;
53 };
54 };
55};
56
57/include/ "fsl/t2080si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t2080rdb.dts b/arch/powerpc/boot/dts/t2080rdb.dts
new file mode 100644
index 000000000000..e8891047600c
--- /dev/null
+++ b/arch/powerpc/boot/dts/t2080rdb.dts
@@ -0,0 +1,57 @@
1/*
2 * T2080PCIe-RDB Board Device Tree Source
3 *
4 * Copyright 2014 Freescale Semiconductor Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Freescale Semiconductor nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 *
18 * ALTERNATIVELY, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") as published by the Free Software
20 * Foundation, either version 2 of that License or (at your option) any
21 * later version.
22 *
23 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/include/ "fsl/t208xsi-pre.dtsi"
36/include/ "t208xrdb.dtsi"
37
38/ {
39 model = "fsl,T2080RDB";
40 compatible = "fsl,T2080RDB";
41 #address-cells = <2>;
42 #size-cells = <2>;
43 interrupt-parent = <&mpic>;
44
45 rio: rapidio@ffe0c0000 {
46 reg = <0xf 0xfe0c0000 0 0x11000>;
47
48 port1 {
49 ranges = <0 0 0xc 0x20000000 0 0x10000000>;
50 };
51 port2 {
52 ranges = <0 0 0xc 0x30000000 0 0x10000000>;
53 };
54 };
55};
56
57/include/ "fsl/t2080si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t2081qds.dts b/arch/powerpc/boot/dts/t2081qds.dts
new file mode 100644
index 000000000000..8ec80a71e102
--- /dev/null
+++ b/arch/powerpc/boot/dts/t2081qds.dts
@@ -0,0 +1,46 @@
1/*
2 * T2081QDS Device Tree Source
3 *
4 * Copyright 2013 Freescale Semiconductor Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Freescale Semiconductor nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 *
18 * ALTERNATIVELY, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") as published by the Free Software
20 * Foundation, either version 2 of that License or (at your option) any
21 * later version.
22 *
23 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/include/ "fsl/t208xsi-pre.dtsi"
36/include/ "t208xqds.dtsi"
37
38/ {
39 model = "fsl,T2081QDS";
40 compatible = "fsl,T2081QDS";
41 #address-cells = <2>;
42 #size-cells = <2>;
43 interrupt-parent = <&mpic>;
44};
45
46/include/ "fsl/t2081si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t208xqds.dtsi b/arch/powerpc/boot/dts/t208xqds.dtsi
new file mode 100644
index 000000000000..555dc6e03d89
--- /dev/null
+++ b/arch/powerpc/boot/dts/t208xqds.dtsi
@@ -0,0 +1,239 @@
1/*
2 * T2080/T2081 QDS Device Tree Source
3 *
4 * Copyright 2013 Freescale Semiconductor Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Freescale Semiconductor nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 *
18 * ALTERNATIVELY, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") as published by the Free Software
20 * Foundation, either version 2 of that License or (at your option) any
21 * later version.
22 *
23 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/ {
36 model = "fsl,T2080QDS";
37 compatible = "fsl,T2080QDS";
38 #address-cells = <2>;
39 #size-cells = <2>;
40 interrupt-parent = <&mpic>;
41
42 ifc: localbus@ffe124000 {
43 reg = <0xf 0xfe124000 0 0x2000>;
44 ranges = <0 0 0xf 0xe8000000 0x08000000
45 2 0 0xf 0xff800000 0x00010000
46 3 0 0xf 0xffdf0000 0x00008000>;
47
48 nor@0,0 {
49 #address-cells = <1>;
50 #size-cells = <1>;
51 compatible = "cfi-flash";
52 reg = <0x0 0x0 0x8000000>;
53 bank-width = <2>;
54 device-width = <1>;
55 };
56
57 nand@2,0 {
58 #address-cells = <1>;
59 #size-cells = <1>;
60 compatible = "fsl,ifc-nand";
61 reg = <0x2 0x0 0x10000>;
62 };
63
64 boardctrl: board-control@3,0 {
65 #address-cells = <1>;
66 #size-cells = <1>;
67 compatible = "fsl,fpga-qixis";
68 reg = <3 0 0x300>;
69 ranges = <0 3 0 0x300>;
70 };
71 };
72
73 memory {
74 device_type = "memory";
75 };
76
77 dcsr: dcsr@f00000000 {
78 ranges = <0x00000000 0xf 0x00000000 0x01072000>;
79 };
80
81 soc: soc@ffe000000 {
82 ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
83 reg = <0xf 0xfe000000 0 0x00001000>;
84 spi@110000 {
85 flash@0 {
86 #address-cells = <1>;
87 #size-cells = <1>;
88 compatible = "micron,n25q128a11"; /* 16MB */
89 reg = <0>;
90 spi-max-frequency = <40000000>; /* input clock */
91 };
92
93 flash@1 {
94 #address-cells = <1>;
95 #size-cells = <1>;
96 compatible = "sst,sst25wf040";
97 reg = <1>;
98 spi-max-frequency = <35000000>;
99 };
100
101 flash@2 {
102 #address-cells = <1>;
103 #size-cells = <1>;
104 compatible = "eon,en25s64";
105 reg = <2>;
106 spi-max-frequency = <35000000>;
107 };
108 };
109
110 i2c@118000 {
111 pca9547@77 {
112 compatible = "nxp,pca9547";
113 reg = <0x77>;
114 #address-cells = <1>;
115 #size-cells = <0>;
116
117 i2c@0 {
118 #address-cells = <1>;
119 #size-cells = <0>;
120 reg = <0x0>;
121
122 eeprom@50 {
123 compatible = "at24,24c512";
124 reg = <0x50>;
125 };
126
127 eeprom@51 {
128 compatible = "at24,24c02";
129 reg = <0x51>;
130 };
131
132 eeprom@57 {
133 compatible = "at24,24c02";
134 reg = <0x57>;
135 };
136
137 rtc@68 {
138 compatible = "dallas,ds3232";
139 reg = <0x68>;
140 interrupts = <0x1 0x1 0 0>;
141 };
142 };
143
144 i2c@1 {
145 #address-cells = <1>;
146 #size-cells = <0>;
147 reg = <0x1>;
148
149 eeprom@55 {
150 compatible = "at24,24c02";
151 reg = <0x55>;
152 };
153 };
154
155 i2c@2 {
156 #address-cells = <1>;
157 #size-cells = <0>;
158 reg = <0x2>;
159
160 ina220@40 {
161 compatible = "ti,ina220";
162 reg = <0x40>;
163 shunt-resistor = <1000>;
164 };
165
166 ina220@41 {
167 compatible = "ti,ina220";
168 reg = <0x41>;
169 shunt-resistor = <1000>;
170 };
171 };
172 };
173 };
174
175 sdhc@114000 {
176 voltage-ranges = <1800 1800 3300 3300>;
177 };
178 };
179
180 pci0: pcie@ffe240000 {
181 reg = <0xf 0xfe240000 0 0x10000>;
182 ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
183 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
184 pcie@0 {
185 ranges = <0x02000000 0 0xe0000000
186 0x02000000 0 0xe0000000
187 0 0x20000000
188
189 0x01000000 0 0x00000000
190 0x01000000 0 0x00000000
191 0 0x00010000>;
192 };
193 };
194
195 pci1: pcie@ffe250000 {
196 reg = <0xf 0xfe250000 0 0x10000>;
197 ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x10000000
198 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
199 pcie@0 {
200 ranges = <0x02000000 0 0xe0000000
201 0x02000000 0 0xe0000000
202 0 0x20000000
203
204 0x01000000 0 0x00000000
205 0x01000000 0 0x00000000
206 0 0x00010000>;
207 };
208 };
209
210 pci2: pcie@ffe260000 {
211 reg = <0xf 0xfe260000 0 0x1000>;
212 ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000
213 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
214 pcie@0 {
215 ranges = <0x02000000 0 0xe0000000
216 0x02000000 0 0xe0000000
217 0 0x20000000
218
219 0x01000000 0 0x00000000
220 0x01000000 0 0x00000000
221 0 0x00010000>;
222 };
223 };
224
225 pci3: pcie@ffe270000 {
226 reg = <0xf 0xfe270000 0 0x10000>;
227 ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x10000000
228 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
229 pcie@0 {
230 ranges = <0x02000000 0 0xe0000000
231 0x02000000 0 0xe0000000
232 0 0x20000000
233
234 0x01000000 0 0x00000000
235 0x01000000 0 0x00000000
236 0 0x00010000>;
237 };
238 };
239};
diff --git a/arch/powerpc/boot/dts/t208xrdb.dtsi b/arch/powerpc/boot/dts/t208xrdb.dtsi
new file mode 100644
index 000000000000..1481e192e783
--- /dev/null
+++ b/arch/powerpc/boot/dts/t208xrdb.dtsi
@@ -0,0 +1,184 @@
1/*
2 * T2080PCIe-RDB Board Device Tree Source
3 *
4 * Copyright 2014 Freescale Semiconductor Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Freescale Semiconductor nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 *
18 * ALTERNATIVELY, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") as published by the Free Software
20 * Foundation, either version 2 of that License or (at your option) any
21 * later version.
22 *
23 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/ {
36 model = "fsl,T2080RDB";
37 compatible = "fsl,T2080RDB";
38 #address-cells = <2>;
39 #size-cells = <2>;
40 interrupt-parent = <&mpic>;
41
42 ifc: localbus@ffe124000 {
43 reg = <0xf 0xfe124000 0 0x2000>;
44 ranges = <0 0 0xf 0xe8000000 0x08000000
45 2 0 0xf 0xff800000 0x00010000
46 3 0 0xf 0xffdf0000 0x00008000>;
47
48 nor@0,0 {
49 #address-cells = <1>;
50 #size-cells = <1>;
51 compatible = "cfi-flash";
52 reg = <0x0 0x0 0x8000000>;
53
54 bank-width = <2>;
55 device-width = <1>;
56 };
57
58 nand@1,0 {
59 #address-cells = <1>;
60 #size-cells = <1>;
61 compatible = "fsl,ifc-nand";
62 reg = <0x2 0x0 0x10000>;
63 };
64
65 boardctrl: board-control@2,0 {
66 #address-cells = <1>;
67 #size-cells = <1>;
68 compatible = "fsl,t2080-cpld";
69 reg = <3 0 0x300>;
70 ranges = <0 3 0 0x300>;
71 };
72 };
73
74 memory {
75 device_type = "memory";
76 };
77
78 dcsr: dcsr@f00000000 {
79 ranges = <0x00000000 0xf 0x00000000 0x01072000>;
80 };
81
82 soc: soc@ffe000000 {
83 ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
84 reg = <0xf 0xfe000000 0 0x00001000>;
85 spi@110000 {
86 flash@0 {
87 #address-cells = <1>;
88 #size-cells = <1>;
89 compatible = "micron,n25q512a";
90 reg = <0>;
91 spi-max-frequency = <10000000>; /* input clock */
92 };
93 };
94
95 i2c@118000 {
96 adt7481@4c {
97 compatible = "adi,adt7481";
98 reg = <0x4c>;
99 };
100
101 rtc@68 {
102 compatible = "dallas,ds1339";
103 reg = <0x68>;
104 interrupts = <0x1 0x1 0 0>;
105 };
106
107 eeprom@50 {
108 compatible = "atmel,24c256";
109 reg = <0x50>;
110 };
111 };
112
113 i2c@118100 {
114 pca9546@77 {
115 compatible = "nxp,pca9546";
116 reg = <0x77>;
117 };
118 };
119
120 sdhc@114000 {
121 voltage-ranges = <1800 1800 3300 3300>;
122 };
123 };
124
125 pci0: pcie@ffe240000 {
126 reg = <0xf 0xfe240000 0 0x10000>;
127 ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
128 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
129 pcie@0 {
130 ranges = <0x02000000 0 0xe0000000
131 0x02000000 0 0xe0000000
132 0 0x20000000
133
134 0x01000000 0 0x00000000
135 0x01000000 0 0x00000000
136 0 0x00010000>;
137 };
138 };
139
140 pci1: pcie@ffe250000 {
141 reg = <0xf 0xfe250000 0 0x10000>;
142 ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x10000000
143 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
144 pcie@0 {
145 ranges = <0x02000000 0 0xe0000000
146 0x02000000 0 0xe0000000
147 0 0x20000000
148
149 0x01000000 0 0x00000000
150 0x01000000 0 0x00000000
151 0 0x00010000>;
152 };
153 };
154
155 pci2: pcie@ffe260000 {
156 reg = <0xf 0xfe260000 0 0x1000>;
157 ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000
158 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
159 pcie@0 {
160 ranges = <0x02000000 0 0xe0000000
161 0x02000000 0 0xe0000000
162 0 0x20000000
163
164 0x01000000 0 0x00000000
165 0x01000000 0 0x00000000
166 0 0x00010000>;
167 };
168 };
169
170 pci3: pcie@ffe270000 {
171 reg = <0xf 0xfe270000 0 0x10000>;
172 ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x10000000
173 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
174 pcie@0 {
175 ranges = <0x02000000 0 0xe0000000
176 0x02000000 0 0xe0000000
177 0 0x20000000
178
179 0x01000000 0 0x00000000
180 0x01000000 0 0x00000000
181 0 0x00010000>;
182 };
183 };
184};
diff --git a/arch/powerpc/boot/dts/t4240rdb.dts b/arch/powerpc/boot/dts/t4240rdb.dts
new file mode 100644
index 000000000000..53761d4e8c51
--- /dev/null
+++ b/arch/powerpc/boot/dts/t4240rdb.dts
@@ -0,0 +1,186 @@
1/*
2 * T4240RDB Device Tree Source
3 *
4 * Copyright 2014 Freescale Semiconductor Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Freescale Semiconductor nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 *
18 * ALTERNATIVELY, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") as published by the Free Software
20 * Foundation, either version 2 of that License or (at your option) any
21 * later version.
22 *
23 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/include/ "fsl/t4240si-pre.dtsi"
36
37/ {
38 model = "fsl,T4240RDB";
39 compatible = "fsl,T4240RDB";
40 #address-cells = <2>;
41 #size-cells = <2>;
42 interrupt-parent = <&mpic>;
43
44 ifc: localbus@ffe124000 {
45 reg = <0xf 0xfe124000 0 0x2000>;
46 ranges = <0 0 0xf 0xe8000000 0x08000000
47 2 0 0xf 0xff800000 0x00010000
48 3 0 0xf 0xffdf0000 0x00008000>;
49
50 nor@0,0 {
51 #address-cells = <1>;
52 #size-cells = <1>;
53 compatible = "cfi-flash";
54 reg = <0x0 0x0 0x8000000>;
55
56 bank-width = <2>;
57 device-width = <1>;
58 };
59
60 nand@2,0 {
61 #address-cells = <1>;
62 #size-cells = <1>;
63 compatible = "fsl,ifc-nand";
64 reg = <0x2 0x0 0x10000>;
65 };
66 };
67
68 memory {
69 device_type = "memory";
70 };
71
72 dcsr: dcsr@f00000000 {
73 ranges = <0x00000000 0xf 0x00000000 0x01072000>;
74 };
75
76 soc: soc@ffe000000 {
77 ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
78 reg = <0xf 0xfe000000 0 0x00001000>;
79 spi@110000 {
80 flash@0 {
81 #address-cells = <1>;
82 #size-cells = <1>;
83 compatible = "sst,sst25wf040";
84 reg = <0>;
85 spi-max-frequency = <40000000>; /* input clock */
86 };
87 };
88
89 i2c@118000 {
90 eeprom@52 {
91 compatible = "at24,24c256";
92 reg = <0x52>;
93 };
94 eeprom@54 {
95 compatible = "at24,24c256";
96 reg = <0x54>;
97 };
98 eeprom@56 {
99 compatible = "at24,24c256";
100 reg = <0x56>;
101 };
102 rtc@68 {
103 compatible = "dallas,ds1374";
104 reg = <0x68>;
105 interrupts = <0x1 0x1 0 0>;
106 };
107 };
108
109 sdhc@114000 {
110 voltage-ranges = <1800 1800 3300 3300>;
111 };
112 };
113
114 pci0: pcie@ffe240000 {
115 reg = <0xf 0xfe240000 0 0x10000>;
116 ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
117 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
118 pcie@0 {
119 ranges = <0x02000000 0 0xe0000000
120 0x02000000 0 0xe0000000
121 0 0x20000000
122
123 0x01000000 0 0x00000000
124 0x01000000 0 0x00000000
125 0 0x00010000>;
126 };
127 };
128
129 pci1: pcie@ffe250000 {
130 reg = <0xf 0xfe250000 0 0x10000>;
131 ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
132 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
133 pcie@0 {
134 ranges = <0x02000000 0 0xe0000000
135 0x02000000 0 0xe0000000
136 0 0x20000000
137
138 0x01000000 0 0x00000000
139 0x01000000 0 0x00000000
140 0 0x00010000>;
141 };
142 };
143
144 pci2: pcie@ffe260000 {
145 reg = <0xf 0xfe260000 0 0x1000>;
146 ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
147 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
148 pcie@0 {
149 ranges = <0x02000000 0 0xe0000000
150 0x02000000 0 0xe0000000
151 0 0x20000000
152
153 0x01000000 0 0x00000000
154 0x01000000 0 0x00000000
155 0 0x00010000>;
156 };
157 };
158
159 pci3: pcie@ffe270000 {
160 reg = <0xf 0xfe270000 0 0x10000>;
161 ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000
162 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
163 pcie@0 {
164 ranges = <0x02000000 0 0xe0000000
165 0x02000000 0 0xe0000000
166 0 0x20000000
167
168 0x01000000 0 0x00000000
169 0x01000000 0 0x00000000
170 0 0x00010000>;
171 };
172 };
173
174 rio: rapidio@ffe0c0000 {
175 reg = <0xf 0xfe0c0000 0 0x11000>;
176
177 port1 {
178 ranges = <0 0 0xc 0x20000000 0 0x10000000>;
179 };
180 port2 {
181 ranges = <0 0 0xc 0x30000000 0 0x10000000>;
182 };
183 };
184};
185
186/include/ "fsl/t4240si-post.dtsi"
diff --git a/arch/powerpc/boot/io.h b/arch/powerpc/boot/io.h
index 7c09f4861fe1..394da5500466 100644
--- a/arch/powerpc/boot/io.h
+++ b/arch/powerpc/boot/io.h
@@ -1,5 +1,5 @@
1#ifndef _IO_H 1#ifndef _IO_H
2#define __IO_H 2#define _IO_H
3 3
4#include "types.h" 4#include "types.h"
5 5
diff --git a/arch/powerpc/configs/corenet32_smp_defconfig b/arch/powerpc/configs/corenet32_smp_defconfig
index c19ff057d0f9..6a3c58adf253 100644
--- a/arch/powerpc/configs/corenet32_smp_defconfig
+++ b/arch/powerpc/configs/corenet32_smp_defconfig
@@ -139,8 +139,9 @@ CONFIG_EDAC=y
139CONFIG_EDAC_MM_EDAC=y 139CONFIG_EDAC_MM_EDAC=y
140CONFIG_EDAC_MPC85XX=y 140CONFIG_EDAC_MPC85XX=y
141CONFIG_RTC_CLASS=y 141CONFIG_RTC_CLASS=y
142CONFIG_RTC_DRV_DS1307=y
143CONFIG_RTC_DRV_DS1374=y
142CONFIG_RTC_DRV_DS3232=y 144CONFIG_RTC_DRV_DS3232=y
143CONFIG_RTC_DRV_CMOS=y
144CONFIG_UIO=y 145CONFIG_UIO=y
145CONFIG_STAGING=y 146CONFIG_STAGING=y
146CONFIG_VIRT_DRIVERS=y 147CONFIG_VIRT_DRIVERS=y
@@ -179,3 +180,4 @@ CONFIG_CRYPTO_SHA512=y
179CONFIG_CRYPTO_AES=y 180CONFIG_CRYPTO_AES=y
180# CONFIG_CRYPTO_ANSI_CPRNG is not set 181# CONFIG_CRYPTO_ANSI_CPRNG is not set
181CONFIG_CRYPTO_DEV_FSL_CAAM=y 182CONFIG_CRYPTO_DEV_FSL_CAAM=y
183CONFIG_FSL_CORENET_CF=y
diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig
index 5c7fa19ae4ef..4b07bade1ba9 100644
--- a/arch/powerpc/configs/corenet64_smp_defconfig
+++ b/arch/powerpc/configs/corenet64_smp_defconfig
@@ -123,6 +123,10 @@ CONFIG_USB_EHCI_FSL=y
123CONFIG_USB_STORAGE=y 123CONFIG_USB_STORAGE=y
124CONFIG_MMC=y 124CONFIG_MMC=y
125CONFIG_MMC_SDHCI=y 125CONFIG_MMC_SDHCI=y
126CONFIG_RTC_CLASS=y
127CONFIG_RTC_DRV_DS1307=y
128CONFIG_RTC_DRV_DS1374=y
129CONFIG_RTC_DRV_DS3232=y
126CONFIG_EDAC=y 130CONFIG_EDAC=y
127CONFIG_EDAC_MM_EDAC=y 131CONFIG_EDAC_MM_EDAC=y
128CONFIG_DMADEVICES=y 132CONFIG_DMADEVICES=y
@@ -175,3 +179,4 @@ CONFIG_CRYPTO_SHA256=y
175CONFIG_CRYPTO_SHA512=y 179CONFIG_CRYPTO_SHA512=y
176# CONFIG_CRYPTO_ANSI_CPRNG is not set 180# CONFIG_CRYPTO_ANSI_CPRNG is not set
177CONFIG_CRYPTO_DEV_FSL_CAAM=y 181CONFIG_CRYPTO_DEV_FSL_CAAM=y
182CONFIG_FSL_CORENET_CF=y
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig
index 55765c8cb08f..fa1bfd37f1ec 100644
--- a/arch/powerpc/configs/mpc85xx_defconfig
+++ b/arch/powerpc/configs/mpc85xx_defconfig
@@ -209,6 +209,9 @@ CONFIG_MMC_SDHCI_OF_ESDHC=y
209CONFIG_EDAC=y 209CONFIG_EDAC=y
210CONFIG_EDAC_MM_EDAC=y 210CONFIG_EDAC_MM_EDAC=y
211CONFIG_RTC_CLASS=y 211CONFIG_RTC_CLASS=y
212CONFIG_RTC_DRV_DS1307=y
213CONFIG_RTC_DRV_DS1374=y
214CONFIG_RTC_DRV_DS3232=y
212CONFIG_RTC_DRV_CMOS=y 215CONFIG_RTC_DRV_CMOS=y
213CONFIG_RTC_DRV_DS1307=y 216CONFIG_RTC_DRV_DS1307=y
214CONFIG_DMADEVICES=y 217CONFIG_DMADEVICES=y
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig
index 5c6ecdc0f70e..0b452ebd8b3d 100644
--- a/arch/powerpc/configs/mpc85xx_smp_defconfig
+++ b/arch/powerpc/configs/mpc85xx_smp_defconfig
@@ -210,6 +210,9 @@ CONFIG_MMC_SDHCI_OF_ESDHC=y
210CONFIG_EDAC=y 210CONFIG_EDAC=y
211CONFIG_EDAC_MM_EDAC=y 211CONFIG_EDAC_MM_EDAC=y
212CONFIG_RTC_CLASS=y 212CONFIG_RTC_CLASS=y
213CONFIG_RTC_DRV_DS1307=y
214CONFIG_RTC_DRV_DS1374=y
215CONFIG_RTC_DRV_DS3232=y
213CONFIG_RTC_DRV_CMOS=y 216CONFIG_RTC_DRV_CMOS=y
214CONFIG_RTC_DRV_DS1307=y 217CONFIG_RTC_DRV_DS1307=y
215CONFIG_DMADEVICES=y 218CONFIG_DMADEVICES=y
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 0fdd7eece6d9..642e436d4595 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -195,8 +195,7 @@ extern const char *powerpc_base_platform;
195 195
196#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN) 196#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN)
197 197
198#define MMU_FTR_PPCAS_ARCH_V2 (MMU_FTR_SLB | MMU_FTR_TLBIEL | \ 198#define MMU_FTR_PPCAS_ARCH_V2 (MMU_FTR_TLBIEL | MMU_FTR_16M_PAGE)
199 MMU_FTR_16M_PAGE)
200 199
201/* We only set the altivec features if the kernel was compiled with altivec 200/* We only set the altivec features if the kernel was compiled with altivec
202 * support 201 * support
@@ -268,10 +267,6 @@ extern const char *powerpc_base_platform;
268#define CPU_FTR_MAYBE_CAN_NAP 0 267#define CPU_FTR_MAYBE_CAN_NAP 0
269#endif 268#endif
270 269
271#define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \
272 !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \
273 !defined(CONFIG_BOOKE))
274
275#define CPU_FTRS_PPC601 (CPU_FTR_COMMON | CPU_FTR_601 | \ 270#define CPU_FTRS_PPC601 (CPU_FTR_COMMON | CPU_FTR_601 | \
276 CPU_FTR_COHERENT_ICACHE | CPU_FTR_UNIFIED_ID_CACHE) 271 CPU_FTR_COHERENT_ICACHE | CPU_FTR_UNIFIED_ID_CACHE)
277#define CPU_FTRS_603 (CPU_FTR_COMMON | \ 272#define CPU_FTRS_603 (CPU_FTR_COMMON | \
@@ -396,15 +391,10 @@ extern const char *powerpc_base_platform;
396 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ 391 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
397 CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ 392 CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
398 CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_ALTIVEC_COMP | \ 393 CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_ALTIVEC_COMP | \
399 CPU_FTR_CELL_TB_BUG) 394 CPU_FTR_CELL_TB_BUG | CPU_FTR_SMT)
400#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) 395#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
401 396
402/* 64-bit CPUs */ 397/* 64-bit CPUs */
403#define CPU_FTRS_POWER3 (CPU_FTR_USE_TB | \
404 CPU_FTR_IABR | CPU_FTR_PPC_LE)
405#define CPU_FTRS_RS64 (CPU_FTR_USE_TB | \
406 CPU_FTR_IABR | \
407 CPU_FTR_MMCRA | CPU_FTR_CTRL)
408#define CPU_FTRS_POWER4 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ 398#define CPU_FTRS_POWER4 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
409 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 399 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
410 CPU_FTR_MMCRA | CPU_FTR_CP_USE_DCBTZ | \ 400 CPU_FTR_MMCRA | CPU_FTR_CP_USE_DCBTZ | \
@@ -467,15 +457,14 @@ extern const char *powerpc_base_platform;
467#define CPU_FTRS_POSSIBLE (CPU_FTRS_E6500 | CPU_FTRS_E5500 | CPU_FTRS_A2) 457#define CPU_FTRS_POSSIBLE (CPU_FTRS_E6500 | CPU_FTRS_E5500 | CPU_FTRS_A2)
468#else 458#else
469#define CPU_FTRS_POSSIBLE \ 459#define CPU_FTRS_POSSIBLE \
470 (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | \ 460 (CPU_FTRS_POWER4 | CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \
471 CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 | \ 461 CPU_FTRS_POWER6 | CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | \
472 CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | CPU_FTRS_POWER8 | \ 462 CPU_FTRS_POWER8 | CPU_FTRS_CELL | CPU_FTRS_PA6T | CPU_FTR_VSX)
473 CPU_FTRS_CELL | CPU_FTRS_PA6T | CPU_FTR_VSX)
474#endif 463#endif
475#else 464#else
476enum { 465enum {
477 CPU_FTRS_POSSIBLE = 466 CPU_FTRS_POSSIBLE =
478#if CLASSIC_PPC 467#ifdef CONFIG_PPC_BOOK3S_32
479 CPU_FTRS_PPC601 | CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU | 468 CPU_FTRS_PPC601 | CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU |
480 CPU_FTRS_740 | CPU_FTRS_750 | CPU_FTRS_750FX1 | 469 CPU_FTRS_740 | CPU_FTRS_750 | CPU_FTRS_750FX1 |
481 CPU_FTRS_750FX2 | CPU_FTRS_750FX | CPU_FTRS_750GX | 470 CPU_FTRS_750FX2 | CPU_FTRS_750FX | CPU_FTRS_750GX |
@@ -518,14 +507,14 @@ enum {
518#define CPU_FTRS_ALWAYS (CPU_FTRS_E6500 & CPU_FTRS_E5500 & CPU_FTRS_A2) 507#define CPU_FTRS_ALWAYS (CPU_FTRS_E6500 & CPU_FTRS_E5500 & CPU_FTRS_A2)
519#else 508#else
520#define CPU_FTRS_ALWAYS \ 509#define CPU_FTRS_ALWAYS \
521 (CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 & \ 510 (CPU_FTRS_POWER4 & CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & \
522 CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_POWER6 & \ 511 CPU_FTRS_POWER6 & CPU_FTRS_POWER7 & CPU_FTRS_CELL & \
523 CPU_FTRS_POWER7 & CPU_FTRS_CELL & CPU_FTRS_PA6T & CPU_FTRS_POSSIBLE) 512 CPU_FTRS_PA6T & CPU_FTRS_POSSIBLE)
524#endif 513#endif
525#else 514#else
526enum { 515enum {
527 CPU_FTRS_ALWAYS = 516 CPU_FTRS_ALWAYS =
528#if CLASSIC_PPC 517#ifdef CONFIG_PPC_BOOK3S_32
529 CPU_FTRS_PPC601 & CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU & 518 CPU_FTRS_PPC601 & CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU &
530 CPU_FTRS_740 & CPU_FTRS_750 & CPU_FTRS_750FX1 & 519 CPU_FTRS_740 & CPU_FTRS_750 & CPU_FTRS_750FX1 &
531 CPU_FTRS_750FX2 & CPU_FTRS_750FX & CPU_FTRS_750GX & 520 CPU_FTRS_750FX2 & CPU_FTRS_750FX & CPU_FTRS_750GX &
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index fab7743c2640..9983c3d26bca 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -25,6 +25,7 @@
25#include <linux/list.h> 25#include <linux/list.h>
26#include <linux/string.h> 26#include <linux/string.h>
27#include <linux/time.h> 27#include <linux/time.h>
28#include <linux/atomic.h>
28 29
29struct pci_dev; 30struct pci_dev;
30struct pci_bus; 31struct pci_bus;
@@ -33,10 +34,11 @@ struct device_node;
33#ifdef CONFIG_EEH 34#ifdef CONFIG_EEH
34 35
35/* EEH subsystem flags */ 36/* EEH subsystem flags */
36#define EEH_ENABLED 0x1 /* EEH enabled */ 37#define EEH_ENABLED 0x01 /* EEH enabled */
37#define EEH_FORCE_DISABLED 0x2 /* EEH disabled */ 38#define EEH_FORCE_DISABLED 0x02 /* EEH disabled */
38#define EEH_PROBE_MODE_DEV 0x4 /* From PCI device */ 39#define EEH_PROBE_MODE_DEV 0x04 /* From PCI device */
39#define EEH_PROBE_MODE_DEVTREE 0x8 /* From device tree */ 40#define EEH_PROBE_MODE_DEVTREE 0x08 /* From device tree */
41#define EEH_ENABLE_IO_FOR_LOG 0x10 /* Enable IO for log */
40 42
41/* 43/*
42 * Delay for PE reset, all in ms 44 * Delay for PE reset, all in ms
@@ -84,7 +86,9 @@ struct eeh_pe {
84 int freeze_count; /* Times of froze up */ 86 int freeze_count; /* Times of froze up */
85 struct timeval tstamp; /* Time on first-time freeze */ 87 struct timeval tstamp; /* Time on first-time freeze */
86 int false_positives; /* Times of reported #ff's */ 88 int false_positives; /* Times of reported #ff's */
89 atomic_t pass_dev_cnt; /* Count of passed through devs */
87 struct eeh_pe *parent; /* Parent PE */ 90 struct eeh_pe *parent; /* Parent PE */
91 void *data; /* PE auxillary data */
88 struct list_head child_list; /* Link PE to the child list */ 92 struct list_head child_list; /* Link PE to the child list */
89 struct list_head edevs; /* Link list of EEH devices */ 93 struct list_head edevs; /* Link list of EEH devices */
90 struct list_head child; /* Child PEs */ 94 struct list_head child; /* Child PEs */
@@ -93,6 +97,11 @@ struct eeh_pe {
93#define eeh_pe_for_each_dev(pe, edev, tmp) \ 97#define eeh_pe_for_each_dev(pe, edev, tmp) \
94 list_for_each_entry_safe(edev, tmp, &pe->edevs, list) 98 list_for_each_entry_safe(edev, tmp, &pe->edevs, list)
95 99
100static inline bool eeh_pe_passed(struct eeh_pe *pe)
101{
102 return pe ? !!atomic_read(&pe->pass_dev_cnt) : false;
103}
104
96/* 105/*
97 * The struct is used to trace EEH state for the associated 106 * The struct is used to trace EEH state for the associated
98 * PCI device node or PCI device. In future, it might 107 * PCI device node or PCI device. In future, it might
@@ -165,6 +174,11 @@ enum {
165#define EEH_STATE_DMA_ACTIVE (1 << 4) /* Active DMA */ 174#define EEH_STATE_DMA_ACTIVE (1 << 4) /* Active DMA */
166#define EEH_STATE_MMIO_ENABLED (1 << 5) /* MMIO enabled */ 175#define EEH_STATE_MMIO_ENABLED (1 << 5) /* MMIO enabled */
167#define EEH_STATE_DMA_ENABLED (1 << 6) /* DMA enabled */ 176#define EEH_STATE_DMA_ENABLED (1 << 6) /* DMA enabled */
177#define EEH_PE_STATE_NORMAL 0 /* Normal state */
178#define EEH_PE_STATE_RESET 1 /* PE reset asserted */
179#define EEH_PE_STATE_STOPPED_IO_DMA 2 /* Frozen PE */
180#define EEH_PE_STATE_STOPPED_DMA 4 /* Stopped DMA, Enabled IO */
181#define EEH_PE_STATE_UNAVAIL 5 /* Unavailable */
168#define EEH_RESET_DEACTIVATE 0 /* Deactivate the PE reset */ 182#define EEH_RESET_DEACTIVATE 0 /* Deactivate the PE reset */
169#define EEH_RESET_HOT 1 /* Hot reset */ 183#define EEH_RESET_HOT 1 /* Hot reset */
170#define EEH_RESET_FUNDAMENTAL 3 /* Fundamental reset */ 184#define EEH_RESET_FUNDAMENTAL 3 /* Fundamental reset */
@@ -194,36 +208,28 @@ extern int eeh_subsystem_flags;
194extern struct eeh_ops *eeh_ops; 208extern struct eeh_ops *eeh_ops;
195extern raw_spinlock_t confirm_error_lock; 209extern raw_spinlock_t confirm_error_lock;
196 210
197static inline bool eeh_enabled(void) 211static inline void eeh_add_flag(int flag)
198{ 212{
199 if ((eeh_subsystem_flags & EEH_FORCE_DISABLED) || 213 eeh_subsystem_flags |= flag;
200 !(eeh_subsystem_flags & EEH_ENABLED))
201 return false;
202
203 return true;
204} 214}
205 215
206static inline void eeh_set_enable(bool mode) 216static inline void eeh_clear_flag(int flag)
207{ 217{
208 if (mode) 218 eeh_subsystem_flags &= ~flag;
209 eeh_subsystem_flags |= EEH_ENABLED;
210 else
211 eeh_subsystem_flags &= ~EEH_ENABLED;
212} 219}
213 220
214static inline void eeh_probe_mode_set(int flag) 221static inline bool eeh_has_flag(int flag)
215{ 222{
216 eeh_subsystem_flags |= flag; 223 return !!(eeh_subsystem_flags & flag);
217} 224}
218 225
219static inline int eeh_probe_mode_devtree(void) 226static inline bool eeh_enabled(void)
220{ 227{
221 return (eeh_subsystem_flags & EEH_PROBE_MODE_DEVTREE); 228 if (eeh_has_flag(EEH_FORCE_DISABLED) ||
222} 229 !eeh_has_flag(EEH_ENABLED))
230 return false;
223 231
224static inline int eeh_probe_mode_dev(void) 232 return true;
225{
226 return (eeh_subsystem_flags & EEH_PROBE_MODE_DEV);
227} 233}
228 234
229static inline void eeh_serialize_lock(unsigned long *flags) 235static inline void eeh_serialize_lock(unsigned long *flags)
@@ -243,6 +249,7 @@ static inline void eeh_serialize_unlock(unsigned long flags)
243#define EEH_MAX_ALLOWED_FREEZES 5 249#define EEH_MAX_ALLOWED_FREEZES 5
244 250
245typedef void *(*eeh_traverse_func)(void *data, void *flag); 251typedef void *(*eeh_traverse_func)(void *data, void *flag);
252void eeh_set_pe_aux_size(int size);
246int eeh_phb_pe_create(struct pci_controller *phb); 253int eeh_phb_pe_create(struct pci_controller *phb);
247struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb); 254struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb);
248struct eeh_pe *eeh_pe_get(struct eeh_dev *edev); 255struct eeh_pe *eeh_pe_get(struct eeh_dev *edev);
@@ -272,6 +279,13 @@ void eeh_add_device_late(struct pci_dev *);
272void eeh_add_device_tree_late(struct pci_bus *); 279void eeh_add_device_tree_late(struct pci_bus *);
273void eeh_add_sysfs_files(struct pci_bus *); 280void eeh_add_sysfs_files(struct pci_bus *);
274void eeh_remove_device(struct pci_dev *); 281void eeh_remove_device(struct pci_dev *);
282int eeh_dev_open(struct pci_dev *pdev);
283void eeh_dev_release(struct pci_dev *pdev);
284struct eeh_pe *eeh_iommu_group_to_pe(struct iommu_group *group);
285int eeh_pe_set_option(struct eeh_pe *pe, int option);
286int eeh_pe_get_state(struct eeh_pe *pe);
287int eeh_pe_reset(struct eeh_pe *pe, int option);
288int eeh_pe_configure(struct eeh_pe *pe);
275 289
276/** 290/**
277 * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure. 291 * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure.
@@ -295,8 +309,6 @@ static inline bool eeh_enabled(void)
295 return false; 309 return false;
296} 310}
297 311
298static inline void eeh_set_enable(bool mode) { }
299
300static inline int eeh_init(void) 312static inline int eeh_init(void)
301{ 313{
302 return 0; 314 return 0;
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 8f35cd7d59cc..77f52b26dad6 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -425,6 +425,8 @@ label##_relon_hv: \
425#define SOFTEN_VALUE_0xa00 PACA_IRQ_DBELL 425#define SOFTEN_VALUE_0xa00 PACA_IRQ_DBELL
426#define SOFTEN_VALUE_0xe80 PACA_IRQ_DBELL 426#define SOFTEN_VALUE_0xe80 PACA_IRQ_DBELL
427#define SOFTEN_VALUE_0xe82 PACA_IRQ_DBELL 427#define SOFTEN_VALUE_0xe82 PACA_IRQ_DBELL
428#define SOFTEN_VALUE_0xe60 PACA_IRQ_HMI
429#define SOFTEN_VALUE_0xe62 PACA_IRQ_HMI
428 430
429#define __SOFTEN_TEST(h, vec) \ 431#define __SOFTEN_TEST(h, vec) \
430 lbz r10,PACASOFTIRQEN(r13); \ 432 lbz r10,PACASOFTIRQEN(r13); \
@@ -513,8 +515,11 @@ label##_relon_hv: \
513 * runlatch, etc... 515 * runlatch, etc...
514 */ 516 */
515 517
516/* Exception addition: Hard disable interrupts */ 518/*
517#define DISABLE_INTS RECONCILE_IRQ_STATE(r10,r11) 519 * This addition reconciles our actual IRQ state with the various software
520 * flags that track it. This may call C code.
521 */
522#define ADD_RECONCILE RECONCILE_IRQ_STATE(r10,r11)
518 523
519#define ADD_NVGPRS \ 524#define ADD_NVGPRS \
520 bl save_nvgprs 525 bl save_nvgprs
@@ -532,6 +537,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
532 .globl label##_common; \ 537 .globl label##_common; \
533label##_common: \ 538label##_common: \
534 EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ 539 EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
540 /* Volatile regs are potentially clobbered here */ \
535 additions; \ 541 additions; \
536 addi r3,r1,STACK_FRAME_OVERHEAD; \ 542 addi r3,r1,STACK_FRAME_OVERHEAD; \
537 bl hdlr; \ 543 bl hdlr; \
@@ -539,7 +545,7 @@ label##_common: \
539 545
540#define STD_EXCEPTION_COMMON(trap, label, hdlr) \ 546#define STD_EXCEPTION_COMMON(trap, label, hdlr) \
541 EXCEPTION_COMMON(trap, label, hdlr, ret_from_except, \ 547 EXCEPTION_COMMON(trap, label, hdlr, ret_from_except, \
542 ADD_NVGPRS;DISABLE_INTS) 548 ADD_NVGPRS;ADD_RECONCILE)
543 549
544/* 550/*
545 * Like STD_EXCEPTION_COMMON, but for exceptions that can occur 551 * Like STD_EXCEPTION_COMMON, but for exceptions that can occur
@@ -548,7 +554,7 @@ label##_common: \
548 */ 554 */
549#define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr) \ 555#define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr) \
550 EXCEPTION_COMMON(trap, label, hdlr, ret_from_except_lite, \ 556 EXCEPTION_COMMON(trap, label, hdlr, ret_from_except_lite, \
551 FINISH_NAP;DISABLE_INTS;RUNLATCH_ON) 557 FINISH_NAP;ADD_RECONCILE;RUNLATCH_ON)
552 558
553/* 559/*
554 * When the idle code in power4_idle puts the CPU into NAP mode, 560 * When the idle code in power4_idle puts the CPU into NAP mode,
diff --git a/arch/powerpc/include/asm/fs_pd.h b/arch/powerpc/include/asm/fs_pd.h
index 9361cd5342cc..f79d6c74eb2a 100644
--- a/arch/powerpc/include/asm/fs_pd.h
+++ b/arch/powerpc/include/asm/fs_pd.h
@@ -28,7 +28,6 @@
28 28
29#ifdef CONFIG_8xx 29#ifdef CONFIG_8xx
30#include <asm/8xx_immap.h> 30#include <asm/8xx_immap.h>
31#include <asm/mpc8xx.h>
32 31
33extern immap_t __iomem *mpc8xx_immr; 32extern immap_t __iomem *mpc8xx_immr;
34 33
diff --git a/arch/powerpc/include/asm/hardirq.h b/arch/powerpc/include/asm/hardirq.h
index 418fb654370d..1bbb3013d6aa 100644
--- a/arch/powerpc/include/asm/hardirq.h
+++ b/arch/powerpc/include/asm/hardirq.h
@@ -11,6 +11,7 @@ typedef struct {
11 unsigned int pmu_irqs; 11 unsigned int pmu_irqs;
12 unsigned int mce_exceptions; 12 unsigned int mce_exceptions;
13 unsigned int spurious_irqs; 13 unsigned int spurious_irqs;
14 unsigned int hmi_exceptions;
14#ifdef CONFIG_PPC_DOORBELL 15#ifdef CONFIG_PPC_DOORBELL
15 unsigned int doorbell_irqs; 16 unsigned int doorbell_irqs;
16#endif 17#endif
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index 10be1dd01c6b..b59ac27a6b7d 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -25,6 +25,7 @@
25#define PACA_IRQ_EE 0x04 25#define PACA_IRQ_EE 0x04
26#define PACA_IRQ_DEC 0x08 /* Or FIT */ 26#define PACA_IRQ_DEC 0x08 /* Or FIT */
27#define PACA_IRQ_EE_EDGE 0x10 /* BookE only */ 27#define PACA_IRQ_EE_EDGE 0x10 /* BookE only */
28#define PACA_IRQ_HMI 0x20
28 29
29#endif /* CONFIG_PPC64 */ 30#endif /* CONFIG_PPC64 */
30 31
diff --git a/arch/powerpc/include/asm/irqflags.h b/arch/powerpc/include/asm/irqflags.h
index e20eb95429a8..f2149066fe5d 100644
--- a/arch/powerpc/include/asm/irqflags.h
+++ b/arch/powerpc/include/asm/irqflags.h
@@ -32,9 +32,8 @@
32#endif 32#endif
33 33
34/* 34/*
35 * Most of the CPU's IRQ-state tracing is done from assembly code; we 35 * These are calls to C code, so the caller must be prepared for volatiles to
36 * have to call a C function so call a wrapper that saves all the 36 * be clobbered.
37 * C-clobbered registers.
38 */ 37 */
39#define TRACE_ENABLE_INTS TRACE_WITH_FRAME_BUFFER(trace_hardirqs_on) 38#define TRACE_ENABLE_INTS TRACE_WITH_FRAME_BUFFER(trace_hardirqs_on)
40#define TRACE_DISABLE_INTS TRACE_WITH_FRAME_BUFFER(trace_hardirqs_off) 39#define TRACE_DISABLE_INTS TRACE_WITH_FRAME_BUFFER(trace_hardirqs_off)
@@ -42,6 +41,9 @@
42/* 41/*
43 * This is used by assembly code to soft-disable interrupts first and 42 * This is used by assembly code to soft-disable interrupts first and
44 * reconcile irq state. 43 * reconcile irq state.
44 *
45 * NB: This may call C code, so the caller must be prepared for volatiles to
46 * be clobbered.
45 */ 47 */
46#define RECONCILE_IRQ_STATE(__rA, __rB) \ 48#define RECONCILE_IRQ_STATE(__rA, __rB) \
47 lbz __rA,PACASOFTIRQEN(r13); \ 49 lbz __rA,PACASOFTIRQEN(r13); \
diff --git a/arch/powerpc/include/asm/jump_label.h b/arch/powerpc/include/asm/jump_label.h
index f016bb699b5f..efbf9a322a23 100644
--- a/arch/powerpc/include/asm/jump_label.h
+++ b/arch/powerpc/include/asm/jump_label.h
@@ -10,6 +10,7 @@
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 */ 11 */
12 12
13#ifndef __ASSEMBLY__
13#include <linux/types.h> 14#include <linux/types.h>
14 15
15#include <asm/feature-fixups.h> 16#include <asm/feature-fixups.h>
@@ -42,4 +43,12 @@ struct jump_entry {
42 jump_label_t key; 43 jump_label_t key;
43}; 44};
44 45
46#else
47#define ARCH_STATIC_BRANCH(LABEL, KEY) \
481098: nop; \
49 .pushsection __jump_table, "aw"; \
50 FTR_ENTRY_LONG 1098b, LABEL, KEY; \
51 .popsection
52#endif
53
45#endif /* _ASM_POWERPC_JUMP_LABEL_H */ 54#endif /* _ASM_POWERPC_JUMP_LABEL_H */
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h
index 9601741080e5..ecf7e133a4f2 100644
--- a/arch/powerpc/include/asm/kvm_asm.h
+++ b/arch/powerpc/include/asm/kvm_asm.h
@@ -98,6 +98,7 @@
98#define BOOK3S_INTERRUPT_H_DATA_STORAGE 0xe00 98#define BOOK3S_INTERRUPT_H_DATA_STORAGE 0xe00
99#define BOOK3S_INTERRUPT_H_INST_STORAGE 0xe20 99#define BOOK3S_INTERRUPT_H_INST_STORAGE 0xe20
100#define BOOK3S_INTERRUPT_H_EMUL_ASSIST 0xe40 100#define BOOK3S_INTERRUPT_H_EMUL_ASSIST 0xe40
101#define BOOK3S_INTERRUPT_HMI 0xe60
101#define BOOK3S_INTERRUPT_H_DOORBELL 0xe80 102#define BOOK3S_INTERRUPT_H_DOORBELL 0xe80
102#define BOOK3S_INTERRUPT_PERFMON 0xf00 103#define BOOK3S_INTERRUPT_PERFMON 0xf00
103#define BOOK3S_INTERRUPT_ALTIVEC 0xf20 104#define BOOK3S_INTERRUPT_ALTIVEC 0xf20
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index f92b0b54e921..44e90516519b 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -174,6 +174,10 @@ struct machdep_calls {
174 /* Exception handlers */ 174 /* Exception handlers */
175 int (*system_reset_exception)(struct pt_regs *regs); 175 int (*system_reset_exception)(struct pt_regs *regs);
176 int (*machine_check_exception)(struct pt_regs *regs); 176 int (*machine_check_exception)(struct pt_regs *regs);
177 int (*handle_hmi_exception)(struct pt_regs *regs);
178
179 /* Early exception handlers called in realmode */
180 int (*hmi_exception_early)(struct pt_regs *regs);
177 181
178 /* Called during machine check exception to retrive fixup address. */ 182 /* Called during machine check exception to retrive fixup address. */
179 bool (*mce_check_early_recovery)(struct pt_regs *regs); 183 bool (*mce_check_early_recovery)(struct pt_regs *regs);
@@ -366,6 +370,7 @@ static inline void log_error(char *buf, unsigned int err_type, int fatal)
366 } \ 370 } \
367 __define_initcall(__machine_initcall_##mach##_##fn, id); 371 __define_initcall(__machine_initcall_##mach##_##fn, id);
368 372
373#define machine_early_initcall(mach, fn) __define_machine_initcall(mach, fn, early)
369#define machine_core_initcall(mach, fn) __define_machine_initcall(mach, fn, 1) 374#define machine_core_initcall(mach, fn) __define_machine_initcall(mach, fn, 1)
370#define machine_core_initcall_sync(mach, fn) __define_machine_initcall(mach, fn, 1s) 375#define machine_core_initcall_sync(mach, fn) __define_machine_initcall(mach, fn, 1s)
371#define machine_postcore_initcall(mach, fn) __define_machine_initcall(mach, fn, 2) 376#define machine_postcore_initcall(mach, fn) __define_machine_initcall(mach, fn, 2)
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index c2b4dcf23d03..d76514487d6f 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -25,26 +25,6 @@
25#include <asm/processor.h> 25#include <asm/processor.h>
26 26
27/* 27/*
28 * Segment table
29 */
30
31#define STE_ESID_V 0x80
32#define STE_ESID_KS 0x20
33#define STE_ESID_KP 0x10
34#define STE_ESID_N 0x08
35
36#define STE_VSID_SHIFT 12
37
38/* Location of cpu0's segment table */
39#define STAB0_PAGE 0x8
40#define STAB0_OFFSET (STAB0_PAGE << 12)
41#define STAB0_PHYS_ADDR (STAB0_OFFSET + PHYSICAL_START)
42
43#ifndef __ASSEMBLY__
44extern char initial_stab[];
45#endif /* ! __ASSEMBLY */
46
47/*
48 * SLB 28 * SLB
49 */ 29 */
50 30
@@ -370,10 +350,8 @@ extern void hpte_init_lpar(void);
370extern void hpte_init_beat(void); 350extern void hpte_init_beat(void);
371extern void hpte_init_beat_v3(void); 351extern void hpte_init_beat_v3(void);
372 352
373extern void stabs_alloc(void);
374extern void slb_initialize(void); 353extern void slb_initialize(void);
375extern void slb_flush_and_rebolt(void); 354extern void slb_flush_and_rebolt(void);
376extern void stab_initialize(unsigned long stab);
377 355
378extern void slb_vmalloc_update(void); 356extern void slb_vmalloc_update(void);
379extern void slb_set_size(u16 size); 357extern void slb_set_size(u16 size);
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index e61f24ed4e65..3d5abfe6ba67 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -64,9 +64,9 @@
64 */ 64 */
65#define MMU_FTR_USE_PAIRED_MAS ASM_CONST(0x01000000) 65#define MMU_FTR_USE_PAIRED_MAS ASM_CONST(0x01000000)
66 66
67/* MMU is SLB-based 67/* Doesn't support the B bit (1T segment) in SLBIE
68 */ 68 */
69#define MMU_FTR_SLB ASM_CONST(0x02000000) 69#define MMU_FTR_NO_SLBIE_B ASM_CONST(0x02000000)
70 70
71/* Support 16M large pages 71/* Support 16M large pages
72 */ 72 */
@@ -88,10 +88,6 @@
88 */ 88 */
89#define MMU_FTR_1T_SEGMENT ASM_CONST(0x40000000) 89#define MMU_FTR_1T_SEGMENT ASM_CONST(0x40000000)
90 90
91/* Doesn't support the B bit (1T segment) in SLBIE
92 */
93#define MMU_FTR_NO_SLBIE_B ASM_CONST(0x80000000)
94
95/* MMU feature bit sets for various CPUs */ 91/* MMU feature bit sets for various CPUs */
96#define MMU_FTRS_DEFAULT_HPTE_ARCH_V2 \ 92#define MMU_FTRS_DEFAULT_HPTE_ARCH_V2 \
97 MMU_FTR_HPTE_TABLE | MMU_FTR_PPCAS_ARCH_V2 93 MMU_FTR_HPTE_TABLE | MMU_FTR_PPCAS_ARCH_V2
diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
index b467530e2485..73382eba02dc 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -18,7 +18,6 @@ extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
18extern void destroy_context(struct mm_struct *mm); 18extern void destroy_context(struct mm_struct *mm);
19 19
20extern void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next); 20extern void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next);
21extern void switch_stab(struct task_struct *tsk, struct mm_struct *mm);
22extern void switch_slb(struct task_struct *tsk, struct mm_struct *mm); 21extern void switch_slb(struct task_struct *tsk, struct mm_struct *mm);
23extern void set_context(unsigned long id, pgd_t *pgd); 22extern void set_context(unsigned long id, pgd_t *pgd);
24 23
@@ -77,10 +76,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
77 * sub architectures. 76 * sub architectures.
78 */ 77 */
79#ifdef CONFIG_PPC_STD_MMU_64 78#ifdef CONFIG_PPC_STD_MMU_64
80 if (mmu_has_feature(MMU_FTR_SLB)) 79 switch_slb(tsk, next);
81 switch_slb(tsk, next);
82 else
83 switch_stab(tsk, next);
84#else 80#else
85 /* Out of line for now */ 81 /* Out of line for now */
86 switch_mmu_context(prev, next); 82 switch_mmu_context(prev, next);
diff --git a/arch/powerpc/include/asm/mpc85xx.h b/arch/powerpc/include/asm/mpc85xx.h
index 736d4acc05a8..3bef74a9914b 100644
--- a/arch/powerpc/include/asm/mpc85xx.h
+++ b/arch/powerpc/include/asm/mpc85xx.h
@@ -77,6 +77,8 @@
77#define SVR_T1020 0x852100 77#define SVR_T1020 0x852100
78#define SVR_T1021 0x852101 78#define SVR_T1021 0x852101
79#define SVR_T1022 0x852102 79#define SVR_T1022 0x852102
80#define SVR_T2080 0x853000
81#define SVR_T2081 0x853100
80 82
81#define SVR_8610 0x80A000 83#define SVR_8610 0x80A000
82#define SVR_8641 0x809000 84#define SVR_8641 0x809000
diff --git a/arch/powerpc/include/asm/mpc8xx.h b/arch/powerpc/include/asm/mpc8xx.h
deleted file mode 100644
index 98f3c4f17328..000000000000
--- a/arch/powerpc/include/asm/mpc8xx.h
+++ /dev/null
@@ -1,12 +0,0 @@
1/* This is the single file included by all MPC8xx build options.
2 * Since there are many different boards and no standard configuration,
3 * we have a unique include file for each. Rather than change every
4 * file that has to include MPC8xx configuration, they all include
5 * this one and the configuration switching is done here.
6 */
7#ifndef __CONFIG_8xx_DEFS
8#define __CONFIG_8xx_DEFS
9
10extern struct mpc8xx_pcmcia_ops m8xx_pcmcia_ops;
11
12#endif /* __CONFIG_8xx_DEFS */
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 0da1dbd42e02..b2f8ce1fd0d7 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -147,6 +147,8 @@ struct opal_sg_list {
147#define OPAL_SET_PARAM 90 147#define OPAL_SET_PARAM 90
148#define OPAL_DUMP_RESEND 91 148#define OPAL_DUMP_RESEND 91
149#define OPAL_DUMP_INFO2 94 149#define OPAL_DUMP_INFO2 94
150#define OPAL_PCI_EEH_FREEZE_SET 97
151#define OPAL_HANDLE_HMI 98
150 152
151#ifndef __ASSEMBLY__ 153#ifndef __ASSEMBLY__
152 154
@@ -170,7 +172,11 @@ enum OpalFreezeState {
170enum OpalEehFreezeActionToken { 172enum OpalEehFreezeActionToken {
171 OPAL_EEH_ACTION_CLEAR_FREEZE_MMIO = 1, 173 OPAL_EEH_ACTION_CLEAR_FREEZE_MMIO = 1,
172 OPAL_EEH_ACTION_CLEAR_FREEZE_DMA = 2, 174 OPAL_EEH_ACTION_CLEAR_FREEZE_DMA = 2,
173 OPAL_EEH_ACTION_CLEAR_FREEZE_ALL = 3 175 OPAL_EEH_ACTION_CLEAR_FREEZE_ALL = 3,
176
177 OPAL_EEH_ACTION_SET_FREEZE_MMIO = 1,
178 OPAL_EEH_ACTION_SET_FREEZE_DMA = 2,
179 OPAL_EEH_ACTION_SET_FREEZE_ALL = 3
174}; 180};
175 181
176enum OpalPciStatusToken { 182enum OpalPciStatusToken {
@@ -240,6 +246,7 @@ enum OpalMessageType {
240 OPAL_MSG_MEM_ERR, 246 OPAL_MSG_MEM_ERR,
241 OPAL_MSG_EPOW, 247 OPAL_MSG_EPOW,
242 OPAL_MSG_SHUTDOWN, 248 OPAL_MSG_SHUTDOWN,
249 OPAL_MSG_HMI_EVT,
243 OPAL_MSG_TYPE_MAX, 250 OPAL_MSG_TYPE_MAX,
244}; 251};
245 252
@@ -340,6 +347,12 @@ enum OpalMveEnableAction {
340 OPAL_ENABLE_MVE = 1 347 OPAL_ENABLE_MVE = 1
341}; 348};
342 349
350enum OpalM64EnableAction {
351 OPAL_DISABLE_M64 = 0,
352 OPAL_ENABLE_M64_SPLIT = 1,
353 OPAL_ENABLE_M64_NON_SPLIT = 2
354};
355
343enum OpalPciResetScope { 356enum OpalPciResetScope {
344 OPAL_PHB_COMPLETE = 1, OPAL_PCI_LINK = 2, OPAL_PHB_ERROR = 3, 357 OPAL_PHB_COMPLETE = 1, OPAL_PCI_LINK = 2, OPAL_PHB_ERROR = 3,
345 OPAL_PCI_HOT_RESET = 4, OPAL_PCI_FUNDAMENTAL_RESET = 5, 358 OPAL_PCI_HOT_RESET = 4, OPAL_PCI_FUNDAMENTAL_RESET = 5,
@@ -502,6 +515,50 @@ struct OpalMemoryErrorData {
502 } u; 515 } u;
503}; 516};
504 517
518/* HMI interrupt event */
519enum OpalHMI_Version {
520 OpalHMIEvt_V1 = 1,
521};
522
523enum OpalHMI_Severity {
524 OpalHMI_SEV_NO_ERROR = 0,
525 OpalHMI_SEV_WARNING = 1,
526 OpalHMI_SEV_ERROR_SYNC = 2,
527 OpalHMI_SEV_FATAL = 3,
528};
529
530enum OpalHMI_Disposition {
531 OpalHMI_DISPOSITION_RECOVERED = 0,
532 OpalHMI_DISPOSITION_NOT_RECOVERED = 1,
533};
534
535enum OpalHMI_ErrType {
536 OpalHMI_ERROR_MALFUNC_ALERT = 0,
537 OpalHMI_ERROR_PROC_RECOV_DONE,
538 OpalHMI_ERROR_PROC_RECOV_DONE_AGAIN,
539 OpalHMI_ERROR_PROC_RECOV_MASKED,
540 OpalHMI_ERROR_TFAC,
541 OpalHMI_ERROR_TFMR_PARITY,
542 OpalHMI_ERROR_HA_OVERFLOW_WARN,
543 OpalHMI_ERROR_XSCOM_FAIL,
544 OpalHMI_ERROR_XSCOM_DONE,
545 OpalHMI_ERROR_SCOM_FIR,
546 OpalHMI_ERROR_DEBUG_TRIG_FIR,
547 OpalHMI_ERROR_HYP_RESOURCE,
548};
549
550struct OpalHMIEvent {
551 uint8_t version; /* 0x00 */
552 uint8_t severity; /* 0x01 */
553 uint8_t type; /* 0x02 */
554 uint8_t disposition; /* 0x03 */
555 uint8_t reserved_1[4]; /* 0x04 */
556
557 __be64 hmer;
558 /* TFMR register. Valid only for TFAC and TFMR_PARITY error type. */
559 __be64 tfmr;
560};
561
505enum { 562enum {
506 OPAL_P7IOC_DIAG_TYPE_NONE = 0, 563 OPAL_P7IOC_DIAG_TYPE_NONE = 0,
507 OPAL_P7IOC_DIAG_TYPE_RGC = 1, 564 OPAL_P7IOC_DIAG_TYPE_RGC = 1,
@@ -513,40 +570,40 @@ enum {
513}; 570};
514 571
515struct OpalIoP7IOCErrorData { 572struct OpalIoP7IOCErrorData {
516 uint16_t type; 573 __be16 type;
517 574
518 /* GEM */ 575 /* GEM */
519 uint64_t gemXfir; 576 __be64 gemXfir;
520 uint64_t gemRfir; 577 __be64 gemRfir;
521 uint64_t gemRirqfir; 578 __be64 gemRirqfir;
522 uint64_t gemMask; 579 __be64 gemMask;
523 uint64_t gemRwof; 580 __be64 gemRwof;
524 581
525 /* LEM */ 582 /* LEM */
526 uint64_t lemFir; 583 __be64 lemFir;
527 uint64_t lemErrMask; 584 __be64 lemErrMask;
528 uint64_t lemAction0; 585 __be64 lemAction0;
529 uint64_t lemAction1; 586 __be64 lemAction1;
530 uint64_t lemWof; 587 __be64 lemWof;
531 588
532 union { 589 union {
533 struct OpalIoP7IOCRgcErrorData { 590 struct OpalIoP7IOCRgcErrorData {
534 uint64_t rgcStatus; /* 3E1C10 */ 591 __be64 rgcStatus; /* 3E1C10 */
535 uint64_t rgcLdcp; /* 3E1C18 */ 592 __be64 rgcLdcp; /* 3E1C18 */
536 }rgc; 593 }rgc;
537 struct OpalIoP7IOCBiErrorData { 594 struct OpalIoP7IOCBiErrorData {
538 uint64_t biLdcp0; /* 3C0100, 3C0118 */ 595 __be64 biLdcp0; /* 3C0100, 3C0118 */
539 uint64_t biLdcp1; /* 3C0108, 3C0120 */ 596 __be64 biLdcp1; /* 3C0108, 3C0120 */
540 uint64_t biLdcp2; /* 3C0110, 3C0128 */ 597 __be64 biLdcp2; /* 3C0110, 3C0128 */
541 uint64_t biFenceStatus; /* 3C0130, 3C0130 */ 598 __be64 biFenceStatus; /* 3C0130, 3C0130 */
542 599
543 uint8_t biDownbound; /* BI Downbound or Upbound */ 600 u8 biDownbound; /* BI Downbound or Upbound */
544 }bi; 601 }bi;
545 struct OpalIoP7IOCCiErrorData { 602 struct OpalIoP7IOCCiErrorData {
546 uint64_t ciPortStatus; /* 3Dn008 */ 603 __be64 ciPortStatus; /* 3Dn008 */
547 uint64_t ciPortLdcp; /* 3Dn010 */ 604 __be64 ciPortLdcp; /* 3Dn010 */
548 605
549 uint8_t ciPort; /* Index of CI port: 0/1 */ 606 u8 ciPort; /* Index of CI port: 0/1 */
550 }ci; 607 }ci;
551 }; 608 };
552}; 609};
@@ -578,60 +635,60 @@ struct OpalIoPhbErrorCommon {
578struct OpalIoP7IOCPhbErrorData { 635struct OpalIoP7IOCPhbErrorData {
579 struct OpalIoPhbErrorCommon common; 636 struct OpalIoPhbErrorCommon common;
580 637
581 uint32_t brdgCtl; 638 __be32 brdgCtl;
582 639
583 // P7IOC utl regs 640 // P7IOC utl regs
584 uint32_t portStatusReg; 641 __be32 portStatusReg;
585 uint32_t rootCmplxStatus; 642 __be32 rootCmplxStatus;
586 uint32_t busAgentStatus; 643 __be32 busAgentStatus;
587 644
588 // P7IOC cfg regs 645 // P7IOC cfg regs
589 uint32_t deviceStatus; 646 __be32 deviceStatus;
590 uint32_t slotStatus; 647 __be32 slotStatus;
591 uint32_t linkStatus; 648 __be32 linkStatus;
592 uint32_t devCmdStatus; 649 __be32 devCmdStatus;
593 uint32_t devSecStatus; 650 __be32 devSecStatus;
594 651
595 // cfg AER regs 652 // cfg AER regs
596 uint32_t rootErrorStatus; 653 __be32 rootErrorStatus;
597 uint32_t uncorrErrorStatus; 654 __be32 uncorrErrorStatus;
598 uint32_t corrErrorStatus; 655 __be32 corrErrorStatus;
599 uint32_t tlpHdr1; 656 __be32 tlpHdr1;
600 uint32_t tlpHdr2; 657 __be32 tlpHdr2;
601 uint32_t tlpHdr3; 658 __be32 tlpHdr3;
602 uint32_t tlpHdr4; 659 __be32 tlpHdr4;
603 uint32_t sourceId; 660 __be32 sourceId;
604 661
605 uint32_t rsv3; 662 __be32 rsv3;
606 663
607 // Record data about the call to allocate a buffer. 664 // Record data about the call to allocate a buffer.
608 uint64_t errorClass; 665 __be64 errorClass;
609 uint64_t correlator; 666 __be64 correlator;
610 667
611 //P7IOC MMIO Error Regs 668 //P7IOC MMIO Error Regs
612 uint64_t p7iocPlssr; // n120 669 __be64 p7iocPlssr; // n120
613 uint64_t p7iocCsr; // n110 670 __be64 p7iocCsr; // n110
614 uint64_t lemFir; // nC00 671 __be64 lemFir; // nC00
615 uint64_t lemErrorMask; // nC18 672 __be64 lemErrorMask; // nC18
616 uint64_t lemWOF; // nC40 673 __be64 lemWOF; // nC40
617 uint64_t phbErrorStatus; // nC80 674 __be64 phbErrorStatus; // nC80
618 uint64_t phbFirstErrorStatus; // nC88 675 __be64 phbFirstErrorStatus; // nC88
619 uint64_t phbErrorLog0; // nCC0 676 __be64 phbErrorLog0; // nCC0
620 uint64_t phbErrorLog1; // nCC8 677 __be64 phbErrorLog1; // nCC8
621 uint64_t mmioErrorStatus; // nD00 678 __be64 mmioErrorStatus; // nD00
622 uint64_t mmioFirstErrorStatus; // nD08 679 __be64 mmioFirstErrorStatus; // nD08
623 uint64_t mmioErrorLog0; // nD40 680 __be64 mmioErrorLog0; // nD40
624 uint64_t mmioErrorLog1; // nD48 681 __be64 mmioErrorLog1; // nD48
625 uint64_t dma0ErrorStatus; // nD80 682 __be64 dma0ErrorStatus; // nD80
626 uint64_t dma0FirstErrorStatus; // nD88 683 __be64 dma0FirstErrorStatus; // nD88
627 uint64_t dma0ErrorLog0; // nDC0 684 __be64 dma0ErrorLog0; // nDC0
628 uint64_t dma0ErrorLog1; // nDC8 685 __be64 dma0ErrorLog1; // nDC8
629 uint64_t dma1ErrorStatus; // nE00 686 __be64 dma1ErrorStatus; // nE00
630 uint64_t dma1FirstErrorStatus; // nE08 687 __be64 dma1FirstErrorStatus; // nE08
631 uint64_t dma1ErrorLog0; // nE40 688 __be64 dma1ErrorLog0; // nE40
632 uint64_t dma1ErrorLog1; // nE48 689 __be64 dma1ErrorLog1; // nE48
633 uint64_t pestA[OPAL_P7IOC_NUM_PEST_REGS]; 690 __be64 pestA[OPAL_P7IOC_NUM_PEST_REGS];
634 uint64_t pestB[OPAL_P7IOC_NUM_PEST_REGS]; 691 __be64 pestB[OPAL_P7IOC_NUM_PEST_REGS];
635}; 692};
636 693
637struct OpalIoPhb3ErrorData { 694struct OpalIoPhb3ErrorData {
@@ -758,6 +815,8 @@ int64_t opal_pci_eeh_freeze_status(uint64_t phb_id, uint64_t pe_number,
758 __be64 *phb_status); 815 __be64 *phb_status);
759int64_t opal_pci_eeh_freeze_clear(uint64_t phb_id, uint64_t pe_number, 816int64_t opal_pci_eeh_freeze_clear(uint64_t phb_id, uint64_t pe_number,
760 uint64_t eeh_action_token); 817 uint64_t eeh_action_token);
818int64_t opal_pci_eeh_freeze_set(uint64_t phb_id, uint64_t pe_number,
819 uint64_t eeh_action_token);
761int64_t opal_pci_shpc(uint64_t phb_id, uint64_t shpc_action, uint8_t *state); 820int64_t opal_pci_shpc(uint64_t phb_id, uint64_t shpc_action, uint8_t *state);
762 821
763 822
@@ -768,7 +827,7 @@ int64_t opal_pci_set_phb_mem_window(uint64_t phb_id, uint16_t window_type,
768 uint16_t window_num, 827 uint16_t window_num,
769 uint64_t starting_real_address, 828 uint64_t starting_real_address,
770 uint64_t starting_pci_address, 829 uint64_t starting_pci_address,
771 uint16_t segment_size); 830 uint64_t size);
772int64_t opal_pci_map_pe_mmio_window(uint64_t phb_id, uint16_t pe_number, 831int64_t opal_pci_map_pe_mmio_window(uint64_t phb_id, uint16_t pe_number,
773 uint16_t window_type, uint16_t window_num, 832 uint16_t window_type, uint16_t window_num,
774 uint16_t segment_num); 833 uint16_t segment_num);
@@ -860,6 +919,7 @@ int64_t opal_get_param(uint64_t token, uint32_t param_id, uint64_t buffer,
860int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer, 919int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer,
861 uint64_t length); 920 uint64_t length);
862int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data); 921int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data);
922int64_t opal_handle_hmi(void);
863 923
864/* Internal functions */ 924/* Internal functions */
865extern int early_init_dt_scan_opal(unsigned long node, const char *uname, 925extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
@@ -902,6 +962,8 @@ extern void opal_msglog_init(void);
902 962
903extern int opal_machine_check(struct pt_regs *regs); 963extern int opal_machine_check(struct pt_regs *regs);
904extern bool opal_mce_check_early_recovery(struct pt_regs *regs); 964extern bool opal_mce_check_early_recovery(struct pt_regs *regs);
965extern int opal_hmi_exception_early(struct pt_regs *regs);
966extern int opal_handle_hmi_exception(struct pt_regs *regs);
905 967
906extern void opal_shutdown(void); 968extern void opal_shutdown(void);
907extern int opal_resync_timebase(void); 969extern int opal_resync_timebase(void);
diff --git a/arch/powerpc/include/asm/oprofile_impl.h b/arch/powerpc/include/asm/oprofile_impl.h
index d697b08994c9..61fe5d6f18e1 100644
--- a/arch/powerpc/include/asm/oprofile_impl.h
+++ b/arch/powerpc/include/asm/oprofile_impl.h
@@ -61,7 +61,6 @@ struct op_powerpc_model {
61}; 61};
62 62
63extern struct op_powerpc_model op_model_fsl_emb; 63extern struct op_powerpc_model op_model_fsl_emb;
64extern struct op_powerpc_model op_model_rs64;
65extern struct op_powerpc_model op_model_power4; 64extern struct op_powerpc_model op_model_power4;
66extern struct op_powerpc_model op_model_7450; 65extern struct op_powerpc_model op_model_7450;
67extern struct op_powerpc_model op_model_cell; 66extern struct op_powerpc_model op_model_cell;
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index bb0bd25f20d0..a5139ea6910b 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -78,10 +78,6 @@ struct paca_struct {
78 u64 kernel_toc; /* Kernel TOC address */ 78 u64 kernel_toc; /* Kernel TOC address */
79 u64 kernelbase; /* Base address of kernel */ 79 u64 kernelbase; /* Base address of kernel */
80 u64 kernel_msr; /* MSR while running in kernel */ 80 u64 kernel_msr; /* MSR while running in kernel */
81#ifdef CONFIG_PPC_STD_MMU_64
82 u64 stab_real; /* Absolute address of segment table */
83 u64 stab_addr; /* Virtual address of segment table */
84#endif /* CONFIG_PPC_STD_MMU_64 */
85 void *emergency_sp; /* pointer to emergency stack */ 81 void *emergency_sp; /* pointer to emergency stack */
86 u64 data_offset; /* per cpu data offset */ 82 u64 data_offset; /* per cpu data offset */
87 s16 hw_cpu_id; /* Physical processor number */ 83 s16 hw_cpu_id; /* Physical processor number */
@@ -171,6 +167,7 @@ struct paca_struct {
171 * and already using emergency stack. 167 * and already using emergency stack.
172 */ 168 */
173 u16 in_mce; 169 u16 in_mce;
170 u8 hmi_event_available; /* HMI event is available */
174#endif 171#endif
175 172
176 /* Stuff for accurate time accounting */ 173 /* Stuff for accurate time accounting */
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h
index b3e936027b26..814622146d5a 100644
--- a/arch/powerpc/include/asm/perf_event_server.h
+++ b/arch/powerpc/include/asm/perf_event_server.h
@@ -19,6 +19,8 @@
19#define MAX_EVENT_ALTERNATIVES 8 19#define MAX_EVENT_ALTERNATIVES 8
20#define MAX_LIMITED_HWCOUNTERS 2 20#define MAX_LIMITED_HWCOUNTERS 2
21 21
22struct perf_event;
23
22/* 24/*
23 * This struct provides the constants and functions needed to 25 * This struct provides the constants and functions needed to
24 * describe the PMU on a particular POWER-family CPU. 26 * describe the PMU on a particular POWER-family CPU.
@@ -30,7 +32,8 @@ struct power_pmu {
30 unsigned long add_fields; 32 unsigned long add_fields;
31 unsigned long test_adder; 33 unsigned long test_adder;
32 int (*compute_mmcr)(u64 events[], int n_ev, 34 int (*compute_mmcr)(u64 events[], int n_ev,
33 unsigned int hwc[], unsigned long mmcr[]); 35 unsigned int hwc[], unsigned long mmcr[],
36 struct perf_event *pevents[]);
34 int (*get_constraint)(u64 event_id, unsigned long *mskp, 37 int (*get_constraint)(u64 event_id, unsigned long *mskp,
35 unsigned long *valp); 38 unsigned long *valp);
36 int (*get_alternatives)(u64 event_id, unsigned int flags, 39 int (*get_alternatives)(u64 event_id, unsigned int flags,
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index 3132bb9365f3..e316dad6ba76 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -150,8 +150,10 @@
150#define PPC_INST_MCRXR_MASK 0xfc0007fe 150#define PPC_INST_MCRXR_MASK 0xfc0007fe
151#define PPC_INST_MFSPR_PVR 0x7c1f42a6 151#define PPC_INST_MFSPR_PVR 0x7c1f42a6
152#define PPC_INST_MFSPR_PVR_MASK 0xfc1fffff 152#define PPC_INST_MFSPR_PVR_MASK 0xfc1fffff
153#define PPC_INST_MFTMR 0x7c0002dc
153#define PPC_INST_MSGSND 0x7c00019c 154#define PPC_INST_MSGSND 0x7c00019c
154#define PPC_INST_MSGSNDP 0x7c00011c 155#define PPC_INST_MSGSNDP 0x7c00011c
156#define PPC_INST_MTTMR 0x7c0003dc
155#define PPC_INST_NOP 0x60000000 157#define PPC_INST_NOP 0x60000000
156#define PPC_INST_POPCNTB 0x7c0000f4 158#define PPC_INST_POPCNTB 0x7c0000f4
157#define PPC_INST_POPCNTB_MASK 0xfc0007fe 159#define PPC_INST_POPCNTB_MASK 0xfc0007fe
@@ -369,4 +371,11 @@
369#define TABORT(r) stringify_in_c(.long PPC_INST_TABORT \ 371#define TABORT(r) stringify_in_c(.long PPC_INST_TABORT \
370 | __PPC_RA(r)) 372 | __PPC_RA(r))
371 373
374/* book3e thread control instructions */
375#define TMRN(x) ((((x) & 0x1f) << 16) | (((x) & 0x3e0) << 6))
376#define MTTMR(tmr, r) stringify_in_c(.long PPC_INST_MTTMR | \
377 TMRN(tmr) | ___PPC_RS(r))
378#define MFTMR(tmr, r) stringify_in_c(.long PPC_INST_MFTMR | \
379 TMRN(tmr) | ___PPC_RT(r))
380
372#endif /* _ASM_POWERPC_PPC_OPCODE_H */ 381#endif /* _ASM_POWERPC_PPC_OPCODE_H */
diff --git a/arch/powerpc/include/asm/pte-fsl-booke.h b/arch/powerpc/include/asm/pte-fsl-booke.h
index 2c12be5f677a..e84dd7ed505e 100644
--- a/arch/powerpc/include/asm/pte-fsl-booke.h
+++ b/arch/powerpc/include/asm/pte-fsl-booke.h
@@ -37,5 +37,7 @@
37#define _PMD_PRESENT_MASK (PAGE_MASK) 37#define _PMD_PRESENT_MASK (PAGE_MASK)
38#define _PMD_BAD (~PAGE_MASK) 38#define _PMD_BAD (~PAGE_MASK)
39 39
40#define PTE_WIMGE_SHIFT (6)
41
40#endif /* __KERNEL__ */ 42#endif /* __KERNEL__ */
41#endif /* _ASM_POWERPC_PTE_FSL_BOOKE_H */ 43#endif /* _ASM_POWERPC_PTE_FSL_BOOKE_H */
diff --git a/arch/powerpc/include/asm/pte-hash64-64k.h b/arch/powerpc/include/asm/pte-hash64-64k.h
index d836d945068d..b6d2d42f84b5 100644
--- a/arch/powerpc/include/asm/pte-hash64-64k.h
+++ b/arch/powerpc/include/asm/pte-hash64-64k.h
@@ -75,7 +75,8 @@
75 (((pte) & _PAGE_COMBO)? MMU_PAGE_4K: MMU_PAGE_64K) 75 (((pte) & _PAGE_COMBO)? MMU_PAGE_4K: MMU_PAGE_64K)
76 76
77#define remap_4k_pfn(vma, addr, pfn, prot) \ 77#define remap_4k_pfn(vma, addr, pfn, prot) \
78 remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \ 78 (WARN_ON(((pfn) >= (1UL << (64 - PTE_RPN_SHIFT)))) ? -EINVAL : \
79 __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN)) 79 remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \
80 __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN)))
80 81
81#endif /* __ASSEMBLY__ */ 82#endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index bffd89d27301..f7b97b895708 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -254,7 +254,7 @@
254#define DSISR_PROTFAULT 0x08000000 /* protection fault */ 254#define DSISR_PROTFAULT 0x08000000 /* protection fault */
255#define DSISR_ISSTORE 0x02000000 /* access was a store */ 255#define DSISR_ISSTORE 0x02000000 /* access was a store */
256#define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */ 256#define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */
257#define DSISR_NOSEGMENT 0x00200000 /* STAB/SLB miss */ 257#define DSISR_NOSEGMENT 0x00200000 /* SLB miss */
258#define DSISR_KEYFAULT 0x00200000 /* Key fault */ 258#define DSISR_KEYFAULT 0x00200000 /* Key fault */
259#define SPRN_TBRL 0x10C /* Time Base Read Lower Register (user, R/O) */ 259#define SPRN_TBRL 0x10C /* Time Base Read Lower Register (user, R/O) */
260#define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */ 260#define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 464f1089b532..1d653308a33c 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -15,16 +15,28 @@
15#ifndef __ASM_POWERPC_REG_BOOKE_H__ 15#ifndef __ASM_POWERPC_REG_BOOKE_H__
16#define __ASM_POWERPC_REG_BOOKE_H__ 16#define __ASM_POWERPC_REG_BOOKE_H__
17 17
18#include <asm/ppc-opcode.h>
19
18/* Machine State Register (MSR) Fields */ 20/* Machine State Register (MSR) Fields */
19#define MSR_GS (1<<28) /* Guest state */ 21#define MSR_GS_LG 28 /* Guest state */
20#define MSR_UCLE (1<<26) /* User-mode cache lock enable */ 22#define MSR_UCLE_LG 26 /* User-mode cache lock enable */
21#define MSR_SPE (1<<25) /* Enable SPE */ 23#define MSR_SPE_LG 25 /* Enable SPE */
22#define MSR_DWE (1<<10) /* Debug Wait Enable */ 24#define MSR_DWE_LG 10 /* Debug Wait Enable */
23#define MSR_UBLE (1<<10) /* BTB lock enable (e500) */ 25#define MSR_UBLE_LG 10 /* BTB lock enable (e500) */
24#define MSR_IS MSR_IR /* Instruction Space */ 26#define MSR_IS_LG MSR_IR_LG /* Instruction Space */
25#define MSR_DS MSR_DR /* Data Space */ 27#define MSR_DS_LG MSR_DR_LG /* Data Space */
26#define MSR_PMM (1<<2) /* Performance monitor mark bit */ 28#define MSR_PMM_LG 2 /* Performance monitor mark bit */
27#define MSR_CM (1<<31) /* Computation Mode (0=32-bit, 1=64-bit) */ 29#define MSR_CM_LG 31 /* Computation Mode (0=32-bit, 1=64-bit) */
30
31#define MSR_GS __MASK(MSR_GS_LG)
32#define MSR_UCLE __MASK(MSR_UCLE_LG)
33#define MSR_SPE __MASK(MSR_SPE_LG)
34#define MSR_DWE __MASK(MSR_DWE_LG)
35#define MSR_UBLE __MASK(MSR_UBLE_LG)
36#define MSR_IS __MASK(MSR_IS_LG)
37#define MSR_DS __MASK(MSR_DS_LG)
38#define MSR_PMM __MASK(MSR_PMM_LG)
39#define MSR_CM __MASK(MSR_CM_LG)
28 40
29#if defined(CONFIG_PPC_BOOK3E_64) 41#if defined(CONFIG_PPC_BOOK3E_64)
30#define MSR_64BIT MSR_CM 42#define MSR_64BIT MSR_CM
@@ -260,7 +272,7 @@
260 272
261/* e500mc */ 273/* e500mc */
262#define MCSR_DCPERR_MC 0x20000000UL /* D-Cache Parity Error */ 274#define MCSR_DCPERR_MC 0x20000000UL /* D-Cache Parity Error */
263#define MCSR_L2MMU_MHIT 0x04000000UL /* Hit on multiple TLB entries */ 275#define MCSR_L2MMU_MHIT 0x08000000UL /* Hit on multiple TLB entries */
264#define MCSR_NMI 0x00100000UL /* Non-Maskable Interrupt */ 276#define MCSR_NMI 0x00100000UL /* Non-Maskable Interrupt */
265#define MCSR_MAV 0x00080000UL /* MCAR address valid */ 277#define MCSR_MAV 0x00080000UL /* MCAR address valid */
266#define MCSR_MEA 0x00040000UL /* MCAR is effective address */ 278#define MCSR_MEA 0x00040000UL /* MCAR is effective address */
@@ -598,6 +610,13 @@
598/* Bit definitions for L1CSR2. */ 610/* Bit definitions for L1CSR2. */
599#define L1CSR2_DCWS 0x40000000 /* Data Cache write shadow */ 611#define L1CSR2_DCWS 0x40000000 /* Data Cache write shadow */
600 612
613/* Bit definitions for BUCSR. */
614#define BUCSR_STAC_EN 0x01000000 /* Segment Target Address Cache */
615#define BUCSR_LS_EN 0x00400000 /* Link Stack */
616#define BUCSR_BBFI 0x00000200 /* Branch Buffer flash invalidate */
617#define BUCSR_BPEN 0x00000001 /* Branch prediction enable */
618#define BUCSR_INIT (BUCSR_STAC_EN | BUCSR_LS_EN | BUCSR_BBFI | BUCSR_BPEN)
619
601/* Bit definitions for L2CSR0. */ 620/* Bit definitions for L2CSR0. */
602#define L2CSR0_L2E 0x80000000 /* L2 Cache Enable */ 621#define L2CSR0_L2E 0x80000000 /* L2 Cache Enable */
603#define L2CSR0_L2PE 0x40000000 /* L2 Cache Parity/ECC Enable */ 622#define L2CSR0_L2PE 0x40000000 /* L2 Cache Parity/ECC Enable */
@@ -721,5 +740,23 @@
721#define MMUBE1_VBE4 0x00000002 740#define MMUBE1_VBE4 0x00000002
722#define MMUBE1_VBE5 0x00000001 741#define MMUBE1_VBE5 0x00000001
723 742
743#define TMRN_IMSR0 0x120 /* Initial MSR Register 0 (e6500) */
744#define TMRN_IMSR1 0x121 /* Initial MSR Register 1 (e6500) */
745#define TMRN_INIA0 0x140 /* Next Instruction Address Register 0 */
746#define TMRN_INIA1 0x141 /* Next Instruction Address Register 1 */
747#define SPRN_TENSR 0x1b5 /* Thread Enable Status Register */
748#define SPRN_TENS 0x1b6 /* Thread Enable Set Register */
749#define SPRN_TENC 0x1b7 /* Thread Enable Clear Register */
750
751#define TEN_THREAD(x) (1 << (x))
752
753#ifndef __ASSEMBLY__
754#define mftmr(rn) ({unsigned long rval; \
755 asm volatile(MFTMR(rn, %0) : "=r" (rval)); rval;})
756#define mttmr(rn, v) asm volatile(MTTMR(rn, %0) : \
757 : "r" ((unsigned long)(v)) \
758 : "memory")
759#endif /* !__ASSEMBLY__ */
760
724#endif /* __ASM_POWERPC_REG_BOOKE_H__ */ 761#endif /* __ASM_POWERPC_REG_BOOKE_H__ */
725#endif /* __KERNEL__ */ 762#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index babbeca6850f..542bc0f0673f 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -77,10 +77,10 @@ SYSCALL_SPU(setreuid)
77SYSCALL_SPU(setregid) 77SYSCALL_SPU(setregid)
78#define compat_sys_sigsuspend sys_sigsuspend 78#define compat_sys_sigsuspend sys_sigsuspend
79SYS32ONLY(sigsuspend) 79SYS32ONLY(sigsuspend)
80COMPAT_SYS(sigpending) 80SYSX(sys_ni_syscall,compat_sys_sigpending,sys_sigpending)
81SYSCALL_SPU(sethostname) 81SYSCALL_SPU(sethostname)
82COMPAT_SYS_SPU(setrlimit) 82COMPAT_SYS_SPU(setrlimit)
83COMPAT_SYS(old_getrlimit) 83SYSX(sys_ni_syscall,compat_sys_old_getrlimit,sys_old_getrlimit)
84COMPAT_SYS_SPU(getrusage) 84COMPAT_SYS_SPU(getrusage)
85COMPAT_SYS_SPU(gettimeofday) 85COMPAT_SYS_SPU(gettimeofday)
86COMPAT_SYS_SPU(settimeofday) 86COMPAT_SYS_SPU(settimeofday)
diff --git a/arch/powerpc/include/asm/trace.h b/arch/powerpc/include/asm/trace.h
index 5712f06905a9..c15da6073cb8 100644
--- a/arch/powerpc/include/asm/trace.h
+++ b/arch/powerpc/include/asm/trace.h
@@ -99,6 +99,51 @@ TRACE_EVENT_FN(hcall_exit,
99); 99);
100#endif 100#endif
101 101
102#ifdef CONFIG_PPC_POWERNV
103extern void opal_tracepoint_regfunc(void);
104extern void opal_tracepoint_unregfunc(void);
105
106TRACE_EVENT_FN(opal_entry,
107
108 TP_PROTO(unsigned long opcode, unsigned long *args),
109
110 TP_ARGS(opcode, args),
111
112 TP_STRUCT__entry(
113 __field(unsigned long, opcode)
114 ),
115
116 TP_fast_assign(
117 __entry->opcode = opcode;
118 ),
119
120 TP_printk("opcode=%lu", __entry->opcode),
121
122 opal_tracepoint_regfunc, opal_tracepoint_unregfunc
123);
124
125TRACE_EVENT_FN(opal_exit,
126
127 TP_PROTO(unsigned long opcode, unsigned long retval),
128
129 TP_ARGS(opcode, retval),
130
131 TP_STRUCT__entry(
132 __field(unsigned long, opcode)
133 __field(unsigned long, retval)
134 ),
135
136 TP_fast_assign(
137 __entry->opcode = opcode;
138 __entry->retval = retval;
139 ),
140
141 TP_printk("opcode=%lu retval=%lu", __entry->opcode, __entry->retval),
142
143 opal_tracepoint_regfunc, opal_tracepoint_unregfunc
144);
145#endif
146
102#endif /* _TRACE_POWERPC_H */ 147#endif /* _TRACE_POWERPC_H */
103 148
104#undef TRACE_INCLUDE_PATH 149#undef TRACE_INCLUDE_PATH
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index f5995a912213..e35054054c32 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -216,8 +216,6 @@ int main(void)
216#endif /* CONFIG_PPC_BOOK3E */ 216#endif /* CONFIG_PPC_BOOK3E */
217 217
218#ifdef CONFIG_PPC_STD_MMU_64 218#ifdef CONFIG_PPC_STD_MMU_64
219 DEFINE(PACASTABREAL, offsetof(struct paca_struct, stab_real));
220 DEFINE(PACASTABVIRT, offsetof(struct paca_struct, stab_addr));
221 DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache)); 219 DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
222 DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr)); 220 DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
223 DEFINE(PACAVMALLOCSLLP, offsetof(struct paca_struct, vmalloc_sllp)); 221 DEFINE(PACAVMALLOCSLLP, offsetof(struct paca_struct, vmalloc_sllp));
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 0c157642c2a1..9b6dcaaec1a3 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -123,96 +123,6 @@ extern void __restore_cpu_e6500(void);
123 123
124static struct cpu_spec __initdata cpu_specs[] = { 124static struct cpu_spec __initdata cpu_specs[] = {
125#ifdef CONFIG_PPC_BOOK3S_64 125#ifdef CONFIG_PPC_BOOK3S_64
126 { /* Power3 */
127 .pvr_mask = 0xffff0000,
128 .pvr_value = 0x00400000,
129 .cpu_name = "POWER3 (630)",
130 .cpu_features = CPU_FTRS_POWER3,
131 .cpu_user_features = COMMON_USER_PPC64|PPC_FEATURE_PPC_LE,
132 .mmu_features = MMU_FTR_HPTE_TABLE,
133 .icache_bsize = 128,
134 .dcache_bsize = 128,
135 .num_pmcs = 8,
136 .pmc_type = PPC_PMC_IBM,
137 .oprofile_cpu_type = "ppc64/power3",
138 .oprofile_type = PPC_OPROFILE_RS64,
139 .platform = "power3",
140 },
141 { /* Power3+ */
142 .pvr_mask = 0xffff0000,
143 .pvr_value = 0x00410000,
144 .cpu_name = "POWER3 (630+)",
145 .cpu_features = CPU_FTRS_POWER3,
146 .cpu_user_features = COMMON_USER_PPC64|PPC_FEATURE_PPC_LE,
147 .mmu_features = MMU_FTR_HPTE_TABLE,
148 .icache_bsize = 128,
149 .dcache_bsize = 128,
150 .num_pmcs = 8,
151 .pmc_type = PPC_PMC_IBM,
152 .oprofile_cpu_type = "ppc64/power3",
153 .oprofile_type = PPC_OPROFILE_RS64,
154 .platform = "power3",
155 },
156 { /* Northstar */
157 .pvr_mask = 0xffff0000,
158 .pvr_value = 0x00330000,
159 .cpu_name = "RS64-II (northstar)",
160 .cpu_features = CPU_FTRS_RS64,
161 .cpu_user_features = COMMON_USER_PPC64,
162 .mmu_features = MMU_FTR_HPTE_TABLE,
163 .icache_bsize = 128,
164 .dcache_bsize = 128,
165 .num_pmcs = 8,
166 .pmc_type = PPC_PMC_IBM,
167 .oprofile_cpu_type = "ppc64/rs64",
168 .oprofile_type = PPC_OPROFILE_RS64,
169 .platform = "rs64",
170 },
171 { /* Pulsar */
172 .pvr_mask = 0xffff0000,
173 .pvr_value = 0x00340000,
174 .cpu_name = "RS64-III (pulsar)",
175 .cpu_features = CPU_FTRS_RS64,
176 .cpu_user_features = COMMON_USER_PPC64,
177 .mmu_features = MMU_FTR_HPTE_TABLE,
178 .icache_bsize = 128,
179 .dcache_bsize = 128,
180 .num_pmcs = 8,
181 .pmc_type = PPC_PMC_IBM,
182 .oprofile_cpu_type = "ppc64/rs64",
183 .oprofile_type = PPC_OPROFILE_RS64,
184 .platform = "rs64",
185 },
186 { /* I-star */
187 .pvr_mask = 0xffff0000,
188 .pvr_value = 0x00360000,
189 .cpu_name = "RS64-III (icestar)",
190 .cpu_features = CPU_FTRS_RS64,
191 .cpu_user_features = COMMON_USER_PPC64,
192 .mmu_features = MMU_FTR_HPTE_TABLE,
193 .icache_bsize = 128,
194 .dcache_bsize = 128,
195 .num_pmcs = 8,
196 .pmc_type = PPC_PMC_IBM,
197 .oprofile_cpu_type = "ppc64/rs64",
198 .oprofile_type = PPC_OPROFILE_RS64,
199 .platform = "rs64",
200 },
201 { /* S-star */
202 .pvr_mask = 0xffff0000,
203 .pvr_value = 0x00370000,
204 .cpu_name = "RS64-IV (sstar)",
205 .cpu_features = CPU_FTRS_RS64,
206 .cpu_user_features = COMMON_USER_PPC64,
207 .mmu_features = MMU_FTR_HPTE_TABLE,
208 .icache_bsize = 128,
209 .dcache_bsize = 128,
210 .num_pmcs = 8,
211 .pmc_type = PPC_PMC_IBM,
212 .oprofile_cpu_type = "ppc64/rs64",
213 .oprofile_type = PPC_OPROFILE_RS64,
214 .platform = "rs64",
215 },
216 { /* Power4 */ 126 { /* Power4 */
217 .pvr_mask = 0xffff0000, 127 .pvr_mask = 0xffff0000,
218 .pvr_value = 0x00350000, 128 .pvr_value = 0x00350000,
@@ -617,7 +527,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
617#endif /* CONFIG_PPC_BOOK3S_64 */ 527#endif /* CONFIG_PPC_BOOK3S_64 */
618 528
619#ifdef CONFIG_PPC32 529#ifdef CONFIG_PPC32
620#if CLASSIC_PPC 530#ifdef CONFIG_PPC_BOOK3S_32
621 { /* 601 */ 531 { /* 601 */
622 .pvr_mask = 0xffff0000, 532 .pvr_mask = 0xffff0000,
623 .pvr_value = 0x00010000, 533 .pvr_value = 0x00010000,
@@ -1257,7 +1167,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1257 .machine_check = machine_check_generic, 1167 .machine_check = machine_check_generic,
1258 .platform = "ppc603", 1168 .platform = "ppc603",
1259 }, 1169 },
1260#endif /* CLASSIC_PPC */ 1170#endif /* CONFIG_PPC_BOOK3S_32 */
1261#ifdef CONFIG_8xx 1171#ifdef CONFIG_8xx
1262 { /* 8xx */ 1172 { /* 8xx */
1263 .pvr_mask = 0xffff0000, 1173 .pvr_mask = 0xffff0000,
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 86e25702aaca..59a64f8dc85f 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -27,6 +27,7 @@
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/pci.h> 29#include <linux/pci.h>
30#include <linux/iommu.h>
30#include <linux/proc_fs.h> 31#include <linux/proc_fs.h>
31#include <linux/rbtree.h> 32#include <linux/rbtree.h>
32#include <linux/reboot.h> 33#include <linux/reboot.h>
@@ -40,6 +41,7 @@
40#include <asm/eeh.h> 41#include <asm/eeh.h>
41#include <asm/eeh_event.h> 42#include <asm/eeh_event.h>
42#include <asm/io.h> 43#include <asm/io.h>
44#include <asm/iommu.h>
43#include <asm/machdep.h> 45#include <asm/machdep.h>
44#include <asm/ppc-pci.h> 46#include <asm/ppc-pci.h>
45#include <asm/rtas.h> 47#include <asm/rtas.h>
@@ -108,6 +110,9 @@ struct eeh_ops *eeh_ops = NULL;
108/* Lock to avoid races due to multiple reports of an error */ 110/* Lock to avoid races due to multiple reports of an error */
109DEFINE_RAW_SPINLOCK(confirm_error_lock); 111DEFINE_RAW_SPINLOCK(confirm_error_lock);
110 112
113/* Lock to protect passed flags */
114static DEFINE_MUTEX(eeh_dev_mutex);
115
111/* Buffer for reporting pci register dumps. Its here in BSS, and 116/* Buffer for reporting pci register dumps. Its here in BSS, and
112 * not dynamically alloced, so that it ends up in RMO where RTAS 117 * not dynamically alloced, so that it ends up in RMO where RTAS
113 * can access it. 118 * can access it.
@@ -137,7 +142,7 @@ static struct eeh_stats eeh_stats;
137static int __init eeh_setup(char *str) 142static int __init eeh_setup(char *str)
138{ 143{
139 if (!strcmp(str, "off")) 144 if (!strcmp(str, "off"))
140 eeh_subsystem_flags |= EEH_FORCE_DISABLED; 145 eeh_add_flag(EEH_FORCE_DISABLED);
141 146
142 return 1; 147 return 1;
143} 148}
@@ -152,12 +157,13 @@ __setup("eeh=", eeh_setup);
152 * This routine captures assorted PCI configuration space data, 157 * This routine captures assorted PCI configuration space data,
153 * and puts them into a buffer for RTAS error logging. 158 * and puts them into a buffer for RTAS error logging.
154 */ 159 */
155static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len) 160static size_t eeh_gather_pci_data(struct eeh_dev *edev, char *buf, size_t len)
156{ 161{
157 struct device_node *dn = eeh_dev_to_of_node(edev); 162 struct device_node *dn = eeh_dev_to_of_node(edev);
158 u32 cfg; 163 u32 cfg;
159 int cap, i; 164 int cap, i;
160 int n = 0; 165 int n = 0, l = 0;
166 char buffer[128];
161 167
162 n += scnprintf(buf+n, len-n, "%s\n", dn->full_name); 168 n += scnprintf(buf+n, len-n, "%s\n", dn->full_name);
163 pr_warn("EEH: of node=%s\n", dn->full_name); 169 pr_warn("EEH: of node=%s\n", dn->full_name);
@@ -202,8 +208,22 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len)
202 for (i=0; i<=8; i++) { 208 for (i=0; i<=8; i++) {
203 eeh_ops->read_config(dn, cap+4*i, 4, &cfg); 209 eeh_ops->read_config(dn, cap+4*i, 4, &cfg);
204 n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg); 210 n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg);
205 pr_warn("EEH: PCI-E %02x: %08x\n", i, cfg); 211
212 if ((i % 4) == 0) {
213 if (i != 0)
214 pr_warn("%s\n", buffer);
215
216 l = scnprintf(buffer, sizeof(buffer),
217 "EEH: PCI-E %02x: %08x ",
218 4*i, cfg);
219 } else {
220 l += scnprintf(buffer+l, sizeof(buffer)-l,
221 "%08x ", cfg);
222 }
223
206 } 224 }
225
226 pr_warn("%s\n", buffer);
207 } 227 }
208 228
209 /* If AER capable, dump it */ 229 /* If AER capable, dump it */
@@ -212,11 +232,24 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len)
212 n += scnprintf(buf+n, len-n, "pci-e AER:\n"); 232 n += scnprintf(buf+n, len-n, "pci-e AER:\n");
213 pr_warn("EEH: PCI-E AER capability register set follows:\n"); 233 pr_warn("EEH: PCI-E AER capability register set follows:\n");
214 234
215 for (i=0; i<14; i++) { 235 for (i=0; i<=13; i++) {
216 eeh_ops->read_config(dn, cap+4*i, 4, &cfg); 236 eeh_ops->read_config(dn, cap+4*i, 4, &cfg);
217 n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg); 237 n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg);
218 pr_warn("EEH: PCI-E AER %02x: %08x\n", i, cfg); 238
239 if ((i % 4) == 0) {
240 if (i != 0)
241 pr_warn("%s\n", buffer);
242
243 l = scnprintf(buffer, sizeof(buffer),
244 "EEH: PCI-E AER %02x: %08x ",
245 4*i, cfg);
246 } else {
247 l += scnprintf(buffer+l, sizeof(buffer)-l,
248 "%08x ", cfg);
249 }
219 } 250 }
251
252 pr_warn("%s\n", buffer);
220 } 253 }
221 254
222 return n; 255 return n;
@@ -247,7 +280,7 @@ void eeh_slot_error_detail(struct eeh_pe *pe, int severity)
247 * 0xFF's is always returned from PCI config space. 280 * 0xFF's is always returned from PCI config space.
248 */ 281 */
249 if (!(pe->type & EEH_PE_PHB)) { 282 if (!(pe->type & EEH_PE_PHB)) {
250 if (eeh_probe_mode_devtree()) 283 if (eeh_has_flag(EEH_ENABLE_IO_FOR_LOG))
251 eeh_pci_enable(pe, EEH_OPT_THAW_MMIO); 284 eeh_pci_enable(pe, EEH_OPT_THAW_MMIO);
252 eeh_ops->configure_bridge(pe); 285 eeh_ops->configure_bridge(pe);
253 eeh_pe_restore_bars(pe); 286 eeh_pe_restore_bars(pe);
@@ -298,14 +331,14 @@ static int eeh_phb_check_failure(struct eeh_pe *pe)
298 unsigned long flags; 331 unsigned long flags;
299 int ret; 332 int ret;
300 333
301 if (!eeh_probe_mode_dev()) 334 if (!eeh_has_flag(EEH_PROBE_MODE_DEV))
302 return -EPERM; 335 return -EPERM;
303 336
304 /* Find the PHB PE */ 337 /* Find the PHB PE */
305 phb_pe = eeh_phb_pe_get(pe->phb); 338 phb_pe = eeh_phb_pe_get(pe->phb);
306 if (!phb_pe) { 339 if (!phb_pe) {
307 pr_warning("%s Can't find PE for PHB#%d\n", 340 pr_warn("%s Can't find PE for PHB#%d\n",
308 __func__, pe->phb->global_number); 341 __func__, pe->phb->global_number);
309 return -EEXIST; 342 return -EEXIST;
310 } 343 }
311 344
@@ -400,6 +433,14 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
400 if (ret > 0) 433 if (ret > 0)
401 return ret; 434 return ret;
402 435
436 /*
437 * If the PE isn't owned by us, we shouldn't check the
438 * state. Instead, let the owner handle it if the PE has
439 * been frozen.
440 */
441 if (eeh_pe_passed(pe))
442 return 0;
443
403 /* If we already have a pending isolation event for this 444 /* If we already have a pending isolation event for this
404 * slot, we know it's bad already, we don't need to check. 445 * slot, we know it's bad already, we don't need to check.
405 * Do this checking under a lock; as multiple PCI devices 446 * Do this checking under a lock; as multiple PCI devices
@@ -746,13 +787,13 @@ void eeh_save_bars(struct eeh_dev *edev)
746int __init eeh_ops_register(struct eeh_ops *ops) 787int __init eeh_ops_register(struct eeh_ops *ops)
747{ 788{
748 if (!ops->name) { 789 if (!ops->name) {
749 pr_warning("%s: Invalid EEH ops name for %p\n", 790 pr_warn("%s: Invalid EEH ops name for %p\n",
750 __func__, ops); 791 __func__, ops);
751 return -EINVAL; 792 return -EINVAL;
752 } 793 }
753 794
754 if (eeh_ops && eeh_ops != ops) { 795 if (eeh_ops && eeh_ops != ops) {
755 pr_warning("%s: EEH ops of platform %s already existing (%s)\n", 796 pr_warn("%s: EEH ops of platform %s already existing (%s)\n",
756 __func__, eeh_ops->name, ops->name); 797 __func__, eeh_ops->name, ops->name);
757 return -EEXIST; 798 return -EEXIST;
758 } 799 }
@@ -772,7 +813,7 @@ int __init eeh_ops_register(struct eeh_ops *ops)
772int __exit eeh_ops_unregister(const char *name) 813int __exit eeh_ops_unregister(const char *name)
773{ 814{
774 if (!name || !strlen(name)) { 815 if (!name || !strlen(name)) {
775 pr_warning("%s: Invalid EEH ops name\n", 816 pr_warn("%s: Invalid EEH ops name\n",
776 __func__); 817 __func__);
777 return -EINVAL; 818 return -EINVAL;
778 } 819 }
@@ -788,7 +829,7 @@ int __exit eeh_ops_unregister(const char *name)
788static int eeh_reboot_notifier(struct notifier_block *nb, 829static int eeh_reboot_notifier(struct notifier_block *nb,
789 unsigned long action, void *unused) 830 unsigned long action, void *unused)
790{ 831{
791 eeh_set_enable(false); 832 eeh_clear_flag(EEH_ENABLED);
792 return NOTIFY_DONE; 833 return NOTIFY_DONE;
793} 834}
794 835
@@ -837,11 +878,11 @@ int eeh_init(void)
837 878
838 /* call platform initialization function */ 879 /* call platform initialization function */
839 if (!eeh_ops) { 880 if (!eeh_ops) {
840 pr_warning("%s: Platform EEH operation not found\n", 881 pr_warn("%s: Platform EEH operation not found\n",
841 __func__); 882 __func__);
842 return -EEXIST; 883 return -EEXIST;
843 } else if ((ret = eeh_ops->init())) { 884 } else if ((ret = eeh_ops->init())) {
844 pr_warning("%s: Failed to call platform init function (%d)\n", 885 pr_warn("%s: Failed to call platform init function (%d)\n",
845 __func__, ret); 886 __func__, ret);
846 return ret; 887 return ret;
847 } 888 }
@@ -852,13 +893,13 @@ int eeh_init(void)
852 return ret; 893 return ret;
853 894
854 /* Enable EEH for all adapters */ 895 /* Enable EEH for all adapters */
855 if (eeh_probe_mode_devtree()) { 896 if (eeh_has_flag(EEH_PROBE_MODE_DEVTREE)) {
856 list_for_each_entry_safe(hose, tmp, 897 list_for_each_entry_safe(hose, tmp,
857 &hose_list, list_node) { 898 &hose_list, list_node) {
858 phb = hose->dn; 899 phb = hose->dn;
859 traverse_pci_devices(phb, eeh_ops->of_probe, NULL); 900 traverse_pci_devices(phb, eeh_ops->of_probe, NULL);
860 } 901 }
861 } else if (eeh_probe_mode_dev()) { 902 } else if (eeh_has_flag(EEH_PROBE_MODE_DEV)) {
862 list_for_each_entry_safe(hose, tmp, 903 list_for_each_entry_safe(hose, tmp,
863 &hose_list, list_node) 904 &hose_list, list_node)
864 pci_walk_bus(hose->bus, eeh_ops->dev_probe, NULL); 905 pci_walk_bus(hose->bus, eeh_ops->dev_probe, NULL);
@@ -882,7 +923,7 @@ int eeh_init(void)
882 if (eeh_enabled()) 923 if (eeh_enabled())
883 pr_info("EEH: PCI Enhanced I/O Error Handling Enabled\n"); 924 pr_info("EEH: PCI Enhanced I/O Error Handling Enabled\n");
884 else 925 else
885 pr_warning("EEH: No capable adapters found\n"); 926 pr_warn("EEH: No capable adapters found\n");
886 927
887 return ret; 928 return ret;
888} 929}
@@ -910,7 +951,7 @@ void eeh_add_device_early(struct device_node *dn)
910 * would delay the probe until late stage because 951 * would delay the probe until late stage because
911 * the PCI device isn't available this moment. 952 * the PCI device isn't available this moment.
912 */ 953 */
913 if (!eeh_probe_mode_devtree()) 954 if (!eeh_has_flag(EEH_PROBE_MODE_DEVTREE))
914 return; 955 return;
915 956
916 if (!of_node_to_eeh_dev(dn)) 957 if (!of_node_to_eeh_dev(dn))
@@ -996,7 +1037,7 @@ void eeh_add_device_late(struct pci_dev *dev)
996 * We have to do the EEH probe here because the PCI device 1037 * We have to do the EEH probe here because the PCI device
997 * hasn't been created yet in the early stage. 1038 * hasn't been created yet in the early stage.
998 */ 1039 */
999 if (eeh_probe_mode_dev()) 1040 if (eeh_has_flag(EEH_PROBE_MODE_DEV))
1000 eeh_ops->dev_probe(dev, NULL); 1041 eeh_ops->dev_probe(dev, NULL);
1001 1042
1002 eeh_addr_cache_insert_dev(dev); 1043 eeh_addr_cache_insert_dev(dev);
@@ -1100,6 +1141,285 @@ void eeh_remove_device(struct pci_dev *dev)
1100 edev->mode &= ~EEH_DEV_SYSFS; 1141 edev->mode &= ~EEH_DEV_SYSFS;
1101} 1142}
1102 1143
1144/**
1145 * eeh_dev_open - Increase count of pass through devices for PE
1146 * @pdev: PCI device
1147 *
1148 * Increase count of passed through devices for the indicated
1149 * PE. In the result, the EEH errors detected on the PE won't be
1150 * reported. The PE owner will be responsible for detection
1151 * and recovery.
1152 */
1153int eeh_dev_open(struct pci_dev *pdev)
1154{
1155 struct eeh_dev *edev;
1156
1157 mutex_lock(&eeh_dev_mutex);
1158
1159 /* No PCI device ? */
1160 if (!pdev)
1161 goto out;
1162
1163 /* No EEH device or PE ? */
1164 edev = pci_dev_to_eeh_dev(pdev);
1165 if (!edev || !edev->pe)
1166 goto out;
1167
1168 /* Increase PE's pass through count */
1169 atomic_inc(&edev->pe->pass_dev_cnt);
1170 mutex_unlock(&eeh_dev_mutex);
1171
1172 return 0;
1173out:
1174 mutex_unlock(&eeh_dev_mutex);
1175 return -ENODEV;
1176}
1177EXPORT_SYMBOL_GPL(eeh_dev_open);
1178
1179/**
1180 * eeh_dev_release - Decrease count of pass through devices for PE
1181 * @pdev: PCI device
1182 *
1183 * Decrease count of pass through devices for the indicated PE. If
1184 * there is no passed through device in PE, the EEH errors detected
1185 * on the PE will be reported and handled as usual.
1186 */
1187void eeh_dev_release(struct pci_dev *pdev)
1188{
1189 struct eeh_dev *edev;
1190
1191 mutex_lock(&eeh_dev_mutex);
1192
1193 /* No PCI device ? */
1194 if (!pdev)
1195 goto out;
1196
1197 /* No EEH device ? */
1198 edev = pci_dev_to_eeh_dev(pdev);
1199 if (!edev || !edev->pe || !eeh_pe_passed(edev->pe))
1200 goto out;
1201
1202 /* Decrease PE's pass through count */
1203 atomic_dec(&edev->pe->pass_dev_cnt);
1204 WARN_ON(atomic_read(&edev->pe->pass_dev_cnt) < 0);
1205out:
1206 mutex_unlock(&eeh_dev_mutex);
1207}
1208EXPORT_SYMBOL(eeh_dev_release);
1209
1210#ifdef CONFIG_IOMMU_API
1211
1212static int dev_has_iommu_table(struct device *dev, void *data)
1213{
1214 struct pci_dev *pdev = to_pci_dev(dev);
1215 struct pci_dev **ppdev = data;
1216 struct iommu_table *tbl;
1217
1218 if (!dev)
1219 return 0;
1220
1221 tbl = get_iommu_table_base(dev);
1222 if (tbl && tbl->it_group) {
1223 *ppdev = pdev;
1224 return 1;
1225 }
1226
1227 return 0;
1228}
1229
1230/**
1231 * eeh_iommu_group_to_pe - Convert IOMMU group to EEH PE
1232 * @group: IOMMU group
1233 *
1234 * The routine is called to convert IOMMU group to EEH PE.
1235 */
1236struct eeh_pe *eeh_iommu_group_to_pe(struct iommu_group *group)
1237{
1238 struct pci_dev *pdev = NULL;
1239 struct eeh_dev *edev;
1240 int ret;
1241
1242 /* No IOMMU group ? */
1243 if (!group)
1244 return NULL;
1245
1246 ret = iommu_group_for_each_dev(group, &pdev, dev_has_iommu_table);
1247 if (!ret || !pdev)
1248 return NULL;
1249
1250 /* No EEH device or PE ? */
1251 edev = pci_dev_to_eeh_dev(pdev);
1252 if (!edev || !edev->pe)
1253 return NULL;
1254
1255 return edev->pe;
1256}
1257EXPORT_SYMBOL_GPL(eeh_iommu_group_to_pe);
1258
1259#endif /* CONFIG_IOMMU_API */
1260
1261/**
1262 * eeh_pe_set_option - Set options for the indicated PE
1263 * @pe: EEH PE
1264 * @option: requested option
1265 *
1266 * The routine is called to enable or disable EEH functionality
1267 * on the indicated PE, to enable IO or DMA for the frozen PE.
1268 */
1269int eeh_pe_set_option(struct eeh_pe *pe, int option)
1270{
1271 int ret = 0;
1272
1273 /* Invalid PE ? */
1274 if (!pe)
1275 return -ENODEV;
1276
1277 /*
1278 * EEH functionality could possibly be disabled, just
1279 * return error for the case. And the EEH functinality
1280 * isn't expected to be disabled on one specific PE.
1281 */
1282 switch (option) {
1283 case EEH_OPT_ENABLE:
1284 if (eeh_enabled())
1285 break;
1286 ret = -EIO;
1287 break;
1288 case EEH_OPT_DISABLE:
1289 break;
1290 case EEH_OPT_THAW_MMIO:
1291 case EEH_OPT_THAW_DMA:
1292 if (!eeh_ops || !eeh_ops->set_option) {
1293 ret = -ENOENT;
1294 break;
1295 }
1296
1297 ret = eeh_ops->set_option(pe, option);
1298 break;
1299 default:
1300 pr_debug("%s: Option %d out of range (%d, %d)\n",
1301 __func__, option, EEH_OPT_DISABLE, EEH_OPT_THAW_DMA);
1302 ret = -EINVAL;
1303 }
1304
1305 return ret;
1306}
1307EXPORT_SYMBOL_GPL(eeh_pe_set_option);
1308
1309/**
1310 * eeh_pe_get_state - Retrieve PE's state
1311 * @pe: EEH PE
1312 *
1313 * Retrieve the PE's state, which includes 3 aspects: enabled
1314 * DMA, enabled IO and asserted reset.
1315 */
1316int eeh_pe_get_state(struct eeh_pe *pe)
1317{
1318 int result, ret = 0;
1319 bool rst_active, dma_en, mmio_en;
1320
1321 /* Existing PE ? */
1322 if (!pe)
1323 return -ENODEV;
1324
1325 if (!eeh_ops || !eeh_ops->get_state)
1326 return -ENOENT;
1327
1328 result = eeh_ops->get_state(pe, NULL);
1329 rst_active = !!(result & EEH_STATE_RESET_ACTIVE);
1330 dma_en = !!(result & EEH_STATE_DMA_ENABLED);
1331 mmio_en = !!(result & EEH_STATE_MMIO_ENABLED);
1332
1333 if (rst_active)
1334 ret = EEH_PE_STATE_RESET;
1335 else if (dma_en && mmio_en)
1336 ret = EEH_PE_STATE_NORMAL;
1337 else if (!dma_en && !mmio_en)
1338 ret = EEH_PE_STATE_STOPPED_IO_DMA;
1339 else if (!dma_en && mmio_en)
1340 ret = EEH_PE_STATE_STOPPED_DMA;
1341 else
1342 ret = EEH_PE_STATE_UNAVAIL;
1343
1344 return ret;
1345}
1346EXPORT_SYMBOL_GPL(eeh_pe_get_state);
1347
1348/**
1349 * eeh_pe_reset - Issue PE reset according to specified type
1350 * @pe: EEH PE
1351 * @option: reset type
1352 *
1353 * The routine is called to reset the specified PE with the
1354 * indicated type, either fundamental reset or hot reset.
1355 * PE reset is the most important part for error recovery.
1356 */
1357int eeh_pe_reset(struct eeh_pe *pe, int option)
1358{
1359 int ret = 0;
1360
1361 /* Invalid PE ? */
1362 if (!pe)
1363 return -ENODEV;
1364
1365 if (!eeh_ops || !eeh_ops->set_option || !eeh_ops->reset)
1366 return -ENOENT;
1367
1368 switch (option) {
1369 case EEH_RESET_DEACTIVATE:
1370 ret = eeh_ops->reset(pe, option);
1371 if (ret)
1372 break;
1373
1374 /*
1375 * The PE is still in frozen state and we need to clear
1376 * that. It's good to clear frozen state after deassert
1377 * to avoid messy IO access during reset, which might
1378 * cause recursive frozen PE.
1379 */
1380 ret = eeh_ops->set_option(pe, EEH_OPT_THAW_MMIO);
1381 if (!ret)
1382 ret = eeh_ops->set_option(pe, EEH_OPT_THAW_DMA);
1383 if (!ret)
1384 eeh_pe_state_clear(pe, EEH_PE_ISOLATED);
1385 break;
1386 case EEH_RESET_HOT:
1387 case EEH_RESET_FUNDAMENTAL:
1388 ret = eeh_ops->reset(pe, option);
1389 break;
1390 default:
1391 pr_debug("%s: Unsupported option %d\n",
1392 __func__, option);
1393 ret = -EINVAL;
1394 }
1395
1396 return ret;
1397}
1398EXPORT_SYMBOL_GPL(eeh_pe_reset);
1399
1400/**
1401 * eeh_pe_configure - Configure PCI bridges after PE reset
1402 * @pe: EEH PE
1403 *
1404 * The routine is called to restore the PCI config space for
1405 * those PCI devices, especially PCI bridges affected by PE
1406 * reset issued previously.
1407 */
1408int eeh_pe_configure(struct eeh_pe *pe)
1409{
1410 int ret = 0;
1411
1412 /* Invalid PE ? */
1413 if (!pe)
1414 return -ENODEV;
1415
1416 /* Restore config space for the affected devices */
1417 eeh_pe_restore_bars(pe);
1418
1419 return ret;
1420}
1421EXPORT_SYMBOL_GPL(eeh_pe_configure);
1422
1103static int proc_eeh_show(struct seq_file *m, void *v) 1423static int proc_eeh_show(struct seq_file *m, void *v)
1104{ 1424{
1105 if (!eeh_enabled()) { 1425 if (!eeh_enabled()) {
@@ -1143,9 +1463,9 @@ static const struct file_operations proc_eeh_operations = {
1143static int eeh_enable_dbgfs_set(void *data, u64 val) 1463static int eeh_enable_dbgfs_set(void *data, u64 val)
1144{ 1464{
1145 if (val) 1465 if (val)
1146 eeh_subsystem_flags &= ~EEH_FORCE_DISABLED; 1466 eeh_clear_flag(EEH_FORCE_DISABLED);
1147 else 1467 else
1148 eeh_subsystem_flags |= EEH_FORCE_DISABLED; 1468 eeh_add_flag(EEH_FORCE_DISABLED);
1149 1469
1150 /* Notify the backend */ 1470 /* Notify the backend */
1151 if (eeh_ops->post_init) 1471 if (eeh_ops->post_init)
diff --git a/arch/powerpc/kernel/eeh_cache.c b/arch/powerpc/kernel/eeh_cache.c
index e8c9fd546a5c..07d8a2423a61 100644
--- a/arch/powerpc/kernel/eeh_cache.c
+++ b/arch/powerpc/kernel/eeh_cache.c
@@ -143,7 +143,7 @@ eeh_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
143 } else { 143 } else {
144 if (dev != piar->pcidev || 144 if (dev != piar->pcidev ||
145 alo != piar->addr_lo || ahi != piar->addr_hi) { 145 alo != piar->addr_lo || ahi != piar->addr_hi) {
146 pr_warning("PIAR: overlapping address range\n"); 146 pr_warn("PIAR: overlapping address range\n");
147 } 147 }
148 return piar; 148 return piar;
149 } 149 }
@@ -177,19 +177,20 @@ static void __eeh_addr_cache_insert_dev(struct pci_dev *dev)
177 177
178 dn = pci_device_to_OF_node(dev); 178 dn = pci_device_to_OF_node(dev);
179 if (!dn) { 179 if (!dn) {
180 pr_warning("PCI: no pci dn found for dev=%s\n", pci_name(dev)); 180 pr_warn("PCI: no pci dn found for dev=%s\n",
181 pci_name(dev));
181 return; 182 return;
182 } 183 }
183 184
184 edev = of_node_to_eeh_dev(dn); 185 edev = of_node_to_eeh_dev(dn);
185 if (!edev) { 186 if (!edev) {
186 pr_warning("PCI: no EEH dev found for dn=%s\n", 187 pr_warn("PCI: no EEH dev found for dn=%s\n",
187 dn->full_name); 188 dn->full_name);
188 return; 189 return;
189 } 190 }
190 191
191 /* Skip any devices for which EEH is not enabled. */ 192 /* Skip any devices for which EEH is not enabled. */
192 if (!eeh_probe_mode_dev() && !edev->pe) { 193 if (!edev->pe) {
193#ifdef DEBUG 194#ifdef DEBUG
194 pr_info("PCI: skip building address cache for=%s - %s\n", 195 pr_info("PCI: skip building address cache for=%s - %s\n",
195 pci_name(dev), dn->full_name); 196 pci_name(dev), dn->full_name);
diff --git a/arch/powerpc/kernel/eeh_dev.c b/arch/powerpc/kernel/eeh_dev.c
index 1efa28f5fc54..e5274ee9a75f 100644
--- a/arch/powerpc/kernel/eeh_dev.c
+++ b/arch/powerpc/kernel/eeh_dev.c
@@ -57,7 +57,8 @@ void *eeh_dev_init(struct device_node *dn, void *data)
57 /* Allocate EEH device */ 57 /* Allocate EEH device */
58 edev = kzalloc(sizeof(*edev), GFP_KERNEL); 58 edev = kzalloc(sizeof(*edev), GFP_KERNEL);
59 if (!edev) { 59 if (!edev) {
60 pr_warning("%s: out of memory\n", __func__); 60 pr_warn("%s: out of memory\n",
61 __func__);
61 return NULL; 62 return NULL;
62 } 63 }
63 64
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 420da61d4ce0..6a0dcee8e931 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -599,7 +599,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
599 pe->freeze_count++; 599 pe->freeze_count++;
600 if (pe->freeze_count > EEH_MAX_ALLOWED_FREEZES) 600 if (pe->freeze_count > EEH_MAX_ALLOWED_FREEZES)
601 goto excess_failures; 601 goto excess_failures;
602 pr_warning("EEH: This PCI device has failed %d times in the last hour\n", 602 pr_warn("EEH: This PCI device has failed %d times in the last hour\n",
603 pe->freeze_count); 603 pe->freeze_count);
604 604
605 /* Walk the various device drivers attached to this slot through 605 /* Walk the various device drivers attached to this slot through
@@ -616,7 +616,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
616 */ 616 */
617 rc = eeh_ops->wait_state(pe, MAX_WAIT_FOR_RECOVERY*1000); 617 rc = eeh_ops->wait_state(pe, MAX_WAIT_FOR_RECOVERY*1000);
618 if (rc < 0 || rc == EEH_STATE_NOT_SUPPORT) { 618 if (rc < 0 || rc == EEH_STATE_NOT_SUPPORT) {
619 pr_warning("EEH: Permanent failure\n"); 619 pr_warn("EEH: Permanent failure\n");
620 goto hard_fail; 620 goto hard_fail;
621 } 621 }
622 622
@@ -635,8 +635,8 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
635 pr_info("EEH: Reset with hotplug activity\n"); 635 pr_info("EEH: Reset with hotplug activity\n");
636 rc = eeh_reset_device(pe, frozen_bus); 636 rc = eeh_reset_device(pe, frozen_bus);
637 if (rc) { 637 if (rc) {
638 pr_warning("%s: Unable to reset, err=%d\n", 638 pr_warn("%s: Unable to reset, err=%d\n",
639 __func__, rc); 639 __func__, rc);
640 goto hard_fail; 640 goto hard_fail;
641 } 641 }
642 } 642 }
@@ -678,7 +678,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
678 678
679 /* If any device has a hard failure, then shut off everything. */ 679 /* If any device has a hard failure, then shut off everything. */
680 if (result == PCI_ERS_RESULT_DISCONNECT) { 680 if (result == PCI_ERS_RESULT_DISCONNECT) {
681 pr_warning("EEH: Device driver gave up\n"); 681 pr_warn("EEH: Device driver gave up\n");
682 goto hard_fail; 682 goto hard_fail;
683 } 683 }
684 684
@@ -687,8 +687,8 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
687 pr_info("EEH: Reset without hotplug activity\n"); 687 pr_info("EEH: Reset without hotplug activity\n");
688 rc = eeh_reset_device(pe, NULL); 688 rc = eeh_reset_device(pe, NULL);
689 if (rc) { 689 if (rc) {
690 pr_warning("%s: Cannot reset, err=%d\n", 690 pr_warn("%s: Cannot reset, err=%d\n",
691 __func__, rc); 691 __func__, rc);
692 goto hard_fail; 692 goto hard_fail;
693 } 693 }
694 694
@@ -701,7 +701,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
701 /* All devices should claim they have recovered by now. */ 701 /* All devices should claim they have recovered by now. */
702 if ((result != PCI_ERS_RESULT_RECOVERED) && 702 if ((result != PCI_ERS_RESULT_RECOVERED) &&
703 (result != PCI_ERS_RESULT_NONE)) { 703 (result != PCI_ERS_RESULT_NONE)) {
704 pr_warning("EEH: Not recovered\n"); 704 pr_warn("EEH: Not recovered\n");
705 goto hard_fail; 705 goto hard_fail;
706 } 706 }
707 707
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index fbd01eba4473..00e3844525a6 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -32,9 +32,24 @@
32#include <asm/pci-bridge.h> 32#include <asm/pci-bridge.h>
33#include <asm/ppc-pci.h> 33#include <asm/ppc-pci.h>
34 34
35static int eeh_pe_aux_size = 0;
35static LIST_HEAD(eeh_phb_pe); 36static LIST_HEAD(eeh_phb_pe);
36 37
37/** 38/**
39 * eeh_set_pe_aux_size - Set PE auxillary data size
40 * @size: PE auxillary data size
41 *
42 * Set PE auxillary data size
43 */
44void eeh_set_pe_aux_size(int size)
45{
46 if (size < 0)
47 return;
48
49 eeh_pe_aux_size = size;
50}
51
52/**
38 * eeh_pe_alloc - Allocate PE 53 * eeh_pe_alloc - Allocate PE
39 * @phb: PCI controller 54 * @phb: PCI controller
40 * @type: PE type 55 * @type: PE type
@@ -44,9 +59,16 @@ static LIST_HEAD(eeh_phb_pe);
44static struct eeh_pe *eeh_pe_alloc(struct pci_controller *phb, int type) 59static struct eeh_pe *eeh_pe_alloc(struct pci_controller *phb, int type)
45{ 60{
46 struct eeh_pe *pe; 61 struct eeh_pe *pe;
62 size_t alloc_size;
63
64 alloc_size = sizeof(struct eeh_pe);
65 if (eeh_pe_aux_size) {
66 alloc_size = ALIGN(alloc_size, cache_line_size());
67 alloc_size += eeh_pe_aux_size;
68 }
47 69
48 /* Allocate PHB PE */ 70 /* Allocate PHB PE */
49 pe = kzalloc(sizeof(struct eeh_pe), GFP_KERNEL); 71 pe = kzalloc(alloc_size, GFP_KERNEL);
50 if (!pe) return NULL; 72 if (!pe) return NULL;
51 73
52 /* Initialize PHB PE */ 74 /* Initialize PHB PE */
@@ -56,6 +78,8 @@ static struct eeh_pe *eeh_pe_alloc(struct pci_controller *phb, int type)
56 INIT_LIST_HEAD(&pe->child); 78 INIT_LIST_HEAD(&pe->child);
57 INIT_LIST_HEAD(&pe->edevs); 79 INIT_LIST_HEAD(&pe->edevs);
58 80
81 pe->data = (void *)pe + ALIGN(sizeof(struct eeh_pe),
82 cache_line_size());
59 return pe; 83 return pe;
60} 84}
61 85
@@ -179,7 +203,8 @@ void *eeh_pe_dev_traverse(struct eeh_pe *root,
179 void *ret; 203 void *ret;
180 204
181 if (!root) { 205 if (!root) {
182 pr_warning("%s: Invalid PE %p\n", __func__, root); 206 pr_warn("%s: Invalid PE %p\n",
207 __func__, root);
183 return NULL; 208 return NULL;
184 } 209 }
185 210
@@ -351,17 +376,6 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
351 pe->config_addr = edev->config_addr; 376 pe->config_addr = edev->config_addr;
352 377
353 /* 378 /*
354 * While doing PE reset, we probably hot-reset the
355 * upstream bridge. However, the PCI devices including
356 * the associated EEH devices might be removed when EEH
357 * core is doing recovery. So that won't safe to retrieve
358 * the bridge through downstream EEH device. We have to
359 * trace the parent PCI bus, then the upstream bridge.
360 */
361 if (eeh_probe_mode_dev())
362 pe->bus = eeh_dev_to_pci_dev(edev)->bus;
363
364 /*
365 * Put the new EEH PE into hierarchy tree. If the parent 379 * Put the new EEH PE into hierarchy tree. If the parent
366 * can't be found, the newly created PE will be attached 380 * can't be found, the newly created PE will be attached
367 * to PHB directly. Otherwise, we have to associate the 381 * to PHB directly. Otherwise, we have to associate the
@@ -802,53 +816,33 @@ void eeh_pe_restore_bars(struct eeh_pe *pe)
802 */ 816 */
803const char *eeh_pe_loc_get(struct eeh_pe *pe) 817const char *eeh_pe_loc_get(struct eeh_pe *pe)
804{ 818{
805 struct pci_controller *hose;
806 struct pci_bus *bus = eeh_pe_bus_get(pe); 819 struct pci_bus *bus = eeh_pe_bus_get(pe);
807 struct pci_dev *pdev; 820 struct device_node *dn = pci_bus_to_OF_node(bus);
808 struct device_node *dn; 821 const char *loc = NULL;
809 const char *loc;
810 822
811 if (!bus) 823 if (!dn)
812 return "N/A"; 824 goto out;
813 825
814 /* PHB PE or root PE ? */ 826 /* PHB PE or root PE ? */
815 if (pci_is_root_bus(bus)) { 827 if (pci_is_root_bus(bus)) {
816 hose = pci_bus_to_host(bus); 828 loc = of_get_property(dn, "ibm,loc-code", NULL);
817 loc = of_get_property(hose->dn, 829 if (!loc)
818 "ibm,loc-code", NULL); 830 loc = of_get_property(dn, "ibm,io-base-loc-code", NULL);
819 if (loc) 831 if (loc)
820 return loc; 832 goto out;
821 loc = of_get_property(hose->dn,
822 "ibm,io-base-loc-code", NULL);
823 if (loc)
824 return loc;
825
826 pdev = pci_get_slot(bus, 0x0);
827 } else {
828 pdev = bus->self;
829 }
830
831 if (!pdev) {
832 loc = "N/A";
833 goto out;
834 }
835 833
836 dn = pci_device_to_OF_node(pdev); 834 /* Check the root port */
837 if (!dn) { 835 dn = dn->child;
838 loc = "N/A"; 836 if (!dn)
839 goto out; 837 goto out;
840 } 838 }
841 839
842 loc = of_get_property(dn, "ibm,loc-code", NULL); 840 loc = of_get_property(dn, "ibm,loc-code", NULL);
843 if (!loc) 841 if (!loc)
844 loc = of_get_property(dn, "ibm,slot-location-code", NULL); 842 loc = of_get_property(dn, "ibm,slot-location-code", NULL);
845 if (!loc)
846 loc = "N/A";
847 843
848out: 844out:
849 if (pci_is_root_bus(bus) && pdev) 845 return loc ? loc : "N/A";
850 pci_dev_put(pdev);
851 return loc;
852} 846}
853 847
854/** 848/**
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 6528c5e2cc44..5bbd1bc8c3b0 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -482,16 +482,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_STCX_CHECKS_ADDRESS)
482 ld r8,KSP(r4) /* new stack pointer */ 482 ld r8,KSP(r4) /* new stack pointer */
483#ifdef CONFIG_PPC_BOOK3S 483#ifdef CONFIG_PPC_BOOK3S
484BEGIN_FTR_SECTION 484BEGIN_FTR_SECTION
485 BEGIN_FTR_SECTION_NESTED(95)
486 clrrdi r6,r8,28 /* get its ESID */ 485 clrrdi r6,r8,28 /* get its ESID */
487 clrrdi r9,r1,28 /* get current sp ESID */ 486 clrrdi r9,r1,28 /* get current sp ESID */
488 FTR_SECTION_ELSE_NESTED(95) 487FTR_SECTION_ELSE
489 clrrdi r6,r8,40 /* get its 1T ESID */ 488 clrrdi r6,r8,40 /* get its 1T ESID */
490 clrrdi r9,r1,40 /* get current sp 1T ESID */ 489 clrrdi r9,r1,40 /* get current sp 1T ESID */
491 ALT_MMU_FTR_SECTION_END_NESTED_IFCLR(MMU_FTR_1T_SEGMENT, 95) 490ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_1T_SEGMENT)
492FTR_SECTION_ELSE
493 b 2f
494ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_SLB)
495 clrldi. r0,r6,2 /* is new ESID c00000000? */ 491 clrldi. r0,r6,2 /* is new ESID c00000000? */
496 cmpd cr1,r6,r9 /* or is new ESID the same as current ESID? */ 492 cmpd cr1,r6,r9 /* or is new ESID the same as current ESID? */
497 cror eq,4*cr1+eq,eq 493 cror eq,4*cr1+eq,eq
@@ -919,6 +915,11 @@ restore_check_irq_replay:
919 addi r3,r1,STACK_FRAME_OVERHEAD; 915 addi r3,r1,STACK_FRAME_OVERHEAD;
920 bl do_IRQ 916 bl do_IRQ
921 b ret_from_except 917 b ret_from_except
9181: cmpwi cr0,r3,0xe60
919 bne 1f
920 addi r3,r1,STACK_FRAME_OVERHEAD;
921 bl handle_hmi_exception
922 b ret_from_except
9221: cmpwi cr0,r3,0x900 9231: cmpwi cr0,r3,0x900
923 bne 1f 924 bne 1f
924 addi r3,r1,STACK_FRAME_OVERHEAD; 925 addi r3,r1,STACK_FRAME_OVERHEAD;
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index a7d36b19221d..6144d5a6bfe7 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -188,10 +188,6 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
188data_access_pSeries: 188data_access_pSeries:
189 HMT_MEDIUM_PPR_DISCARD 189 HMT_MEDIUM_PPR_DISCARD
190 SET_SCRATCH0(r13) 190 SET_SCRATCH0(r13)
191BEGIN_FTR_SECTION
192 b data_access_check_stab
193data_access_not_stab:
194END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB)
195 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common, EXC_STD, 191 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common, EXC_STD,
196 KVMTEST, 0x300) 192 KVMTEST, 0x300)
197 193
@@ -339,7 +335,7 @@ emulation_assist_trampoline:
339hv_exception_trampoline: 335hv_exception_trampoline:
340 SET_SCRATCH0(r13) 336 SET_SCRATCH0(r13)
341 EXCEPTION_PROLOG_0(PACA_EXGEN) 337 EXCEPTION_PROLOG_0(PACA_EXGEN)
342 b hmi_exception_hv 338 b hmi_exception_early
343 339
344 . = 0xe80 340 . = 0xe80
345hv_doorbell_trampoline: 341hv_doorbell_trampoline:
@@ -514,34 +510,6 @@ machine_check_pSeries_0:
514 EXCEPTION_PROLOG_1(PACA_EXMC, KVMTEST, 0x200) 510 EXCEPTION_PROLOG_1(PACA_EXMC, KVMTEST, 0x200)
515 EXCEPTION_PROLOG_PSERIES_1(machine_check_common, EXC_STD) 511 EXCEPTION_PROLOG_PSERIES_1(machine_check_common, EXC_STD)
516 KVM_HANDLER_SKIP(PACA_EXMC, EXC_STD, 0x200) 512 KVM_HANDLER_SKIP(PACA_EXMC, EXC_STD, 0x200)
517
518 /* moved from 0x300 */
519data_access_check_stab:
520 GET_PACA(r13)
521 std r9,PACA_EXSLB+EX_R9(r13)
522 std r10,PACA_EXSLB+EX_R10(r13)
523 mfspr r10,SPRN_DAR
524 mfspr r9,SPRN_DSISR
525 srdi r10,r10,60
526 rlwimi r10,r9,16,0x20
527#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
528 lbz r9,HSTATE_IN_GUEST(r13)
529 rlwimi r10,r9,8,0x300
530#endif
531 mfcr r9
532 cmpwi r10,0x2c
533 beq do_stab_bolted_pSeries
534 mtcrf 0x80,r9
535 ld r9,PACA_EXSLB+EX_R9(r13)
536 ld r10,PACA_EXSLB+EX_R10(r13)
537 b data_access_not_stab
538do_stab_bolted_pSeries:
539 std r11,PACA_EXSLB+EX_R11(r13)
540 std r12,PACA_EXSLB+EX_R12(r13)
541 GET_SCRATCH0(r10)
542 std r10,PACA_EXSLB+EX_R13(r13)
543 EXCEPTION_PROLOG_PSERIES_1(do_stab_bolted, EXC_STD)
544
545 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300) 513 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300)
546 KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380) 514 KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380)
547 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x400) 515 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x400)
@@ -621,8 +589,64 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
621 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe22) 589 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe22)
622 STD_EXCEPTION_HV_OOL(0xe42, emulation_assist) 590 STD_EXCEPTION_HV_OOL(0xe42, emulation_assist)
623 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe42) 591 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe42)
624 STD_EXCEPTION_HV_OOL(0xe62, hmi_exception) /* need to flush cache ? */ 592 MASKABLE_EXCEPTION_HV_OOL(0xe62, hmi_exception)
625 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe62) 593 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe62)
594
595 .globl hmi_exception_early
596hmi_exception_early:
597 EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0xe60)
598 mr r10,r1 /* Save r1 */
599 ld r1,PACAEMERGSP(r13) /* Use emergency stack */
600 subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
601 std r9,_CCR(r1) /* save CR in stackframe */
602 mfspr r11,SPRN_HSRR0 /* Save HSRR0 */
603 std r11,_NIP(r1) /* save HSRR0 in stackframe */
604 mfspr r12,SPRN_HSRR1 /* Save SRR1 */
605 std r12,_MSR(r1) /* save SRR1 in stackframe */
606 std r10,0(r1) /* make stack chain pointer */
607 std r0,GPR0(r1) /* save r0 in stackframe */
608 std r10,GPR1(r1) /* save r1 in stackframe */
609 EXCEPTION_PROLOG_COMMON_2(PACA_EXGEN)
610 EXCEPTION_PROLOG_COMMON_3(0xe60)
611 addi r3,r1,STACK_FRAME_OVERHEAD
612 bl hmi_exception_realmode
613 /* Windup the stack. */
614 /* Clear MSR_RI before setting SRR0 and SRR1. */
615 li r0,MSR_RI
616 mfmsr r9 /* get MSR value */
617 andc r9,r9,r0
618 mtmsrd r9,1 /* Clear MSR_RI */
619 /* Move original HSRR0 and HSRR1 into the respective regs */
620 ld r9,_MSR(r1)
621 mtspr SPRN_HSRR1,r9
622 ld r3,_NIP(r1)
623 mtspr SPRN_HSRR0,r3
624 ld r9,_CTR(r1)
625 mtctr r9
626 ld r9,_XER(r1)
627 mtxer r9
628 ld r9,_LINK(r1)
629 mtlr r9
630 REST_GPR(0, r1)
631 REST_8GPRS(2, r1)
632 REST_GPR(10, r1)
633 ld r11,_CCR(r1)
634 mtcr r11
635 REST_GPR(11, r1)
636 REST_2GPRS(12, r1)
637 /* restore original r1. */
638 ld r1,GPR1(r1)
639
640 /*
641 * Go to virtual mode and pull the HMI event information from
642 * firmware.
643 */
644 .globl hmi_exception_after_realmode
645hmi_exception_after_realmode:
646 SET_SCRATCH0(r13)
647 EXCEPTION_PROLOG_0(PACA_EXGEN)
648 b hmi_exception_hv
649
626 MASKABLE_EXCEPTION_HV_OOL(0xe82, h_doorbell) 650 MASKABLE_EXCEPTION_HV_OOL(0xe82, h_doorbell)
627 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe82) 651 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe82)
628 652
@@ -643,6 +667,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
643 * - If it was a decrementer interrupt, we bump the dec to max and and return. 667 * - If it was a decrementer interrupt, we bump the dec to max and and return.
644 * - If it was a doorbell we return immediately since doorbells are edge 668 * - If it was a doorbell we return immediately since doorbells are edge
645 * triggered and won't automatically refire. 669 * triggered and won't automatically refire.
670 * - If it was a HMI we return immediately since we handled it in realmode
671 * and it won't refire.
646 * - else we hard disable and return. 672 * - else we hard disable and return.
647 * This is called with r10 containing the value to OR to the paca field. 673 * This is called with r10 containing the value to OR to the paca field.
648 */ 674 */
@@ -660,6 +686,8 @@ masked_##_H##interrupt: \
660 b 2f; \ 686 b 2f; \
6611: cmpwi r10,PACA_IRQ_DBELL; \ 6871: cmpwi r10,PACA_IRQ_DBELL; \
662 beq 2f; \ 688 beq 2f; \
689 cmpwi r10,PACA_IRQ_HMI; \
690 beq 2f; \
663 mfspr r10,SPRN_##_H##SRR1; \ 691 mfspr r10,SPRN_##_H##SRR1; \
664 rldicl r10,r10,48,1; /* clear MSR_EE */ \ 692 rldicl r10,r10,48,1; /* clear MSR_EE */ \
665 rotldi r10,r10,16; \ 693 rotldi r10,r10,16; \
@@ -799,7 +827,7 @@ kvmppc_skip_Hinterrupt:
799 STD_EXCEPTION_COMMON(0xd00, single_step, single_step_exception) 827 STD_EXCEPTION_COMMON(0xd00, single_step, single_step_exception)
800 STD_EXCEPTION_COMMON(0xe00, trap_0e, unknown_exception) 828 STD_EXCEPTION_COMMON(0xe00, trap_0e, unknown_exception)
801 STD_EXCEPTION_COMMON(0xe40, emulation_assist, emulation_assist_interrupt) 829 STD_EXCEPTION_COMMON(0xe40, emulation_assist, emulation_assist_interrupt)
802 STD_EXCEPTION_COMMON(0xe60, hmi_exception, unknown_exception) 830 STD_EXCEPTION_COMMON_ASYNC(0xe60, hmi_exception, handle_hmi_exception)
803#ifdef CONFIG_PPC_DOORBELL 831#ifdef CONFIG_PPC_DOORBELL
804 STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, doorbell_exception) 832 STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, doorbell_exception)
805#else 833#else
@@ -985,66 +1013,6 @@ ppc64_runlatch_on_trampoline:
985 b __ppc64_runlatch_on 1013 b __ppc64_runlatch_on
986 1014
987/* 1015/*
988 * Here we have detected that the kernel stack pointer is bad.
989 * R9 contains the saved CR, r13 points to the paca,
990 * r10 contains the (bad) kernel stack pointer,
991 * r11 and r12 contain the saved SRR0 and SRR1.
992 * We switch to using an emergency stack, save the registers there,
993 * and call kernel_bad_stack(), which panics.
994 */
995bad_stack:
996 ld r1,PACAEMERGSP(r13)
997 subi r1,r1,64+INT_FRAME_SIZE
998 std r9,_CCR(r1)
999 std r10,GPR1(r1)
1000 std r11,_NIP(r1)
1001 std r12,_MSR(r1)
1002 mfspr r11,SPRN_DAR
1003 mfspr r12,SPRN_DSISR
1004 std r11,_DAR(r1)
1005 std r12,_DSISR(r1)
1006 mflr r10
1007 mfctr r11
1008 mfxer r12
1009 std r10,_LINK(r1)
1010 std r11,_CTR(r1)
1011 std r12,_XER(r1)
1012 SAVE_GPR(0,r1)
1013 SAVE_GPR(2,r1)
1014 ld r10,EX_R3(r3)
1015 std r10,GPR3(r1)
1016 SAVE_GPR(4,r1)
1017 SAVE_4GPRS(5,r1)
1018 ld r9,EX_R9(r3)
1019 ld r10,EX_R10(r3)
1020 SAVE_2GPRS(9,r1)
1021 ld r9,EX_R11(r3)
1022 ld r10,EX_R12(r3)
1023 ld r11,EX_R13(r3)
1024 std r9,GPR11(r1)
1025 std r10,GPR12(r1)
1026 std r11,GPR13(r1)
1027BEGIN_FTR_SECTION
1028 ld r10,EX_CFAR(r3)
1029 std r10,ORIG_GPR3(r1)
1030END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
1031 SAVE_8GPRS(14,r1)
1032 SAVE_10GPRS(22,r1)
1033 lhz r12,PACA_TRAP_SAVE(r13)
1034 std r12,_TRAP(r1)
1035 addi r11,r1,INT_FRAME_SIZE
1036 std r11,0(r1)
1037 li r12,0
1038 std r12,0(r11)
1039 ld r2,PACATOC(r13)
1040 ld r11,exception_marker@toc(r2)
1041 std r12,RESULT(r1)
1042 std r11,STACK_FRAME_OVERHEAD-16(r1)
10431: addi r3,r1,STACK_FRAME_OVERHEAD
1044 bl kernel_bad_stack
1045 b 1b
1046
1047/*
1048 * Here r13 points to the paca, r9 contains the saved CR, 1016 * Here r13 points to the paca, r9 contains the saved CR,
1049 * SRR0 and SRR1 are saved in r11 and r12, 1017 * SRR0 and SRR1 are saved in r11 and r12,
1050 * r9 - r13 are saved in paca->exgen. 1018 * r9 - r13 are saved in paca->exgen.
@@ -1057,7 +1025,7 @@ data_access_common:
1057 mfspr r10,SPRN_DSISR 1025 mfspr r10,SPRN_DSISR
1058 stw r10,PACA_EXGEN+EX_DSISR(r13) 1026 stw r10,PACA_EXGEN+EX_DSISR(r13)
1059 EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN) 1027 EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
1060 DISABLE_INTS 1028 RECONCILE_IRQ_STATE(r10, r11)
1061 ld r12,_MSR(r1) 1029 ld r12,_MSR(r1)
1062 ld r3,PACA_EXGEN+EX_DAR(r13) 1030 ld r3,PACA_EXGEN+EX_DAR(r13)
1063 lwz r4,PACA_EXGEN+EX_DSISR(r13) 1031 lwz r4,PACA_EXGEN+EX_DSISR(r13)
@@ -1073,7 +1041,7 @@ h_data_storage_common:
1073 stw r10,PACA_EXGEN+EX_DSISR(r13) 1041 stw r10,PACA_EXGEN+EX_DSISR(r13)
1074 EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN) 1042 EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN)
1075 bl save_nvgprs 1043 bl save_nvgprs
1076 DISABLE_INTS 1044 RECONCILE_IRQ_STATE(r10, r11)
1077 addi r3,r1,STACK_FRAME_OVERHEAD 1045 addi r3,r1,STACK_FRAME_OVERHEAD
1078 bl unknown_exception 1046 bl unknown_exception
1079 b ret_from_except 1047 b ret_from_except
@@ -1082,7 +1050,7 @@ h_data_storage_common:
1082 .globl instruction_access_common 1050 .globl instruction_access_common
1083instruction_access_common: 1051instruction_access_common:
1084 EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN) 1052 EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
1085 DISABLE_INTS 1053 RECONCILE_IRQ_STATE(r10, r11)
1086 ld r12,_MSR(r1) 1054 ld r12,_MSR(r1)
1087 ld r3,_NIP(r1) 1055 ld r3,_NIP(r1)
1088 andis. r4,r12,0x5820 1056 andis. r4,r12,0x5820
@@ -1146,7 +1114,7 @@ slb_miss_fault:
1146 1114
1147unrecov_user_slb: 1115unrecov_user_slb:
1148 EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN) 1116 EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
1149 DISABLE_INTS 1117 RECONCILE_IRQ_STATE(r10, r11)
1150 bl save_nvgprs 1118 bl save_nvgprs
11511: addi r3,r1,STACK_FRAME_OVERHEAD 11191: addi r3,r1,STACK_FRAME_OVERHEAD
1152 bl unrecoverable_exception 1120 bl unrecoverable_exception
@@ -1169,7 +1137,7 @@ machine_check_common:
1169 stw r10,PACA_EXGEN+EX_DSISR(r13) 1137 stw r10,PACA_EXGEN+EX_DSISR(r13)
1170 EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) 1138 EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
1171 FINISH_NAP 1139 FINISH_NAP
1172 DISABLE_INTS 1140 RECONCILE_IRQ_STATE(r10, r11)
1173 ld r3,PACA_EXGEN+EX_DAR(r13) 1141 ld r3,PACA_EXGEN+EX_DAR(r13)
1174 lwz r4,PACA_EXGEN+EX_DSISR(r13) 1142 lwz r4,PACA_EXGEN+EX_DSISR(r13)
1175 std r3,_DAR(r1) 1143 std r3,_DAR(r1)
@@ -1192,7 +1160,7 @@ alignment_common:
1192 std r3,_DAR(r1) 1160 std r3,_DAR(r1)
1193 std r4,_DSISR(r1) 1161 std r4,_DSISR(r1)
1194 bl save_nvgprs 1162 bl save_nvgprs
1195 DISABLE_INTS 1163 RECONCILE_IRQ_STATE(r10, r11)
1196 addi r3,r1,STACK_FRAME_OVERHEAD 1164 addi r3,r1,STACK_FRAME_OVERHEAD
1197 bl alignment_exception 1165 bl alignment_exception
1198 b ret_from_except 1166 b ret_from_except
@@ -1202,7 +1170,7 @@ alignment_common:
1202program_check_common: 1170program_check_common:
1203 EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN) 1171 EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
1204 bl save_nvgprs 1172 bl save_nvgprs
1205 DISABLE_INTS 1173 RECONCILE_IRQ_STATE(r10, r11)
1206 addi r3,r1,STACK_FRAME_OVERHEAD 1174 addi r3,r1,STACK_FRAME_OVERHEAD
1207 bl program_check_exception 1175 bl program_check_exception
1208 b ret_from_except 1176 b ret_from_except
@@ -1213,7 +1181,7 @@ fp_unavailable_common:
1213 EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN) 1181 EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
1214 bne 1f /* if from user, just load it up */ 1182 bne 1f /* if from user, just load it up */
1215 bl save_nvgprs 1183 bl save_nvgprs
1216 DISABLE_INTS 1184 RECONCILE_IRQ_STATE(r10, r11)
1217 addi r3,r1,STACK_FRAME_OVERHEAD 1185 addi r3,r1,STACK_FRAME_OVERHEAD
1218 bl kernel_fp_unavailable_exception 1186 bl kernel_fp_unavailable_exception
1219 BUG_OPCODE 1187 BUG_OPCODE
@@ -1232,7 +1200,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
1232#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 1200#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
12332: /* User process was in a transaction */ 12012: /* User process was in a transaction */
1234 bl save_nvgprs 1202 bl save_nvgprs
1235 DISABLE_INTS 1203 RECONCILE_IRQ_STATE(r10, r11)
1236 addi r3,r1,STACK_FRAME_OVERHEAD 1204 addi r3,r1,STACK_FRAME_OVERHEAD
1237 bl fp_unavailable_tm 1205 bl fp_unavailable_tm
1238 b ret_from_except 1206 b ret_from_except
@@ -1258,7 +1226,7 @@ BEGIN_FTR_SECTION
1258#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 1226#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
12592: /* User process was in a transaction */ 12272: /* User process was in a transaction */
1260 bl save_nvgprs 1228 bl save_nvgprs
1261 DISABLE_INTS 1229 RECONCILE_IRQ_STATE(r10, r11)
1262 addi r3,r1,STACK_FRAME_OVERHEAD 1230 addi r3,r1,STACK_FRAME_OVERHEAD
1263 bl altivec_unavailable_tm 1231 bl altivec_unavailable_tm
1264 b ret_from_except 1232 b ret_from_except
@@ -1267,7 +1235,7 @@ BEGIN_FTR_SECTION
1267END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 1235END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
1268#endif 1236#endif
1269 bl save_nvgprs 1237 bl save_nvgprs
1270 DISABLE_INTS 1238 RECONCILE_IRQ_STATE(r10, r11)
1271 addi r3,r1,STACK_FRAME_OVERHEAD 1239 addi r3,r1,STACK_FRAME_OVERHEAD
1272 bl altivec_unavailable_exception 1240 bl altivec_unavailable_exception
1273 b ret_from_except 1241 b ret_from_except
@@ -1292,7 +1260,7 @@ BEGIN_FTR_SECTION
1292#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 1260#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
12932: /* User process was in a transaction */ 12612: /* User process was in a transaction */
1294 bl save_nvgprs 1262 bl save_nvgprs
1295 DISABLE_INTS 1263 RECONCILE_IRQ_STATE(r10, r11)
1296 addi r3,r1,STACK_FRAME_OVERHEAD 1264 addi r3,r1,STACK_FRAME_OVERHEAD
1297 bl vsx_unavailable_tm 1265 bl vsx_unavailable_tm
1298 b ret_from_except 1266 b ret_from_except
@@ -1301,7 +1269,7 @@ BEGIN_FTR_SECTION
1301END_FTR_SECTION_IFSET(CPU_FTR_VSX) 1269END_FTR_SECTION_IFSET(CPU_FTR_VSX)
1302#endif 1270#endif
1303 bl save_nvgprs 1271 bl save_nvgprs
1304 DISABLE_INTS 1272 RECONCILE_IRQ_STATE(r10, r11)
1305 addi r3,r1,STACK_FRAME_OVERHEAD 1273 addi r3,r1,STACK_FRAME_OVERHEAD
1306 bl vsx_unavailable_exception 1274 bl vsx_unavailable_exception
1307 b ret_from_except 1275 b ret_from_except
@@ -1338,12 +1306,6 @@ fwnmi_data_area:
1338 . = 0x8000 1306 . = 0x8000
1339#endif /* defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */ 1307#endif /* defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
1340 1308
1341/* Space for CPU0's segment table */
1342 .balign 4096
1343 .globl initial_stab
1344initial_stab:
1345 .space 4096
1346
1347#ifdef CONFIG_PPC_POWERNV 1309#ifdef CONFIG_PPC_POWERNV
1348_GLOBAL(opal_mc_secondary_handler) 1310_GLOBAL(opal_mc_secondary_handler)
1349 HMT_MEDIUM_PPR_DISCARD 1311 HMT_MEDIUM_PPR_DISCARD
@@ -1566,7 +1528,7 @@ slb_miss_realmode:
1566 1528
1567unrecov_slb: 1529unrecov_slb:
1568 EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB) 1530 EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
1569 DISABLE_INTS 1531 RECONCILE_IRQ_STATE(r10, r11)
1570 bl save_nvgprs 1532 bl save_nvgprs
15711: addi r3,r1,STACK_FRAME_OVERHEAD 15331: addi r3,r1,STACK_FRAME_OVERHEAD
1572 bl unrecoverable_exception 1534 bl unrecoverable_exception
@@ -1594,12 +1556,6 @@ do_hash_page:
1594 bne- handle_page_fault /* if not, try to insert a HPTE */ 1556 bne- handle_page_fault /* if not, try to insert a HPTE */
1595 andis. r0,r4,DSISR_DABRMATCH@h 1557 andis. r0,r4,DSISR_DABRMATCH@h
1596 bne- handle_dabr_fault 1558 bne- handle_dabr_fault
1597
1598BEGIN_FTR_SECTION
1599 andis. r0,r4,0x0020 /* Is it a segment table fault? */
1600 bne- do_ste_alloc /* If so handle it */
1601END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB)
1602
1603 CURRENT_THREAD_INFO(r11, r1) 1559 CURRENT_THREAD_INFO(r11, r1)
1604 lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */ 1560 lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */
1605 andis. r0,r0,NMI_MASK@h /* (i.e. an irq when soft-disabled) */ 1561 andis. r0,r0,NMI_MASK@h /* (i.e. an irq when soft-disabled) */
@@ -1681,113 +1637,62 @@ handle_dabr_fault:
1681 bl bad_page_fault 1637 bl bad_page_fault
1682 b ret_from_except 1638 b ret_from_except
1683 1639
1684 /* here we have a segment miss */
1685do_ste_alloc:
1686 bl ste_allocate /* try to insert stab entry */
1687 cmpdi r3,0
1688 bne- handle_page_fault
1689 b fast_exception_return
1690
1691/* 1640/*
1692 * r13 points to the PACA, r9 contains the saved CR, 1641 * Here we have detected that the kernel stack pointer is bad.
1642 * R9 contains the saved CR, r13 points to the paca,
1643 * r10 contains the (bad) kernel stack pointer,
1693 * r11 and r12 contain the saved SRR0 and SRR1. 1644 * r11 and r12 contain the saved SRR0 and SRR1.
1694 * r9 - r13 are saved in paca->exslb. 1645 * We switch to using an emergency stack, save the registers there,
1695 * We assume we aren't going to take any exceptions during this procedure. 1646 * and call kernel_bad_stack(), which panics.
1696 * We assume (DAR >> 60) == 0xc.
1697 */ 1647 */
1698 .align 7 1648bad_stack:
1699do_stab_bolted: 1649 ld r1,PACAEMERGSP(r13)
1700 stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ 1650 subi r1,r1,64+INT_FRAME_SIZE
1701 std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */ 1651 std r9,_CCR(r1)
1702 mfspr r11,SPRN_DAR /* ea */ 1652 std r10,GPR1(r1)
1703 1653 std r11,_NIP(r1)
1704 /* 1654 std r12,_MSR(r1)
1705 * check for bad kernel/user address 1655 mfspr r11,SPRN_DAR
1706 * (ea & ~REGION_MASK) >= PGTABLE_RANGE 1656 mfspr r12,SPRN_DSISR
1707 */ 1657 std r11,_DAR(r1)
1708 rldicr. r9,r11,4,(63 - 46 - 4) 1658 std r12,_DSISR(r1)
1709 li r9,0 /* VSID = 0 for bad address */ 1659 mflr r10
1710 bne- 0f 1660 mfctr r11
1711 1661 mfxer r12
1712 /* 1662 std r10,_LINK(r1)
1713 * Calculate VSID: 1663 std r11,_CTR(r1)
1714 * This is the kernel vsid, we take the top for context from 1664 std r12,_XER(r1)
1715 * the range. context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1 1665 SAVE_GPR(0,r1)
1716 * Here we know that (ea >> 60) == 0xc 1666 SAVE_GPR(2,r1)
1717 */ 1667 ld r10,EX_R3(r3)
1718 lis r9,(MAX_USER_CONTEXT + 1)@ha 1668 std r10,GPR3(r1)
1719 addi r9,r9,(MAX_USER_CONTEXT + 1)@l 1669 SAVE_GPR(4,r1)
1720 1670 SAVE_4GPRS(5,r1)
1721 srdi r10,r11,SID_SHIFT 1671 ld r9,EX_R9(r3)
1722 rldimi r10,r9,ESID_BITS,0 /* proto vsid */ 1672 ld r10,EX_R10(r3)
1723 ASM_VSID_SCRAMBLE(r10, r9, 256M) 1673 SAVE_2GPRS(9,r1)
1724 rldic r9,r10,12,16 /* r9 = vsid << 12 */ 1674 ld r9,EX_R11(r3)
1725 1675 ld r10,EX_R12(r3)
17260: 1676 ld r11,EX_R13(r3)
1727 /* Hash to the primary group */ 1677 std r9,GPR11(r1)
1728 ld r10,PACASTABVIRT(r13) 1678 std r10,GPR12(r1)
1729 srdi r11,r11,SID_SHIFT 1679 std r11,GPR13(r1)
1730 rldimi r10,r11,7,52 /* r10 = first ste of the group */ 1680BEGIN_FTR_SECTION
1731 1681 ld r10,EX_CFAR(r3)
1732 /* Search the primary group for a free entry */ 1682 std r10,ORIG_GPR3(r1)
17331: ld r11,0(r10) /* Test valid bit of the current ste */ 1683END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
1734 andi. r11,r11,0x80 1684 SAVE_8GPRS(14,r1)
1735 beq 2f 1685 SAVE_10GPRS(22,r1)
1736 addi r10,r10,16 1686 lhz r12,PACA_TRAP_SAVE(r13)
1737 andi. r11,r10,0x70 1687 std r12,_TRAP(r1)
1738 bne 1b 1688 addi r11,r1,INT_FRAME_SIZE
1739 1689 std r11,0(r1)
1740 /* Stick for only searching the primary group for now. */ 1690 li r12,0
1741 /* At least for now, we use a very simple random castout scheme */ 1691 std r12,0(r11)
1742 /* Use the TB as a random number ; OR in 1 to avoid entry 0 */ 1692 ld r2,PACATOC(r13)
1743 mftb r11 1693 ld r11,exception_marker@toc(r2)
1744 rldic r11,r11,4,57 /* r11 = (r11 << 4) & 0x70 */ 1694 std r12,RESULT(r1)
1745 ori r11,r11,0x10 1695 std r11,STACK_FRAME_OVERHEAD-16(r1)
1746 16961: addi r3,r1,STACK_FRAME_OVERHEAD
1747 /* r10 currently points to an ste one past the group of interest */ 1697 bl kernel_bad_stack
1748 /* make it point to the randomly selected entry */ 1698 b 1b
1749 subi r10,r10,128
1750 or r10,r10,r11 /* r10 is the entry to invalidate */
1751
1752 isync /* mark the entry invalid */
1753 ld r11,0(r10)
1754 rldicl r11,r11,56,1 /* clear the valid bit */
1755 rotldi r11,r11,8
1756 std r11,0(r10)
1757 sync
1758
1759 clrrdi r11,r11,28 /* Get the esid part of the ste */
1760 slbie r11
1761
17622: std r9,8(r10) /* Store the vsid part of the ste */
1763 eieio
1764
1765 mfspr r11,SPRN_DAR /* Get the new esid */
1766 clrrdi r11,r11,28 /* Permits a full 32b of ESID */
1767 ori r11,r11,0x90 /* Turn on valid and kp */
1768 std r11,0(r10) /* Put new entry back into the stab */
1769
1770 sync
1771
1772 /* All done -- return from exception. */
1773 lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
1774 ld r11,PACA_EXSLB+EX_SRR0(r13) /* get saved SRR0 */
1775
1776 andi. r10,r12,MSR_RI
1777 beq- unrecov_slb
1778
1779 mtcrf 0x80,r9 /* restore CR */
1780
1781 mfmsr r10
1782 clrrdi r10,r10,2
1783 mtmsrd r10,1
1784
1785 mtspr SPRN_SRR0,r11
1786 mtspr SPRN_SRR1,r12
1787 ld r9,PACA_EXSLB+EX_R9(r13)
1788 ld r10,PACA_EXSLB+EX_R10(r13)
1789 ld r11,PACA_EXSLB+EX_R11(r13)
1790 ld r12,PACA_EXSLB+EX_R12(r13)
1791 ld r13,PACA_EXSLB+EX_R13(r13)
1792 rfid
1793 b . /* prevent speculative execution */
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index a95145d7f61b..d48125d0c048 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -180,6 +180,28 @@ exception_marker:
180#include "exceptions-64s.S" 180#include "exceptions-64s.S"
181#endif 181#endif
182 182
183#ifdef CONFIG_PPC_BOOK3E
184_GLOBAL(fsl_secondary_thread_init)
185 /* Enable branch prediction */
186 lis r3,BUCSR_INIT@h
187 ori r3,r3,BUCSR_INIT@l
188 mtspr SPRN_BUCSR,r3
189 isync
190
191 /*
192 * Fix PIR to match the linear numbering in the device tree.
193 *
194 * On e6500, the reset value of PIR uses the low three bits for
195 * the thread within a core, and the upper bits for the core
196 * number. There are two threads per core, so shift everything
197 * but the low bit right by two bits so that the cpu numbering is
198 * continuous.
199 */
200 mfspr r3, SPRN_PIR
201 rlwimi r3, r3, 30, 2, 30
202 mtspr SPRN_PIR, r3
203#endif
204
183_GLOBAL(generic_secondary_thread_init) 205_GLOBAL(generic_secondary_thread_init)
184 mr r24,r3 206 mr r24,r3
185 207
@@ -618,7 +640,7 @@ __secondary_start:
618 addi r14,r14,THREAD_SIZE-STACK_FRAME_OVERHEAD 640 addi r14,r14,THREAD_SIZE-STACK_FRAME_OVERHEAD
619 std r14,PACAKSAVE(r13) 641 std r14,PACAKSAVE(r13)
620 642
621 /* Do early setup for that CPU (stab, slb, hash table pointer) */ 643 /* Do early setup for that CPU (SLB and hash table pointer) */
622 bl early_setup_secondary 644 bl early_setup_secondary
623 645
624 /* 646 /*
@@ -771,8 +793,10 @@ start_here_multiplatform:
771 li r0,0 793 li r0,0
772 stdu r0,-STACK_FRAME_OVERHEAD(r1) 794 stdu r0,-STACK_FRAME_OVERHEAD(r1)
773 795
774 /* Do very early kernel initializations, including initial hash table, 796 /*
775 * stab and slb setup before we turn on relocation. */ 797 * Do very early kernel initializations, including initial hash table
798 * and SLB setup before we turn on relocation.
799 */
776 800
777 /* Restore parameters passed from prom_init/kexec */ 801 /* Restore parameters passed from prom_init/kexec */
778 mr r3,r31 802 mr r3,r31
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S
index 5cf3d367190d..be05841396cf 100644
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -135,17 +135,68 @@ _GLOBAL(power7_sleep)
135 b power7_powersave_common 135 b power7_powersave_common
136 /* No return */ 136 /* No return */
137 137
138/*
139 * Make opal call in realmode. This is a generic function to be called
140 * from realmode from reset vector. It handles endianess.
141 *
142 * r13 - paca pointer
143 * r1 - stack pointer
144 * r3 - opal token
145 */
146opal_call_realmode:
147 mflr r12
148 std r12,_LINK(r1)
149 ld r2,PACATOC(r13)
150 /* Set opal return address */
151 LOAD_REG_ADDR(r0,return_from_opal_call)
152 mtlr r0
153 /* Handle endian-ness */
154 li r0,MSR_LE
155 mfmsr r12
156 andc r12,r12,r0
157 mtspr SPRN_HSRR1,r12
158 mr r0,r3 /* Move opal token to r0 */
159 LOAD_REG_ADDR(r11,opal)
160 ld r12,8(r11)
161 ld r2,0(r11)
162 mtspr SPRN_HSRR0,r12
163 hrfid
164
165return_from_opal_call:
166 FIXUP_ENDIAN
167 ld r0,_LINK(r1)
168 mtlr r0
169 blr
170
171#define CHECK_HMI_INTERRUPT \
172 mfspr r0,SPRN_SRR1; \
173BEGIN_FTR_SECTION_NESTED(66); \
174 rlwinm r0,r0,45-31,0xf; /* extract wake reason field (P8) */ \
175FTR_SECTION_ELSE_NESTED(66); \
176 rlwinm r0,r0,45-31,0xe; /* P7 wake reason field is 3 bits */ \
177ALT_FTR_SECTION_END_NESTED_IFSET(CPU_FTR_ARCH_207S, 66); \
178 cmpwi r0,0xa; /* Hypervisor maintenance ? */ \
179 bne 20f; \
180 /* Invoke opal call to handle hmi */ \
181 ld r2,PACATOC(r13); \
182 ld r1,PACAR1(r13); \
183 std r3,ORIG_GPR3(r1); /* Save original r3 */ \
184 li r3,OPAL_HANDLE_HMI; /* Pass opal token argument*/ \
185 bl opal_call_realmode; \
186 ld r3,ORIG_GPR3(r1); /* Restore original r3 */ \
18720: nop;
188
189
138_GLOBAL(power7_wakeup_tb_loss) 190_GLOBAL(power7_wakeup_tb_loss)
139 ld r2,PACATOC(r13); 191 ld r2,PACATOC(r13);
140 ld r1,PACAR1(r13) 192 ld r1,PACAR1(r13)
141 193
194BEGIN_FTR_SECTION
195 CHECK_HMI_INTERRUPT
196END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
142 /* Time base re-sync */ 197 /* Time base re-sync */
143 li r0,OPAL_RESYNC_TIMEBASE 198 li r3,OPAL_RESYNC_TIMEBASE
144 LOAD_REG_ADDR(r11,opal); 199 bl opal_call_realmode;
145 ld r12,8(r11);
146 ld r2,0(r11);
147 mtctr r12
148 bctrl
149 200
150 /* TODO: Check r3 for failure */ 201 /* TODO: Check r3 for failure */
151 202
@@ -163,6 +214,9 @@ _GLOBAL(power7_wakeup_tb_loss)
163 214
164_GLOBAL(power7_wakeup_loss) 215_GLOBAL(power7_wakeup_loss)
165 ld r1,PACAR1(r13) 216 ld r1,PACAR1(r13)
217BEGIN_FTR_SECTION
218 CHECK_HMI_INTERRUPT
219END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
166 REST_NVGPRS(r1) 220 REST_NVGPRS(r1)
167 REST_GPR(2, r1) 221 REST_GPR(2, r1)
168 ld r3,_CCR(r1) 222 ld r3,_CCR(r1)
@@ -178,6 +232,9 @@ _GLOBAL(power7_wakeup_noloss)
178 lbz r0,PACA_NAPSTATELOST(r13) 232 lbz r0,PACA_NAPSTATELOST(r13)
179 cmpwi r0,0 233 cmpwi r0,0
180 bne power7_wakeup_loss 234 bne power7_wakeup_loss
235BEGIN_FTR_SECTION
236 CHECK_HMI_INTERRUPT
237END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
181 ld r1,PACAR1(r13) 238 ld r1,PACAR1(r13)
182 ld r4,_MSR(r1) 239 ld r4,_MSR(r1)
183 ld r5,_NIP(r1) 240 ld r5,_NIP(r1)
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 88e3ec6e1d96..f84f799babb1 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -1037,7 +1037,7 @@ int iommu_tce_build(struct iommu_table *tbl, unsigned long entry,
1037 1037
1038 /* if (unlikely(ret)) 1038 /* if (unlikely(ret))
1039 pr_err("iommu_tce: %s failed on hwaddr=%lx ioba=%lx kva=%lx ret=%d\n", 1039 pr_err("iommu_tce: %s failed on hwaddr=%lx ioba=%lx kva=%lx ret=%d\n",
1040 __func__, hwaddr, entry << IOMMU_PAGE_SHIFT(tbl), 1040 __func__, hwaddr, entry << tbl->it_page_shift,
1041 hwaddr, ret); */ 1041 hwaddr, ret); */
1042 1042
1043 return ret; 1043 return ret;
@@ -1056,7 +1056,7 @@ int iommu_put_tce_user_mode(struct iommu_table *tbl, unsigned long entry,
1056 direction != DMA_TO_DEVICE, &page); 1056 direction != DMA_TO_DEVICE, &page);
1057 if (unlikely(ret != 1)) { 1057 if (unlikely(ret != 1)) {
1058 /* pr_err("iommu_tce: get_user_pages_fast failed tce=%lx ioba=%lx ret=%d\n", 1058 /* pr_err("iommu_tce: get_user_pages_fast failed tce=%lx ioba=%lx ret=%d\n",
1059 tce, entry << IOMMU_PAGE_SHIFT(tbl), ret); */ 1059 tce, entry << tbl->it_page_shift, ret); */
1060 return -EFAULT; 1060 return -EFAULT;
1061 } 1061 }
1062 hwaddr = (unsigned long) page_address(page) + offset; 1062 hwaddr = (unsigned long) page_address(page) + offset;
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 248ee7e5bebd..4c5891de162e 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -189,6 +189,11 @@ notrace unsigned int __check_irq_replay(void)
189 } 189 }
190#endif /* CONFIG_PPC_BOOK3E */ 190#endif /* CONFIG_PPC_BOOK3E */
191 191
192 /* Check if an hypervisor Maintenance interrupt happened */
193 local_paca->irq_happened &= ~PACA_IRQ_HMI;
194 if (happened & PACA_IRQ_HMI)
195 return 0xe60;
196
192 /* There should be nothing left ! */ 197 /* There should be nothing left ! */
193 BUG_ON(local_paca->irq_happened != 0); 198 BUG_ON(local_paca->irq_happened != 0);
194 199
@@ -377,6 +382,14 @@ int arch_show_interrupts(struct seq_file *p, int prec)
377 seq_printf(p, "%10u ", per_cpu(irq_stat, j).mce_exceptions); 382 seq_printf(p, "%10u ", per_cpu(irq_stat, j).mce_exceptions);
378 seq_printf(p, " Machine check exceptions\n"); 383 seq_printf(p, " Machine check exceptions\n");
379 384
385 if (cpu_has_feature(CPU_FTR_HVMODE)) {
386 seq_printf(p, "%*s: ", prec, "HMI");
387 for_each_online_cpu(j)
388 seq_printf(p, "%10u ",
389 per_cpu(irq_stat, j).hmi_exceptions);
390 seq_printf(p, " Hypervisor Maintenance Interrupts\n");
391 }
392
380#ifdef CONFIG_PPC_DOORBELL 393#ifdef CONFIG_PPC_DOORBELL
381 if (cpu_has_feature(CPU_FTR_DBELL)) { 394 if (cpu_has_feature(CPU_FTR_DBELL)) {
382 seq_printf(p, "%*s: ", prec, "DBL"); 395 seq_printf(p, "%*s: ", prec, "DBL");
@@ -400,6 +413,7 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
400 sum += per_cpu(irq_stat, cpu).mce_exceptions; 413 sum += per_cpu(irq_stat, cpu).mce_exceptions;
401 sum += per_cpu(irq_stat, cpu).spurious_irqs; 414 sum += per_cpu(irq_stat, cpu).spurious_irqs;
402 sum += per_cpu(irq_stat, cpu).timer_irqs_others; 415 sum += per_cpu(irq_stat, cpu).timer_irqs_others;
416 sum += per_cpu(irq_stat, cpu).hmi_exceptions;
403#ifdef CONFIG_PPC_DOORBELL 417#ifdef CONFIG_PPC_DOORBELL
404 sum += per_cpu(irq_stat, cpu).doorbell_irqs; 418 sum += per_cpu(irq_stat, cpu).doorbell_irqs;
405#endif 419#endif
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index be99774d3f44..bf44ae962ab8 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1095,6 +1095,23 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
1095 return 0; 1095 return 0;
1096} 1096}
1097 1097
1098static void setup_ksp_vsid(struct task_struct *p, unsigned long sp)
1099{
1100#ifdef CONFIG_PPC_STD_MMU_64
1101 unsigned long sp_vsid;
1102 unsigned long llp = mmu_psize_defs[mmu_linear_psize].sllp;
1103
1104 if (mmu_has_feature(MMU_FTR_1T_SEGMENT))
1105 sp_vsid = get_kernel_vsid(sp, MMU_SEGSIZE_1T)
1106 << SLB_VSID_SHIFT_1T;
1107 else
1108 sp_vsid = get_kernel_vsid(sp, MMU_SEGSIZE_256M)
1109 << SLB_VSID_SHIFT;
1110 sp_vsid |= SLB_VSID_KERNEL | llp;
1111 p->thread.ksp_vsid = sp_vsid;
1112#endif
1113}
1114
1098/* 1115/*
1099 * Copy a thread.. 1116 * Copy a thread..
1100 */ 1117 */
@@ -1174,21 +1191,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
1174 p->thread.vr_save_area = NULL; 1191 p->thread.vr_save_area = NULL;
1175#endif 1192#endif
1176 1193
1177#ifdef CONFIG_PPC_STD_MMU_64 1194 setup_ksp_vsid(p, sp);
1178 if (mmu_has_feature(MMU_FTR_SLB)) {
1179 unsigned long sp_vsid;
1180 unsigned long llp = mmu_psize_defs[mmu_linear_psize].sllp;
1181 1195
1182 if (mmu_has_feature(MMU_FTR_1T_SEGMENT))
1183 sp_vsid = get_kernel_vsid(sp, MMU_SEGSIZE_1T)
1184 << SLB_VSID_SHIFT_1T;
1185 else
1186 sp_vsid = get_kernel_vsid(sp, MMU_SEGSIZE_256M)
1187 << SLB_VSID_SHIFT;
1188 sp_vsid |= SLB_VSID_KERNEL | llp;
1189 p->thread.ksp_vsid = sp_vsid;
1190 }
1191#endif /* CONFIG_PPC_STD_MMU_64 */
1192#ifdef CONFIG_PPC64 1196#ifdef CONFIG_PPC64
1193 if (cpu_has_feature(CPU_FTR_DSCR)) { 1197 if (cpu_has_feature(CPU_FTR_DSCR)) {
1194 p->thread.dscr_inherit = current->thread.dscr_inherit; 1198 p->thread.dscr_inherit = current->thread.dscr_inherit;
@@ -1577,7 +1581,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
1577 struct pt_regs *regs = (struct pt_regs *) 1581 struct pt_regs *regs = (struct pt_regs *)
1578 (sp + STACK_FRAME_OVERHEAD); 1582 (sp + STACK_FRAME_OVERHEAD);
1579 lr = regs->link; 1583 lr = regs->link;
1580 printk("--- Exception: %lx at %pS\n LR = %pS\n", 1584 printk("--- interrupt: %lx at %pS\n LR = %pS\n",
1581 regs->trap, (void *)regs->nip, (void *)lr); 1585 regs->trap, (void *)regs->nip, (void *)lr);
1582 firstframe = 1; 1586 firstframe = 1;
1583 } 1587 }
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index b694b0730971..1a3b1055f5eb 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -155,7 +155,6 @@ static struct ibm_pa_feature {
155} ibm_pa_features[] __initdata = { 155} ibm_pa_features[] __initdata = {
156 {0, 0, PPC_FEATURE_HAS_MMU, 0, 0, 0}, 156 {0, 0, PPC_FEATURE_HAS_MMU, 0, 0, 0},
157 {0, 0, PPC_FEATURE_HAS_FPU, 0, 1, 0}, 157 {0, 0, PPC_FEATURE_HAS_FPU, 0, 1, 0},
158 {0, MMU_FTR_SLB, 0, 0, 2, 0},
159 {CPU_FTR_CTRL, 0, 0, 0, 3, 0}, 158 {CPU_FTR_CTRL, 0, 0, 0, 3, 0},
160 {CPU_FTR_NOEXECUTE, 0, 0, 0, 6, 0}, 159 {CPU_FTR_NOEXECUTE, 0, 0, 0, 6, 0},
161 {CPU_FTR_NODSISRALIGN, 0, 0, 1, 1, 1}, 160 {CPU_FTR_NODSISRALIGN, 0, 0, 1, 1, 1},
@@ -309,12 +308,10 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
309 308
310 /* Get physical cpuid */ 309 /* Get physical cpuid */
311 intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len); 310 intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len);
312 if (intserv) { 311 if (!intserv)
313 nthreads = len / sizeof(int); 312 intserv = of_get_flat_dt_prop(node, "reg", &len);
314 } else { 313
315 intserv = of_get_flat_dt_prop(node, "reg", NULL); 314 nthreads = len / sizeof(int);
316 nthreads = 1;
317 }
318 315
319 /* 316 /*
320 * Now see if any of these threads match our boot cpu. 317 * Now see if any of these threads match our boot cpu.
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index e5b022c55ccd..1b0e26013a62 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -456,18 +456,20 @@ void __init smp_setup_cpu_maps(void)
456 intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", 456 intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s",
457 &len); 457 &len);
458 if (intserv) { 458 if (intserv) {
459 nthreads = len / sizeof(int);
460 DBG(" ibm,ppc-interrupt-server#s -> %d threads\n", 459 DBG(" ibm,ppc-interrupt-server#s -> %d threads\n",
461 nthreads); 460 nthreads);
462 } else { 461 } else {
463 DBG(" no ibm,ppc-interrupt-server#s -> 1 thread\n"); 462 DBG(" no ibm,ppc-interrupt-server#s -> 1 thread\n");
464 intserv = of_get_property(dn, "reg", NULL); 463 intserv = of_get_property(dn, "reg", &len);
465 if (!intserv) { 464 if (!intserv) {
466 cpu_be = cpu_to_be32(cpu); 465 cpu_be = cpu_to_be32(cpu);
467 intserv = &cpu_be; /* assume logical == phys */ 466 intserv = &cpu_be; /* assume logical == phys */
467 len = 4;
468 } 468 }
469 } 469 }
470 470
471 nthreads = len / sizeof(int);
472
471 for (j = 0; j < nthreads && cpu < nr_cpu_ids; j++) { 473 for (j = 0; j < nthreads && cpu < nr_cpu_ids; j++) {
472 bool avail; 474 bool avail;
473 475
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index ee082d771178..d0225572faa1 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -201,7 +201,11 @@ static void cpu_ready_for_interrupts(void)
201 /* Set IR and DR in PACA MSR */ 201 /* Set IR and DR in PACA MSR */
202 get_paca()->kernel_msr = MSR_KERNEL; 202 get_paca()->kernel_msr = MSR_KERNEL;
203 203
204 /* Enable AIL if supported */ 204 /*
205 * Enable AIL if supported, and we are in hypervisor mode. If we are
206 * not in hypervisor mode, we enable relocation-on interrupts later
207 * in pSeries_setup_arch() using the H_SET_MODE hcall.
208 */
205 if (cpu_has_feature(CPU_FTR_HVMODE) && 209 if (cpu_has_feature(CPU_FTR_HVMODE) &&
206 cpu_has_feature(CPU_FTR_ARCH_207S)) { 210 cpu_has_feature(CPU_FTR_ARCH_207S)) {
207 unsigned long lpcr = mfspr(SPRN_LPCR); 211 unsigned long lpcr = mfspr(SPRN_LPCR);
@@ -507,7 +511,11 @@ void __init setup_system(void)
507 check_smt_enabled(); 511 check_smt_enabled();
508 setup_tlb_core_data(); 512 setup_tlb_core_data();
509 513
510#ifdef CONFIG_SMP 514 /*
515 * Freescale Book3e parts spin in a loop provided by firmware,
516 * so smp_release_cpus() does nothing for them
517 */
518#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_FSL_BOOK3E)
511 /* Release secondary cpus out of their spinloops at 0x60 now that 519 /* Release secondary cpus out of their spinloops at 0x60 now that
512 * we can map physical -> logical CPU ids 520 * we can map physical -> logical CPU ids
513 */ 521 */
@@ -673,9 +681,6 @@ void __init setup_arch(char **cmdline_p)
673 exc_lvl_early_init(); 681 exc_lvl_early_init();
674 emergency_stack_init(); 682 emergency_stack_init();
675 683
676#ifdef CONFIG_PPC_STD_MMU_64
677 stabs_alloc();
678#endif
679 /* set up the bootmem stuff with available memory */ 684 /* set up the bootmem stuff with available memory */
680 do_init_bootmem(); 685 do_init_bootmem();
681 sparse_init(); 686 sparse_init();
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
index 895c50ca943c..7ab5d434e2ee 100644
--- a/arch/powerpc/kernel/systbl.S
+++ b/arch/powerpc/kernel/systbl.S
@@ -39,9 +39,6 @@
39.section .rodata,"a" 39.section .rodata,"a"
40 40
41#ifdef CONFIG_PPC64 41#ifdef CONFIG_PPC64
42#define sys_sigpending sys_ni_syscall
43#define sys_old_getrlimit sys_ni_syscall
44
45 .p2align 3 42 .p2align 3
46#endif 43#endif
47 44
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 239f1cde3fff..0dc43f9932cf 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -302,6 +302,16 @@ long machine_check_early(struct pt_regs *regs)
302 return handled; 302 return handled;
303} 303}
304 304
305long hmi_exception_realmode(struct pt_regs *regs)
306{
307 __get_cpu_var(irq_stat).hmi_exceptions++;
308
309 if (ppc_md.hmi_exception_early)
310 ppc_md.hmi_exception_early(regs);
311
312 return 0;
313}
314
305#endif 315#endif
306 316
307/* 317/*
@@ -609,7 +619,7 @@ int machine_check_e500(struct pt_regs *regs)
609 if (reason & MCSR_BUS_RBERR) 619 if (reason & MCSR_BUS_RBERR)
610 printk("Bus - Read Data Bus Error\n"); 620 printk("Bus - Read Data Bus Error\n");
611 if (reason & MCSR_BUS_WBERR) 621 if (reason & MCSR_BUS_WBERR)
612 printk("Bus - Read Data Bus Error\n"); 622 printk("Bus - Write Data Bus Error\n");
613 if (reason & MCSR_BUS_IPERR) 623 if (reason & MCSR_BUS_IPERR)
614 printk("Bus - Instruction Parity Error\n"); 624 printk("Bus - Instruction Parity Error\n");
615 if (reason & MCSR_BUS_RPERR) 625 if (reason & MCSR_BUS_RPERR)
@@ -738,6 +748,20 @@ void SMIException(struct pt_regs *regs)
738 die("System Management Interrupt", regs, SIGABRT); 748 die("System Management Interrupt", regs, SIGABRT);
739} 749}
740 750
751void handle_hmi_exception(struct pt_regs *regs)
752{
753 struct pt_regs *old_regs;
754
755 old_regs = set_irq_regs(regs);
756 irq_enter();
757
758 if (ppc_md.handle_hmi_exception)
759 ppc_md.handle_hmi_exception(regs);
760
761 irq_exit();
762 set_irq_regs(old_regs);
763}
764
741void unknown_exception(struct pt_regs *regs) 765void unknown_exception(struct pt_regs *regs)
742{ 766{
743 enum ctx_state prev_state = exception_enter(); 767 enum ctx_state prev_state = exception_enter();
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 558a67df8126..7faf8fd05738 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -159,6 +159,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
159 cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL 159 cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
160BEGIN_FTR_SECTION 160BEGIN_FTR_SECTION
161 beq 11f 161 beq 11f
162 cmpwi cr2, r12, BOOK3S_INTERRUPT_HMI
163 beq cr2, 14f /* HMI check */
162END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) 164END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
163 165
164 /* RFI into the highmem handler, or branch to interrupt handler */ 166 /* RFI into the highmem handler, or branch to interrupt handler */
@@ -179,6 +181,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
179 181
18013: b machine_check_fwnmi 18213: b machine_check_fwnmi
181 183
18414: mtspr SPRN_HSRR0, r8
185 mtspr SPRN_HSRR1, r7
186 b hmi_exception_after_realmode
187
182kvmppc_primary_no_guest: 188kvmppc_primary_no_guest:
183 /* We handle this much like a ceded vcpu */ 189 /* We handle this much like a ceded vcpu */
184 /* set our bit in napping_threads */ 190 /* set our bit in napping_threads */
diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S
index 0860ee46013c..f09899e35991 100644
--- a/arch/powerpc/lib/copyuser_64.S
+++ b/arch/powerpc/lib/copyuser_64.S
@@ -461,8 +461,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
461/* 461/*
462 * Routine to copy a whole page of data, optimized for POWER4. 462 * Routine to copy a whole page of data, optimized for POWER4.
463 * On POWER4 it is more than 50% faster than the simple loop 463 * On POWER4 it is more than 50% faster than the simple loop
464 * above (following the .Ldst_aligned label) but it runs slightly 464 * above (following the .Ldst_aligned label).
465 * slower on POWER3.
466 */ 465 */
467.Lcopy_page_4K: 466.Lcopy_page_4K:
468 std r31,-32(1) 467 std r31,-32(1)
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 51230ee6a407..d0130fff20e5 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -13,9 +13,7 @@ obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o tlb_nohash.o \
13 tlb_nohash_low.o 13 tlb_nohash_low.o
14obj-$(CONFIG_PPC_BOOK3E) += tlb_low_$(CONFIG_WORD_SIZE)e.o 14obj-$(CONFIG_PPC_BOOK3E) += tlb_low_$(CONFIG_WORD_SIZE)e.o
15hash64-$(CONFIG_PPC_NATIVE) := hash_native_64.o 15hash64-$(CONFIG_PPC_NATIVE) := hash_native_64.o
16obj-$(CONFIG_PPC_STD_MMU_64) += hash_utils_64.o \ 16obj-$(CONFIG_PPC_STD_MMU_64) += hash_utils_64.o slb_low.o slb.o $(hash64-y)
17 slb_low.o slb.o stab.o \
18 $(hash64-y)
19obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o 17obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o
20obj-$(CONFIG_PPC_STD_MMU) += hash_low_$(CONFIG_WORD_SIZE).o \ 18obj-$(CONFIG_PPC_STD_MMU) += hash_low_$(CONFIG_WORD_SIZE).o \
21 tlb_hash$(CONFIG_WORD_SIZE).o \ 19 tlb_hash$(CONFIG_WORD_SIZE).o \
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 88fdd9d25077..daee7f4e5a14 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -243,7 +243,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
243} 243}
244 244
245#ifdef CONFIG_MEMORY_HOTPLUG 245#ifdef CONFIG_MEMORY_HOTPLUG
246static int htab_remove_mapping(unsigned long vstart, unsigned long vend, 246int htab_remove_mapping(unsigned long vstart, unsigned long vend,
247 int psize, int ssize) 247 int psize, int ssize)
248{ 248{
249 unsigned long vaddr; 249 unsigned long vaddr;
@@ -821,21 +821,14 @@ static void __init htab_initialize(void)
821 821
822void __init early_init_mmu(void) 822void __init early_init_mmu(void)
823{ 823{
824 /* Setup initial STAB address in the PACA */
825 get_paca()->stab_real = __pa((u64)&initial_stab);
826 get_paca()->stab_addr = (u64)&initial_stab;
827
828 /* Initialize the MMU Hash table and create the linear mapping 824 /* Initialize the MMU Hash table and create the linear mapping
829 * of memory. Has to be done before stab/slb initialization as 825 * of memory. Has to be done before SLB initialization as this is
830 * this is currently where the page size encoding is obtained 826 * currently where the page size encoding is obtained.
831 */ 827 */
832 htab_initialize(); 828 htab_initialize();
833 829
834 /* Initialize stab / SLB management */ 830 /* Initialize SLB management */
835 if (mmu_has_feature(MMU_FTR_SLB)) 831 slb_initialize();
836 slb_initialize();
837 else
838 stab_initialize(get_paca()->stab_real);
839} 832}
840 833
841#ifdef CONFIG_SMP 834#ifdef CONFIG_SMP
@@ -845,13 +838,8 @@ void early_init_mmu_secondary(void)
845 if (!firmware_has_feature(FW_FEATURE_LPAR)) 838 if (!firmware_has_feature(FW_FEATURE_LPAR))
846 mtspr(SPRN_SDR1, _SDR1); 839 mtspr(SPRN_SDR1, _SDR1);
847 840
848 /* Initialize STAB/SLB. We use a virtual address as it works 841 /* Initialize SLB */
849 * in real mode on pSeries. 842 slb_initialize();
850 */
851 if (mmu_has_feature(MMU_FTR_SLB))
852 slb_initialize();
853 else
854 stab_initialize(get_paca()->stab_addr);
855} 843}
856#endif /* CONFIG_SMP */ 844#endif /* CONFIG_SMP */
857 845
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index e3734edffa69..253b4b971c8a 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -175,9 +175,10 @@ static unsigned long __meminit vmemmap_section_start(unsigned long page)
175static int __meminit vmemmap_populated(unsigned long start, int page_size) 175static int __meminit vmemmap_populated(unsigned long start, int page_size)
176{ 176{
177 unsigned long end = start + page_size; 177 unsigned long end = start + page_size;
178 start = (unsigned long)(pfn_to_page(vmemmap_section_start(start)));
178 179
179 for (; start < end; start += (PAGES_PER_SECTION * sizeof(struct page))) 180 for (; start < end; start += (PAGES_PER_SECTION * sizeof(struct page)))
180 if (pfn_valid(vmemmap_section_start(start))) 181 if (pfn_valid(page_to_pfn((struct page *)start)))
181 return 1; 182 return 1;
182 183
183 return 0; 184 return 0;
@@ -212,6 +213,13 @@ static void __meminit vmemmap_create_mapping(unsigned long start,
212 for (i = 0; i < page_size; i += PAGE_SIZE) 213 for (i = 0; i < page_size; i += PAGE_SIZE)
213 BUG_ON(map_kernel_page(start + i, phys, flags)); 214 BUG_ON(map_kernel_page(start + i, phys, flags));
214} 215}
216
217#ifdef CONFIG_MEMORY_HOTPLUG
218static void vmemmap_remove_mapping(unsigned long start,
219 unsigned long page_size)
220{
221}
222#endif
215#else /* CONFIG_PPC_BOOK3E */ 223#else /* CONFIG_PPC_BOOK3E */
216static void __meminit vmemmap_create_mapping(unsigned long start, 224static void __meminit vmemmap_create_mapping(unsigned long start,
217 unsigned long page_size, 225 unsigned long page_size,
@@ -223,17 +231,42 @@ static void __meminit vmemmap_create_mapping(unsigned long start,
223 mmu_kernel_ssize); 231 mmu_kernel_ssize);
224 BUG_ON(mapped < 0); 232 BUG_ON(mapped < 0);
225} 233}
234
235#ifdef CONFIG_MEMORY_HOTPLUG
236extern int htab_remove_mapping(unsigned long vstart, unsigned long vend,
237 int psize, int ssize);
238
239static void vmemmap_remove_mapping(unsigned long start,
240 unsigned long page_size)
241{
242 int mapped = htab_remove_mapping(start, start + page_size,
243 mmu_vmemmap_psize,
244 mmu_kernel_ssize);
245 BUG_ON(mapped < 0);
246}
247#endif
248
226#endif /* CONFIG_PPC_BOOK3E */ 249#endif /* CONFIG_PPC_BOOK3E */
227 250
228struct vmemmap_backing *vmemmap_list; 251struct vmemmap_backing *vmemmap_list;
252static struct vmemmap_backing *next;
253static int num_left;
254static int num_freed;
229 255
230static __meminit struct vmemmap_backing * vmemmap_list_alloc(int node) 256static __meminit struct vmemmap_backing * vmemmap_list_alloc(int node)
231{ 257{
232 static struct vmemmap_backing *next; 258 struct vmemmap_backing *vmem_back;
233 static int num_left; 259 /* get from freed entries first */
260 if (num_freed) {
261 num_freed--;
262 vmem_back = next;
263 next = next->list;
264
265 return vmem_back;
266 }
234 267
235 /* allocate a page when required and hand out chunks */ 268 /* allocate a page when required and hand out chunks */
236 if (!next || !num_left) { 269 if (!num_left) {
237 next = vmemmap_alloc_block(PAGE_SIZE, node); 270 next = vmemmap_alloc_block(PAGE_SIZE, node);
238 if (unlikely(!next)) { 271 if (unlikely(!next)) {
239 WARN_ON(1); 272 WARN_ON(1);
@@ -296,10 +329,85 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
296 return 0; 329 return 0;
297} 330}
298 331
299void vmemmap_free(unsigned long start, unsigned long end) 332#ifdef CONFIG_MEMORY_HOTPLUG
333static unsigned long vmemmap_list_free(unsigned long start)
300{ 334{
335 struct vmemmap_backing *vmem_back, *vmem_back_prev;
336
337 vmem_back_prev = vmem_back = vmemmap_list;
338
339 /* look for it with prev pointer recorded */
340 for (; vmem_back; vmem_back = vmem_back->list) {
341 if (vmem_back->virt_addr == start)
342 break;
343 vmem_back_prev = vmem_back;
344 }
345
346 if (unlikely(!vmem_back)) {
347 WARN_ON(1);
348 return 0;
349 }
350
351 /* remove it from vmemmap_list */
352 if (vmem_back == vmemmap_list) /* remove head */
353 vmemmap_list = vmem_back->list;
354 else
355 vmem_back_prev->list = vmem_back->list;
356
357 /* next point to this freed entry */
358 vmem_back->list = next;
359 next = vmem_back;
360 num_freed++;
361
362 return vmem_back->phys;
301} 363}
302 364
365void __ref vmemmap_free(unsigned long start, unsigned long end)
366{
367 unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift;
368
369 start = _ALIGN_DOWN(start, page_size);
370
371 pr_debug("vmemmap_free %lx...%lx\n", start, end);
372
373 for (; start < end; start += page_size) {
374 unsigned long addr;
375
376 /*
377 * the section has already be marked as invalid, so
378 * vmemmap_populated() true means some other sections still
379 * in this page, so skip it.
380 */
381 if (vmemmap_populated(start, page_size))
382 continue;
383
384 addr = vmemmap_list_free(start);
385 if (addr) {
386 struct page *page = pfn_to_page(addr >> PAGE_SHIFT);
387
388 if (PageReserved(page)) {
389 /* allocated from bootmem */
390 if (page_size < PAGE_SIZE) {
391 /*
392 * this shouldn't happen, but if it is
393 * the case, leave the memory there
394 */
395 WARN_ON_ONCE(1);
396 } else {
397 unsigned int nr_pages =
398 1 << get_order(page_size);
399 while (nr_pages--)
400 free_reserved_page(page++);
401 }
402 } else
403 free_pages((unsigned long)(__va(addr)),
404 get_order(page_size));
405
406 vmemmap_remove_mapping(start, page_size);
407 }
408 }
409}
410#endif
303void register_page_bootmem_memmap(unsigned long section_nr, 411void register_page_bootmem_memmap(unsigned long section_nr,
304 struct page *start_page, unsigned long size) 412 struct page *start_page, unsigned long size)
305{ 413{
@@ -331,16 +439,16 @@ struct page *realmode_pfn_to_page(unsigned long pfn)
331 if (pg_va < vmem_back->virt_addr) 439 if (pg_va < vmem_back->virt_addr)
332 continue; 440 continue;
333 441
334 /* Check that page struct is not split between real pages */ 442 /* After vmemmap_list entry free is possible, need check all */
335 if ((pg_va + sizeof(struct page)) > 443 if ((pg_va + sizeof(struct page)) <=
336 (vmem_back->virt_addr + page_size)) 444 (vmem_back->virt_addr + page_size)) {
337 return NULL; 445 page = (struct page *) (vmem_back->phys + pg_va -
338
339 page = (struct page *) (vmem_back->phys + pg_va -
340 vmem_back->virt_addr); 446 vmem_back->virt_addr);
341 return page; 447 return page;
448 }
342 } 449 }
343 450
451 /* Probably that page struct is split between real pages */
344 return NULL; 452 return NULL;
345} 453}
346EXPORT_SYMBOL_GPL(realmode_pfn_to_page); 454EXPORT_SYMBOL_GPL(realmode_pfn_to_page);
diff --git a/arch/powerpc/mm/mmu_context_hash32.c b/arch/powerpc/mm/mmu_context_hash32.c
index 78fef6726e10..aa5a7fd89461 100644
--- a/arch/powerpc/mm/mmu_context_hash32.c
+++ b/arch/powerpc/mm/mmu_context_hash32.c
@@ -2,7 +2,7 @@
2 * This file contains the routines for handling the MMU on those 2 * This file contains the routines for handling the MMU on those
3 * PowerPC implementations where the MMU substantially follows the 3 * PowerPC implementations where the MMU substantially follows the
4 * architecture specification. This includes the 6xx, 7xx, 7xxx, 4 * architecture specification. This includes the 6xx, 7xx, 7xxx,
5 * 8260, and POWER3 implementations but excludes the 8xx and 4xx. 5 * and 8260 implementations but excludes the 8xx and 4xx.
6 * -- paulus 6 * -- paulus
7 * 7 *
8 * Derived from arch/ppc/mm/init.c: 8 * Derived from arch/ppc/mm/init.c:
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 3b181b22cd46..d3e9a78eaed3 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -611,8 +611,8 @@ static int cpu_numa_callback(struct notifier_block *nfb, unsigned long action,
611 case CPU_UP_CANCELED: 611 case CPU_UP_CANCELED:
612 case CPU_UP_CANCELED_FROZEN: 612 case CPU_UP_CANCELED_FROZEN:
613 unmap_cpu_from_node(lcpu); 613 unmap_cpu_from_node(lcpu);
614 break;
615 ret = NOTIFY_OK; 614 ret = NOTIFY_OK;
615 break;
616#endif 616#endif
617 } 617 }
618 return ret; 618 return ret;
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 343a87fa78b5..cf11342bf519 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -41,7 +41,7 @@ unsigned long ioremap_base;
41unsigned long ioremap_bot; 41unsigned long ioremap_bot;
42EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */ 42EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */
43 43
44#if defined(CONFIG_6xx) || defined(CONFIG_POWER3) 44#ifdef CONFIG_6xx
45#define HAVE_BATS 1 45#define HAVE_BATS 1
46#endif 46#endif
47 47
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index f6ce1f111f5b..3b3c4d34c7a0 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -68,7 +68,7 @@
68unsigned long ioremap_bot = IOREMAP_BASE; 68unsigned long ioremap_bot = IOREMAP_BASE;
69 69
70#ifdef CONFIG_PPC_MMU_NOHASH 70#ifdef CONFIG_PPC_MMU_NOHASH
71static void *early_alloc_pgtable(unsigned long size) 71static __ref void *early_alloc_pgtable(unsigned long size)
72{ 72{
73 void *pt; 73 void *pt;
74 74
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index 11571e118831..5029dc19b517 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -2,7 +2,7 @@
2 * This file contains the routines for handling the MMU on those 2 * This file contains the routines for handling the MMU on those
3 * PowerPC implementations where the MMU substantially follows the 3 * PowerPC implementations where the MMU substantially follows the
4 * architecture specification. This includes the 6xx, 7xx, 7xxx, 4 * architecture specification. This includes the 6xx, 7xx, 7xxx,
5 * 8260, and POWER3 implementations but excludes the 8xx and 4xx. 5 * and 8260 implementations but excludes the 8xx and 4xx.
6 * -- paulus 6 * -- paulus
7 * 7 *
8 * Derived from arch/ppc/mm/init.c: 8 * Derived from arch/ppc/mm/init.c:
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c
deleted file mode 100644
index 3f8efa6f2997..000000000000
--- a/arch/powerpc/mm/stab.c
+++ /dev/null
@@ -1,286 +0,0 @@
1/*
2 * PowerPC64 Segment Translation Support.
3 *
4 * Dave Engebretsen and Mike Corrigan {engebret|mikejc}@us.ibm.com
5 * Copyright (c) 2001 Dave Engebretsen
6 *
7 * Copyright (C) 2002 Anton Blanchard <anton@au.ibm.com>, IBM
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 */
14
15#include <linux/memblock.h>
16
17#include <asm/pgtable.h>
18#include <asm/mmu.h>
19#include <asm/mmu_context.h>
20#include <asm/paca.h>
21#include <asm/cputable.h>
22#include <asm/prom.h>
23
24struct stab_entry {
25 unsigned long esid_data;
26 unsigned long vsid_data;
27};
28
29#define NR_STAB_CACHE_ENTRIES 8
30static DEFINE_PER_CPU(long, stab_cache_ptr);
31static DEFINE_PER_CPU(long [NR_STAB_CACHE_ENTRIES], stab_cache);
32
33/*
34 * Create a segment table entry for the given esid/vsid pair.
35 */
36static int make_ste(unsigned long stab, unsigned long esid, unsigned long vsid)
37{
38 unsigned long esid_data, vsid_data;
39 unsigned long entry, group, old_esid, castout_entry, i;
40 unsigned int global_entry;
41 struct stab_entry *ste, *castout_ste;
42 unsigned long kernel_segment = (esid << SID_SHIFT) >= PAGE_OFFSET;
43
44 vsid_data = vsid << STE_VSID_SHIFT;
45 esid_data = esid << SID_SHIFT | STE_ESID_KP | STE_ESID_V;
46 if (! kernel_segment)
47 esid_data |= STE_ESID_KS;
48
49 /* Search the primary group first. */
50 global_entry = (esid & 0x1f) << 3;
51 ste = (struct stab_entry *)(stab | ((esid & 0x1f) << 7));
52
53 /* Find an empty entry, if one exists. */
54 for (group = 0; group < 2; group++) {
55 for (entry = 0; entry < 8; entry++, ste++) {
56 if (!(ste->esid_data & STE_ESID_V)) {
57 ste->vsid_data = vsid_data;
58 eieio();
59 ste->esid_data = esid_data;
60 return (global_entry | entry);
61 }
62 }
63 /* Now search the secondary group. */
64 global_entry = ((~esid) & 0x1f) << 3;
65 ste = (struct stab_entry *)(stab | (((~esid) & 0x1f) << 7));
66 }
67
68 /*
69 * Could not find empty entry, pick one with a round robin selection.
70 * Search all entries in the two groups.
71 */
72 castout_entry = get_paca()->stab_rr;
73 for (i = 0; i < 16; i++) {
74 if (castout_entry < 8) {
75 global_entry = (esid & 0x1f) << 3;
76 ste = (struct stab_entry *)(stab | ((esid & 0x1f) << 7));
77 castout_ste = ste + castout_entry;
78 } else {
79 global_entry = ((~esid) & 0x1f) << 3;
80 ste = (struct stab_entry *)(stab | (((~esid) & 0x1f) << 7));
81 castout_ste = ste + (castout_entry - 8);
82 }
83
84 /* Dont cast out the first kernel segment */
85 if ((castout_ste->esid_data & ESID_MASK) != PAGE_OFFSET)
86 break;
87
88 castout_entry = (castout_entry + 1) & 0xf;
89 }
90
91 get_paca()->stab_rr = (castout_entry + 1) & 0xf;
92
93 /* Modify the old entry to the new value. */
94
95 /* Force previous translations to complete. DRENG */
96 asm volatile("isync" : : : "memory");
97
98 old_esid = castout_ste->esid_data >> SID_SHIFT;
99 castout_ste->esid_data = 0; /* Invalidate old entry */
100
101 asm volatile("sync" : : : "memory"); /* Order update */
102
103 castout_ste->vsid_data = vsid_data;
104 eieio(); /* Order update */
105 castout_ste->esid_data = esid_data;
106
107 asm volatile("slbie %0" : : "r" (old_esid << SID_SHIFT));
108 /* Ensure completion of slbie */
109 asm volatile("sync" : : : "memory");
110
111 return (global_entry | (castout_entry & 0x7));
112}
113
114/*
115 * Allocate a segment table entry for the given ea and mm
116 */
117static int __ste_allocate(unsigned long ea, struct mm_struct *mm)
118{
119 unsigned long vsid;
120 unsigned char stab_entry;
121 unsigned long offset;
122
123 /* Kernel or user address? */
124 if (is_kernel_addr(ea)) {
125 vsid = get_kernel_vsid(ea, MMU_SEGSIZE_256M);
126 } else {
127 if ((ea >= TASK_SIZE_USER64) || (! mm))
128 return 1;
129
130 vsid = get_vsid(mm->context.id, ea, MMU_SEGSIZE_256M);
131 }
132
133 stab_entry = make_ste(get_paca()->stab_addr, GET_ESID(ea), vsid);
134
135 if (!is_kernel_addr(ea)) {
136 offset = __get_cpu_var(stab_cache_ptr);
137 if (offset < NR_STAB_CACHE_ENTRIES)
138 __get_cpu_var(stab_cache[offset++]) = stab_entry;
139 else
140 offset = NR_STAB_CACHE_ENTRIES+1;
141 __get_cpu_var(stab_cache_ptr) = offset;
142
143 /* Order update */
144 asm volatile("sync":::"memory");
145 }
146
147 return 0;
148}
149
150int ste_allocate(unsigned long ea)
151{
152 return __ste_allocate(ea, current->mm);
153}
154
155/*
156 * Do the segment table work for a context switch: flush all user
157 * entries from the table, then preload some probably useful entries
158 * for the new task
159 */
160void switch_stab(struct task_struct *tsk, struct mm_struct *mm)
161{
162 struct stab_entry *stab = (struct stab_entry *) get_paca()->stab_addr;
163 struct stab_entry *ste;
164 unsigned long offset;
165 unsigned long pc = KSTK_EIP(tsk);
166 unsigned long stack = KSTK_ESP(tsk);
167 unsigned long unmapped_base;
168
169 /* Force previous translations to complete. DRENG */
170 asm volatile("isync" : : : "memory");
171
172 /*
173 * We need interrupts hard-disabled here, not just soft-disabled,
174 * so that a PMU interrupt can't occur, which might try to access
175 * user memory (to get a stack trace) and possible cause an STAB miss
176 * which would update the stab_cache/stab_cache_ptr per-cpu variables.
177 */
178 hard_irq_disable();
179
180 offset = __get_cpu_var(stab_cache_ptr);
181 if (offset <= NR_STAB_CACHE_ENTRIES) {
182 int i;
183
184 for (i = 0; i < offset; i++) {
185 ste = stab + __get_cpu_var(stab_cache[i]);
186 ste->esid_data = 0; /* invalidate entry */
187 }
188 } else {
189 unsigned long entry;
190
191 /* Invalidate all entries. */
192 ste = stab;
193
194 /* Never flush the first entry. */
195 ste += 1;
196 for (entry = 1;
197 entry < (HW_PAGE_SIZE / sizeof(struct stab_entry));
198 entry++, ste++) {
199 unsigned long ea;
200 ea = ste->esid_data & ESID_MASK;
201 if (!is_kernel_addr(ea)) {
202 ste->esid_data = 0;
203 }
204 }
205 }
206
207 asm volatile("sync; slbia; sync":::"memory");
208
209 __get_cpu_var(stab_cache_ptr) = 0;
210
211 /* Now preload some entries for the new task */
212 if (test_tsk_thread_flag(tsk, TIF_32BIT))
213 unmapped_base = TASK_UNMAPPED_BASE_USER32;
214 else
215 unmapped_base = TASK_UNMAPPED_BASE_USER64;
216
217 __ste_allocate(pc, mm);
218
219 if (GET_ESID(pc) == GET_ESID(stack))
220 return;
221
222 __ste_allocate(stack, mm);
223
224 if ((GET_ESID(pc) == GET_ESID(unmapped_base))
225 || (GET_ESID(stack) == GET_ESID(unmapped_base)))
226 return;
227
228 __ste_allocate(unmapped_base, mm);
229
230 /* Order update */
231 asm volatile("sync" : : : "memory");
232}
233
234/*
235 * Allocate segment tables for secondary CPUs. These must all go in
236 * the first (bolted) segment, so that do_stab_bolted won't get a
237 * recursive segment miss on the segment table itself.
238 */
239void __init stabs_alloc(void)
240{
241 int cpu;
242
243 if (mmu_has_feature(MMU_FTR_SLB))
244 return;
245
246 for_each_possible_cpu(cpu) {
247 unsigned long newstab;
248
249 if (cpu == 0)
250 continue; /* stab for CPU 0 is statically allocated */
251
252 newstab = memblock_alloc_base(HW_PAGE_SIZE, HW_PAGE_SIZE,
253 1<<SID_SHIFT);
254 newstab = (unsigned long)__va(newstab);
255
256 memset((void *)newstab, 0, HW_PAGE_SIZE);
257
258 paca[cpu].stab_addr = newstab;
259 paca[cpu].stab_real = __pa(newstab);
260 printk(KERN_INFO "Segment table for CPU %d at 0x%llx "
261 "virtual, 0x%llx absolute\n",
262 cpu, paca[cpu].stab_addr, paca[cpu].stab_real);
263 }
264}
265
266/*
267 * Build an entry for the base kernel segment and put it into
268 * the segment table or SLB. All other segment table or SLB
269 * entries are faulted in.
270 */
271void stab_initialize(unsigned long stab)
272{
273 unsigned long vsid = get_kernel_vsid(PAGE_OFFSET, MMU_SEGSIZE_256M);
274 unsigned long stabreal;
275
276 asm volatile("isync; slbia; isync":::"memory");
277 make_ste(stab, GET_ESID(PAGE_OFFSET), vsid);
278
279 /* Order update */
280 asm volatile("sync":::"memory");
281
282 /* Set ASR */
283 stabreal = get_paca()->stab_real | 0x1ul;
284
285 mtspr(SPRN_ASR, stabreal);
286}
diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S
index 356e8b41fb09..89bf95bd63b1 100644
--- a/arch/powerpc/mm/tlb_low_64e.S
+++ b/arch/powerpc/mm/tlb_low_64e.S
@@ -296,9 +296,12 @@ itlb_miss_fault_bolted:
296 * r14 = page table base 296 * r14 = page table base
297 * r13 = PACA 297 * r13 = PACA
298 * r11 = tlb_per_core ptr 298 * r11 = tlb_per_core ptr
299 * r10 = cpu number 299 * r10 = crap (free to use)
300 */ 300 */
301tlb_miss_common_e6500: 301tlb_miss_common_e6500:
302 crmove cr2*4+2,cr0*4+2 /* cr2.eq != 0 if kernel address */
303
304BEGIN_FTR_SECTION /* CPU_FTR_SMT */
302 /* 305 /*
303 * Search if we already have an indirect entry for that virtual 306 * Search if we already have an indirect entry for that virtual
304 * address, and if we do, bail out. 307 * address, and if we do, bail out.
@@ -309,6 +312,7 @@ tlb_miss_common_e6500:
309 lhz r10,PACAPACAINDEX(r13) 312 lhz r10,PACAPACAINDEX(r13)
310 cmpdi r15,0 313 cmpdi r15,0
311 cmpdi cr1,r15,1 /* set cr1.eq = 0 for non-recursive */ 314 cmpdi cr1,r15,1 /* set cr1.eq = 0 for non-recursive */
315 addi r10,r10,1
312 bne 2f 316 bne 2f
313 stbcx. r10,0,r11 317 stbcx. r10,0,r11
314 bne 1b 318 bne 1b
@@ -322,18 +326,62 @@ tlb_miss_common_e6500:
322 b 1b 326 b 1b
323 .previous 327 .previous
324 328
329 /*
330 * Erratum A-008139 says that we can't use tlbwe to change
331 * an indirect entry in any way (including replacing or
332 * invalidating) if the other thread could be in the process
333 * of a lookup. The workaround is to invalidate the entry
334 * with tlbilx before overwriting.
335 */
336
337 lbz r15,TCD_ESEL_NEXT(r11)
338 rlwinm r10,r15,16,0xff0000
339 oris r10,r10,MAS0_TLBSEL(1)@h
340 mtspr SPRN_MAS0,r10
341 isync
342 tlbre
343 mfspr r15,SPRN_MAS1
344 andis. r15,r15,MAS1_VALID@h
345 beq 5f
346
347BEGIN_FTR_SECTION_NESTED(532)
348 mfspr r10,SPRN_MAS8
349 rlwinm r10,r10,0,0x80000fff /* tgs,tlpid -> sgs,slpid */
350 mtspr SPRN_MAS5,r10
351END_FTR_SECTION_NESTED(CPU_FTR_EMB_HV,CPU_FTR_EMB_HV,532)
352
353 mfspr r10,SPRN_MAS1
354 rlwinm r15,r10,0,0x3fff0000 /* tid -> spid */
355 rlwimi r15,r10,20,0x00000003 /* ind,ts -> sind,sas */
356 mfspr r10,SPRN_MAS6
357 mtspr SPRN_MAS6,r15
358
325 mfspr r15,SPRN_MAS2 359 mfspr r15,SPRN_MAS2
360 isync
361 tlbilxva 0,r15
362 isync
363
364 mtspr SPRN_MAS6,r10
365
3665:
367BEGIN_FTR_SECTION_NESTED(532)
368 li r10,0
369 mtspr SPRN_MAS8,r10
370 mtspr SPRN_MAS5,r10
371END_FTR_SECTION_NESTED(CPU_FTR_EMB_HV,CPU_FTR_EMB_HV,532)
326 372
327 tlbsx 0,r16 373 tlbsx 0,r16
328 mfspr r10,SPRN_MAS1 374 mfspr r10,SPRN_MAS1
329 andis. r10,r10,MAS1_VALID@h 375 andis. r15,r10,MAS1_VALID@h
330 bne tlb_miss_done_e6500 376 bne tlb_miss_done_e6500
331 377FTR_SECTION_ELSE
332 /* Undo MAS-damage from the tlbsx */
333 mfspr r10,SPRN_MAS1 378 mfspr r10,SPRN_MAS1
379ALT_FTR_SECTION_END_IFSET(CPU_FTR_SMT)
380
334 oris r10,r10,MAS1_VALID@h 381 oris r10,r10,MAS1_VALID@h
335 mtspr SPRN_MAS1,r10 382 beq cr2,4f
336 mtspr SPRN_MAS2,r15 383 rlwinm r10,r10,0,16,1 /* Clear TID */
3844: mtspr SPRN_MAS1,r10
337 385
338 /* Now, we need to walk the page tables. First check if we are in 386 /* Now, we need to walk the page tables. First check if we are in
339 * range. 387 * range.
@@ -394,11 +442,13 @@ tlb_miss_common_e6500:
394 442
395tlb_miss_done_e6500: 443tlb_miss_done_e6500:
396 .macro tlb_unlock_e6500 444 .macro tlb_unlock_e6500
445BEGIN_FTR_SECTION
397 beq cr1,1f /* no unlock if lock was recursively grabbed */ 446 beq cr1,1f /* no unlock if lock was recursively grabbed */
398 li r15,0 447 li r15,0
399 isync 448 isync
400 stb r15,0(r11) 449 stb r15,0(r11)
4011: 4501:
451END_FTR_SECTION_IFSET(CPU_FTR_SMT)
402 .endm 452 .endm
403 453
404 tlb_unlock_e6500 454 tlb_unlock_e6500
@@ -407,12 +457,9 @@ tlb_miss_done_e6500:
407 rfi 457 rfi
408 458
409tlb_miss_kernel_e6500: 459tlb_miss_kernel_e6500:
410 mfspr r10,SPRN_MAS1
411 ld r14,PACA_KERNELPGD(r13) 460 ld r14,PACA_KERNELPGD(r13)
412 cmpldi cr0,r15,8 /* Check for vmalloc region */ 461 cmpldi cr1,r15,8 /* Check for vmalloc region */
413 rlwinm r10,r10,0,16,1 /* Clear TID */ 462 beq+ cr1,tlb_miss_common_e6500
414 mtspr SPRN_MAS1,r10
415 beq+ tlb_miss_common_e6500
416 463
417tlb_miss_fault_e6500: 464tlb_miss_fault_e6500:
418 tlb_unlock_e6500 465 tlb_unlock_e6500
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
index 751ec7bd5018..cedbbeced632 100644
--- a/arch/powerpc/oprofile/Makefile
+++ b/arch/powerpc/oprofile/Makefile
@@ -14,6 +14,6 @@ oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
14oprofile-$(CONFIG_OPROFILE_CELL) += op_model_cell.o \ 14oprofile-$(CONFIG_OPROFILE_CELL) += op_model_cell.o \
15 cell/spu_profiler.o cell/vma_map.o \ 15 cell/spu_profiler.o cell/vma_map.o \
16 cell/spu_task_sync.o 16 cell/spu_task_sync.o
17oprofile-$(CONFIG_PPC_BOOK3S_64) += op_model_rs64.o op_model_power4.o op_model_pa6t.o 17oprofile-$(CONFIG_PPC_BOOK3S_64) += op_model_power4.o op_model_pa6t.o
18oprofile-$(CONFIG_FSL_EMB_PERFMON) += op_model_fsl_emb.o 18oprofile-$(CONFIG_FSL_EMB_PERFMON) += op_model_fsl_emb.o
19oprofile-$(CONFIG_6xx) += op_model_7450.o 19oprofile-$(CONFIG_6xx) += op_model_7450.o
diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c
index c77348c5d463..bf094c5a4bd9 100644
--- a/arch/powerpc/oprofile/common.c
+++ b/arch/powerpc/oprofile/common.c
@@ -205,9 +205,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
205 ops->sync_stop = model->sync_stop; 205 ops->sync_stop = model->sync_stop;
206 break; 206 break;
207#endif 207#endif
208 case PPC_OPROFILE_RS64:
209 model = &op_model_rs64;
210 break;
211 case PPC_OPROFILE_POWER4: 208 case PPC_OPROFILE_POWER4:
212 model = &op_model_power4; 209 model = &op_model_power4;
213 break; 210 break;
diff --git a/arch/powerpc/oprofile/op_model_rs64.c b/arch/powerpc/oprofile/op_model_rs64.c
deleted file mode 100644
index 7e5b8ed3a1b7..000000000000
--- a/arch/powerpc/oprofile/op_model_rs64.c
+++ /dev/null
@@ -1,222 +0,0 @@
1/*
2 * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
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/oprofile.h>
11#include <linux/smp.h>
12#include <asm/ptrace.h>
13#include <asm/processor.h>
14#include <asm/cputable.h>
15#include <asm/oprofile_impl.h>
16
17#define dbg(args...)
18
19static void ctrl_write(unsigned int i, unsigned int val)
20{
21 unsigned int tmp = 0;
22 unsigned long shift = 0, mask = 0;
23
24 dbg("ctrl_write %d %x\n", i, val);
25
26 switch(i) {
27 case 0:
28 tmp = mfspr(SPRN_MMCR0);
29 shift = 6;
30 mask = 0x7F;
31 break;
32 case 1:
33 tmp = mfspr(SPRN_MMCR0);
34 shift = 0;
35 mask = 0x3F;
36 break;
37 case 2:
38 tmp = mfspr(SPRN_MMCR1);
39 shift = 31 - 4;
40 mask = 0x1F;
41 break;
42 case 3:
43 tmp = mfspr(SPRN_MMCR1);
44 shift = 31 - 9;
45 mask = 0x1F;
46 break;
47 case 4:
48 tmp = mfspr(SPRN_MMCR1);
49 shift = 31 - 14;
50 mask = 0x1F;
51 break;
52 case 5:
53 tmp = mfspr(SPRN_MMCR1);
54 shift = 31 - 19;
55 mask = 0x1F;
56 break;
57 case 6:
58 tmp = mfspr(SPRN_MMCR1);
59 shift = 31 - 24;
60 mask = 0x1F;
61 break;
62 case 7:
63 tmp = mfspr(SPRN_MMCR1);
64 shift = 31 - 28;
65 mask = 0xF;
66 break;
67 }
68
69 tmp = tmp & ~(mask << shift);
70 tmp |= val << shift;
71
72 switch(i) {
73 case 0:
74 case 1:
75 mtspr(SPRN_MMCR0, tmp);
76 break;
77 default:
78 mtspr(SPRN_MMCR1, tmp);
79 }
80
81 dbg("ctrl_write mmcr0 %lx mmcr1 %lx\n", mfspr(SPRN_MMCR0),
82 mfspr(SPRN_MMCR1));
83}
84
85static unsigned long reset_value[OP_MAX_COUNTER];
86
87static int num_counters;
88
89static int rs64_reg_setup(struct op_counter_config *ctr,
90 struct op_system_config *sys,
91 int num_ctrs)
92{
93 int i;
94
95 num_counters = num_ctrs;
96
97 for (i = 0; i < num_counters; ++i)
98 reset_value[i] = 0x80000000UL - ctr[i].count;
99
100 /* XXX setup user and kernel profiling */
101 return 0;
102}
103
104static int rs64_cpu_setup(struct op_counter_config *ctr)
105{
106 unsigned int mmcr0;
107
108 /* reset MMCR0 and set the freeze bit */
109 mmcr0 = MMCR0_FC;
110 mtspr(SPRN_MMCR0, mmcr0);
111
112 /* reset MMCR1, MMCRA */
113 mtspr(SPRN_MMCR1, 0);
114
115 if (cpu_has_feature(CPU_FTR_MMCRA))
116 mtspr(SPRN_MMCRA, 0);
117
118 mmcr0 |= MMCR0_FCM1|MMCR0_PMXE|MMCR0_FCECE;
119 /* Only applies to POWER3, but should be safe on RS64 */
120 mmcr0 |= MMCR0_PMC1CE|MMCR0_PMCjCE;
121 mtspr(SPRN_MMCR0, mmcr0);
122
123 dbg("setup on cpu %d, mmcr0 %lx\n", smp_processor_id(),
124 mfspr(SPRN_MMCR0));
125 dbg("setup on cpu %d, mmcr1 %lx\n", smp_processor_id(),
126 mfspr(SPRN_MMCR1));
127
128 return 0;
129}
130
131static int rs64_start(struct op_counter_config *ctr)
132{
133 int i;
134 unsigned int mmcr0;
135
136 /* set the PMM bit (see comment below) */
137 mtmsrd(mfmsr() | MSR_PMM);
138
139 for (i = 0; i < num_counters; ++i) {
140 if (ctr[i].enabled) {
141 classic_ctr_write(i, reset_value[i]);
142 ctrl_write(i, ctr[i].event);
143 } else {
144 classic_ctr_write(i, 0);
145 }
146 }
147
148 mmcr0 = mfspr(SPRN_MMCR0);
149
150 /*
151 * now clear the freeze bit, counting will not start until we
152 * rfid from this excetion, because only at that point will
153 * the PMM bit be cleared
154 */
155 mmcr0 &= ~MMCR0_FC;
156 mtspr(SPRN_MMCR0, mmcr0);
157
158 dbg("start on cpu %d, mmcr0 %x\n", smp_processor_id(), mmcr0);
159 return 0;
160}
161
162static void rs64_stop(void)
163{
164 unsigned int mmcr0;
165
166 /* freeze counters */
167 mmcr0 = mfspr(SPRN_MMCR0);
168 mmcr0 |= MMCR0_FC;
169 mtspr(SPRN_MMCR0, mmcr0);
170
171 dbg("stop on cpu %d, mmcr0 %x\n", smp_processor_id(), mmcr0);
172
173 mb();
174}
175
176static void rs64_handle_interrupt(struct pt_regs *regs,
177 struct op_counter_config *ctr)
178{
179 unsigned int mmcr0;
180 int is_kernel;
181 int val;
182 int i;
183 unsigned long pc = mfspr(SPRN_SIAR);
184
185 is_kernel = is_kernel_addr(pc);
186
187 /* set the PMM bit (see comment below) */
188 mtmsrd(mfmsr() | MSR_PMM);
189
190 for (i = 0; i < num_counters; ++i) {
191 val = classic_ctr_read(i);
192 if (val < 0) {
193 if (ctr[i].enabled) {
194 oprofile_add_ext_sample(pc, regs, i, is_kernel);
195 classic_ctr_write(i, reset_value[i]);
196 } else {
197 classic_ctr_write(i, 0);
198 }
199 }
200 }
201
202 mmcr0 = mfspr(SPRN_MMCR0);
203
204 /* reset the perfmon trigger */
205 mmcr0 |= MMCR0_PMXE;
206
207 /*
208 * now clear the freeze bit, counting will not start until we
209 * rfid from this exception, because only at that point will
210 * the PMM bit be cleared
211 */
212 mmcr0 &= ~MMCR0_FC;
213 mtspr(SPRN_MMCR0, mmcr0);
214}
215
216struct op_powerpc_model op_model_rs64 = {
217 .reg_setup = rs64_reg_setup,
218 .cpu_setup = rs64_cpu_setup,
219 .start = rs64_start,
220 .stop = rs64_stop,
221 .handle_interrupt = rs64_handle_interrupt,
222};
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index fe52db2eea6a..b7cd00b0171e 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -36,7 +36,12 @@ struct cpu_hw_events {
36 struct perf_event *event[MAX_HWEVENTS]; 36 struct perf_event *event[MAX_HWEVENTS];
37 u64 events[MAX_HWEVENTS]; 37 u64 events[MAX_HWEVENTS];
38 unsigned int flags[MAX_HWEVENTS]; 38 unsigned int flags[MAX_HWEVENTS];
39 unsigned long mmcr[3]; 39 /*
40 * The order of the MMCR array is:
41 * - 64-bit, MMCR0, MMCR1, MMCRA, MMCR2
42 * - 32-bit, MMCR0, MMCR1, MMCR2
43 */
44 unsigned long mmcr[4];
40 struct perf_event *limited_counter[MAX_LIMITED_HWCOUNTERS]; 45 struct perf_event *limited_counter[MAX_LIMITED_HWCOUNTERS];
41 u8 limited_hwidx[MAX_LIMITED_HWCOUNTERS]; 46 u8 limited_hwidx[MAX_LIMITED_HWCOUNTERS];
42 u64 alternatives[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES]; 47 u64 alternatives[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
@@ -112,9 +117,9 @@ static bool is_ebb_event(struct perf_event *event) { return false; }
112static int ebb_event_check(struct perf_event *event) { return 0; } 117static int ebb_event_check(struct perf_event *event) { return 0; }
113static void ebb_event_add(struct perf_event *event) { } 118static void ebb_event_add(struct perf_event *event) { }
114static void ebb_switch_out(unsigned long mmcr0) { } 119static void ebb_switch_out(unsigned long mmcr0) { }
115static unsigned long ebb_switch_in(bool ebb, unsigned long mmcr0) 120static unsigned long ebb_switch_in(bool ebb, struct cpu_hw_events *cpuhw)
116{ 121{
117 return mmcr0; 122 return cpuhw->mmcr[0];
118} 123}
119 124
120static inline void power_pmu_bhrb_enable(struct perf_event *event) {} 125static inline void power_pmu_bhrb_enable(struct perf_event *event) {}
@@ -542,8 +547,10 @@ static void ebb_switch_out(unsigned long mmcr0)
542 current->thread.mmcr2 = mfspr(SPRN_MMCR2) & MMCR2_USER_MASK; 547 current->thread.mmcr2 = mfspr(SPRN_MMCR2) & MMCR2_USER_MASK;
543} 548}
544 549
545static unsigned long ebb_switch_in(bool ebb, unsigned long mmcr0) 550static unsigned long ebb_switch_in(bool ebb, struct cpu_hw_events *cpuhw)
546{ 551{
552 unsigned long mmcr0 = cpuhw->mmcr[0];
553
547 if (!ebb) 554 if (!ebb)
548 goto out; 555 goto out;
549 556
@@ -568,7 +575,15 @@ static unsigned long ebb_switch_in(bool ebb, unsigned long mmcr0)
568 mtspr(SPRN_SIAR, current->thread.siar); 575 mtspr(SPRN_SIAR, current->thread.siar);
569 mtspr(SPRN_SIER, current->thread.sier); 576 mtspr(SPRN_SIER, current->thread.sier);
570 mtspr(SPRN_SDAR, current->thread.sdar); 577 mtspr(SPRN_SDAR, current->thread.sdar);
571 mtspr(SPRN_MMCR2, current->thread.mmcr2); 578
579 /*
580 * Merge the kernel & user values of MMCR2. The semantics we implement
581 * are that the user MMCR2 can set bits, ie. cause counters to freeze,
582 * but not clear bits. If a task wants to be able to clear bits, ie.
583 * unfreeze counters, it should not set exclude_xxx in its events and
584 * instead manage the MMCR2 entirely by itself.
585 */
586 mtspr(SPRN_MMCR2, cpuhw->mmcr[3] | current->thread.mmcr2);
572out: 587out:
573 return mmcr0; 588 return mmcr0;
574} 589}
@@ -915,6 +930,14 @@ static int check_excludes(struct perf_event **ctrs, unsigned int cflags[],
915 int i, n, first; 930 int i, n, first;
916 struct perf_event *event; 931 struct perf_event *event;
917 932
933 /*
934 * If the PMU we're on supports per event exclude settings then we
935 * don't need to do any of this logic. NB. This assumes no PMU has both
936 * per event exclude and limited PMCs.
937 */
938 if (ppmu->flags & PPMU_ARCH_207S)
939 return 0;
940
918 n = n_prev + n_new; 941 n = n_prev + n_new;
919 if (n <= 1) 942 if (n <= 1)
920 return 0; 943 return 0;
@@ -1219,28 +1242,31 @@ static void power_pmu_enable(struct pmu *pmu)
1219 } 1242 }
1220 1243
1221 /* 1244 /*
1222 * Compute MMCR* values for the new set of events 1245 * Clear all MMCR settings and recompute them for the new set of events.
1223 */ 1246 */
1247 memset(cpuhw->mmcr, 0, sizeof(cpuhw->mmcr));
1248
1224 if (ppmu->compute_mmcr(cpuhw->events, cpuhw->n_events, hwc_index, 1249 if (ppmu->compute_mmcr(cpuhw->events, cpuhw->n_events, hwc_index,
1225 cpuhw->mmcr)) { 1250 cpuhw->mmcr, cpuhw->event)) {
1226 /* shouldn't ever get here */ 1251 /* shouldn't ever get here */
1227 printk(KERN_ERR "oops compute_mmcr failed\n"); 1252 printk(KERN_ERR "oops compute_mmcr failed\n");
1228 goto out; 1253 goto out;
1229 } 1254 }
1230 1255
1231 /* 1256 if (!(ppmu->flags & PPMU_ARCH_207S)) {
1232 * Add in MMCR0 freeze bits corresponding to the 1257 /*
1233 * attr.exclude_* bits for the first event. 1258 * Add in MMCR0 freeze bits corresponding to the attr.exclude_*
1234 * We have already checked that all events have the 1259 * bits for the first event. We have already checked that all
1235 * same values for these bits as the first event. 1260 * events have the same value for these bits as the first event.
1236 */ 1261 */
1237 event = cpuhw->event[0]; 1262 event = cpuhw->event[0];
1238 if (event->attr.exclude_user) 1263 if (event->attr.exclude_user)
1239 cpuhw->mmcr[0] |= MMCR0_FCP; 1264 cpuhw->mmcr[0] |= MMCR0_FCP;
1240 if (event->attr.exclude_kernel) 1265 if (event->attr.exclude_kernel)
1241 cpuhw->mmcr[0] |= freeze_events_kernel; 1266 cpuhw->mmcr[0] |= freeze_events_kernel;
1242 if (event->attr.exclude_hv) 1267 if (event->attr.exclude_hv)
1243 cpuhw->mmcr[0] |= MMCR0_FCHV; 1268 cpuhw->mmcr[0] |= MMCR0_FCHV;
1269 }
1244 1270
1245 /* 1271 /*
1246 * Write the new configuration to MMCR* with the freeze 1272 * Write the new configuration to MMCR* with the freeze
@@ -1252,6 +1278,8 @@ static void power_pmu_enable(struct pmu *pmu)
1252 mtspr(SPRN_MMCR1, cpuhw->mmcr[1]); 1278 mtspr(SPRN_MMCR1, cpuhw->mmcr[1]);
1253 mtspr(SPRN_MMCR0, (cpuhw->mmcr[0] & ~(MMCR0_PMC1CE | MMCR0_PMCjCE)) 1279 mtspr(SPRN_MMCR0, (cpuhw->mmcr[0] & ~(MMCR0_PMC1CE | MMCR0_PMCjCE))
1254 | MMCR0_FC); 1280 | MMCR0_FC);
1281 if (ppmu->flags & PPMU_ARCH_207S)
1282 mtspr(SPRN_MMCR2, cpuhw->mmcr[3]);
1255 1283
1256 /* 1284 /*
1257 * Read off any pre-existing events that need to move 1285 * Read off any pre-existing events that need to move
@@ -1307,10 +1335,7 @@ static void power_pmu_enable(struct pmu *pmu)
1307 out_enable: 1335 out_enable:
1308 pmao_restore_workaround(ebb); 1336 pmao_restore_workaround(ebb);
1309 1337
1310 if (ppmu->flags & PPMU_ARCH_207S) 1338 mmcr0 = ebb_switch_in(ebb, cpuhw);
1311 mtspr(SPRN_MMCR2, 0);
1312
1313 mmcr0 = ebb_switch_in(ebb, cpuhw->mmcr[0]);
1314 1339
1315 mb(); 1340 mb();
1316 if (cpuhw->bhrb_users) 1341 if (cpuhw->bhrb_users)
diff --git a/arch/powerpc/perf/mpc7450-pmu.c b/arch/powerpc/perf/mpc7450-pmu.c
index fe21b515ca44..d115c5635bf3 100644
--- a/arch/powerpc/perf/mpc7450-pmu.c
+++ b/arch/powerpc/perf/mpc7450-pmu.c
@@ -260,8 +260,9 @@ static const u32 pmcsel_mask[N_COUNTER] = {
260/* 260/*
261 * Compute MMCR0/1/2 values for a set of events. 261 * Compute MMCR0/1/2 values for a set of events.
262 */ 262 */
263static int mpc7450_compute_mmcr(u64 event[], int n_ev, 263static int mpc7450_compute_mmcr(u64 event[], int n_ev, unsigned int hwc[],
264 unsigned int hwc[], unsigned long mmcr[]) 264 unsigned long mmcr[],
265 struct perf_event *pevents[])
265{ 266{
266 u8 event_index[N_CLASSES][N_COUNTER]; 267 u8 event_index[N_CLASSES][N_COUNTER];
267 int n_classevent[N_CLASSES]; 268 int n_classevent[N_CLASSES];
diff --git a/arch/powerpc/perf/power4-pmu.c b/arch/powerpc/perf/power4-pmu.c
index 9103a1de864d..ce6072fa481b 100644
--- a/arch/powerpc/perf/power4-pmu.c
+++ b/arch/powerpc/perf/power4-pmu.c
@@ -356,7 +356,7 @@ static int p4_get_alternatives(u64 event, unsigned int flags, u64 alt[])
356} 356}
357 357
358static int p4_compute_mmcr(u64 event[], int n_ev, 358static int p4_compute_mmcr(u64 event[], int n_ev,
359 unsigned int hwc[], unsigned long mmcr[]) 359 unsigned int hwc[], unsigned long mmcr[], struct perf_event *pevents[])
360{ 360{
361 unsigned long mmcr0 = 0, mmcr1 = 0, mmcra = 0; 361 unsigned long mmcr0 = 0, mmcr1 = 0, mmcra = 0;
362 unsigned int pmc, unit, byte, psel, lower; 362 unsigned int pmc, unit, byte, psel, lower;
diff --git a/arch/powerpc/perf/power5+-pmu.c b/arch/powerpc/perf/power5+-pmu.c
index b03b6dc0172d..0526dac66007 100644
--- a/arch/powerpc/perf/power5+-pmu.c
+++ b/arch/powerpc/perf/power5+-pmu.c
@@ -452,7 +452,7 @@ static int power5p_marked_instr_event(u64 event)
452} 452}
453 453
454static int power5p_compute_mmcr(u64 event[], int n_ev, 454static int power5p_compute_mmcr(u64 event[], int n_ev,
455 unsigned int hwc[], unsigned long mmcr[]) 455 unsigned int hwc[], unsigned long mmcr[], struct perf_event *pevents[])
456{ 456{
457 unsigned long mmcr1 = 0; 457 unsigned long mmcr1 = 0;
458 unsigned long mmcra = 0; 458 unsigned long mmcra = 0;
diff --git a/arch/powerpc/perf/power5-pmu.c b/arch/powerpc/perf/power5-pmu.c
index 1e8ce423c3af..4dc99f9f7962 100644
--- a/arch/powerpc/perf/power5-pmu.c
+++ b/arch/powerpc/perf/power5-pmu.c
@@ -383,7 +383,7 @@ static int power5_marked_instr_event(u64 event)
383} 383}
384 384
385static int power5_compute_mmcr(u64 event[], int n_ev, 385static int power5_compute_mmcr(u64 event[], int n_ev,
386 unsigned int hwc[], unsigned long mmcr[]) 386 unsigned int hwc[], unsigned long mmcr[], struct perf_event *pevents[])
387{ 387{
388 unsigned long mmcr1 = 0; 388 unsigned long mmcr1 = 0;
389 unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS; 389 unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS;
diff --git a/arch/powerpc/perf/power6-pmu.c b/arch/powerpc/perf/power6-pmu.c
index 31128e086fed..9c9d646b68a1 100644
--- a/arch/powerpc/perf/power6-pmu.c
+++ b/arch/powerpc/perf/power6-pmu.c
@@ -175,7 +175,7 @@ static int power6_marked_instr_event(u64 event)
175 * Assign PMC numbers and compute MMCR1 value for a set of events 175 * Assign PMC numbers and compute MMCR1 value for a set of events
176 */ 176 */
177static int p6_compute_mmcr(u64 event[], int n_ev, 177static int p6_compute_mmcr(u64 event[], int n_ev,
178 unsigned int hwc[], unsigned long mmcr[]) 178 unsigned int hwc[], unsigned long mmcr[], struct perf_event *pevents[])
179{ 179{
180 unsigned long mmcr1 = 0; 180 unsigned long mmcr1 = 0;
181 unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS; 181 unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS;
diff --git a/arch/powerpc/perf/power7-pmu.c b/arch/powerpc/perf/power7-pmu.c
index 56c67bca2f75..5b62f2389290 100644
--- a/arch/powerpc/perf/power7-pmu.c
+++ b/arch/powerpc/perf/power7-pmu.c
@@ -245,7 +245,7 @@ static int power7_marked_instr_event(u64 event)
245} 245}
246 246
247static int power7_compute_mmcr(u64 event[], int n_ev, 247static int power7_compute_mmcr(u64 event[], int n_ev,
248 unsigned int hwc[], unsigned long mmcr[]) 248 unsigned int hwc[], unsigned long mmcr[], struct perf_event *pevents[])
249{ 249{
250 unsigned long mmcr1 = 0; 250 unsigned long mmcr1 = 0;
251 unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS; 251 unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS;
diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
index 639cd9156585..396351db601b 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -15,6 +15,7 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/perf_event.h> 16#include <linux/perf_event.h>
17#include <asm/firmware.h> 17#include <asm/firmware.h>
18#include <asm/cputable.h>
18 19
19 20
20/* 21/*
@@ -266,6 +267,11 @@
266#define MMCRA_SDAR_MODE_TLB (1ull << 42) 267#define MMCRA_SDAR_MODE_TLB (1ull << 42)
267#define MMCRA_IFM_SHIFT 30 268#define MMCRA_IFM_SHIFT 30
268 269
270/* Bits in MMCR2 for POWER8 */
271#define MMCR2_FCS(pmc) (1ull << (63 - (((pmc) - 1) * 9)))
272#define MMCR2_FCP(pmc) (1ull << (62 - (((pmc) - 1) * 9)))
273#define MMCR2_FCH(pmc) (1ull << (57 - (((pmc) - 1) * 9)))
274
269 275
270static inline bool event_is_fab_match(u64 event) 276static inline bool event_is_fab_match(u64 event)
271{ 277{
@@ -393,9 +399,10 @@ static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long
393} 399}
394 400
395static int power8_compute_mmcr(u64 event[], int n_ev, 401static int power8_compute_mmcr(u64 event[], int n_ev,
396 unsigned int hwc[], unsigned long mmcr[]) 402 unsigned int hwc[], unsigned long mmcr[],
403 struct perf_event *pevents[])
397{ 404{
398 unsigned long mmcra, mmcr1, unit, combine, psel, cache, val; 405 unsigned long mmcra, mmcr1, mmcr2, unit, combine, psel, cache, val;
399 unsigned int pmc, pmc_inuse; 406 unsigned int pmc, pmc_inuse;
400 int i; 407 int i;
401 408
@@ -410,7 +417,7 @@ static int power8_compute_mmcr(u64 event[], int n_ev,
410 417
411 /* In continous sampling mode, update SDAR on TLB miss */ 418 /* In continous sampling mode, update SDAR on TLB miss */
412 mmcra = MMCRA_SDAR_MODE_TLB; 419 mmcra = MMCRA_SDAR_MODE_TLB;
413 mmcr1 = 0; 420 mmcr1 = mmcr2 = 0;
414 421
415 /* Second pass: assign PMCs, set all MMCR1 fields */ 422 /* Second pass: assign PMCs, set all MMCR1 fields */
416 for (i = 0; i < n_ev; ++i) { 423 for (i = 0; i < n_ev; ++i) {
@@ -472,6 +479,19 @@ static int power8_compute_mmcr(u64 event[], int n_ev,
472 mmcra |= val << MMCRA_IFM_SHIFT; 479 mmcra |= val << MMCRA_IFM_SHIFT;
473 } 480 }
474 481
482 if (pevents[i]->attr.exclude_user)
483 mmcr2 |= MMCR2_FCP(pmc);
484
485 if (pevents[i]->attr.exclude_hv)
486 mmcr2 |= MMCR2_FCH(pmc);
487
488 if (pevents[i]->attr.exclude_kernel) {
489 if (cpu_has_feature(CPU_FTR_HVMODE))
490 mmcr2 |= MMCR2_FCH(pmc);
491 else
492 mmcr2 |= MMCR2_FCS(pmc);
493 }
494
475 hwc[i] = pmc - 1; 495 hwc[i] = pmc - 1;
476 } 496 }
477 497
@@ -491,6 +511,7 @@ static int power8_compute_mmcr(u64 event[], int n_ev,
491 511
492 mmcr[1] = mmcr1; 512 mmcr[1] = mmcr1;
493 mmcr[2] = mmcra; 513 mmcr[2] = mmcra;
514 mmcr[3] = mmcr2;
494 515
495 return 0; 516 return 0;
496} 517}
diff --git a/arch/powerpc/perf/ppc970-pmu.c b/arch/powerpc/perf/ppc970-pmu.c
index 20139ceeacf6..8b6a8a36fa38 100644
--- a/arch/powerpc/perf/ppc970-pmu.c
+++ b/arch/powerpc/perf/ppc970-pmu.c
@@ -257,7 +257,7 @@ static int p970_get_alternatives(u64 event, unsigned int flags, u64 alt[])
257} 257}
258 258
259static int p970_compute_mmcr(u64 event[], int n_ev, 259static int p970_compute_mmcr(u64 event[], int n_ev,
260 unsigned int hwc[], unsigned long mmcr[]) 260 unsigned int hwc[], unsigned long mmcr[], struct perf_event *pevents[])
261{ 261{
262 unsigned long mmcr0 = 0, mmcr1 = 0, mmcra = 0; 262 unsigned long mmcr0 = 0, mmcr1 = 0, mmcra = 0;
263 unsigned int pmc, unit, byte, psel; 263 unsigned int pmc, unit, byte, psel;
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index f442120e0033..0c1e6903597e 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -274,7 +274,7 @@ config CORENET_GENERIC
274 For 32bit kernel, the following boards are supported: 274 For 32bit kernel, the following boards are supported:
275 P2041 RDB, P3041 DS, P4080 DS, kmcoge4, and OCA4080 275 P2041 RDB, P3041 DS, P4080 DS, kmcoge4, and OCA4080
276 For 64bit kernel, the following boards are supported: 276 For 64bit kernel, the following boards are supported:
277 T4240 QDS and B4 QDS 277 T208x QDS/RDB, T4240 QDS/RDB and B4 QDS
278 The following boards are supported for both 32bit and 64bit kernel: 278 The following boards are supported for both 32bit and 64bit kernel:
279 P5020 DS, P5040 DS and T104xQDS 279 P5020 DS, P5040 DS and T104xQDS
280 280
diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c
index 5db1e117fdde..d22dd85e50bf 100644
--- a/arch/powerpc/platforms/85xx/corenet_generic.c
+++ b/arch/powerpc/platforms/85xx/corenet_generic.c
@@ -119,7 +119,11 @@ static const char * const boards[] __initconst = {
119 "fsl,P4080DS", 119 "fsl,P4080DS",
120 "fsl,P5020DS", 120 "fsl,P5020DS",
121 "fsl,P5040DS", 121 "fsl,P5040DS",
122 "fsl,T2080QDS",
123 "fsl,T2080RDB",
124 "fsl,T2081QDS",
122 "fsl,T4240QDS", 125 "fsl,T4240QDS",
126 "fsl,T4240RDB",
123 "fsl,B4860QDS", 127 "fsl,B4860QDS",
124 "fsl,B4420QDS", 128 "fsl,B4420QDS",
125 "fsl,B4220QDS", 129 "fsl,B4220QDS",
@@ -129,28 +133,14 @@ static const char * const boards[] __initconst = {
129 NULL 133 NULL
130}; 134};
131 135
132static const char * const hv_boards[] __initconst = {
133 "fsl,P2041RDB-hv",
134 "fsl,P3041DS-hv",
135 "fsl,OCA4080-hv",
136 "fsl,P4080DS-hv",
137 "fsl,P5020DS-hv",
138 "fsl,P5040DS-hv",
139 "fsl,T4240QDS-hv",
140 "fsl,B4860QDS-hv",
141 "fsl,B4420QDS-hv",
142 "fsl,B4220QDS-hv",
143 "fsl,T1040QDS-hv",
144 "fsl,T1042QDS-hv",
145 NULL
146};
147
148/* 136/*
149 * Called very early, device-tree isn't unflattened 137 * Called very early, device-tree isn't unflattened
150 */ 138 */
151static int __init corenet_generic_probe(void) 139static int __init corenet_generic_probe(void)
152{ 140{
153 unsigned long root = of_get_flat_dt_root(); 141 unsigned long root = of_get_flat_dt_root();
142 char hv_compat[24];
143 int i;
154#ifdef CONFIG_SMP 144#ifdef CONFIG_SMP
155 extern struct smp_ops_t smp_85xx_ops; 145 extern struct smp_ops_t smp_85xx_ops;
156#endif 146#endif
@@ -159,21 +149,26 @@ static int __init corenet_generic_probe(void)
159 return 1; 149 return 1;
160 150
161 /* Check if we're running under the Freescale hypervisor */ 151 /* Check if we're running under the Freescale hypervisor */
162 if (of_flat_dt_match(root, hv_boards)) { 152 for (i = 0; boards[i]; i++) {
163 ppc_md.init_IRQ = ehv_pic_init; 153 snprintf(hv_compat, sizeof(hv_compat), "%s-hv", boards[i]);
164 ppc_md.get_irq = ehv_pic_get_irq; 154 if (of_flat_dt_is_compatible(root, hv_compat)) {
165 ppc_md.restart = fsl_hv_restart; 155 ppc_md.init_IRQ = ehv_pic_init;
166 ppc_md.power_off = fsl_hv_halt; 156
167 ppc_md.halt = fsl_hv_halt; 157 ppc_md.get_irq = ehv_pic_get_irq;
158 ppc_md.restart = fsl_hv_restart;
159 ppc_md.power_off = fsl_hv_halt;
160 ppc_md.halt = fsl_hv_halt;
168#ifdef CONFIG_SMP 161#ifdef CONFIG_SMP
169 /* 162 /*
170 * Disable the timebase sync operations because we can't write 163 * Disable the timebase sync operations because we
171 * to the timebase registers under the hypervisor. 164 * can't write to the timebase registers under the
172 */ 165 * hypervisor.
173 smp_85xx_ops.give_timebase = NULL; 166 */
174 smp_85xx_ops.take_timebase = NULL; 167 smp_85xx_ops.give_timebase = NULL;
168 smp_85xx_ops.take_timebase = NULL;
175#endif 169#endif
176 return 1; 170 return 1;
171 }
177 } 172 }
178 173
179 return 0; 174 return 0;
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index ba093f553678..d7c1e69f3070 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -28,6 +28,7 @@
28#include <asm/dbell.h> 28#include <asm/dbell.h>
29#include <asm/fsl_guts.h> 29#include <asm/fsl_guts.h>
30#include <asm/code-patching.h> 30#include <asm/code-patching.h>
31#include <asm/cputhreads.h>
31 32
32#include <sysdev/fsl_soc.h> 33#include <sysdev/fsl_soc.h>
33#include <sysdev/mpic.h> 34#include <sysdev/mpic.h>
@@ -168,6 +169,24 @@ static inline u32 read_spin_table_addr_l(void *spin_table)
168 return in_be32(&((struct epapr_spin_table *)spin_table)->addr_l); 169 return in_be32(&((struct epapr_spin_table *)spin_table)->addr_l);
169} 170}
170 171
172#ifdef CONFIG_PPC64
173static void wake_hw_thread(void *info)
174{
175 void fsl_secondary_thread_init(void);
176 unsigned long imsr1, inia1;
177 int nr = *(const int *)info;
178
179 imsr1 = MSR_KERNEL;
180 inia1 = *(unsigned long *)fsl_secondary_thread_init;
181
182 mttmr(TMRN_IMSR1, imsr1);
183 mttmr(TMRN_INIA1, inia1);
184 mtspr(SPRN_TENS, TEN_THREAD(1));
185
186 smp_generic_kick_cpu(nr);
187}
188#endif
189
171static int smp_85xx_kick_cpu(int nr) 190static int smp_85xx_kick_cpu(int nr)
172{ 191{
173 unsigned long flags; 192 unsigned long flags;
@@ -183,6 +202,31 @@ static int smp_85xx_kick_cpu(int nr)
183 202
184 pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr); 203 pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr);
185 204
205#ifdef CONFIG_PPC64
206 /* Threads don't use the spin table */
207 if (cpu_thread_in_core(nr) != 0) {
208 int primary = cpu_first_thread_sibling(nr);
209
210 if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT)))
211 return -ENOENT;
212
213 if (cpu_thread_in_core(nr) != 1) {
214 pr_err("%s: cpu %d: invalid hw thread %d\n",
215 __func__, nr, cpu_thread_in_core(nr));
216 return -ENOENT;
217 }
218
219 if (!cpu_online(primary)) {
220 pr_err("%s: cpu %d: primary %d not online\n",
221 __func__, nr, primary);
222 return -ENOENT;
223 }
224
225 smp_call_function_single(primary, wake_hw_thread, &nr, 0);
226 return 0;
227 }
228#endif
229
186 np = of_get_cpu_node(nr, NULL); 230 np = of_get_cpu_node(nr, NULL);
187 cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL); 231 cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL);
188 232
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index 587a2828b06c..d3037747031d 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -18,7 +18,6 @@
18#include <linux/fsl_devices.h> 18#include <linux/fsl_devices.h>
19 19
20#include <asm/io.h> 20#include <asm/io.h>
21#include <asm/mpc8xx.h>
22#include <asm/8xx_immap.h> 21#include <asm/8xx_immap.h>
23#include <asm/prom.h> 22#include <asm/prom.h>
24#include <asm/fs_pd.h> 23#include <asm/fs_pd.h>
@@ -28,8 +27,6 @@
28 27
29#include "mpc8xx.h" 28#include "mpc8xx.h"
30 29
31struct mpc8xx_pcmcia_ops m8xx_pcmcia_ops;
32
33extern int cpm_pic_init(void); 30extern int cpm_pic_init(void);
34extern int cpm_get_irq(void); 31extern int cpm_get_irq(void);
35 32
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index c1262581b63c..5921dcb498fd 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -35,7 +35,6 @@
35#include <asm/page.h> 35#include <asm/page.h>
36#include <asm/processor.h> 36#include <asm/processor.h>
37#include <asm/time.h> 37#include <asm/time.h>
38#include <asm/mpc8xx.h>
39#include <asm/8xx_immap.h> 38#include <asm/8xx_immap.h>
40#include <asm/cpm1.h> 39#include <asm/cpm1.h>
41#include <asm/fs_pd.h> 40#include <asm/fs_pd.h>
@@ -46,61 +45,6 @@
46 45
47static u32 __iomem *bcsr, *bcsr5; 46static u32 __iomem *bcsr, *bcsr5;
48 47
49#ifdef CONFIG_PCMCIA_M8XX
50static void pcmcia_hw_setup(int slot, int enable)
51{
52 if (enable)
53 clrbits32(&bcsr[1], BCSR1_PCCEN);
54 else
55 setbits32(&bcsr[1], BCSR1_PCCEN);
56}
57
58static int pcmcia_set_voltage(int slot, int vcc, int vpp)
59{
60 u32 reg = 0;
61
62 switch (vcc) {
63 case 0:
64 break;
65 case 33:
66 reg |= BCSR1_PCCVCC0;
67 break;
68 case 50:
69 reg |= BCSR1_PCCVCC1;
70 break;
71 default:
72 return 1;
73 }
74
75 switch (vpp) {
76 case 0:
77 break;
78 case 33:
79 case 50:
80 if (vcc == vpp)
81 reg |= BCSR1_PCCVPP1;
82 else
83 return 1;
84 break;
85 case 120:
86 if ((vcc == 33) || (vcc == 50))
87 reg |= BCSR1_PCCVPP0;
88 else
89 return 1;
90 default:
91 return 1;
92 }
93
94 /* first, turn off all power */
95 clrbits32(&bcsr[1], 0x00610000);
96
97 /* enable new powersettings */
98 setbits32(&bcsr[1], reg);
99
100 return 0;
101}
102#endif
103
104struct cpm_pin { 48struct cpm_pin {
105 int port, pin, flags; 49 int port, pin, flags;
106}; 50};
@@ -245,12 +189,6 @@ static void __init mpc885ads_setup_arch(void)
245 of_detach_node(np); 189 of_detach_node(np);
246 of_node_put(np); 190 of_node_put(np);
247 } 191 }
248
249#ifdef CONFIG_PCMCIA_M8XX
250 /* Set up board specific hook-ups.*/
251 m8xx_pcmcia_ops.hw_ctrl = pcmcia_hw_setup;
252 m8xx_pcmcia_ops.voltage_set = pcmcia_set_voltage;
253#endif
254} 192}
255 193
256static int __init mpc885ads_probe(void) 194static int __init mpc885ads_probe(void)
diff --git a/arch/powerpc/platforms/8xx/tqm8xx_setup.c b/arch/powerpc/platforms/8xx/tqm8xx_setup.c
index 251aba8759e4..dda607807def 100644
--- a/arch/powerpc/platforms/8xx/tqm8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/tqm8xx_setup.c
@@ -37,7 +37,6 @@
37#include <asm/page.h> 37#include <asm/page.h>
38#include <asm/processor.h> 38#include <asm/processor.h>
39#include <asm/time.h> 39#include <asm/time.h>
40#include <asm/mpc8xx.h>
41#include <asm/8xx_immap.h> 40#include <asm/8xx_immap.h>
42#include <asm/cpm1.h> 41#include <asm/cpm1.h>
43#include <asm/fs_pd.h> 42#include <asm/fs_pd.h>
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index a41bd023647a..e8bc40869cbd 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -61,7 +61,7 @@ choice
61 help 61 help
62 There are two families of 64 bit PowerPC chips supported. 62 There are two families of 64 bit PowerPC chips supported.
63 The most common ones are the desktop and server CPUs 63 The most common ones are the desktop and server CPUs
64 (POWER3, RS64, POWER4, POWER5, POWER5+, POWER6, ...) 64 (POWER4, POWER5, 970, POWER5+, POWER6, POWER7, POWER8 ...)
65 65
66 The other are the "embedded" processors compliant with the 66 The other are the "embedded" processors compliant with the
67 "Book 3E" variant of the architecture 67 "Book 3E" variant of the architecture
@@ -140,14 +140,6 @@ config 6xx
140 depends on PPC32 && PPC_BOOK3S 140 depends on PPC32 && PPC_BOOK3S
141 select PPC_HAVE_PMU_SUPPORT 141 select PPC_HAVE_PMU_SUPPORT
142 142
143config POWER3
144 depends on PPC64 && PPC_BOOK3S
145 def_bool y
146
147config POWER4
148 depends on PPC64 && PPC_BOOK3S
149 def_bool y
150
151config TUNE_CELL 143config TUNE_CELL
152 bool "Optimize for Cell Broadband Engine" 144 bool "Optimize for Cell Broadband Engine"
153 depends on PPC64 && PPC_BOOK3S 145 depends on PPC64 && PPC_BOOK3S
@@ -244,7 +236,7 @@ config PHYS_64BIT
244 236
245config ALTIVEC 237config ALTIVEC
246 bool "AltiVec Support" 238 bool "AltiVec Support"
247 depends on 6xx || POWER4 || (PPC_E500MC && PPC64) 239 depends on 6xx || PPC_BOOK3S_64 || (PPC_E500MC && PPC64)
248 ---help--- 240 ---help---
249 This option enables kernel support for the Altivec extensions to the 241 This option enables kernel support for the Altivec extensions to the
250 PowerPC processor. The kernel currently supports saving and restoring 242 PowerPC processor. The kernel currently supports saving and restoring
@@ -260,7 +252,7 @@ config ALTIVEC
260 252
261config VSX 253config VSX
262 bool "VSX Support" 254 bool "VSX Support"
263 depends on POWER4 && ALTIVEC && PPC_FPU 255 depends on PPC_BOOK3S_64 && ALTIVEC && PPC_FPU
264 ---help--- 256 ---help---
265 257
266 This option enables kernel support for the Vector Scaler extensions 258 This option enables kernel support for the Vector Scaler extensions
@@ -276,7 +268,7 @@ config VSX
276 268
277config PPC_ICSWX 269config PPC_ICSWX
278 bool "Support for PowerPC icswx coprocessor instruction" 270 bool "Support for PowerPC icswx coprocessor instruction"
279 depends on POWER4 271 depends on PPC_BOOK3S_64
280 default n 272 default n
281 ---help--- 273 ---help---
282 274
@@ -294,7 +286,7 @@ config PPC_ICSWX
294 286
295config PPC_ICSWX_PID 287config PPC_ICSWX_PID
296 bool "icswx requires direct PID management" 288 bool "icswx requires direct PID management"
297 depends on PPC_ICSWX && POWER4 289 depends on PPC_ICSWX
298 default y 290 default y
299 ---help--- 291 ---help---
300 The PID register in server is used explicitly for ICSWX. In 292 The PID register in server is used explicitly for ICSWX. In
diff --git a/arch/powerpc/platforms/powermac/Kconfig b/arch/powerpc/platforms/powermac/Kconfig
index 1afd10f67858..607124bae2e7 100644
--- a/arch/powerpc/platforms/powermac/Kconfig
+++ b/arch/powerpc/platforms/powermac/Kconfig
@@ -10,7 +10,7 @@ config PPC_PMAC
10 10
11config PPC_PMAC64 11config PPC_PMAC64
12 bool 12 bool
13 depends on PPC_PMAC && POWER4 13 depends on PPC_PMAC && PPC64
14 select MPIC 14 select MPIC
15 select U3_DART 15 select U3_DART
16 select MPIC_U3_HT_IRQS 16 select MPIC_U3_HT_IRQS
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index 63d82bbc05e9..1413e72bc2e1 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -158,7 +158,7 @@ static inline int simple_feature_tweak(struct device_node *node, int type,
158 return 0; 158 return 0;
159} 159}
160 160
161#ifndef CONFIG_POWER4 161#ifndef CONFIG_PPC64
162 162
163static long ohare_htw_scc_enable(struct device_node *node, long param, 163static long ohare_htw_scc_enable(struct device_node *node, long param,
164 long value) 164 long value)
@@ -1318,7 +1318,7 @@ intrepid_aack_delay_enable(struct device_node *node, long param, long value)
1318} 1318}
1319 1319
1320 1320
1321#endif /* CONFIG_POWER4 */ 1321#endif /* CONFIG_PPC64 */
1322 1322
1323static long 1323static long
1324core99_read_gpio(struct device_node *node, long param, long value) 1324core99_read_gpio(struct device_node *node, long param, long value)
@@ -1338,7 +1338,7 @@ core99_write_gpio(struct device_node *node, long param, long value)
1338 return 0; 1338 return 0;
1339} 1339}
1340 1340
1341#ifdef CONFIG_POWER4 1341#ifdef CONFIG_PPC64
1342static long g5_gmac_enable(struct device_node *node, long param, long value) 1342static long g5_gmac_enable(struct device_node *node, long param, long value)
1343{ 1343{
1344 struct macio_chip *macio = &macio_chips[0]; 1344 struct macio_chip *macio = &macio_chips[0];
@@ -1550,9 +1550,9 @@ void g5_phy_disable_cpu1(void)
1550 if (uninorth_maj == 3) 1550 if (uninorth_maj == 3)
1551 UN_OUT(U3_API_PHY_CONFIG_1, 0); 1551 UN_OUT(U3_API_PHY_CONFIG_1, 0);
1552} 1552}
1553#endif /* CONFIG_POWER4 */ 1553#endif /* CONFIG_PPC64 */
1554 1554
1555#ifndef CONFIG_POWER4 1555#ifndef CONFIG_PPC64
1556 1556
1557 1557
1558#ifdef CONFIG_PM 1558#ifdef CONFIG_PM
@@ -1864,7 +1864,7 @@ core99_sleep_state(struct device_node *node, long param, long value)
1864 return 0; 1864 return 0;
1865} 1865}
1866 1866
1867#endif /* CONFIG_POWER4 */ 1867#endif /* CONFIG_PPC64 */
1868 1868
1869static long 1869static long
1870generic_dev_can_wake(struct device_node *node, long param, long value) 1870generic_dev_can_wake(struct device_node *node, long param, long value)
@@ -1906,7 +1906,7 @@ static struct feature_table_entry any_features[] = {
1906 { 0, NULL } 1906 { 0, NULL }
1907}; 1907};
1908 1908
1909#ifndef CONFIG_POWER4 1909#ifndef CONFIG_PPC64
1910 1910
1911/* OHare based motherboards. Currently, we only use these on the 1911/* OHare based motherboards. Currently, we only use these on the
1912 * 2400,3400 and 3500 series powerbooks. Some older desktops seem 1912 * 2400,3400 and 3500 series powerbooks. Some older desktops seem
@@ -2056,7 +2056,7 @@ static struct feature_table_entry intrepid_features[] = {
2056 { 0, NULL } 2056 { 0, NULL }
2057}; 2057};
2058 2058
2059#else /* CONFIG_POWER4 */ 2059#else /* CONFIG_PPC64 */
2060 2060
2061/* G5 features 2061/* G5 features
2062 */ 2062 */
@@ -2074,10 +2074,10 @@ static struct feature_table_entry g5_features[] = {
2074 { 0, NULL } 2074 { 0, NULL }
2075}; 2075};
2076 2076
2077#endif /* CONFIG_POWER4 */ 2077#endif /* CONFIG_PPC64 */
2078 2078
2079static struct pmac_mb_def pmac_mb_defs[] = { 2079static struct pmac_mb_def pmac_mb_defs[] = {
2080#ifndef CONFIG_POWER4 2080#ifndef CONFIG_PPC64
2081 /* 2081 /*
2082 * Desktops 2082 * Desktops
2083 */ 2083 */
@@ -2342,7 +2342,7 @@ static struct pmac_mb_def pmac_mb_defs[] = {
2342 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, 2342 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2343 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, 2343 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2344 }, 2344 },
2345#else /* CONFIG_POWER4 */ 2345#else /* CONFIG_PPC64 */
2346 { "PowerMac7,2", "PowerMac G5", 2346 { "PowerMac7,2", "PowerMac G5",
2347 PMAC_TYPE_POWERMAC_G5, g5_features, 2347 PMAC_TYPE_POWERMAC_G5, g5_features,
2348 0, 2348 0,
@@ -2373,7 +2373,7 @@ static struct pmac_mb_def pmac_mb_defs[] = {
2373 0, 2373 0,
2374 }, 2374 },
2375#endif /* CONFIG_PPC64 */ 2375#endif /* CONFIG_PPC64 */
2376#endif /* CONFIG_POWER4 */ 2376#endif /* CONFIG_PPC64 */
2377}; 2377};
2378 2378
2379/* 2379/*
@@ -2441,7 +2441,7 @@ static int __init probe_motherboard(void)
2441 2441
2442 /* Fallback to selection depending on mac-io chip type */ 2442 /* Fallback to selection depending on mac-io chip type */
2443 switch(macio->type) { 2443 switch(macio->type) {
2444#ifndef CONFIG_POWER4 2444#ifndef CONFIG_PPC64
2445 case macio_grand_central: 2445 case macio_grand_central:
2446 pmac_mb.model_id = PMAC_TYPE_PSURGE; 2446 pmac_mb.model_id = PMAC_TYPE_PSURGE;
2447 pmac_mb.model_name = "Unknown PowerSurge"; 2447 pmac_mb.model_name = "Unknown PowerSurge";
@@ -2475,7 +2475,7 @@ static int __init probe_motherboard(void)
2475 pmac_mb.model_name = "Unknown Intrepid-based"; 2475 pmac_mb.model_name = "Unknown Intrepid-based";
2476 pmac_mb.features = intrepid_features; 2476 pmac_mb.features = intrepid_features;
2477 break; 2477 break;
2478#else /* CONFIG_POWER4 */ 2478#else /* CONFIG_PPC64 */
2479 case macio_keylargo2: 2479 case macio_keylargo2:
2480 pmac_mb.model_id = PMAC_TYPE_UNKNOWN_K2; 2480 pmac_mb.model_id = PMAC_TYPE_UNKNOWN_K2;
2481 pmac_mb.model_name = "Unknown K2-based"; 2481 pmac_mb.model_name = "Unknown K2-based";
@@ -2486,13 +2486,13 @@ static int __init probe_motherboard(void)
2486 pmac_mb.model_name = "Unknown Shasta-based"; 2486 pmac_mb.model_name = "Unknown Shasta-based";
2487 pmac_mb.features = g5_features; 2487 pmac_mb.features = g5_features;
2488 break; 2488 break;
2489#endif /* CONFIG_POWER4 */ 2489#endif /* CONFIG_PPC64 */
2490 default: 2490 default:
2491 ret = -ENODEV; 2491 ret = -ENODEV;
2492 goto done; 2492 goto done;
2493 } 2493 }
2494found: 2494found:
2495#ifndef CONFIG_POWER4 2495#ifndef CONFIG_PPC64
2496 /* Fixup Hooper vs. Comet */ 2496 /* Fixup Hooper vs. Comet */
2497 if (pmac_mb.model_id == PMAC_TYPE_HOOPER) { 2497 if (pmac_mb.model_id == PMAC_TYPE_HOOPER) {
2498 u32 __iomem * mach_id_ptr = ioremap(0xf3000034, 4); 2498 u32 __iomem * mach_id_ptr = ioremap(0xf3000034, 4);
@@ -2546,9 +2546,9 @@ found:
2546 */ 2546 */
2547 powersave_lowspeed = 1; 2547 powersave_lowspeed = 1;
2548 2548
2549#else /* CONFIG_POWER4 */ 2549#else /* CONFIG_PPC64 */
2550 powersave_nap = 1; 2550 powersave_nap = 1;
2551#endif /* CONFIG_POWER4 */ 2551#endif /* CONFIG_PPC64 */
2552 2552
2553 /* Check for "mobile" machine */ 2553 /* Check for "mobile" machine */
2554 if (model && (strncmp(model, "PowerBook", 9) == 0 2554 if (model && (strncmp(model, "PowerBook", 9) == 0
@@ -2786,7 +2786,7 @@ set_initial_features(void)
2786 MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE); 2786 MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
2787 } 2787 }
2788 2788
2789#ifdef CONFIG_POWER4 2789#ifdef CONFIG_PPC64
2790 if (macio_chips[0].type == macio_keylargo2 || 2790 if (macio_chips[0].type == macio_keylargo2 ||
2791 macio_chips[0].type == macio_shasta) { 2791 macio_chips[0].type == macio_shasta) {
2792#ifndef CONFIG_SMP 2792#ifndef CONFIG_SMP
@@ -2826,7 +2826,7 @@ set_initial_features(void)
2826 np = of_find_node_by_name(np, "firewire"); 2826 np = of_find_node_by_name(np, "firewire");
2827 } 2827 }
2828 } 2828 }
2829#else /* CONFIG_POWER4 */ 2829#else /* CONFIG_PPC64 */
2830 2830
2831 if (macio_chips[0].type == macio_keylargo || 2831 if (macio_chips[0].type == macio_keylargo ||
2832 macio_chips[0].type == macio_pangea || 2832 macio_chips[0].type == macio_pangea ||
@@ -2895,7 +2895,7 @@ set_initial_features(void)
2895 MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N); 2895 MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
2896 } 2896 }
2897 2897
2898#endif /* CONFIG_POWER4 */ 2898#endif /* CONFIG_PPC64 */
2899 2899
2900 /* On all machines, switch modem & serial ports off */ 2900 /* On all machines, switch modem & serial ports off */
2901 for_each_node_by_name(np, "ch-a") 2901 for_each_node_by_name(np, "ch-a")
diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
index 4ad227d04c1a..f241accc053d 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -1,10 +1,11 @@
1obj-y += setup.o opal-wrappers.o opal.o opal-async.o 1obj-y += setup.o opal-wrappers.o opal.o opal-async.o
2obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o 2obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
3obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o 3obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o
4obj-y += opal-msglog.o 4obj-y += opal-msglog.o opal-hmi.o
5 5
6obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o 6obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o
7obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o 7obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o
8obj-$(CONFIG_EEH) += eeh-ioda.o eeh-powernv.o 8obj-$(CONFIG_EEH) += eeh-ioda.o eeh-powernv.o
9obj-$(CONFIG_PPC_SCOM) += opal-xscom.o 9obj-$(CONFIG_PPC_SCOM) += opal-xscom.o
10obj-$(CONFIG_MEMORY_FAILURE) += opal-memory-errors.o 10obj-$(CONFIG_MEMORY_FAILURE) += opal-memory-errors.o
11obj-$(CONFIG_TRACEPOINTS) += opal-tracepoints.o
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c
index 8ad0c5b891f4..c945bed4dc9e 100644
--- a/arch/powerpc/platforms/powernv/eeh-ioda.c
+++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
@@ -187,10 +187,10 @@ static int ioda_eeh_post_init(struct pci_controller *hose)
187 */ 187 */
188static int ioda_eeh_set_option(struct eeh_pe *pe, int option) 188static int ioda_eeh_set_option(struct eeh_pe *pe, int option)
189{ 189{
190 s64 ret;
191 u32 pe_no;
192 struct pci_controller *hose = pe->phb; 190 struct pci_controller *hose = pe->phb;
193 struct pnv_phb *phb = hose->private_data; 191 struct pnv_phb *phb = hose->private_data;
192 int enable, ret = 0;
193 s64 rc;
194 194
195 /* Check on PE number */ 195 /* Check on PE number */
196 if (pe->addr < 0 || pe->addr >= phb->ioda.total_pe) { 196 if (pe->addr < 0 || pe->addr >= phb->ioda.total_pe) {
@@ -201,184 +201,214 @@ static int ioda_eeh_set_option(struct eeh_pe *pe, int option)
201 return -EINVAL; 201 return -EINVAL;
202 } 202 }
203 203
204 pe_no = pe->addr;
205 switch (option) { 204 switch (option) {
206 case EEH_OPT_DISABLE: 205 case EEH_OPT_DISABLE:
207 ret = -EEXIST; 206 return -EPERM;
208 break;
209 case EEH_OPT_ENABLE: 207 case EEH_OPT_ENABLE:
210 ret = 0; 208 return 0;
211 break;
212 case EEH_OPT_THAW_MMIO: 209 case EEH_OPT_THAW_MMIO:
213 ret = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no, 210 enable = OPAL_EEH_ACTION_CLEAR_FREEZE_MMIO;
214 OPAL_EEH_ACTION_CLEAR_FREEZE_MMIO);
215 if (ret) {
216 pr_warning("%s: Failed to enable MMIO for "
217 "PHB#%x-PE#%x, err=%lld\n",
218 __func__, hose->global_number, pe_no, ret);
219 return -EIO;
220 }
221
222 break; 211 break;
223 case EEH_OPT_THAW_DMA: 212 case EEH_OPT_THAW_DMA:
224 ret = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no, 213 enable = OPAL_EEH_ACTION_CLEAR_FREEZE_DMA;
225 OPAL_EEH_ACTION_CLEAR_FREEZE_DMA);
226 if (ret) {
227 pr_warning("%s: Failed to enable DMA for "
228 "PHB#%x-PE#%x, err=%lld\n",
229 __func__, hose->global_number, pe_no, ret);
230 return -EIO;
231 }
232
233 break; 214 break;
234 default: 215 default:
235 pr_warning("%s: Invalid option %d\n", __func__, option); 216 pr_warn("%s: Invalid option %d\n",
217 __func__, option);
236 return -EINVAL; 218 return -EINVAL;
237 } 219 }
238 220
221 /* If PHB supports compound PE, to handle it */
222 if (phb->unfreeze_pe) {
223 ret = phb->unfreeze_pe(phb, pe->addr, enable);
224 } else {
225 rc = opal_pci_eeh_freeze_clear(phb->opal_id,
226 pe->addr,
227 enable);
228 if (rc != OPAL_SUCCESS) {
229 pr_warn("%s: Failure %lld enable %d for PHB#%x-PE#%x\n",
230 __func__, rc, option, phb->hose->global_number,
231 pe->addr);
232 ret = -EIO;
233 }
234 }
235
239 return ret; 236 return ret;
240} 237}
241 238
242static void ioda_eeh_phb_diag(struct pci_controller *hose) 239static void ioda_eeh_phb_diag(struct eeh_pe *pe)
243{ 240{
244 struct pnv_phb *phb = hose->private_data; 241 struct pnv_phb *phb = pe->phb->private_data;
245 long rc; 242 long rc;
246 243
247 rc = opal_pci_get_phb_diag_data2(phb->opal_id, phb->diag.blob, 244 rc = opal_pci_get_phb_diag_data2(phb->opal_id, pe->data,
248 PNV_PCI_DIAG_BUF_SIZE); 245 PNV_PCI_DIAG_BUF_SIZE);
249 if (rc != OPAL_SUCCESS) { 246 if (rc != OPAL_SUCCESS)
250 pr_warning("%s: Failed to get diag-data for PHB#%x (%ld)\n", 247 pr_warn("%s: Failed to get diag-data for PHB#%x (%ld)\n",
251 __func__, hose->global_number, rc); 248 __func__, pe->phb->global_number, rc);
252 return;
253 }
254
255 pnv_pci_dump_phb_diag_data(hose, phb->diag.blob);
256} 249}
257 250
258/** 251static int ioda_eeh_get_phb_state(struct eeh_pe *pe)
259 * ioda_eeh_get_state - Retrieve the state of PE
260 * @pe: EEH PE
261 *
262 * The PE's state should be retrieved from the PEEV, PEST
263 * IODA tables. Since the OPAL has exported the function
264 * to do it, it'd better to use that.
265 */
266static int ioda_eeh_get_state(struct eeh_pe *pe)
267{ 252{
268 s64 ret = 0; 253 struct pnv_phb *phb = pe->phb->private_data;
269 u8 fstate; 254 u8 fstate;
270 __be16 pcierr; 255 __be16 pcierr;
271 u32 pe_no; 256 s64 rc;
272 int result; 257 int result = 0;
273 struct pci_controller *hose = pe->phb; 258
274 struct pnv_phb *phb = hose->private_data; 259 rc = opal_pci_eeh_freeze_status(phb->opal_id,
260 pe->addr,
261 &fstate,
262 &pcierr,
263 NULL);
264 if (rc != OPAL_SUCCESS) {
265 pr_warn("%s: Failure %lld getting PHB#%x state\n",
266 __func__, rc, phb->hose->global_number);
267 return EEH_STATE_NOT_SUPPORT;
268 }
275 269
276 /* 270 /*
277 * Sanity check on PE address. The PHB PE address should 271 * Check PHB state. If the PHB is frozen for the
278 * be zero. 272 * first time, to dump the PHB diag-data.
279 */ 273 */
280 if (pe->addr < 0 || pe->addr >= phb->ioda.total_pe) { 274 if (be16_to_cpu(pcierr) != OPAL_EEH_PHB_ERROR) {
281 pr_err("%s: PE address %x out of range [0, %x] " 275 result = (EEH_STATE_MMIO_ACTIVE |
282 "on PHB#%x\n", 276 EEH_STATE_DMA_ACTIVE |
283 __func__, pe->addr, phb->ioda.total_pe, 277 EEH_STATE_MMIO_ENABLED |
284 hose->global_number); 278 EEH_STATE_DMA_ENABLED);
285 return EEH_STATE_NOT_SUPPORT; 279 } else if (!(pe->state & EEH_PE_ISOLATED)) {
280 eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
281 ioda_eeh_phb_diag(pe);
286 } 282 }
287 283
284 return result;
285}
286
287static int ioda_eeh_get_pe_state(struct eeh_pe *pe)
288{
289 struct pnv_phb *phb = pe->phb->private_data;
290 u8 fstate;
291 __be16 pcierr;
292 s64 rc;
293 int result;
294
288 /* 295 /*
289 * If we're in middle of PE reset, return normal 296 * We don't clobber hardware frozen state until PE
290 * state to keep EEH core going. For PHB reset, we 297 * reset is completed. In order to keep EEH core
291 * still expect to have fenced PHB cleared with 298 * moving forward, we have to return operational
292 * PHB reset. 299 * state during PE reset.
293 */ 300 */
294 if (!(pe->type & EEH_PE_PHB) && 301 if (pe->state & EEH_PE_RESET) {
295 (pe->state & EEH_PE_RESET)) { 302 result = (EEH_STATE_MMIO_ACTIVE |
296 result = (EEH_STATE_MMIO_ACTIVE | 303 EEH_STATE_DMA_ACTIVE |
297 EEH_STATE_DMA_ACTIVE |
298 EEH_STATE_MMIO_ENABLED | 304 EEH_STATE_MMIO_ENABLED |
299 EEH_STATE_DMA_ENABLED); 305 EEH_STATE_DMA_ENABLED);
300 return result; 306 return result;
301 } 307 }
302 308
303 /* Retrieve PE status through OPAL */ 309 /*
304 pe_no = pe->addr; 310 * Fetch PE state from hardware. If the PHB
305 ret = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, 311 * supports compound PE, let it handle that.
306 &fstate, &pcierr, NULL); 312 */
307 if (ret) { 313 if (phb->get_pe_state) {
308 pr_err("%s: Failed to get EEH status on " 314 fstate = phb->get_pe_state(phb, pe->addr);
309 "PHB#%x-PE#%x\n, err=%lld\n", 315 } else {
310 __func__, hose->global_number, pe_no, ret); 316 rc = opal_pci_eeh_freeze_status(phb->opal_id,
311 return EEH_STATE_NOT_SUPPORT; 317 pe->addr,
312 } 318 &fstate,
313 319 &pcierr,
314 /* Check PHB status */ 320 NULL);
315 if (pe->type & EEH_PE_PHB) { 321 if (rc != OPAL_SUCCESS) {
316 result = 0; 322 pr_warn("%s: Failure %lld getting PHB#%x-PE%x state\n",
317 result &= ~EEH_STATE_RESET_ACTIVE; 323 __func__, rc, phb->hose->global_number, pe->addr);
318 324 return EEH_STATE_NOT_SUPPORT;
319 if (be16_to_cpu(pcierr) != OPAL_EEH_PHB_ERROR) {
320 result |= EEH_STATE_MMIO_ACTIVE;
321 result |= EEH_STATE_DMA_ACTIVE;
322 result |= EEH_STATE_MMIO_ENABLED;
323 result |= EEH_STATE_DMA_ENABLED;
324 } else if (!(pe->state & EEH_PE_ISOLATED)) {
325 eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
326 ioda_eeh_phb_diag(hose);
327 } 325 }
328
329 return result;
330 } 326 }
331 327
332 /* Parse result out */ 328 /* Figure out state */
333 result = 0;
334 switch (fstate) { 329 switch (fstate) {
335 case OPAL_EEH_STOPPED_NOT_FROZEN: 330 case OPAL_EEH_STOPPED_NOT_FROZEN:
336 result &= ~EEH_STATE_RESET_ACTIVE; 331 result = (EEH_STATE_MMIO_ACTIVE |
337 result |= EEH_STATE_MMIO_ACTIVE; 332 EEH_STATE_DMA_ACTIVE |
338 result |= EEH_STATE_DMA_ACTIVE; 333 EEH_STATE_MMIO_ENABLED |
339 result |= EEH_STATE_MMIO_ENABLED; 334 EEH_STATE_DMA_ENABLED);
340 result |= EEH_STATE_DMA_ENABLED;
341 break; 335 break;
342 case OPAL_EEH_STOPPED_MMIO_FREEZE: 336 case OPAL_EEH_STOPPED_MMIO_FREEZE:
343 result &= ~EEH_STATE_RESET_ACTIVE; 337 result = (EEH_STATE_DMA_ACTIVE |
344 result |= EEH_STATE_DMA_ACTIVE; 338 EEH_STATE_DMA_ENABLED);
345 result |= EEH_STATE_DMA_ENABLED;
346 break; 339 break;
347 case OPAL_EEH_STOPPED_DMA_FREEZE: 340 case OPAL_EEH_STOPPED_DMA_FREEZE:
348 result &= ~EEH_STATE_RESET_ACTIVE; 341 result = (EEH_STATE_MMIO_ACTIVE |
349 result |= EEH_STATE_MMIO_ACTIVE; 342 EEH_STATE_MMIO_ENABLED);
350 result |= EEH_STATE_MMIO_ENABLED;
351 break; 343 break;
352 case OPAL_EEH_STOPPED_MMIO_DMA_FREEZE: 344 case OPAL_EEH_STOPPED_MMIO_DMA_FREEZE:
353 result &= ~EEH_STATE_RESET_ACTIVE; 345 result = 0;
354 break; 346 break;
355 case OPAL_EEH_STOPPED_RESET: 347 case OPAL_EEH_STOPPED_RESET:
356 result |= EEH_STATE_RESET_ACTIVE; 348 result = EEH_STATE_RESET_ACTIVE;
357 break; 349 break;
358 case OPAL_EEH_STOPPED_TEMP_UNAVAIL: 350 case OPAL_EEH_STOPPED_TEMP_UNAVAIL:
359 result |= EEH_STATE_UNAVAILABLE; 351 result = EEH_STATE_UNAVAILABLE;
360 break; 352 break;
361 case OPAL_EEH_STOPPED_PERM_UNAVAIL: 353 case OPAL_EEH_STOPPED_PERM_UNAVAIL:
362 result |= EEH_STATE_NOT_SUPPORT; 354 result = EEH_STATE_NOT_SUPPORT;
363 break; 355 break;
364 default: 356 default:
365 pr_warning("%s: Unexpected EEH status 0x%x " 357 result = EEH_STATE_NOT_SUPPORT;
366 "on PHB#%x-PE#%x\n", 358 pr_warn("%s: Invalid PHB#%x-PE#%x state %x\n",
367 __func__, fstate, hose->global_number, pe_no); 359 __func__, phb->hose->global_number,
360 pe->addr, fstate);
368 } 361 }
369 362
370 /* Dump PHB diag-data for frozen PE */ 363 /*
371 if (result != EEH_STATE_NOT_SUPPORT && 364 * If PHB supports compound PE, to freeze all
372 (result & (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) != 365 * slave PEs for consistency.
373 (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE) && 366 *
367 * If the PE is switching to frozen state for the
368 * first time, to dump the PHB diag-data.
369 */
370 if (!(result & EEH_STATE_NOT_SUPPORT) &&
371 !(result & EEH_STATE_UNAVAILABLE) &&
372 !(result & EEH_STATE_MMIO_ACTIVE) &&
373 !(result & EEH_STATE_DMA_ACTIVE) &&
374 !(pe->state & EEH_PE_ISOLATED)) { 374 !(pe->state & EEH_PE_ISOLATED)) {
375 if (phb->freeze_pe)
376 phb->freeze_pe(phb, pe->addr);
377
375 eeh_pe_state_mark(pe, EEH_PE_ISOLATED); 378 eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
376 ioda_eeh_phb_diag(hose); 379 ioda_eeh_phb_diag(pe);
377 } 380 }
378 381
379 return result; 382 return result;
380} 383}
381 384
385/**
386 * ioda_eeh_get_state - Retrieve the state of PE
387 * @pe: EEH PE
388 *
389 * The PE's state should be retrieved from the PEEV, PEST
390 * IODA tables. Since the OPAL has exported the function
391 * to do it, it'd better to use that.
392 */
393static int ioda_eeh_get_state(struct eeh_pe *pe)
394{
395 struct pnv_phb *phb = pe->phb->private_data;
396
397 /* Sanity check on PE number. PHB PE should have 0 */
398 if (pe->addr < 0 ||
399 pe->addr >= phb->ioda.total_pe) {
400 pr_warn("%s: PHB#%x-PE#%x out of range [0, %x]\n",
401 __func__, phb->hose->global_number,
402 pe->addr, phb->ioda.total_pe);
403 return EEH_STATE_NOT_SUPPORT;
404 }
405
406 if (pe->type & EEH_PE_PHB)
407 return ioda_eeh_get_phb_state(pe);
408
409 return ioda_eeh_get_pe_state(pe);
410}
411
382static s64 ioda_eeh_phb_poll(struct pnv_phb *phb) 412static s64 ioda_eeh_phb_poll(struct pnv_phb *phb)
383{ 413{
384 s64 rc = OPAL_HARDWARE; 414 s64 rc = OPAL_HARDWARE;
@@ -589,6 +619,24 @@ static int ioda_eeh_reset(struct eeh_pe *pe, int option)
589} 619}
590 620
591/** 621/**
622 * ioda_eeh_get_log - Retrieve error log
623 * @pe: frozen PE
624 * @severity: permanent or temporary error
625 * @drv_log: device driver log
626 * @len: length of device driver log
627 *
628 * Retrieve error log, which contains log from device driver
629 * and firmware.
630 */
631int ioda_eeh_get_log(struct eeh_pe *pe, int severity,
632 char *drv_log, unsigned long len)
633{
634 pnv_pci_dump_phb_diag_data(pe->phb, pe->data);
635
636 return 0;
637}
638
639/**
592 * ioda_eeh_configure_bridge - Configure the PCI bridges for the indicated PE 640 * ioda_eeh_configure_bridge - Configure the PCI bridges for the indicated PE
593 * @pe: EEH PE 641 * @pe: EEH PE
594 * 642 *
@@ -605,18 +653,24 @@ static int ioda_eeh_configure_bridge(struct eeh_pe *pe)
605static void ioda_eeh_hub_diag_common(struct OpalIoP7IOCErrorData *data) 653static void ioda_eeh_hub_diag_common(struct OpalIoP7IOCErrorData *data)
606{ 654{
607 /* GEM */ 655 /* GEM */
608 pr_info(" GEM XFIR: %016llx\n", data->gemXfir); 656 if (data->gemXfir || data->gemRfir ||
609 pr_info(" GEM RFIR: %016llx\n", data->gemRfir); 657 data->gemRirqfir || data->gemMask || data->gemRwof)
610 pr_info(" GEM RIRQFIR: %016llx\n", data->gemRirqfir); 658 pr_info(" GEM: %016llx %016llx %016llx %016llx %016llx\n",
611 pr_info(" GEM Mask: %016llx\n", data->gemMask); 659 be64_to_cpu(data->gemXfir),
612 pr_info(" GEM RWOF: %016llx\n", data->gemRwof); 660 be64_to_cpu(data->gemRfir),
661 be64_to_cpu(data->gemRirqfir),
662 be64_to_cpu(data->gemMask),
663 be64_to_cpu(data->gemRwof));
613 664
614 /* LEM */ 665 /* LEM */
615 pr_info(" LEM FIR: %016llx\n", data->lemFir); 666 if (data->lemFir || data->lemErrMask ||
616 pr_info(" LEM Error Mask: %016llx\n", data->lemErrMask); 667 data->lemAction0 || data->lemAction1 || data->lemWof)
617 pr_info(" LEM Action 0: %016llx\n", data->lemAction0); 668 pr_info(" LEM: %016llx %016llx %016llx %016llx %016llx\n",
618 pr_info(" LEM Action 1: %016llx\n", data->lemAction1); 669 be64_to_cpu(data->lemFir),
619 pr_info(" LEM WOF: %016llx\n", data->lemWof); 670 be64_to_cpu(data->lemErrMask),
671 be64_to_cpu(data->lemAction0),
672 be64_to_cpu(data->lemAction1),
673 be64_to_cpu(data->lemWof));
620} 674}
621 675
622static void ioda_eeh_hub_diag(struct pci_controller *hose) 676static void ioda_eeh_hub_diag(struct pci_controller *hose)
@@ -627,8 +681,8 @@ static void ioda_eeh_hub_diag(struct pci_controller *hose)
627 681
628 rc = opal_pci_get_hub_diag_data(phb->hub_id, data, sizeof(*data)); 682 rc = opal_pci_get_hub_diag_data(phb->hub_id, data, sizeof(*data));
629 if (rc != OPAL_SUCCESS) { 683 if (rc != OPAL_SUCCESS) {
630 pr_warning("%s: Failed to get HUB#%llx diag-data (%ld)\n", 684 pr_warn("%s: Failed to get HUB#%llx diag-data (%ld)\n",
631 __func__, phb->hub_id, rc); 685 __func__, phb->hub_id, rc);
632 return; 686 return;
633 } 687 }
634 688
@@ -636,24 +690,31 @@ static void ioda_eeh_hub_diag(struct pci_controller *hose)
636 case OPAL_P7IOC_DIAG_TYPE_RGC: 690 case OPAL_P7IOC_DIAG_TYPE_RGC:
637 pr_info("P7IOC diag-data for RGC\n\n"); 691 pr_info("P7IOC diag-data for RGC\n\n");
638 ioda_eeh_hub_diag_common(data); 692 ioda_eeh_hub_diag_common(data);
639 pr_info(" RGC Status: %016llx\n", data->rgc.rgcStatus); 693 if (data->rgc.rgcStatus || data->rgc.rgcLdcp)
640 pr_info(" RGC LDCP: %016llx\n", data->rgc.rgcLdcp); 694 pr_info(" RGC: %016llx %016llx\n",
695 be64_to_cpu(data->rgc.rgcStatus),
696 be64_to_cpu(data->rgc.rgcLdcp));
641 break; 697 break;
642 case OPAL_P7IOC_DIAG_TYPE_BI: 698 case OPAL_P7IOC_DIAG_TYPE_BI:
643 pr_info("P7IOC diag-data for BI %s\n\n", 699 pr_info("P7IOC diag-data for BI %s\n\n",
644 data->bi.biDownbound ? "Downbound" : "Upbound"); 700 data->bi.biDownbound ? "Downbound" : "Upbound");
645 ioda_eeh_hub_diag_common(data); 701 ioda_eeh_hub_diag_common(data);
646 pr_info(" BI LDCP 0: %016llx\n", data->bi.biLdcp0); 702 if (data->bi.biLdcp0 || data->bi.biLdcp1 ||
647 pr_info(" BI LDCP 1: %016llx\n", data->bi.biLdcp1); 703 data->bi.biLdcp2 || data->bi.biFenceStatus)
648 pr_info(" BI LDCP 2: %016llx\n", data->bi.biLdcp2); 704 pr_info(" BI: %016llx %016llx %016llx %016llx\n",
649 pr_info(" BI Fence Status: %016llx\n", data->bi.biFenceStatus); 705 be64_to_cpu(data->bi.biLdcp0),
706 be64_to_cpu(data->bi.biLdcp1),
707 be64_to_cpu(data->bi.biLdcp2),
708 be64_to_cpu(data->bi.biFenceStatus));
650 break; 709 break;
651 case OPAL_P7IOC_DIAG_TYPE_CI: 710 case OPAL_P7IOC_DIAG_TYPE_CI:
652 pr_info("P7IOC diag-data for CI Port %d\\nn", 711 pr_info("P7IOC diag-data for CI Port %d\n\n",
653 data->ci.ciPort); 712 data->ci.ciPort);
654 ioda_eeh_hub_diag_common(data); 713 ioda_eeh_hub_diag_common(data);
655 pr_info(" CI Port Status: %016llx\n", data->ci.ciPortStatus); 714 if (data->ci.ciPortStatus || data->ci.ciPortLdcp)
656 pr_info(" CI Port LDCP: %016llx\n", data->ci.ciPortLdcp); 715 pr_info(" CI: %016llx %016llx\n",
716 be64_to_cpu(data->ci.ciPortStatus),
717 be64_to_cpu(data->ci.ciPortLdcp));
657 break; 718 break;
658 case OPAL_P7IOC_DIAG_TYPE_MISC: 719 case OPAL_P7IOC_DIAG_TYPE_MISC:
659 pr_info("P7IOC diag-data for MISC\n\n"); 720 pr_info("P7IOC diag-data for MISC\n\n");
@@ -664,30 +725,51 @@ static void ioda_eeh_hub_diag(struct pci_controller *hose)
664 ioda_eeh_hub_diag_common(data); 725 ioda_eeh_hub_diag_common(data);
665 break; 726 break;
666 default: 727 default:
667 pr_warning("%s: Invalid type of HUB#%llx diag-data (%d)\n", 728 pr_warn("%s: Invalid type of HUB#%llx diag-data (%d)\n",
668 __func__, phb->hub_id, data->type); 729 __func__, phb->hub_id, data->type);
669 } 730 }
670} 731}
671 732
672static int ioda_eeh_get_pe(struct pci_controller *hose, 733static int ioda_eeh_get_pe(struct pci_controller *hose,
673 u16 pe_no, struct eeh_pe **pe) 734 u16 pe_no, struct eeh_pe **pe)
674{ 735{
675 struct eeh_pe *phb_pe, *dev_pe; 736 struct pnv_phb *phb = hose->private_data;
676 struct eeh_dev dev; 737 struct pnv_ioda_pe *pnv_pe;
738 struct eeh_pe *dev_pe;
739 struct eeh_dev edev;
677 740
678 /* Find the PHB PE */ 741 /*
679 phb_pe = eeh_phb_pe_get(hose); 742 * If PHB supports compound PE, to fetch
680 if (!phb_pe) 743 * the master PE because slave PE is invisible
681 return -EEXIST; 744 * to EEH core.
745 */
746 if (phb->get_pe_state) {
747 pnv_pe = &phb->ioda.pe_array[pe_no];
748 if (pnv_pe->flags & PNV_IODA_PE_SLAVE) {
749 pnv_pe = pnv_pe->master;
750 WARN_ON(!pnv_pe ||
751 !(pnv_pe->flags & PNV_IODA_PE_MASTER));
752 pe_no = pnv_pe->pe_number;
753 }
754 }
682 755
683 /* Find the PE according to PE# */ 756 /* Find the PE according to PE# */
684 memset(&dev, 0, sizeof(struct eeh_dev)); 757 memset(&edev, 0, sizeof(struct eeh_dev));
685 dev.phb = hose; 758 edev.phb = hose;
686 dev.pe_config_addr = pe_no; 759 edev.pe_config_addr = pe_no;
687 dev_pe = eeh_pe_get(&dev); 760 dev_pe = eeh_pe_get(&edev);
688 if (!dev_pe) return -EEXIST; 761 if (!dev_pe)
762 return -EEXIST;
689 763
764 /*
765 * At this point, we're sure the compound PE should
766 * be put into frozen state.
767 */
690 *pe = dev_pe; 768 *pe = dev_pe;
769 if (phb->freeze_pe &&
770 !(dev_pe->state & EEH_PE_ISOLATED))
771 phb->freeze_pe(phb, pe_no);
772
691 return 0; 773 return 0;
692} 774}
693 775
@@ -792,7 +874,8 @@ static int ioda_eeh_next_error(struct eeh_pe **pe)
792 "detected, location: %s\n", 874 "detected, location: %s\n",
793 hose->global_number, 875 hose->global_number,
794 eeh_pe_loc_get(phb_pe)); 876 eeh_pe_loc_get(phb_pe));
795 ioda_eeh_phb_diag(hose); 877 ioda_eeh_phb_diag(phb_pe);
878 pnv_pci_dump_phb_diag_data(hose, phb_pe->data);
796 ret = EEH_NEXT_ERR_NONE; 879 ret = EEH_NEXT_ERR_NONE;
797 } 880 }
798 881
@@ -812,7 +895,8 @@ static int ioda_eeh_next_error(struct eeh_pe **pe)
812 opal_pci_eeh_freeze_clear(phb->opal_id, frozen_pe_no, 895 opal_pci_eeh_freeze_clear(phb->opal_id, frozen_pe_no,
813 OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); 896 OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
814 ret = EEH_NEXT_ERR_NONE; 897 ret = EEH_NEXT_ERR_NONE;
815 } else if ((*pe)->state & EEH_PE_ISOLATED) { 898 } else if ((*pe)->state & EEH_PE_ISOLATED ||
899 eeh_pe_passed(*pe)) {
816 ret = EEH_NEXT_ERR_NONE; 900 ret = EEH_NEXT_ERR_NONE;
817 } else { 901 } else {
818 pr_err("EEH: Frozen PE#%x on PHB#%x detected\n", 902 pr_err("EEH: Frozen PE#%x on PHB#%x detected\n",
@@ -839,7 +923,7 @@ static int ioda_eeh_next_error(struct eeh_pe **pe)
839 ret == EEH_NEXT_ERR_FENCED_PHB) && 923 ret == EEH_NEXT_ERR_FENCED_PHB) &&
840 !((*pe)->state & EEH_PE_ISOLATED)) { 924 !((*pe)->state & EEH_PE_ISOLATED)) {
841 eeh_pe_state_mark(*pe, EEH_PE_ISOLATED); 925 eeh_pe_state_mark(*pe, EEH_PE_ISOLATED);
842 ioda_eeh_phb_diag(hose); 926 ioda_eeh_phb_diag(*pe);
843 } 927 }
844 928
845 /* 929 /*
@@ -885,6 +969,7 @@ struct pnv_eeh_ops ioda_eeh_ops = {
885 .set_option = ioda_eeh_set_option, 969 .set_option = ioda_eeh_set_option,
886 .get_state = ioda_eeh_get_state, 970 .get_state = ioda_eeh_get_state,
887 .reset = ioda_eeh_reset, 971 .reset = ioda_eeh_reset,
972 .get_log = ioda_eeh_get_log,
888 .configure_bridge = ioda_eeh_configure_bridge, 973 .configure_bridge = ioda_eeh_configure_bridge,
889 .next_error = ioda_eeh_next_error 974 .next_error = ioda_eeh_next_error
890}; 975};
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
index 56a206f32f77..fd7a16f855ed 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -45,14 +45,31 @@
45 */ 45 */
46static int powernv_eeh_init(void) 46static int powernv_eeh_init(void)
47{ 47{
48 struct pci_controller *hose;
49 struct pnv_phb *phb;
50
48 /* We require OPALv3 */ 51 /* We require OPALv3 */
49 if (!firmware_has_feature(FW_FEATURE_OPALv3)) { 52 if (!firmware_has_feature(FW_FEATURE_OPALv3)) {
50 pr_warning("%s: OPALv3 is required !\n", __func__); 53 pr_warn("%s: OPALv3 is required !\n",
54 __func__);
51 return -EINVAL; 55 return -EINVAL;
52 } 56 }
53 57
54 /* Set EEH probe mode */ 58 /* Set probe mode */
55 eeh_probe_mode_set(EEH_PROBE_MODE_DEV); 59 eeh_add_flag(EEH_PROBE_MODE_DEV);
60
61 /*
62 * P7IOC blocks PCI config access to frozen PE, but PHB3
63 * doesn't do that. So we have to selectively enable I/O
64 * prior to collecting error log.
65 */
66 list_for_each_entry(hose, &hose_list, list_node) {
67 phb = hose->private_data;
68
69 if (phb->model == PNV_PHB_MODEL_P7IOC)
70 eeh_add_flag(EEH_ENABLE_IO_FOR_LOG);
71 break;
72 }
56 73
57 return 0; 74 return 0;
58} 75}
@@ -107,6 +124,7 @@ static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag)
107 struct pnv_phb *phb = hose->private_data; 124 struct pnv_phb *phb = hose->private_data;
108 struct device_node *dn = pci_device_to_OF_node(dev); 125 struct device_node *dn = pci_device_to_OF_node(dev);
109 struct eeh_dev *edev = of_node_to_eeh_dev(dn); 126 struct eeh_dev *edev = of_node_to_eeh_dev(dn);
127 int ret;
110 128
111 /* 129 /*
112 * When probing the root bridge, which doesn't have any 130 * When probing the root bridge, which doesn't have any
@@ -143,13 +161,27 @@ static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag)
143 edev->pe_config_addr = phb->bdfn_to_pe(phb, dev->bus, dev->devfn & 0xff); 161 edev->pe_config_addr = phb->bdfn_to_pe(phb, dev->bus, dev->devfn & 0xff);
144 162
145 /* Create PE */ 163 /* Create PE */
146 eeh_add_to_parent_pe(edev); 164 ret = eeh_add_to_parent_pe(edev);
165 if (ret) {
166 pr_warn("%s: Can't add PCI dev %s to parent PE (%d)\n",
167 __func__, pci_name(dev), ret);
168 return ret;
169 }
170
171 /*
172 * Cache the PE primary bus, which can't be fetched when
173 * full hotplug is in progress. In that case, all child
174 * PCI devices of the PE are expected to be removed prior
175 * to PE reset.
176 */
177 if (!edev->pe->bus)
178 edev->pe->bus = dev->bus;
147 179
148 /* 180 /*
149 * Enable EEH explicitly so that we will do EEH check 181 * Enable EEH explicitly so that we will do EEH check
150 * while accessing I/O stuff 182 * while accessing I/O stuff
151 */ 183 */
152 eeh_set_enable(true); 184 eeh_add_flag(EEH_ENABLED);
153 185
154 /* Save memory bars */ 186 /* Save memory bars */
155 eeh_save_bars(edev); 187 eeh_save_bars(edev);
@@ -273,8 +305,8 @@ static int powernv_eeh_wait_state(struct eeh_pe *pe, int max_wait)
273 305
274 max_wait -= mwait; 306 max_wait -= mwait;
275 if (max_wait <= 0) { 307 if (max_wait <= 0) {
276 pr_warning("%s: Timeout getting PE#%x's state (%d)\n", 308 pr_warn("%s: Timeout getting PE#%x's state (%d)\n",
277 __func__, pe->addr, max_wait); 309 __func__, pe->addr, max_wait);
278 return EEH_STATE_NOT_SUPPORT; 310 return EEH_STATE_NOT_SUPPORT;
279 } 311 }
280 312
@@ -294,7 +326,7 @@ static int powernv_eeh_wait_state(struct eeh_pe *pe, int max_wait)
294 * Retrieve the temporary or permanent error from the PE. 326 * Retrieve the temporary or permanent error from the PE.
295 */ 327 */
296static int powernv_eeh_get_log(struct eeh_pe *pe, int severity, 328static int powernv_eeh_get_log(struct eeh_pe *pe, int severity,
297 char *drv_log, unsigned long len) 329 char *drv_log, unsigned long len)
298{ 330{
299 struct pci_controller *hose = pe->phb; 331 struct pci_controller *hose = pe->phb;
300 struct pnv_phb *phb = hose->private_data; 332 struct pnv_phb *phb = hose->private_data;
@@ -398,9 +430,7 @@ static int __init eeh_powernv_init(void)
398{ 430{
399 int ret = -EINVAL; 431 int ret = -EINVAL;
400 432
401 if (!machine_is(powernv)) 433 eeh_set_pe_aux_size(PNV_PCI_DIAG_BUF_SIZE);
402 return ret;
403
404 ret = eeh_ops_register(&powernv_eeh_ops); 434 ret = eeh_ops_register(&powernv_eeh_ops);
405 if (!ret) 435 if (!ret)
406 pr_info("EEH: PowerNV platform initialized\n"); 436 pr_info("EEH: PowerNV platform initialized\n");
@@ -409,5 +439,4 @@ static int __init eeh_powernv_init(void)
409 439
410 return ret; 440 return ret;
411} 441}
412 442machine_early_initcall(powernv, eeh_powernv_init);
413early_initcall(eeh_powernv_init);
diff --git a/arch/powerpc/platforms/powernv/opal-async.c b/arch/powerpc/platforms/powernv/opal-async.c
index 32e2adfa5320..e462ab947d16 100644
--- a/arch/powerpc/platforms/powernv/opal-async.c
+++ b/arch/powerpc/platforms/powernv/opal-async.c
@@ -20,6 +20,7 @@
20#include <linux/wait.h> 20#include <linux/wait.h>
21#include <linux/gfp.h> 21#include <linux/gfp.h>
22#include <linux/of.h> 22#include <linux/of.h>
23#include <asm/machdep.h>
23#include <asm/opal.h> 24#include <asm/opal.h>
24 25
25#define N_ASYNC_COMPLETIONS 64 26#define N_ASYNC_COMPLETIONS 64
@@ -201,4 +202,4 @@ out_opal_node:
201out: 202out:
202 return err; 203 return err;
203} 204}
204subsys_initcall(opal_async_comp_init); 205machine_subsys_initcall(powernv, opal_async_comp_init);
diff --git a/arch/powerpc/platforms/powernv/opal-hmi.c b/arch/powerpc/platforms/powernv/opal-hmi.c
new file mode 100644
index 000000000000..97ac8dc33667
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-hmi.c
@@ -0,0 +1,188 @@
1/*
2 * OPAL hypervisor Maintenance interrupt handling support in PowreNV.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Copyright 2014 IBM Corporation
18 * Author: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
19 */
20
21#undef DEBUG
22
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/of.h>
26#include <linux/mm.h>
27#include <linux/slab.h>
28
29#include <asm/opal.h>
30#include <asm/cputable.h>
31
32static int opal_hmi_handler_nb_init;
33struct OpalHmiEvtNode {
34 struct list_head list;
35 struct OpalHMIEvent hmi_evt;
36};
37static LIST_HEAD(opal_hmi_evt_list);
38static DEFINE_SPINLOCK(opal_hmi_evt_lock);
39
40static void print_hmi_event_info(struct OpalHMIEvent *hmi_evt)
41{
42 const char *level, *sevstr, *error_info;
43 static const char *hmi_error_types[] = {
44 "Malfunction Alert",
45 "Processor Recovery done",
46 "Processor recovery occurred again",
47 "Processor recovery occurred for masked error",
48 "Timer facility experienced an error",
49 "TFMR SPR is corrupted",
50 "UPS (Uniterrupted Power System) Overflow indication",
51 "An XSCOM operation failure",
52 "An XSCOM operation completed",
53 "SCOM has set a reserved FIR bit to cause recovery",
54 "Debug trigger has set a reserved FIR bit to cause recovery",
55 "A hypervisor resource error occurred"
56 };
57
58 /* Print things out */
59 if (hmi_evt->version != OpalHMIEvt_V1) {
60 pr_err("HMI Interrupt, Unknown event version %d !\n",
61 hmi_evt->version);
62 return;
63 }
64 switch (hmi_evt->severity) {
65 case OpalHMI_SEV_NO_ERROR:
66 level = KERN_INFO;
67 sevstr = "Harmless";
68 break;
69 case OpalHMI_SEV_WARNING:
70 level = KERN_WARNING;
71 sevstr = "";
72 break;
73 case OpalHMI_SEV_ERROR_SYNC:
74 level = KERN_ERR;
75 sevstr = "Severe";
76 break;
77 case OpalHMI_SEV_FATAL:
78 default:
79 level = KERN_ERR;
80 sevstr = "Fatal";
81 break;
82 }
83
84 printk("%s%s Hypervisor Maintenance interrupt [%s]\n",
85 level, sevstr,
86 hmi_evt->disposition == OpalHMI_DISPOSITION_RECOVERED ?
87 "Recovered" : "Not recovered");
88 error_info = hmi_evt->type < ARRAY_SIZE(hmi_error_types) ?
89 hmi_error_types[hmi_evt->type]
90 : "Unknown";
91 printk("%s Error detail: %s\n", level, error_info);
92 printk("%s HMER: %016llx\n", level, be64_to_cpu(hmi_evt->hmer));
93 if ((hmi_evt->type == OpalHMI_ERROR_TFAC) ||
94 (hmi_evt->type == OpalHMI_ERROR_TFMR_PARITY))
95 printk("%s TFMR: %016llx\n", level,
96 be64_to_cpu(hmi_evt->tfmr));
97}
98
99static void hmi_event_handler(struct work_struct *work)
100{
101 unsigned long flags;
102 struct OpalHMIEvent *hmi_evt;
103 struct OpalHmiEvtNode *msg_node;
104 uint8_t disposition;
105
106 spin_lock_irqsave(&opal_hmi_evt_lock, flags);
107 while (!list_empty(&opal_hmi_evt_list)) {
108 msg_node = list_entry(opal_hmi_evt_list.next,
109 struct OpalHmiEvtNode, list);
110 list_del(&msg_node->list);
111 spin_unlock_irqrestore(&opal_hmi_evt_lock, flags);
112
113 hmi_evt = (struct OpalHMIEvent *) &msg_node->hmi_evt;
114 print_hmi_event_info(hmi_evt);
115 disposition = hmi_evt->disposition;
116 kfree(msg_node);
117
118 /*
119 * Check if HMI event has been recovered or not. If not
120 * then we can't continue, invoke panic.
121 */
122 if (disposition != OpalHMI_DISPOSITION_RECOVERED)
123 panic("Unrecoverable HMI exception");
124
125 spin_lock_irqsave(&opal_hmi_evt_lock, flags);
126 }
127 spin_unlock_irqrestore(&opal_hmi_evt_lock, flags);
128}
129
130static DECLARE_WORK(hmi_event_work, hmi_event_handler);
131/*
132 * opal_handle_hmi_event - notifier handler that queues up HMI events
133 * to be preocessed later.
134 */
135static int opal_handle_hmi_event(struct notifier_block *nb,
136 unsigned long msg_type, void *msg)
137{
138 unsigned long flags;
139 struct OpalHMIEvent *hmi_evt;
140 struct opal_msg *hmi_msg = msg;
141 struct OpalHmiEvtNode *msg_node;
142
143 /* Sanity Checks */
144 if (msg_type != OPAL_MSG_HMI_EVT)
145 return 0;
146
147 /* HMI event info starts from param[0] */
148 hmi_evt = (struct OpalHMIEvent *)&hmi_msg->params[0];
149
150 /* Delay the logging of HMI events to workqueue. */
151 msg_node = kzalloc(sizeof(*msg_node), GFP_ATOMIC);
152 if (!msg_node) {
153 pr_err("HMI: out of memory, Opal message event not handled\n");
154 return -ENOMEM;
155 }
156 memcpy(&msg_node->hmi_evt, hmi_evt, sizeof(struct OpalHMIEvent));
157
158 spin_lock_irqsave(&opal_hmi_evt_lock, flags);
159 list_add(&msg_node->list, &opal_hmi_evt_list);
160 spin_unlock_irqrestore(&opal_hmi_evt_lock, flags);
161
162 schedule_work(&hmi_event_work);
163 return 0;
164}
165
166static struct notifier_block opal_hmi_handler_nb = {
167 .notifier_call = opal_handle_hmi_event,
168 .next = NULL,
169 .priority = 0,
170};
171
172static int __init opal_hmi_handler_init(void)
173{
174 int ret;
175
176 if (!opal_hmi_handler_nb_init) {
177 ret = opal_message_notifier_register(
178 OPAL_MSG_HMI_EVT, &opal_hmi_handler_nb);
179 if (ret) {
180 pr_err("%s: Can't register OPAL event notifier (%d)\n",
181 __func__, ret);
182 return ret;
183 }
184 opal_hmi_handler_nb_init = 1;
185 }
186 return 0;
187}
188subsys_initcall(opal_hmi_handler_init);
diff --git a/arch/powerpc/platforms/powernv/opal-lpc.c b/arch/powerpc/platforms/powernv/opal-lpc.c
index f04b4d8aca5a..ad4b31df779a 100644
--- a/arch/powerpc/platforms/powernv/opal-lpc.c
+++ b/arch/powerpc/platforms/powernv/opal-lpc.c
@@ -324,7 +324,7 @@ static int opal_lpc_init_debugfs(void)
324 rc |= opal_lpc_debugfs_create_type(root, "fw", OPAL_LPC_FW); 324 rc |= opal_lpc_debugfs_create_type(root, "fw", OPAL_LPC_FW);
325 return rc; 325 return rc;
326} 326}
327device_initcall(opal_lpc_init_debugfs); 327machine_device_initcall(powernv, opal_lpc_init_debugfs);
328#endif /* CONFIG_DEBUG_FS */ 328#endif /* CONFIG_DEBUG_FS */
329 329
330void opal_lpc_init(void) 330void opal_lpc_init(void)
diff --git a/arch/powerpc/platforms/powernv/opal-memory-errors.c b/arch/powerpc/platforms/powernv/opal-memory-errors.c
index b17a34b695ef..43db2136dbff 100644
--- a/arch/powerpc/platforms/powernv/opal-memory-errors.c
+++ b/arch/powerpc/platforms/powernv/opal-memory-errors.c
@@ -27,6 +27,7 @@
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29 29
30#include <asm/machdep.h>
30#include <asm/opal.h> 31#include <asm/opal.h>
31#include <asm/cputable.h> 32#include <asm/cputable.h>
32 33
@@ -143,4 +144,4 @@ static int __init opal_mem_err_init(void)
143 } 144 }
144 return 0; 145 return 0;
145} 146}
146subsys_initcall(opal_mem_err_init); 147machine_subsys_initcall(powernv, opal_mem_err_init);
diff --git a/arch/powerpc/platforms/powernv/opal-tracepoints.c b/arch/powerpc/platforms/powernv/opal-tracepoints.c
new file mode 100644
index 000000000000..d8a000a9988b
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-tracepoints.c
@@ -0,0 +1,84 @@
1#include <linux/percpu.h>
2#include <linux/jump_label.h>
3#include <asm/trace.h>
4
5#ifdef CONFIG_JUMP_LABEL
6struct static_key opal_tracepoint_key = STATIC_KEY_INIT;
7
8void opal_tracepoint_regfunc(void)
9{
10 static_key_slow_inc(&opal_tracepoint_key);
11}
12
13void opal_tracepoint_unregfunc(void)
14{
15 static_key_slow_dec(&opal_tracepoint_key);
16}
17#else
18/*
19 * We optimise OPAL calls by placing opal_tracepoint_refcount
20 * directly in the TOC so we can check if the opal tracepoints are
21 * enabled via a single load.
22 */
23
24/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
25extern long opal_tracepoint_refcount;
26
27void opal_tracepoint_regfunc(void)
28{
29 opal_tracepoint_refcount++;
30}
31
32void opal_tracepoint_unregfunc(void)
33{
34 opal_tracepoint_refcount--;
35}
36#endif
37
38/*
39 * Since the tracing code might execute OPAL calls we need to guard against
40 * recursion.
41 */
42static DEFINE_PER_CPU(unsigned int, opal_trace_depth);
43
44void __trace_opal_entry(unsigned long opcode, unsigned long *args)
45{
46 unsigned long flags;
47 unsigned int *depth;
48
49 local_irq_save(flags);
50
51 depth = &__get_cpu_var(opal_trace_depth);
52
53 if (*depth)
54 goto out;
55
56 (*depth)++;
57 preempt_disable();
58 trace_opal_entry(opcode, args);
59 (*depth)--;
60
61out:
62 local_irq_restore(flags);
63}
64
65void __trace_opal_exit(long opcode, unsigned long retval)
66{
67 unsigned long flags;
68 unsigned int *depth;
69
70 local_irq_save(flags);
71
72 depth = &__get_cpu_var(opal_trace_depth);
73
74 if (*depth)
75 goto out;
76
77 (*depth)++;
78 trace_opal_exit(opcode, retval);
79 preempt_enable();
80 (*depth)--;
81
82out:
83 local_irq_restore(flags);
84}
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index 4abbff22a61f..a328be44880f 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -13,30 +13,69 @@
13#include <asm/hvcall.h> 13#include <asm/hvcall.h>
14#include <asm/asm-offsets.h> 14#include <asm/asm-offsets.h>
15#include <asm/opal.h> 15#include <asm/opal.h>
16#include <asm/jump_label.h>
17
18 .section ".text"
19
20#ifdef CONFIG_TRACEPOINTS
21#ifdef CONFIG_JUMP_LABEL
22#define OPAL_BRANCH(LABEL) \
23 ARCH_STATIC_BRANCH(LABEL, opal_tracepoint_key)
24#else
25
26 .section ".toc","aw"
27
28 .globl opal_tracepoint_refcount
29opal_tracepoint_refcount:
30 .llong 0
31
32 .section ".text"
33
34/*
35 * We branch around this in early init by using an unconditional cpu
36 * feature.
37 */
38#define OPAL_BRANCH(LABEL) \
39BEGIN_FTR_SECTION; \
40 b 1f; \
41END_FTR_SECTION(0, 1); \
42 ld r12,opal_tracepoint_refcount@toc(r2); \
43 std r12,32(r1); \
44 cmpdi r12,0; \
45 bne- LABEL; \
461:
47
48#endif
49
50#else
51#define OPAL_BRANCH(LABEL)
52#endif
16 53
17/* TODO: 54/* TODO:
18 * 55 *
19 * - Trace irqs in/off (needs saving/restoring all args, argh...) 56 * - Trace irqs in/off (needs saving/restoring all args, argh...)
20 * - Get r11 feed up by Dave so I can have better register usage 57 * - Get r11 feed up by Dave so I can have better register usage
21 */ 58 */
59
22#define OPAL_CALL(name, token) \ 60#define OPAL_CALL(name, token) \
23 _GLOBAL(name); \ 61 _GLOBAL(name); \
24 mflr r0; \ 62 mflr r0; \
25 mfcr r12; \
26 std r0,16(r1); \ 63 std r0,16(r1); \
64 li r0,token; \
65 OPAL_BRANCH(opal_tracepoint_entry) \
66 mfcr r12; \
27 stw r12,8(r1); \ 67 stw r12,8(r1); \
28 std r1,PACAR1(r13); \ 68 std r1,PACAR1(r13); \
29 li r0,0; \ 69 li r11,0; \
30 mfmsr r12; \ 70 mfmsr r12; \
31 ori r0,r0,MSR_EE; \ 71 ori r11,r11,MSR_EE; \
32 std r12,PACASAVEDMSR(r13); \ 72 std r12,PACASAVEDMSR(r13); \
33 andc r12,r12,r0; \ 73 andc r12,r12,r11; \
34 mtmsrd r12,1; \ 74 mtmsrd r12,1; \
35 LOAD_REG_ADDR(r0,opal_return); \ 75 LOAD_REG_ADDR(r11,opal_return); \
36 mtlr r0; \ 76 mtlr r11; \
37 li r0,MSR_DR|MSR_IR|MSR_LE;\ 77 li r11,MSR_DR|MSR_IR|MSR_LE;\
38 andc r12,r12,r0; \ 78 andc r12,r12,r11; \
39 li r0,token; \
40 mtspr SPRN_HSRR1,r12; \ 79 mtspr SPRN_HSRR1,r12; \
41 LOAD_REG_ADDR(r11,opal); \ 80 LOAD_REG_ADDR(r11,opal); \
42 ld r12,8(r11); \ 81 ld r12,8(r11); \
@@ -61,6 +100,64 @@ opal_return:
61 mtcr r4; 100 mtcr r4;
62 rfid 101 rfid
63 102
103#ifdef CONFIG_TRACEPOINTS
104opal_tracepoint_entry:
105 stdu r1,-STACKFRAMESIZE(r1)
106 std r0,STK_REG(R23)(r1)
107 std r3,STK_REG(R24)(r1)
108 std r4,STK_REG(R25)(r1)
109 std r5,STK_REG(R26)(r1)
110 std r6,STK_REG(R27)(r1)
111 std r7,STK_REG(R28)(r1)
112 std r8,STK_REG(R29)(r1)
113 std r9,STK_REG(R30)(r1)
114 std r10,STK_REG(R31)(r1)
115 mr r3,r0
116 addi r4,r1,STK_REG(R24)
117 bl __trace_opal_entry
118 ld r0,STK_REG(R23)(r1)
119 ld r3,STK_REG(R24)(r1)
120 ld r4,STK_REG(R25)(r1)
121 ld r5,STK_REG(R26)(r1)
122 ld r6,STK_REG(R27)(r1)
123 ld r7,STK_REG(R28)(r1)
124 ld r8,STK_REG(R29)(r1)
125 ld r9,STK_REG(R30)(r1)
126 ld r10,STK_REG(R31)(r1)
127 LOAD_REG_ADDR(r11,opal_tracepoint_return)
128 mfcr r12
129 std r11,16(r1)
130 stw r12,8(r1)
131 std r1,PACAR1(r13)
132 li r11,0
133 mfmsr r12
134 ori r11,r11,MSR_EE
135 std r12,PACASAVEDMSR(r13)
136 andc r12,r12,r11
137 mtmsrd r12,1
138 LOAD_REG_ADDR(r11,opal_return)
139 mtlr r11
140 li r11,MSR_DR|MSR_IR|MSR_LE
141 andc r12,r12,r11
142 mtspr SPRN_HSRR1,r12
143 LOAD_REG_ADDR(r11,opal)
144 ld r12,8(r11)
145 ld r2,0(r11)
146 mtspr SPRN_HSRR0,r12
147 hrfid
148
149opal_tracepoint_return:
150 std r3,STK_REG(R31)(r1)
151 mr r4,r3
152 ld r0,STK_REG(R23)(r1)
153 bl __trace_opal_exit
154 ld r3,STK_REG(R31)(r1)
155 addi r1,r1,STACKFRAMESIZE
156 ld r0,16(r1)
157 mtlr r0
158 blr
159#endif
160
64OPAL_CALL(opal_invalid_call, OPAL_INVALID_CALL); 161OPAL_CALL(opal_invalid_call, OPAL_INVALID_CALL);
65OPAL_CALL(opal_console_write, OPAL_CONSOLE_WRITE); 162OPAL_CALL(opal_console_write, OPAL_CONSOLE_WRITE);
66OPAL_CALL(opal_console_read, OPAL_CONSOLE_READ); 163OPAL_CALL(opal_console_read, OPAL_CONSOLE_READ);
@@ -86,6 +183,7 @@ OPAL_CALL(opal_get_xive, OPAL_GET_XIVE);
86OPAL_CALL(opal_register_exception_handler, OPAL_REGISTER_OPAL_EXCEPTION_HANDLER); 183OPAL_CALL(opal_register_exception_handler, OPAL_REGISTER_OPAL_EXCEPTION_HANDLER);
87OPAL_CALL(opal_pci_eeh_freeze_status, OPAL_PCI_EEH_FREEZE_STATUS); 184OPAL_CALL(opal_pci_eeh_freeze_status, OPAL_PCI_EEH_FREEZE_STATUS);
88OPAL_CALL(opal_pci_eeh_freeze_clear, OPAL_PCI_EEH_FREEZE_CLEAR); 185OPAL_CALL(opal_pci_eeh_freeze_clear, OPAL_PCI_EEH_FREEZE_CLEAR);
186OPAL_CALL(opal_pci_eeh_freeze_set, OPAL_PCI_EEH_FREEZE_SET);
89OPAL_CALL(opal_pci_shpc, OPAL_PCI_SHPC); 187OPAL_CALL(opal_pci_shpc, OPAL_PCI_SHPC);
90OPAL_CALL(opal_pci_phb_mmio_enable, OPAL_PCI_PHB_MMIO_ENABLE); 188OPAL_CALL(opal_pci_phb_mmio_enable, OPAL_PCI_PHB_MMIO_ENABLE);
91OPAL_CALL(opal_pci_set_phb_mem_window, OPAL_PCI_SET_PHB_MEM_WINDOW); 189OPAL_CALL(opal_pci_set_phb_mem_window, OPAL_PCI_SET_PHB_MEM_WINDOW);
@@ -146,3 +244,4 @@ OPAL_CALL(opal_sync_host_reboot, OPAL_SYNC_HOST_REBOOT);
146OPAL_CALL(opal_sensor_read, OPAL_SENSOR_READ); 244OPAL_CALL(opal_sensor_read, OPAL_SENSOR_READ);
147OPAL_CALL(opal_get_param, OPAL_GET_PARAM); 245OPAL_CALL(opal_get_param, OPAL_GET_PARAM);
148OPAL_CALL(opal_set_param, OPAL_SET_PARAM); 246OPAL_CALL(opal_set_param, OPAL_SET_PARAM);
247OPAL_CALL(opal_handle_hmi, OPAL_HANDLE_HMI);
diff --git a/arch/powerpc/platforms/powernv/opal-xscom.c b/arch/powerpc/platforms/powernv/opal-xscom.c
index 4cd2ea6c0dbe..7634d1c62299 100644
--- a/arch/powerpc/platforms/powernv/opal-xscom.c
+++ b/arch/powerpc/platforms/powernv/opal-xscom.c
@@ -130,4 +130,4 @@ static int opal_xscom_init(void)
130 scom_init(&opal_scom_controller); 130 scom_init(&opal_scom_controller);
131 return 0; 131 return 0;
132} 132}
133arch_initcall(opal_xscom_init); 133machine_arch_initcall(powernv, opal_xscom_init);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 199975613fe9..f0a01a46a57d 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -22,6 +22,8 @@
22#include <linux/kobject.h> 22#include <linux/kobject.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/memblock.h> 24#include <linux/memblock.h>
25
26#include <asm/machdep.h>
25#include <asm/opal.h> 27#include <asm/opal.h>
26#include <asm/firmware.h> 28#include <asm/firmware.h>
27#include <asm/mce.h> 29#include <asm/mce.h>
@@ -192,16 +194,12 @@ static int __init opal_register_exception_handlers(void)
192 * fwnmi area at 0x7000 to provide the glue space to OPAL 194 * fwnmi area at 0x7000 to provide the glue space to OPAL
193 */ 195 */
194 glue = 0x7000; 196 glue = 0x7000;
195 opal_register_exception_handler(OPAL_HYPERVISOR_MAINTENANCE_HANDLER,
196 0, glue);
197 glue += 128;
198 opal_register_exception_handler(OPAL_SOFTPATCH_HANDLER, 0, glue); 197 opal_register_exception_handler(OPAL_SOFTPATCH_HANDLER, 0, glue);
199#endif 198#endif
200 199
201 return 0; 200 return 0;
202} 201}
203 202machine_early_initcall(powernv, opal_register_exception_handlers);
204early_initcall(opal_register_exception_handlers);
205 203
206int opal_notifier_register(struct notifier_block *nb) 204int opal_notifier_register(struct notifier_block *nb)
207{ 205{
@@ -368,7 +366,7 @@ static int __init opal_message_init(void)
368 } 366 }
369 return 0; 367 return 0;
370} 368}
371early_initcall(opal_message_init); 369machine_early_initcall(powernv, opal_message_init);
372 370
373int opal_get_chars(uint32_t vtermno, char *buf, int count) 371int opal_get_chars(uint32_t vtermno, char *buf, int count)
374{ 372{
@@ -513,6 +511,46 @@ int opal_machine_check(struct pt_regs *regs)
513 return 0; 511 return 0;
514} 512}
515 513
514/* Early hmi handler called in real mode. */
515int opal_hmi_exception_early(struct pt_regs *regs)
516{
517 s64 rc;
518
519 /*
520 * call opal hmi handler. Pass paca address as token.
521 * The return value OPAL_SUCCESS is an indication that there is
522 * an HMI event generated waiting to pull by Linux.
523 */
524 rc = opal_handle_hmi();
525 if (rc == OPAL_SUCCESS) {
526 local_paca->hmi_event_available = 1;
527 return 1;
528 }
529 return 0;
530}
531
532/* HMI exception handler called in virtual mode during check_irq_replay. */
533int opal_handle_hmi_exception(struct pt_regs *regs)
534{
535 s64 rc;
536 __be64 evt = 0;
537
538 /*
539 * Check if HMI event is available.
540 * if Yes, then call opal_poll_events to pull opal messages and
541 * process them.
542 */
543 if (!local_paca->hmi_event_available)
544 return 0;
545
546 local_paca->hmi_event_available = 0;
547 rc = opal_poll_events(&evt);
548 if (rc == OPAL_SUCCESS && evt)
549 opal_do_notifier(be64_to_cpu(evt));
550
551 return 1;
552}
553
516static uint64_t find_recovery_address(uint64_t nip) 554static uint64_t find_recovery_address(uint64_t nip)
517{ 555{
518 int i; 556 int i;
@@ -630,7 +668,7 @@ static int __init opal_init(void)
630 668
631 return 0; 669 return 0;
632} 670}
633subsys_initcall(opal_init); 671machine_subsys_initcall(powernv, opal_init);
634 672
635void opal_shutdown(void) 673void opal_shutdown(void)
636{ 674{
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index de19edeaa7a7..b136108ddc99 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -36,6 +36,7 @@
36#include <asm/tce.h> 36#include <asm/tce.h>
37#include <asm/xics.h> 37#include <asm/xics.h>
38#include <asm/debug.h> 38#include <asm/debug.h>
39#include <asm/firmware.h>
39 40
40#include "powernv.h" 41#include "powernv.h"
41#include "pci.h" 42#include "pci.h"
@@ -82,6 +83,12 @@ static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr)
82 : : "r" (val), "r" (paddr) : "memory"); 83 : : "r" (val), "r" (paddr) : "memory");
83} 84}
84 85
86static inline bool pnv_pci_is_mem_pref_64(unsigned long flags)
87{
88 return ((flags & (IORESOURCE_MEM_64 | IORESOURCE_PREFETCH)) ==
89 (IORESOURCE_MEM_64 | IORESOURCE_PREFETCH));
90}
91
85static int pnv_ioda_alloc_pe(struct pnv_phb *phb) 92static int pnv_ioda_alloc_pe(struct pnv_phb *phb)
86{ 93{
87 unsigned long pe; 94 unsigned long pe;
@@ -106,6 +113,380 @@ static void pnv_ioda_free_pe(struct pnv_phb *phb, int pe)
106 clear_bit(pe, phb->ioda.pe_alloc); 113 clear_bit(pe, phb->ioda.pe_alloc);
107} 114}
108 115
116/* The default M64 BAR is shared by all PEs */
117static int pnv_ioda2_init_m64(struct pnv_phb *phb)
118{
119 const char *desc;
120 struct resource *r;
121 s64 rc;
122
123 /* Configure the default M64 BAR */
124 rc = opal_pci_set_phb_mem_window(phb->opal_id,
125 OPAL_M64_WINDOW_TYPE,
126 phb->ioda.m64_bar_idx,
127 phb->ioda.m64_base,
128 0, /* unused */
129 phb->ioda.m64_size);
130 if (rc != OPAL_SUCCESS) {
131 desc = "configuring";
132 goto fail;
133 }
134
135 /* Enable the default M64 BAR */
136 rc = opal_pci_phb_mmio_enable(phb->opal_id,
137 OPAL_M64_WINDOW_TYPE,
138 phb->ioda.m64_bar_idx,
139 OPAL_ENABLE_M64_SPLIT);
140 if (rc != OPAL_SUCCESS) {
141 desc = "enabling";
142 goto fail;
143 }
144
145 /* Mark the M64 BAR assigned */
146 set_bit(phb->ioda.m64_bar_idx, &phb->ioda.m64_bar_alloc);
147
148 /*
149 * Strip off the segment used by the reserved PE, which is
150 * expected to be 0 or last one of PE capabicity.
151 */
152 r = &phb->hose->mem_resources[1];
153 if (phb->ioda.reserved_pe == 0)
154 r->start += phb->ioda.m64_segsize;
155 else if (phb->ioda.reserved_pe == (phb->ioda.total_pe - 1))
156 r->end -= phb->ioda.m64_segsize;
157 else
158 pr_warn(" Cannot strip M64 segment for reserved PE#%d\n",
159 phb->ioda.reserved_pe);
160
161 return 0;
162
163fail:
164 pr_warn(" Failure %lld %s M64 BAR#%d\n",
165 rc, desc, phb->ioda.m64_bar_idx);
166 opal_pci_phb_mmio_enable(phb->opal_id,
167 OPAL_M64_WINDOW_TYPE,
168 phb->ioda.m64_bar_idx,
169 OPAL_DISABLE_M64);
170 return -EIO;
171}
172
173static void pnv_ioda2_alloc_m64_pe(struct pnv_phb *phb)
174{
175 resource_size_t sgsz = phb->ioda.m64_segsize;
176 struct pci_dev *pdev;
177 struct resource *r;
178 int base, step, i;
179
180 /*
181 * Root bus always has full M64 range and root port has
182 * M64 range used in reality. So we're checking root port
183 * instead of root bus.
184 */
185 list_for_each_entry(pdev, &phb->hose->bus->devices, bus_list) {
186 for (i = PCI_BRIDGE_RESOURCES;
187 i <= PCI_BRIDGE_RESOURCE_END; i++) {
188 r = &pdev->resource[i];
189 if (!r->parent ||
190 !pnv_pci_is_mem_pref_64(r->flags))
191 continue;
192
193 base = (r->start - phb->ioda.m64_base) / sgsz;
194 for (step = 0; step < resource_size(r) / sgsz; step++)
195 set_bit(base + step, phb->ioda.pe_alloc);
196 }
197 }
198}
199
200static int pnv_ioda2_pick_m64_pe(struct pnv_phb *phb,
201 struct pci_bus *bus, int all)
202{
203 resource_size_t segsz = phb->ioda.m64_segsize;
204 struct pci_dev *pdev;
205 struct resource *r;
206 struct pnv_ioda_pe *master_pe, *pe;
207 unsigned long size, *pe_alloc;
208 bool found;
209 int start, i, j;
210
211 /* Root bus shouldn't use M64 */
212 if (pci_is_root_bus(bus))
213 return IODA_INVALID_PE;
214
215 /* We support only one M64 window on each bus */
216 found = false;
217 pci_bus_for_each_resource(bus, r, i) {
218 if (r && r->parent &&
219 pnv_pci_is_mem_pref_64(r->flags)) {
220 found = true;
221 break;
222 }
223 }
224
225 /* No M64 window found ? */
226 if (!found)
227 return IODA_INVALID_PE;
228
229 /* Allocate bitmap */
230 size = _ALIGN_UP(phb->ioda.total_pe / 8, sizeof(unsigned long));
231 pe_alloc = kzalloc(size, GFP_KERNEL);
232 if (!pe_alloc) {
233 pr_warn("%s: Out of memory !\n",
234 __func__);
235 return IODA_INVALID_PE;
236 }
237
238 /*
239 * Figure out reserved PE numbers by the PE
240 * the its child PEs.
241 */
242 start = (r->start - phb->ioda.m64_base) / segsz;
243 for (i = 0; i < resource_size(r) / segsz; i++)
244 set_bit(start + i, pe_alloc);
245
246 if (all)
247 goto done;
248
249 /*
250 * If the PE doesn't cover all subordinate buses,
251 * we need subtract from reserved PEs for children.
252 */
253 list_for_each_entry(pdev, &bus->devices, bus_list) {
254 if (!pdev->subordinate)
255 continue;
256
257 pci_bus_for_each_resource(pdev->subordinate, r, i) {
258 if (!r || !r->parent ||
259 !pnv_pci_is_mem_pref_64(r->flags))
260 continue;
261
262 start = (r->start - phb->ioda.m64_base) / segsz;
263 for (j = 0; j < resource_size(r) / segsz ; j++)
264 clear_bit(start + j, pe_alloc);
265 }
266 }
267
268 /*
269 * the current bus might not own M64 window and that's all
270 * contributed by its child buses. For the case, we needn't
271 * pick M64 dependent PE#.
272 */
273 if (bitmap_empty(pe_alloc, phb->ioda.total_pe)) {
274 kfree(pe_alloc);
275 return IODA_INVALID_PE;
276 }
277
278 /*
279 * Figure out the master PE and put all slave PEs to master
280 * PE's list to form compound PE.
281 */
282done:
283 master_pe = NULL;
284 i = -1;
285 while ((i = find_next_bit(pe_alloc, phb->ioda.total_pe, i + 1)) <
286 phb->ioda.total_pe) {
287 pe = &phb->ioda.pe_array[i];
288 pe->phb = phb;
289 pe->pe_number = i;
290
291 if (!master_pe) {
292 pe->flags |= PNV_IODA_PE_MASTER;
293 INIT_LIST_HEAD(&pe->slaves);
294 master_pe = pe;
295 } else {
296 pe->flags |= PNV_IODA_PE_SLAVE;
297 pe->master = master_pe;
298 list_add_tail(&pe->list, &master_pe->slaves);
299 }
300 }
301
302 kfree(pe_alloc);
303 return master_pe->pe_number;
304}
305
306static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb)
307{
308 struct pci_controller *hose = phb->hose;
309 struct device_node *dn = hose->dn;
310 struct resource *res;
311 const u32 *r;
312 u64 pci_addr;
313
314 if (!firmware_has_feature(FW_FEATURE_OPALv3)) {
315 pr_info(" Firmware too old to support M64 window\n");
316 return;
317 }
318
319 r = of_get_property(dn, "ibm,opal-m64-window", NULL);
320 if (!r) {
321 pr_info(" No <ibm,opal-m64-window> on %s\n",
322 dn->full_name);
323 return;
324 }
325
326 /* FIXME: Support M64 for P7IOC */
327 if (phb->type != PNV_PHB_IODA2) {
328 pr_info(" Not support M64 window\n");
329 return;
330 }
331
332 res = &hose->mem_resources[1];
333 res->start = of_translate_address(dn, r + 2);
334 res->end = res->start + of_read_number(r + 4, 2) - 1;
335 res->flags = (IORESOURCE_MEM | IORESOURCE_MEM_64 | IORESOURCE_PREFETCH);
336 pci_addr = of_read_number(r, 2);
337 hose->mem_offset[1] = res->start - pci_addr;
338
339 phb->ioda.m64_size = resource_size(res);
340 phb->ioda.m64_segsize = phb->ioda.m64_size / phb->ioda.total_pe;
341 phb->ioda.m64_base = pci_addr;
342
343 /* Use last M64 BAR to cover M64 window */
344 phb->ioda.m64_bar_idx = 15;
345 phb->init_m64 = pnv_ioda2_init_m64;
346 phb->alloc_m64_pe = pnv_ioda2_alloc_m64_pe;
347 phb->pick_m64_pe = pnv_ioda2_pick_m64_pe;
348}
349
350static void pnv_ioda_freeze_pe(struct pnv_phb *phb, int pe_no)
351{
352 struct pnv_ioda_pe *pe = &phb->ioda.pe_array[pe_no];
353 struct pnv_ioda_pe *slave;
354 s64 rc;
355
356 /* Fetch master PE */
357 if (pe->flags & PNV_IODA_PE_SLAVE) {
358 pe = pe->master;
359 WARN_ON(!pe || !(pe->flags & PNV_IODA_PE_MASTER));
360 pe_no = pe->pe_number;
361 }
362
363 /* Freeze master PE */
364 rc = opal_pci_eeh_freeze_set(phb->opal_id,
365 pe_no,
366 OPAL_EEH_ACTION_SET_FREEZE_ALL);
367 if (rc != OPAL_SUCCESS) {
368 pr_warn("%s: Failure %lld freezing PHB#%x-PE#%x\n",
369 __func__, rc, phb->hose->global_number, pe_no);
370 return;
371 }
372
373 /* Freeze slave PEs */
374 if (!(pe->flags & PNV_IODA_PE_MASTER))
375 return;
376
377 list_for_each_entry(slave, &pe->slaves, list) {
378 rc = opal_pci_eeh_freeze_set(phb->opal_id,
379 slave->pe_number,
380 OPAL_EEH_ACTION_SET_FREEZE_ALL);
381 if (rc != OPAL_SUCCESS)
382 pr_warn("%s: Failure %lld freezing PHB#%x-PE#%x\n",
383 __func__, rc, phb->hose->global_number,
384 slave->pe_number);
385 }
386}
387
388int pnv_ioda_unfreeze_pe(struct pnv_phb *phb, int pe_no, int opt)
389{
390 struct pnv_ioda_pe *pe, *slave;
391 s64 rc;
392
393 /* Find master PE */
394 pe = &phb->ioda.pe_array[pe_no];
395 if (pe->flags & PNV_IODA_PE_SLAVE) {
396 pe = pe->master;
397 WARN_ON(!pe || !(pe->flags & PNV_IODA_PE_MASTER));
398 pe_no = pe->pe_number;
399 }
400
401 /* Clear frozen state for master PE */
402 rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no, opt);
403 if (rc != OPAL_SUCCESS) {
404 pr_warn("%s: Failure %lld clear %d on PHB#%x-PE#%x\n",
405 __func__, rc, opt, phb->hose->global_number, pe_no);
406 return -EIO;
407 }
408
409 if (!(pe->flags & PNV_IODA_PE_MASTER))
410 return 0;
411
412 /* Clear frozen state for slave PEs */
413 list_for_each_entry(slave, &pe->slaves, list) {
414 rc = opal_pci_eeh_freeze_clear(phb->opal_id,
415 slave->pe_number,
416 opt);
417 if (rc != OPAL_SUCCESS) {
418 pr_warn("%s: Failure %lld clear %d on PHB#%x-PE#%x\n",
419 __func__, rc, opt, phb->hose->global_number,
420 slave->pe_number);
421 return -EIO;
422 }
423 }
424
425 return 0;
426}
427
428static int pnv_ioda_get_pe_state(struct pnv_phb *phb, int pe_no)
429{
430 struct pnv_ioda_pe *slave, *pe;
431 u8 fstate, state;
432 __be16 pcierr;
433 s64 rc;
434
435 /* Sanity check on PE number */
436 if (pe_no < 0 || pe_no >= phb->ioda.total_pe)
437 return OPAL_EEH_STOPPED_PERM_UNAVAIL;
438
439 /*
440 * Fetch the master PE and the PE instance might be
441 * not initialized yet.
442 */
443 pe = &phb->ioda.pe_array[pe_no];
444 if (pe->flags & PNV_IODA_PE_SLAVE) {
445 pe = pe->master;
446 WARN_ON(!pe || !(pe->flags & PNV_IODA_PE_MASTER));
447 pe_no = pe->pe_number;
448 }
449
450 /* Check the master PE */
451 rc = opal_pci_eeh_freeze_status(phb->opal_id, pe_no,
452 &state, &pcierr, NULL);
453 if (rc != OPAL_SUCCESS) {
454 pr_warn("%s: Failure %lld getting "
455 "PHB#%x-PE#%x state\n",
456 __func__, rc,
457 phb->hose->global_number, pe_no);
458 return OPAL_EEH_STOPPED_TEMP_UNAVAIL;
459 }
460
461 /* Check the slave PE */
462 if (!(pe->flags & PNV_IODA_PE_MASTER))
463 return state;
464
465 list_for_each_entry(slave, &pe->slaves, list) {
466 rc = opal_pci_eeh_freeze_status(phb->opal_id,
467 slave->pe_number,
468 &fstate,
469 &pcierr,
470 NULL);
471 if (rc != OPAL_SUCCESS) {
472 pr_warn("%s: Failure %lld getting "
473 "PHB#%x-PE#%x state\n",
474 __func__, rc,
475 phb->hose->global_number, slave->pe_number);
476 return OPAL_EEH_STOPPED_TEMP_UNAVAIL;
477 }
478
479 /*
480 * Override the result based on the ascending
481 * priority.
482 */
483 if (fstate > state)
484 state = fstate;
485 }
486
487 return state;
488}
489
109/* Currently those 2 are only used when MSIs are enabled, this will change 490/* Currently those 2 are only used when MSIs are enabled, this will change
110 * but in the meantime, we need to protect them to avoid warnings 491 * but in the meantime, we need to protect them to avoid warnings
111 */ 492 */
@@ -363,9 +744,16 @@ static void pnv_ioda_setup_bus_PE(struct pci_bus *bus, int all)
363 struct pci_controller *hose = pci_bus_to_host(bus); 744 struct pci_controller *hose = pci_bus_to_host(bus);
364 struct pnv_phb *phb = hose->private_data; 745 struct pnv_phb *phb = hose->private_data;
365 struct pnv_ioda_pe *pe; 746 struct pnv_ioda_pe *pe;
366 int pe_num; 747 int pe_num = IODA_INVALID_PE;
748
749 /* Check if PE is determined by M64 */
750 if (phb->pick_m64_pe)
751 pe_num = phb->pick_m64_pe(phb, bus, all);
752
753 /* The PE number isn't pinned by M64 */
754 if (pe_num == IODA_INVALID_PE)
755 pe_num = pnv_ioda_alloc_pe(phb);
367 756
368 pe_num = pnv_ioda_alloc_pe(phb);
369 if (pe_num == IODA_INVALID_PE) { 757 if (pe_num == IODA_INVALID_PE) {
370 pr_warning("%s: Not enough PE# available for PCI bus %04x:%02x\n", 758 pr_warning("%s: Not enough PE# available for PCI bus %04x:%02x\n",
371 __func__, pci_domain_nr(bus), bus->number); 759 __func__, pci_domain_nr(bus), bus->number);
@@ -373,7 +761,7 @@ static void pnv_ioda_setup_bus_PE(struct pci_bus *bus, int all)
373 } 761 }
374 762
375 pe = &phb->ioda.pe_array[pe_num]; 763 pe = &phb->ioda.pe_array[pe_num];
376 pe->flags = (all ? PNV_IODA_PE_BUS_ALL : PNV_IODA_PE_BUS); 764 pe->flags |= (all ? PNV_IODA_PE_BUS_ALL : PNV_IODA_PE_BUS);
377 pe->pbus = bus; 765 pe->pbus = bus;
378 pe->pdev = NULL; 766 pe->pdev = NULL;
379 pe->tce32_seg = -1; 767 pe->tce32_seg = -1;
@@ -441,8 +829,15 @@ static void pnv_ioda_setup_PEs(struct pci_bus *bus)
441static void pnv_pci_ioda_setup_PEs(void) 829static void pnv_pci_ioda_setup_PEs(void)
442{ 830{
443 struct pci_controller *hose, *tmp; 831 struct pci_controller *hose, *tmp;
832 struct pnv_phb *phb;
444 833
445 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { 834 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
835 phb = hose->private_data;
836
837 /* M64 layout might affect PE allocation */
838 if (phb->alloc_m64_pe)
839 phb->alloc_m64_pe(phb);
840
446 pnv_ioda_setup_PEs(hose->bus); 841 pnv_ioda_setup_PEs(hose->bus);
447 } 842 }
448} 843}
@@ -491,17 +886,26 @@ static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb,
491 set_dma_ops(&pdev->dev, &dma_iommu_ops); 886 set_dma_ops(&pdev->dev, &dma_iommu_ops);
492 set_iommu_table_base(&pdev->dev, &pe->tce32_table); 887 set_iommu_table_base(&pdev->dev, &pe->tce32_table);
493 } 888 }
889 *pdev->dev.dma_mask = dma_mask;
494 return 0; 890 return 0;
495} 891}
496 892
497static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus) 893static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe,
894 struct pci_bus *bus,
895 bool add_to_iommu_group)
498{ 896{
499 struct pci_dev *dev; 897 struct pci_dev *dev;
500 898
501 list_for_each_entry(dev, &bus->devices, bus_list) { 899 list_for_each_entry(dev, &bus->devices, bus_list) {
502 set_iommu_table_base_and_group(&dev->dev, &pe->tce32_table); 900 if (add_to_iommu_group)
901 set_iommu_table_base_and_group(&dev->dev,
902 &pe->tce32_table);
903 else
904 set_iommu_table_base(&dev->dev, &pe->tce32_table);
905
503 if (dev->subordinate) 906 if (dev->subordinate)
504 pnv_ioda_setup_bus_dma(pe, dev->subordinate); 907 pnv_ioda_setup_bus_dma(pe, dev->subordinate,
908 add_to_iommu_group);
505 } 909 }
506} 910}
507 911
@@ -513,15 +917,16 @@ static void pnv_pci_ioda1_tce_invalidate(struct pnv_ioda_pe *pe,
513 (__be64 __iomem *)pe->tce_inval_reg_phys : 917 (__be64 __iomem *)pe->tce_inval_reg_phys :
514 (__be64 __iomem *)tbl->it_index; 918 (__be64 __iomem *)tbl->it_index;
515 unsigned long start, end, inc; 919 unsigned long start, end, inc;
920 const unsigned shift = tbl->it_page_shift;
516 921
517 start = __pa(startp); 922 start = __pa(startp);
518 end = __pa(endp); 923 end = __pa(endp);
519 924
520 /* BML uses this case for p6/p7/galaxy2: Shift addr and put in node */ 925 /* BML uses this case for p6/p7/galaxy2: Shift addr and put in node */
521 if (tbl->it_busno) { 926 if (tbl->it_busno) {
522 start <<= 12; 927 start <<= shift;
523 end <<= 12; 928 end <<= shift;
524 inc = 128 << 12; 929 inc = 128ull << shift;
525 start |= tbl->it_busno; 930 start |= tbl->it_busno;
526 end |= tbl->it_busno; 931 end |= tbl->it_busno;
527 } else if (tbl->it_type & TCE_PCI_SWINV_PAIR) { 932 } else if (tbl->it_type & TCE_PCI_SWINV_PAIR) {
@@ -559,18 +964,19 @@ static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe,
559 __be64 __iomem *invalidate = rm ? 964 __be64 __iomem *invalidate = rm ?
560 (__be64 __iomem *)pe->tce_inval_reg_phys : 965 (__be64 __iomem *)pe->tce_inval_reg_phys :
561 (__be64 __iomem *)tbl->it_index; 966 (__be64 __iomem *)tbl->it_index;
967 const unsigned shift = tbl->it_page_shift;
562 968
563 /* We'll invalidate DMA address in PE scope */ 969 /* We'll invalidate DMA address in PE scope */
564 start = 0x2ul << 60; 970 start = 0x2ull << 60;
565 start |= (pe->pe_number & 0xFF); 971 start |= (pe->pe_number & 0xFF);
566 end = start; 972 end = start;
567 973
568 /* Figure out the start, end and step */ 974 /* Figure out the start, end and step */
569 inc = tbl->it_offset + (((u64)startp - tbl->it_base) / sizeof(u64)); 975 inc = tbl->it_offset + (((u64)startp - tbl->it_base) / sizeof(u64));
570 start |= (inc << 12); 976 start |= (inc << shift);
571 inc = tbl->it_offset + (((u64)endp - tbl->it_base) / sizeof(u64)); 977 inc = tbl->it_offset + (((u64)endp - tbl->it_base) / sizeof(u64));
572 end |= (inc << 12); 978 end |= (inc << shift);
573 inc = (0x1ul << 12); 979 inc = (0x1ull << shift);
574 mb(); 980 mb();
575 981
576 while (start <= end) { 982 while (start <= end) {
@@ -654,7 +1060,7 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
654 /* Setup linux iommu table */ 1060 /* Setup linux iommu table */
655 tbl = &pe->tce32_table; 1061 tbl = &pe->tce32_table;
656 pnv_pci_setup_iommu_table(tbl, addr, TCE32_TABLE_SIZE * segs, 1062 pnv_pci_setup_iommu_table(tbl, addr, TCE32_TABLE_SIZE * segs,
657 base << 28); 1063 base << 28, IOMMU_PAGE_SHIFT_4K);
658 1064
659 /* OPAL variant of P7IOC SW invalidated TCEs */ 1065 /* OPAL variant of P7IOC SW invalidated TCEs */
660 swinvp = of_get_property(phb->hose->dn, "ibm,opal-tce-kill", NULL); 1066 swinvp = of_get_property(phb->hose->dn, "ibm,opal-tce-kill", NULL);
@@ -677,7 +1083,7 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
677 if (pe->pdev) 1083 if (pe->pdev)
678 set_iommu_table_base_and_group(&pe->pdev->dev, tbl); 1084 set_iommu_table_base_and_group(&pe->pdev->dev, tbl);
679 else 1085 else
680 pnv_ioda_setup_bus_dma(pe, pe->pbus); 1086 pnv_ioda_setup_bus_dma(pe, pe->pbus, true);
681 1087
682 return; 1088 return;
683 fail: 1089 fail:
@@ -713,11 +1119,15 @@ static void pnv_pci_ioda2_set_bypass(struct iommu_table *tbl, bool enable)
713 0); 1119 0);
714 1120
715 /* 1121 /*
716 * We might want to reset the DMA ops of all devices on 1122 * EEH needs the mapping between IOMMU table and group
717 * this PE. However in theory, that shouldn't be necessary 1123 * of those VFIO/KVM pass-through devices. We can postpone
718 * as this is used for VFIO/KVM pass-through and the device 1124 * resetting DMA ops until the DMA mask is configured in
719 * hasn't yet been returned to its kernel driver 1125 * host side.
720 */ 1126 */
1127 if (pe->pdev)
1128 set_iommu_table_base(&pe->pdev->dev, tbl);
1129 else
1130 pnv_ioda_setup_bus_dma(pe, pe->pbus, false);
721 } 1131 }
722 if (rc) 1132 if (rc)
723 pe_err(pe, "OPAL error %lld configuring bypass window\n", rc); 1133 pe_err(pe, "OPAL error %lld configuring bypass window\n", rc);
@@ -784,7 +1194,8 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,
784 1194
785 /* Setup linux iommu table */ 1195 /* Setup linux iommu table */
786 tbl = &pe->tce32_table; 1196 tbl = &pe->tce32_table;
787 pnv_pci_setup_iommu_table(tbl, addr, tce_table_size, 0); 1197 pnv_pci_setup_iommu_table(tbl, addr, tce_table_size, 0,
1198 IOMMU_PAGE_SHIFT_4K);
788 1199
789 /* OPAL variant of PHB3 invalidated TCEs */ 1200 /* OPAL variant of PHB3 invalidated TCEs */
790 swinvp = of_get_property(phb->hose->dn, "ibm,opal-tce-kill", NULL); 1201 swinvp = of_get_property(phb->hose->dn, "ibm,opal-tce-kill", NULL);
@@ -805,7 +1216,7 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,
805 if (pe->pdev) 1216 if (pe->pdev)
806 set_iommu_table_base_and_group(&pe->pdev->dev, tbl); 1217 set_iommu_table_base_and_group(&pe->pdev->dev, tbl);
807 else 1218 else
808 pnv_ioda_setup_bus_dma(pe, pe->pbus); 1219 pnv_ioda_setup_bus_dma(pe, pe->pbus, true);
809 1220
810 /* Also create a bypass window */ 1221 /* Also create a bypass window */
811 pnv_pci_ioda2_setup_bypass_pe(phb, pe); 1222 pnv_pci_ioda2_setup_bypass_pe(phb, pe);
@@ -1055,9 +1466,6 @@ static void pnv_ioda_setup_pe_seg(struct pci_controller *hose,
1055 index++; 1466 index++;
1056 } 1467 }
1057 } else if (res->flags & IORESOURCE_MEM) { 1468 } else if (res->flags & IORESOURCE_MEM) {
1058 /* WARNING: Assumes M32 is mem region 0 in PHB. We need to
1059 * harden that algorithm when we start supporting M64
1060 */
1061 region.start = res->start - 1469 region.start = res->start -
1062 hose->mem_offset[0] - 1470 hose->mem_offset[0] -
1063 phb->ioda.m32_pci_base; 1471 phb->ioda.m32_pci_base;
@@ -1141,9 +1549,8 @@ static void pnv_pci_ioda_fixup(void)
1141 pnv_pci_ioda_create_dbgfs(); 1549 pnv_pci_ioda_create_dbgfs();
1142 1550
1143#ifdef CONFIG_EEH 1551#ifdef CONFIG_EEH
1144 eeh_probe_mode_set(EEH_PROBE_MODE_DEV);
1145 eeh_addr_cache_build();
1146 eeh_init(); 1552 eeh_init();
1553 eeh_addr_cache_build();
1147#endif 1554#endif
1148} 1555}
1149 1556
@@ -1178,7 +1585,10 @@ static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus,
1178 bridge = bridge->bus->self; 1585 bridge = bridge->bus->self;
1179 } 1586 }
1180 1587
1181 /* We need support prefetchable memory window later */ 1588 /* We fail back to M32 if M64 isn't supported */
1589 if (phb->ioda.m64_segsize &&
1590 pnv_pci_is_mem_pref_64(type))
1591 return phb->ioda.m64_segsize;
1182 if (type & IORESOURCE_MEM) 1592 if (type & IORESOURCE_MEM)
1183 return phb->ioda.m32_segsize; 1593 return phb->ioda.m32_segsize;
1184 1594
@@ -1299,6 +1709,10 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
1299 prop32 = of_get_property(np, "ibm,opal-reserved-pe", NULL); 1709 prop32 = of_get_property(np, "ibm,opal-reserved-pe", NULL);
1300 if (prop32) 1710 if (prop32)
1301 phb->ioda.reserved_pe = be32_to_cpup(prop32); 1711 phb->ioda.reserved_pe = be32_to_cpup(prop32);
1712
1713 /* Parse 64-bit MMIO range */
1714 pnv_ioda_parse_m64_window(phb);
1715
1302 phb->ioda.m32_size = resource_size(&hose->mem_resources[0]); 1716 phb->ioda.m32_size = resource_size(&hose->mem_resources[0]);
1303 /* FW Has already off top 64k of M32 space (MSI space) */ 1717 /* FW Has already off top 64k of M32 space (MSI space) */
1304 phb->ioda.m32_size += 0x10000; 1718 phb->ioda.m32_size += 0x10000;
@@ -1334,14 +1748,6 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
1334 /* Calculate how many 32-bit TCE segments we have */ 1748 /* Calculate how many 32-bit TCE segments we have */
1335 phb->ioda.tce32_count = phb->ioda.m32_pci_base >> 28; 1749 phb->ioda.tce32_count = phb->ioda.m32_pci_base >> 28;
1336 1750
1337 /* Clear unusable m64 */
1338 hose->mem_resources[1].flags = 0;
1339 hose->mem_resources[1].start = 0;
1340 hose->mem_resources[1].end = 0;
1341 hose->mem_resources[2].flags = 0;
1342 hose->mem_resources[2].start = 0;
1343 hose->mem_resources[2].end = 0;
1344
1345#if 0 /* We should really do that ... */ 1751#if 0 /* We should really do that ... */
1346 rc = opal_pci_set_phb_mem_window(opal->phb_id, 1752 rc = opal_pci_set_phb_mem_window(opal->phb_id,
1347 window_type, 1753 window_type,
@@ -1351,14 +1757,21 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
1351 segment_size); 1757 segment_size);
1352#endif 1758#endif
1353 1759
1354 pr_info(" %d (%d) PE's M32: 0x%x [segment=0x%x]" 1760 pr_info(" %03d (%03d) PE's M32: 0x%x [segment=0x%x]\n",
1355 " IO: 0x%x [segment=0x%x]\n", 1761 phb->ioda.total_pe, phb->ioda.reserved_pe,
1356 phb->ioda.total_pe, 1762 phb->ioda.m32_size, phb->ioda.m32_segsize);
1357 phb->ioda.reserved_pe, 1763 if (phb->ioda.m64_size)
1358 phb->ioda.m32_size, phb->ioda.m32_segsize, 1764 pr_info(" M64: 0x%lx [segment=0x%lx]\n",
1359 phb->ioda.io_size, phb->ioda.io_segsize); 1765 phb->ioda.m64_size, phb->ioda.m64_segsize);
1766 if (phb->ioda.io_size)
1767 pr_info(" IO: 0x%x [segment=0x%x]\n",
1768 phb->ioda.io_size, phb->ioda.io_segsize);
1769
1360 1770
1361 phb->hose->ops = &pnv_pci_ops; 1771 phb->hose->ops = &pnv_pci_ops;
1772 phb->get_pe_state = pnv_ioda_get_pe_state;
1773 phb->freeze_pe = pnv_ioda_freeze_pe;
1774 phb->unfreeze_pe = pnv_ioda_unfreeze_pe;
1362#ifdef CONFIG_EEH 1775#ifdef CONFIG_EEH
1363 phb->eeh_ops = &ioda_eeh_ops; 1776 phb->eeh_ops = &ioda_eeh_ops;
1364#endif 1777#endif
@@ -1404,6 +1817,10 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
1404 ioda_eeh_phb_reset(hose, EEH_RESET_FUNDAMENTAL); 1817 ioda_eeh_phb_reset(hose, EEH_RESET_FUNDAMENTAL);
1405 ioda_eeh_phb_reset(hose, OPAL_DEASSERT_RESET); 1818 ioda_eeh_phb_reset(hose, OPAL_DEASSERT_RESET);
1406 } 1819 }
1820
1821 /* Configure M64 window */
1822 if (phb->init_m64 && phb->init_m64(phb))
1823 hose->mem_resources[1].flags = 0;
1407} 1824}
1408 1825
1409void __init pnv_pci_init_ioda2_phb(struct device_node *np) 1826void __init pnv_pci_init_ioda2_phb(struct device_node *np)
diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
index e3807d69393e..94ce3481490b 100644
--- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c
+++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
@@ -172,7 +172,8 @@ static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id,
172 /* Setup TCEs */ 172 /* Setup TCEs */
173 phb->dma_dev_setup = pnv_pci_p5ioc2_dma_dev_setup; 173 phb->dma_dev_setup = pnv_pci_p5ioc2_dma_dev_setup;
174 pnv_pci_setup_iommu_table(&phb->p5ioc2.iommu_table, 174 pnv_pci_setup_iommu_table(&phb->p5ioc2.iommu_table,
175 tce_mem, tce_size, 0); 175 tce_mem, tce_size, 0,
176 IOMMU_PAGE_SHIFT_4K);
176} 177}
177 178
178void __init pnv_pci_init_p5ioc2_hub(struct device_node *np) 179void __init pnv_pci_init_p5ioc2_hub(struct device_node *np)
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index f91a4e5d872e..b854b57ed5e1 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -132,61 +132,78 @@ static void pnv_pci_dump_p7ioc_diag_data(struct pci_controller *hose,
132 132
133 data = (struct OpalIoP7IOCPhbErrorData *)common; 133 data = (struct OpalIoP7IOCPhbErrorData *)common;
134 pr_info("P7IOC PHB#%d Diag-data (Version: %d)\n", 134 pr_info("P7IOC PHB#%d Diag-data (Version: %d)\n",
135 hose->global_number, common->version); 135 hose->global_number, be32_to_cpu(common->version));
136 136
137 if (data->brdgCtl) 137 if (data->brdgCtl)
138 pr_info("brdgCtl: %08x\n", 138 pr_info("brdgCtl: %08x\n",
139 data->brdgCtl); 139 be32_to_cpu(data->brdgCtl));
140 if (data->portStatusReg || data->rootCmplxStatus || 140 if (data->portStatusReg || data->rootCmplxStatus ||
141 data->busAgentStatus) 141 data->busAgentStatus)
142 pr_info("UtlSts: %08x %08x %08x\n", 142 pr_info("UtlSts: %08x %08x %08x\n",
143 data->portStatusReg, data->rootCmplxStatus, 143 be32_to_cpu(data->portStatusReg),
144 data->busAgentStatus); 144 be32_to_cpu(data->rootCmplxStatus),
145 be32_to_cpu(data->busAgentStatus));
145 if (data->deviceStatus || data->slotStatus || 146 if (data->deviceStatus || data->slotStatus ||
146 data->linkStatus || data->devCmdStatus || 147 data->linkStatus || data->devCmdStatus ||
147 data->devSecStatus) 148 data->devSecStatus)
148 pr_info("RootSts: %08x %08x %08x %08x %08x\n", 149 pr_info("RootSts: %08x %08x %08x %08x %08x\n",
149 data->deviceStatus, data->slotStatus, 150 be32_to_cpu(data->deviceStatus),
150 data->linkStatus, data->devCmdStatus, 151 be32_to_cpu(data->slotStatus),
151 data->devSecStatus); 152 be32_to_cpu(data->linkStatus),
153 be32_to_cpu(data->devCmdStatus),
154 be32_to_cpu(data->devSecStatus));
152 if (data->rootErrorStatus || data->uncorrErrorStatus || 155 if (data->rootErrorStatus || data->uncorrErrorStatus ||
153 data->corrErrorStatus) 156 data->corrErrorStatus)
154 pr_info("RootErrSts: %08x %08x %08x\n", 157 pr_info("RootErrSts: %08x %08x %08x\n",
155 data->rootErrorStatus, data->uncorrErrorStatus, 158 be32_to_cpu(data->rootErrorStatus),
156 data->corrErrorStatus); 159 be32_to_cpu(data->uncorrErrorStatus),
160 be32_to_cpu(data->corrErrorStatus));
157 if (data->tlpHdr1 || data->tlpHdr2 || 161 if (data->tlpHdr1 || data->tlpHdr2 ||
158 data->tlpHdr3 || data->tlpHdr4) 162 data->tlpHdr3 || data->tlpHdr4)
159 pr_info("RootErrLog: %08x %08x %08x %08x\n", 163 pr_info("RootErrLog: %08x %08x %08x %08x\n",
160 data->tlpHdr1, data->tlpHdr2, 164 be32_to_cpu(data->tlpHdr1),
161 data->tlpHdr3, data->tlpHdr4); 165 be32_to_cpu(data->tlpHdr2),
166 be32_to_cpu(data->tlpHdr3),
167 be32_to_cpu(data->tlpHdr4));
162 if (data->sourceId || data->errorClass || 168 if (data->sourceId || data->errorClass ||
163 data->correlator) 169 data->correlator)
164 pr_info("RootErrLog1: %08x %016llx %016llx\n", 170 pr_info("RootErrLog1: %08x %016llx %016llx\n",
165 data->sourceId, data->errorClass, 171 be32_to_cpu(data->sourceId),
166 data->correlator); 172 be64_to_cpu(data->errorClass),
173 be64_to_cpu(data->correlator));
167 if (data->p7iocPlssr || data->p7iocCsr) 174 if (data->p7iocPlssr || data->p7iocCsr)
168 pr_info("PhbSts: %016llx %016llx\n", 175 pr_info("PhbSts: %016llx %016llx\n",
169 data->p7iocPlssr, data->p7iocCsr); 176 be64_to_cpu(data->p7iocPlssr),
177 be64_to_cpu(data->p7iocCsr));
170 if (data->lemFir) 178 if (data->lemFir)
171 pr_info("Lem: %016llx %016llx %016llx\n", 179 pr_info("Lem: %016llx %016llx %016llx\n",
172 data->lemFir, data->lemErrorMask, 180 be64_to_cpu(data->lemFir),
173 data->lemWOF); 181 be64_to_cpu(data->lemErrorMask),
182 be64_to_cpu(data->lemWOF));
174 if (data->phbErrorStatus) 183 if (data->phbErrorStatus)
175 pr_info("PhbErr: %016llx %016llx %016llx %016llx\n", 184 pr_info("PhbErr: %016llx %016llx %016llx %016llx\n",
176 data->phbErrorStatus, data->phbFirstErrorStatus, 185 be64_to_cpu(data->phbErrorStatus),
177 data->phbErrorLog0, data->phbErrorLog1); 186 be64_to_cpu(data->phbFirstErrorStatus),
187 be64_to_cpu(data->phbErrorLog0),
188 be64_to_cpu(data->phbErrorLog1));
178 if (data->mmioErrorStatus) 189 if (data->mmioErrorStatus)
179 pr_info("OutErr: %016llx %016llx %016llx %016llx\n", 190 pr_info("OutErr: %016llx %016llx %016llx %016llx\n",
180 data->mmioErrorStatus, data->mmioFirstErrorStatus, 191 be64_to_cpu(data->mmioErrorStatus),
181 data->mmioErrorLog0, data->mmioErrorLog1); 192 be64_to_cpu(data->mmioFirstErrorStatus),
193 be64_to_cpu(data->mmioErrorLog0),
194 be64_to_cpu(data->mmioErrorLog1));
182 if (data->dma0ErrorStatus) 195 if (data->dma0ErrorStatus)
183 pr_info("InAErr: %016llx %016llx %016llx %016llx\n", 196 pr_info("InAErr: %016llx %016llx %016llx %016llx\n",
184 data->dma0ErrorStatus, data->dma0FirstErrorStatus, 197 be64_to_cpu(data->dma0ErrorStatus),
185 data->dma0ErrorLog0, data->dma0ErrorLog1); 198 be64_to_cpu(data->dma0FirstErrorStatus),
199 be64_to_cpu(data->dma0ErrorLog0),
200 be64_to_cpu(data->dma0ErrorLog1));
186 if (data->dma1ErrorStatus) 201 if (data->dma1ErrorStatus)
187 pr_info("InBErr: %016llx %016llx %016llx %016llx\n", 202 pr_info("InBErr: %016llx %016llx %016llx %016llx\n",
188 data->dma1ErrorStatus, data->dma1FirstErrorStatus, 203 be64_to_cpu(data->dma1ErrorStatus),
189 data->dma1ErrorLog0, data->dma1ErrorLog1); 204 be64_to_cpu(data->dma1FirstErrorStatus),
205 be64_to_cpu(data->dma1ErrorLog0),
206 be64_to_cpu(data->dma1ErrorLog1));
190 207
191 for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) { 208 for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) {
192 if ((data->pestA[i] >> 63) == 0 && 209 if ((data->pestA[i] >> 63) == 0 &&
@@ -194,7 +211,8 @@ static void pnv_pci_dump_p7ioc_diag_data(struct pci_controller *hose,
194 continue; 211 continue;
195 212
196 pr_info("PE[%3d] A/B: %016llx %016llx\n", 213 pr_info("PE[%3d] A/B: %016llx %016llx\n",
197 i, data->pestA[i], data->pestB[i]); 214 i, be64_to_cpu(data->pestA[i]),
215 be64_to_cpu(data->pestB[i]));
198 } 216 }
199} 217}
200 218
@@ -319,43 +337,52 @@ void pnv_pci_dump_phb_diag_data(struct pci_controller *hose,
319static void pnv_pci_handle_eeh_config(struct pnv_phb *phb, u32 pe_no) 337static void pnv_pci_handle_eeh_config(struct pnv_phb *phb, u32 pe_no)
320{ 338{
321 unsigned long flags, rc; 339 unsigned long flags, rc;
322 int has_diag; 340 int has_diag, ret = 0;
323 341
324 spin_lock_irqsave(&phb->lock, flags); 342 spin_lock_irqsave(&phb->lock, flags);
325 343
344 /* Fetch PHB diag-data */
326 rc = opal_pci_get_phb_diag_data2(phb->opal_id, phb->diag.blob, 345 rc = opal_pci_get_phb_diag_data2(phb->opal_id, phb->diag.blob,
327 PNV_PCI_DIAG_BUF_SIZE); 346 PNV_PCI_DIAG_BUF_SIZE);
328 has_diag = (rc == OPAL_SUCCESS); 347 has_diag = (rc == OPAL_SUCCESS);
329 348
330 rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no, 349 /* If PHB supports compound PE, to handle it */
350 if (phb->unfreeze_pe) {
351 ret = phb->unfreeze_pe(phb,
352 pe_no,
331 OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); 353 OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
332 if (rc) { 354 } else {
333 pr_warning("PCI %d: Failed to clear EEH freeze state" 355 rc = opal_pci_eeh_freeze_clear(phb->opal_id,
334 " for PE#%d, err %ld\n", 356 pe_no,
335 phb->hose->global_number, pe_no, rc); 357 OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
336 358 if (rc) {
337 /* For now, let's only display the diag buffer when we fail to clear 359 pr_warn("%s: Failure %ld clearing frozen "
338 * the EEH status. We'll do more sensible things later when we have 360 "PHB#%x-PE#%x\n",
339 * proper EEH support. We need to make sure we don't pollute ourselves 361 __func__, rc, phb->hose->global_number,
340 * with the normal errors generated when probing empty slots 362 pe_no);
341 */ 363 ret = -EIO;
342 if (has_diag) 364 }
343 pnv_pci_dump_phb_diag_data(phb->hose, phb->diag.blob);
344 else
345 pr_warning("PCI %d: No diag data available\n",
346 phb->hose->global_number);
347 } 365 }
348 366
367 /*
368 * For now, let's only display the diag buffer when we fail to clear
369 * the EEH status. We'll do more sensible things later when we have
370 * proper EEH support. We need to make sure we don't pollute ourselves
371 * with the normal errors generated when probing empty slots
372 */
373 if (has_diag && ret)
374 pnv_pci_dump_phb_diag_data(phb->hose, phb->diag.blob);
375
349 spin_unlock_irqrestore(&phb->lock, flags); 376 spin_unlock_irqrestore(&phb->lock, flags);
350} 377}
351 378
352static void pnv_pci_config_check_eeh(struct pnv_phb *phb, 379static void pnv_pci_config_check_eeh(struct pnv_phb *phb,
353 struct device_node *dn) 380 struct device_node *dn)
354{ 381{
355 s64 rc;
356 u8 fstate; 382 u8 fstate;
357 __be16 pcierr; 383 __be16 pcierr;
358 u32 pe_no; 384 int pe_no;
385 s64 rc;
359 386
360 /* 387 /*
361 * Get the PE#. During the PCI probe stage, we might not 388 * Get the PE#. During the PCI probe stage, we might not
@@ -370,20 +397,42 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb,
370 pe_no = phb->ioda.reserved_pe; 397 pe_no = phb->ioda.reserved_pe;
371 } 398 }
372 399
373 /* Read freeze status */ 400 /*
374 rc = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, &fstate, &pcierr, 401 * Fetch frozen state. If the PHB support compound PE,
375 NULL); 402 * we need handle that case.
376 if (rc) { 403 */
377 pr_warning("%s: Can't read EEH status (PE#%d) for " 404 if (phb->get_pe_state) {
378 "%s, err %lld\n", 405 fstate = phb->get_pe_state(phb, pe_no);
379 __func__, pe_no, dn->full_name, rc); 406 } else {
380 return; 407 rc = opal_pci_eeh_freeze_status(phb->opal_id,
408 pe_no,
409 &fstate,
410 &pcierr,
411 NULL);
412 if (rc) {
413 pr_warn("%s: Failure %lld getting PHB#%x-PE#%x state\n",
414 __func__, rc, phb->hose->global_number, pe_no);
415 return;
416 }
381 } 417 }
418
382 cfg_dbg(" -> EEH check, bdfn=%04x PE#%d fstate=%x\n", 419 cfg_dbg(" -> EEH check, bdfn=%04x PE#%d fstate=%x\n",
383 (PCI_DN(dn)->busno << 8) | (PCI_DN(dn)->devfn), 420 (PCI_DN(dn)->busno << 8) | (PCI_DN(dn)->devfn),
384 pe_no, fstate); 421 pe_no, fstate);
385 if (fstate != 0) 422
423 /* Clear the frozen state if applicable */
424 if (fstate == OPAL_EEH_STOPPED_MMIO_FREEZE ||
425 fstate == OPAL_EEH_STOPPED_DMA_FREEZE ||
426 fstate == OPAL_EEH_STOPPED_MMIO_DMA_FREEZE) {
427 /*
428 * If PHB supports compound PE, freeze it for
429 * consistency.
430 */
431 if (phb->freeze_pe)
432 phb->freeze_pe(phb, pe_no);
433
386 pnv_pci_handle_eeh_config(phb, pe_no); 434 pnv_pci_handle_eeh_config(phb, pe_no);
435 }
387} 436}
388 437
389int pnv_pci_cfg_read(struct device_node *dn, 438int pnv_pci_cfg_read(struct device_node *dn,
@@ -564,10 +613,11 @@ static int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
564 proto_tce |= TCE_PCI_WRITE; 613 proto_tce |= TCE_PCI_WRITE;
565 614
566 tces = tcep = ((__be64 *)tbl->it_base) + index - tbl->it_offset; 615 tces = tcep = ((__be64 *)tbl->it_base) + index - tbl->it_offset;
567 rpn = __pa(uaddr) >> TCE_SHIFT; 616 rpn = __pa(uaddr) >> tbl->it_page_shift;
568 617
569 while (npages--) 618 while (npages--)
570 *(tcep++) = cpu_to_be64(proto_tce | (rpn++ << TCE_RPN_SHIFT)); 619 *(tcep++) = cpu_to_be64(proto_tce |
620 (rpn++ << tbl->it_page_shift));
571 621
572 /* Some implementations won't cache invalid TCEs and thus may not 622 /* Some implementations won't cache invalid TCEs and thus may not
573 * need that flush. We'll probably turn it_type into a bit mask 623 * need that flush. We'll probably turn it_type into a bit mask
@@ -627,11 +677,11 @@ static void pnv_tce_free_rm(struct iommu_table *tbl, long index, long npages)
627 677
628void pnv_pci_setup_iommu_table(struct iommu_table *tbl, 678void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
629 void *tce_mem, u64 tce_size, 679 void *tce_mem, u64 tce_size,
630 u64 dma_offset) 680 u64 dma_offset, unsigned page_shift)
631{ 681{
632 tbl->it_blocksize = 16; 682 tbl->it_blocksize = 16;
633 tbl->it_base = (unsigned long)tce_mem; 683 tbl->it_base = (unsigned long)tce_mem;
634 tbl->it_page_shift = IOMMU_PAGE_SHIFT_4K; 684 tbl->it_page_shift = page_shift;
635 tbl->it_offset = dma_offset >> tbl->it_page_shift; 685 tbl->it_offset = dma_offset >> tbl->it_page_shift;
636 tbl->it_index = 0; 686 tbl->it_index = 0;
637 tbl->it_size = tce_size >> 3; 687 tbl->it_size = tce_size >> 3;
@@ -656,7 +706,7 @@ static struct iommu_table *pnv_pci_setup_bml_iommu(struct pci_controller *hose)
656 if (WARN_ON(!tbl)) 706 if (WARN_ON(!tbl))
657 return NULL; 707 return NULL;
658 pnv_pci_setup_iommu_table(tbl, __va(be64_to_cpup(basep)), 708 pnv_pci_setup_iommu_table(tbl, __va(be64_to_cpup(basep)),
659 be32_to_cpup(sizep), 0); 709 be32_to_cpup(sizep), 0, IOMMU_PAGE_SHIFT_4K);
660 iommu_init_table(tbl, hose->node); 710 iommu_init_table(tbl, hose->node);
661 iommu_register_group(tbl, pci_domain_nr(hose->bus), 0); 711 iommu_register_group(tbl, pci_domain_nr(hose->bus), 0);
662 712
@@ -842,5 +892,4 @@ static int __init tce_iommu_bus_notifier_init(void)
842 bus_register_notifier(&pci_bus_type, &tce_iommu_bus_nb); 892 bus_register_notifier(&pci_bus_type, &tce_iommu_bus_nb);
843 return 0; 893 return 0;
844} 894}
845 895machine_subsys_initcall_sync(powernv, tce_iommu_bus_notifier_init);
846subsys_initcall_sync(tce_iommu_bus_notifier_init);
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index 676232c34328..48494d4b6058 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -21,6 +21,8 @@ enum pnv_phb_model {
21#define PNV_IODA_PE_DEV (1 << 0) /* PE has single PCI device */ 21#define PNV_IODA_PE_DEV (1 << 0) /* PE has single PCI device */
22#define PNV_IODA_PE_BUS (1 << 1) /* PE has primary PCI bus */ 22#define PNV_IODA_PE_BUS (1 << 1) /* PE has primary PCI bus */
23#define PNV_IODA_PE_BUS_ALL (1 << 2) /* PE has subordinate buses */ 23#define PNV_IODA_PE_BUS_ALL (1 << 2) /* PE has subordinate buses */
24#define PNV_IODA_PE_MASTER (1 << 3) /* Master PE in compound case */
25#define PNV_IODA_PE_SLAVE (1 << 4) /* Slave PE in compound case */
24 26
25/* Data associated with a PE, including IOMMU tracking etc.. */ 27/* Data associated with a PE, including IOMMU tracking etc.. */
26struct pnv_phb; 28struct pnv_phb;
@@ -64,6 +66,10 @@ struct pnv_ioda_pe {
64 */ 66 */
65 int mve_number; 67 int mve_number;
66 68
69 /* PEs in compound case */
70 struct pnv_ioda_pe *master;
71 struct list_head slaves;
72
67 /* Link in list of PE#s */ 73 /* Link in list of PE#s */
68 struct list_head dma_link; 74 struct list_head dma_link;
69 struct list_head list; 75 struct list_head list;
@@ -119,6 +125,12 @@ struct pnv_phb {
119 void (*fixup_phb)(struct pci_controller *hose); 125 void (*fixup_phb)(struct pci_controller *hose);
120 u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn); 126 u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn);
121 void (*shutdown)(struct pnv_phb *phb); 127 void (*shutdown)(struct pnv_phb *phb);
128 int (*init_m64)(struct pnv_phb *phb);
129 void (*alloc_m64_pe)(struct pnv_phb *phb);
130 int (*pick_m64_pe)(struct pnv_phb *phb, struct pci_bus *bus, int all);
131 int (*get_pe_state)(struct pnv_phb *phb, int pe_no);
132 void (*freeze_pe)(struct pnv_phb *phb, int pe_no);
133 int (*unfreeze_pe)(struct pnv_phb *phb, int pe_no, int opt);
122 134
123 union { 135 union {
124 struct { 136 struct {
@@ -129,9 +141,20 @@ struct pnv_phb {
129 /* Global bridge info */ 141 /* Global bridge info */
130 unsigned int total_pe; 142 unsigned int total_pe;
131 unsigned int reserved_pe; 143 unsigned int reserved_pe;
144
145 /* 32-bit MMIO window */
132 unsigned int m32_size; 146 unsigned int m32_size;
133 unsigned int m32_segsize; 147 unsigned int m32_segsize;
134 unsigned int m32_pci_base; 148 unsigned int m32_pci_base;
149
150 /* 64-bit MMIO window */
151 unsigned int m64_bar_idx;
152 unsigned long m64_size;
153 unsigned long m64_segsize;
154 unsigned long m64_base;
155 unsigned long m64_bar_alloc;
156
157 /* IO ports */
135 unsigned int io_size; 158 unsigned int io_size;
136 unsigned int io_segsize; 159 unsigned int io_segsize;
137 unsigned int io_pci_base; 160 unsigned int io_pci_base;
@@ -198,7 +221,7 @@ int pnv_pci_cfg_write(struct device_node *dn,
198 int where, int size, u32 val); 221 int where, int size, u32 val);
199extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl, 222extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
200 void *tce_mem, u64 tce_size, 223 void *tce_mem, u64 tce_size,
201 u64 dma_offset); 224 u64 dma_offset, unsigned page_shift);
202extern void pnv_pci_init_p5ioc2_hub(struct device_node *np); 225extern void pnv_pci_init_p5ioc2_hub(struct device_node *np);
203extern void pnv_pci_init_ioda_hub(struct device_node *np); 226extern void pnv_pci_init_ioda_hub(struct device_node *np);
204extern void pnv_pci_init_ioda2_phb(struct device_node *np); 227extern void pnv_pci_init_ioda2_phb(struct device_node *np);
diff --git a/arch/powerpc/platforms/powernv/rng.c b/arch/powerpc/platforms/powernv/rng.c
index 1cb160dc1609..80db43944afe 100644
--- a/arch/powerpc/platforms/powernv/rng.c
+++ b/arch/powerpc/platforms/powernv/rng.c
@@ -123,4 +123,4 @@ static __init int rng_init(void)
123 123
124 return 0; 124 return 0;
125} 125}
126subsys_initcall(rng_init); 126machine_subsys_initcall(powernv, rng_init);
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index d9b88fa7c5a3..5a0e2dc6de5f 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -264,6 +264,8 @@ static void __init pnv_setup_machdep_opal(void)
264 ppc_md.halt = pnv_halt; 264 ppc_md.halt = pnv_halt;
265 ppc_md.machine_check_exception = opal_machine_check; 265 ppc_md.machine_check_exception = opal_machine_check;
266 ppc_md.mce_check_early_recovery = opal_mce_check_early_recovery; 266 ppc_md.mce_check_early_recovery = opal_mce_check_early_recovery;
267 ppc_md.hmi_exception_early = opal_hmi_exception_early;
268 ppc_md.handle_hmi_exception = opal_handle_hmi_exception;
267} 269}
268 270
269#ifdef CONFIG_PPC_POWERNV_RTAS 271#ifdef CONFIG_PPC_POWERNV_RTAS
diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c
index 7d61498e45c0..1062f71f5a85 100644
--- a/arch/powerpc/platforms/pseries/dtl.c
+++ b/arch/powerpc/platforms/pseries/dtl.c
@@ -29,6 +29,7 @@
29#include <asm/lppaca.h> 29#include <asm/lppaca.h>
30#include <asm/debug.h> 30#include <asm/debug.h>
31#include <asm/plpar_wrappers.h> 31#include <asm/plpar_wrappers.h>
32#include <asm/machdep.h>
32 33
33struct dtl { 34struct dtl {
34 struct dtl_entry *buf; 35 struct dtl_entry *buf;
@@ -391,4 +392,4 @@ err_remove_dir:
391err: 392err:
392 return rc; 393 return rc;
393} 394}
394arch_initcall(dtl_init); 395machine_arch_initcall(pseries, dtl_init);
diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
index 0bec0c02c5e7..b08053819d99 100644
--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
@@ -89,26 +89,26 @@ static int pseries_eeh_init(void)
89 * of domain/bus/slot/function for EEH RTAS operations. 89 * of domain/bus/slot/function for EEH RTAS operations.
90 */ 90 */
91 if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE) { 91 if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE) {
92 pr_warning("%s: RTAS service <ibm,set-eeh-option> invalid\n", 92 pr_warn("%s: RTAS service <ibm,set-eeh-option> invalid\n",
93 __func__); 93 __func__);
94 return -EINVAL; 94 return -EINVAL;
95 } else if (ibm_set_slot_reset == RTAS_UNKNOWN_SERVICE) { 95 } else if (ibm_set_slot_reset == RTAS_UNKNOWN_SERVICE) {
96 pr_warning("%s: RTAS service <ibm,set-slot-reset> invalid\n", 96 pr_warn("%s: RTAS service <ibm,set-slot-reset> invalid\n",
97 __func__); 97 __func__);
98 return -EINVAL; 98 return -EINVAL;
99 } else if (ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE && 99 } else if (ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE &&
100 ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE) { 100 ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE) {
101 pr_warning("%s: RTAS service <ibm,read-slot-reset-state2> and " 101 pr_warn("%s: RTAS service <ibm,read-slot-reset-state2> and "
102 "<ibm,read-slot-reset-state> invalid\n", 102 "<ibm,read-slot-reset-state> invalid\n",
103 __func__); 103 __func__);
104 return -EINVAL; 104 return -EINVAL;
105 } else if (ibm_slot_error_detail == RTAS_UNKNOWN_SERVICE) { 105 } else if (ibm_slot_error_detail == RTAS_UNKNOWN_SERVICE) {
106 pr_warning("%s: RTAS service <ibm,slot-error-detail> invalid\n", 106 pr_warn("%s: RTAS service <ibm,slot-error-detail> invalid\n",
107 __func__); 107 __func__);
108 return -EINVAL; 108 return -EINVAL;
109 } else if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE && 109 } else if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE &&
110 ibm_configure_bridge == RTAS_UNKNOWN_SERVICE) { 110 ibm_configure_bridge == RTAS_UNKNOWN_SERVICE) {
111 pr_warning("%s: RTAS service <ibm,configure-pe> and " 111 pr_warn("%s: RTAS service <ibm,configure-pe> and "
112 "<ibm,configure-bridge> invalid\n", 112 "<ibm,configure-bridge> invalid\n",
113 __func__); 113 __func__);
114 return -EINVAL; 114 return -EINVAL;
@@ -118,17 +118,17 @@ static int pseries_eeh_init(void)
118 spin_lock_init(&slot_errbuf_lock); 118 spin_lock_init(&slot_errbuf_lock);
119 eeh_error_buf_size = rtas_token("rtas-error-log-max"); 119 eeh_error_buf_size = rtas_token("rtas-error-log-max");
120 if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) { 120 if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
121 pr_warning("%s: unknown EEH error log size\n", 121 pr_warn("%s: unknown EEH error log size\n",
122 __func__); 122 __func__);
123 eeh_error_buf_size = 1024; 123 eeh_error_buf_size = 1024;
124 } else if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) { 124 } else if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) {
125 pr_warning("%s: EEH error log size %d exceeds the maximal %d\n", 125 pr_warn("%s: EEH error log size %d exceeds the maximal %d\n",
126 __func__, eeh_error_buf_size, RTAS_ERROR_LOG_MAX); 126 __func__, eeh_error_buf_size, RTAS_ERROR_LOG_MAX);
127 eeh_error_buf_size = RTAS_ERROR_LOG_MAX; 127 eeh_error_buf_size = RTAS_ERROR_LOG_MAX;
128 } 128 }
129 129
130 /* Set EEH probe mode */ 130 /* Set EEH probe mode */
131 eeh_probe_mode_set(EEH_PROBE_MODE_DEVTREE); 131 eeh_add_flag(EEH_PROBE_MODE_DEVTREE | EEH_ENABLE_IO_FOR_LOG);
132 132
133 return 0; 133 return 0;
134} 134}
@@ -270,7 +270,7 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag)
270 /* Retrieve the device address */ 270 /* Retrieve the device address */
271 regs = of_get_property(dn, "reg", NULL); 271 regs = of_get_property(dn, "reg", NULL);
272 if (!regs) { 272 if (!regs) {
273 pr_warning("%s: OF node property %s::reg not found\n", 273 pr_warn("%s: OF node property %s::reg not found\n",
274 __func__, dn->full_name); 274 __func__, dn->full_name);
275 return NULL; 275 return NULL;
276 } 276 }
@@ -297,7 +297,7 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag)
297 enable = 1; 297 enable = 1;
298 298
299 if (enable) { 299 if (enable) {
300 eeh_set_enable(true); 300 eeh_add_flag(EEH_ENABLED);
301 eeh_add_to_parent_pe(edev); 301 eeh_add_to_parent_pe(edev);
302 302
303 pr_debug("%s: EEH enabled on %s PHB#%d-PE#%x, config addr#%x\n", 303 pr_debug("%s: EEH enabled on %s PHB#%d-PE#%x, config addr#%x\n",
@@ -398,7 +398,7 @@ static int pseries_eeh_get_pe_addr(struct eeh_pe *pe)
398 pe->config_addr, BUID_HI(pe->phb->buid), 398 pe->config_addr, BUID_HI(pe->phb->buid),
399 BUID_LO(pe->phb->buid), 0); 399 BUID_LO(pe->phb->buid), 0);
400 if (ret) { 400 if (ret) {
401 pr_warning("%s: Failed to get address for PHB#%d-PE#%x\n", 401 pr_warn("%s: Failed to get address for PHB#%d-PE#%x\n",
402 __func__, pe->phb->global_number, pe->config_addr); 402 __func__, pe->phb->global_number, pe->config_addr);
403 return 0; 403 return 0;
404 } 404 }
@@ -411,7 +411,7 @@ static int pseries_eeh_get_pe_addr(struct eeh_pe *pe)
411 pe->config_addr, BUID_HI(pe->phb->buid), 411 pe->config_addr, BUID_HI(pe->phb->buid),
412 BUID_LO(pe->phb->buid), 0); 412 BUID_LO(pe->phb->buid), 0);
413 if (ret) { 413 if (ret) {
414 pr_warning("%s: Failed to get address for PHB#%d-PE#%x\n", 414 pr_warn("%s: Failed to get address for PHB#%d-PE#%x\n",
415 __func__, pe->phb->global_number, pe->config_addr); 415 __func__, pe->phb->global_number, pe->config_addr);
416 return 0; 416 return 0;
417 } 417 }
@@ -584,17 +584,17 @@ static int pseries_eeh_wait_state(struct eeh_pe *pe, int max_wait)
584 return ret; 584 return ret;
585 585
586 if (max_wait <= 0) { 586 if (max_wait <= 0) {
587 pr_warning("%s: Timeout when getting PE's state (%d)\n", 587 pr_warn("%s: Timeout when getting PE's state (%d)\n",
588 __func__, max_wait); 588 __func__, max_wait);
589 return EEH_STATE_NOT_SUPPORT; 589 return EEH_STATE_NOT_SUPPORT;
590 } 590 }
591 591
592 if (mwait <= 0) { 592 if (mwait <= 0) {
593 pr_warning("%s: Firmware returned bad wait value %d\n", 593 pr_warn("%s: Firmware returned bad wait value %d\n",
594 __func__, mwait); 594 __func__, mwait);
595 mwait = EEH_STATE_MIN_WAIT_TIME; 595 mwait = EEH_STATE_MIN_WAIT_TIME;
596 } else if (mwait > EEH_STATE_MAX_WAIT_TIME) { 596 } else if (mwait > EEH_STATE_MAX_WAIT_TIME) {
597 pr_warning("%s: Firmware returned too long wait value %d\n", 597 pr_warn("%s: Firmware returned too long wait value %d\n",
598 __func__, mwait); 598 __func__, mwait);
599 mwait = EEH_STATE_MAX_WAIT_TIME; 599 mwait = EEH_STATE_MAX_WAIT_TIME;
600 } 600 }
@@ -675,7 +675,7 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
675 } 675 }
676 676
677 if (ret) 677 if (ret)
678 pr_warning("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n", 678 pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
679 __func__, pe->phb->global_number, pe->addr, ret); 679 __func__, pe->phb->global_number, pe->addr, ret);
680 680
681 return ret; 681 return ret;
@@ -743,10 +743,7 @@ static struct eeh_ops pseries_eeh_ops = {
743 */ 743 */
744static int __init eeh_pseries_init(void) 744static int __init eeh_pseries_init(void)
745{ 745{
746 int ret = -EINVAL; 746 int ret;
747
748 if (!machine_is(pseries))
749 return ret;
750 747
751 ret = eeh_ops_register(&pseries_eeh_ops); 748 ret = eeh_ops_register(&pseries_eeh_ops);
752 if (!ret) 749 if (!ret)
@@ -757,5 +754,4 @@ static int __init eeh_pseries_init(void)
757 754
758 return ret; 755 return ret;
759} 756}
760 757machine_early_initcall(pseries, eeh_pseries_init);
761early_initcall(eeh_pseries_init);
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index 99ecf0a5a929..3fda3f17b84e 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -12,9 +12,13 @@
12#include <asm/ppc_asm.h> 12#include <asm/ppc_asm.h>
13#include <asm/asm-offsets.h> 13#include <asm/asm-offsets.h>
14#include <asm/ptrace.h> 14#include <asm/ptrace.h>
15#include <asm/jump_label.h>
16
17 .section ".text"
15 18
16#ifdef CONFIG_TRACEPOINTS 19#ifdef CONFIG_TRACEPOINTS
17 20
21#ifndef CONFIG_JUMP_LABEL
18 .section ".toc","aw" 22 .section ".toc","aw"
19 23
20 .globl hcall_tracepoint_refcount 24 .globl hcall_tracepoint_refcount
@@ -22,21 +26,13 @@ hcall_tracepoint_refcount:
22 .llong 0 26 .llong 0
23 27
24 .section ".text" 28 .section ".text"
29#endif
25 30
26/* 31/*
27 * precall must preserve all registers. use unused STK_PARAM() 32 * precall must preserve all registers. use unused STK_PARAM()
28 * areas to save snapshots and opcode. We branch around this 33 * areas to save snapshots and opcode.
29 * in early init (eg when populating the MMU hashtable) by using an
30 * unconditional cpu feature.
31 */ 34 */
32#define HCALL_INST_PRECALL(FIRST_REG) \ 35#define HCALL_INST_PRECALL(FIRST_REG) \
33BEGIN_FTR_SECTION; \
34 b 1f; \
35END_FTR_SECTION(0, 1); \
36 ld r12,hcall_tracepoint_refcount@toc(r2); \
37 std r12,32(r1); \
38 cmpdi r12,0; \
39 beq+ 1f; \
40 mflr r0; \ 36 mflr r0; \
41 std r3,STK_PARAM(R3)(r1); \ 37 std r3,STK_PARAM(R3)(r1); \
42 std r4,STK_PARAM(R4)(r1); \ 38 std r4,STK_PARAM(R4)(r1); \
@@ -50,45 +46,29 @@ END_FTR_SECTION(0, 1); \
50 addi r4,r1,STK_PARAM(FIRST_REG); \ 46 addi r4,r1,STK_PARAM(FIRST_REG); \
51 stdu r1,-STACK_FRAME_OVERHEAD(r1); \ 47 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
52 bl __trace_hcall_entry; \ 48 bl __trace_hcall_entry; \
53 addi r1,r1,STACK_FRAME_OVERHEAD; \ 49 ld r3,STACK_FRAME_OVERHEAD+STK_PARAM(R3)(r1); \
54 ld r0,16(r1); \ 50 ld r4,STACK_FRAME_OVERHEAD+STK_PARAM(R4)(r1); \
55 ld r3,STK_PARAM(R3)(r1); \ 51 ld r5,STACK_FRAME_OVERHEAD+STK_PARAM(R5)(r1); \
56 ld r4,STK_PARAM(R4)(r1); \ 52 ld r6,STACK_FRAME_OVERHEAD+STK_PARAM(R6)(r1); \
57 ld r5,STK_PARAM(R5)(r1); \ 53 ld r7,STACK_FRAME_OVERHEAD+STK_PARAM(R7)(r1); \
58 ld r6,STK_PARAM(R6)(r1); \ 54 ld r8,STACK_FRAME_OVERHEAD+STK_PARAM(R8)(r1); \
59 ld r7,STK_PARAM(R7)(r1); \ 55 ld r9,STACK_FRAME_OVERHEAD+STK_PARAM(R9)(r1); \
60 ld r8,STK_PARAM(R8)(r1); \ 56 ld r10,STACK_FRAME_OVERHEAD+STK_PARAM(R10)(r1)
61 ld r9,STK_PARAM(R9)(r1); \
62 ld r10,STK_PARAM(R10)(r1); \
63 mtlr r0; \
641:
65 57
66/* 58/*
67 * postcall is performed immediately before function return which 59 * postcall is performed immediately before function return which
68 * allows liberal use of volatile registers. We branch around this 60 * allows liberal use of volatile registers.
69 * in early init (eg when populating the MMU hashtable) by using an
70 * unconditional cpu feature.
71 */ 61 */
72#define __HCALL_INST_POSTCALL \ 62#define __HCALL_INST_POSTCALL \
73BEGIN_FTR_SECTION; \ 63 ld r0,STACK_FRAME_OVERHEAD+STK_PARAM(R3)(r1); \
74 b 1f; \ 64 std r3,STACK_FRAME_OVERHEAD+STK_PARAM(R3)(r1); \
75END_FTR_SECTION(0, 1); \
76 ld r12,32(r1); \
77 cmpdi r12,0; \
78 beq+ 1f; \
79 mflr r0; \
80 ld r6,STK_PARAM(R3)(r1); \
81 std r3,STK_PARAM(R3)(r1); \
82 mr r4,r3; \ 65 mr r4,r3; \
83 mr r3,r6; \ 66 mr r3,r0; \
84 std r0,16(r1); \
85 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
86 bl __trace_hcall_exit; \ 67 bl __trace_hcall_exit; \
68 ld r0,STACK_FRAME_OVERHEAD+16(r1); \
87 addi r1,r1,STACK_FRAME_OVERHEAD; \ 69 addi r1,r1,STACK_FRAME_OVERHEAD; \
88 ld r0,16(r1); \
89 ld r3,STK_PARAM(R3)(r1); \ 70 ld r3,STK_PARAM(R3)(r1); \
90 mtlr r0; \ 71 mtlr r0
911:
92 72
93#define HCALL_INST_POSTCALL_NORETS \ 73#define HCALL_INST_POSTCALL_NORETS \
94 li r5,0; \ 74 li r5,0; \
@@ -98,37 +78,62 @@ END_FTR_SECTION(0, 1); \
98 mr r5,BUFREG; \ 78 mr r5,BUFREG; \
99 __HCALL_INST_POSTCALL 79 __HCALL_INST_POSTCALL
100 80
81#ifdef CONFIG_JUMP_LABEL
82#define HCALL_BRANCH(LABEL) \
83 ARCH_STATIC_BRANCH(LABEL, hcall_tracepoint_key)
84#else
85
86/*
87 * We branch around this in early init (eg when populating the MMU
88 * hashtable) by using an unconditional cpu feature.
89 */
90#define HCALL_BRANCH(LABEL) \
91BEGIN_FTR_SECTION; \
92 b 1f; \
93END_FTR_SECTION(0, 1); \
94 ld r12,hcall_tracepoint_refcount@toc(r2); \
95 std r12,32(r1); \
96 cmpdi r12,0; \
97 bne- LABEL; \
981:
99#endif
100
101#else 101#else
102#define HCALL_INST_PRECALL(FIRST_ARG) 102#define HCALL_INST_PRECALL(FIRST_ARG)
103#define HCALL_INST_POSTCALL_NORETS 103#define HCALL_INST_POSTCALL_NORETS
104#define HCALL_INST_POSTCALL(BUFREG) 104#define HCALL_INST_POSTCALL(BUFREG)
105#define HCALL_BRANCH(LABEL)
105#endif 106#endif
106 107
107 .text
108
109_GLOBAL_TOC(plpar_hcall_norets) 108_GLOBAL_TOC(plpar_hcall_norets)
110 HMT_MEDIUM 109 HMT_MEDIUM
111 110
112 mfcr r0 111 mfcr r0
113 stw r0,8(r1) 112 stw r0,8(r1)
114 113 HCALL_BRANCH(plpar_hcall_norets_trace)
115 HCALL_INST_PRECALL(R4)
116
117 HVSC /* invoke the hypervisor */ 114 HVSC /* invoke the hypervisor */
118 115
119 HCALL_INST_POSTCALL_NORETS
120
121 lwz r0,8(r1) 116 lwz r0,8(r1)
122 mtcrf 0xff,r0 117 mtcrf 0xff,r0
123 blr /* return r3 = status */ 118 blr /* return r3 = status */
124 119
120#ifdef CONFIG_TRACEPOINTS
121plpar_hcall_norets_trace:
122 HCALL_INST_PRECALL(R4)
123 HVSC
124 HCALL_INST_POSTCALL_NORETS
125 lwz r0,8(r1)
126 mtcrf 0xff,r0
127 blr
128#endif
129
125_GLOBAL_TOC(plpar_hcall) 130_GLOBAL_TOC(plpar_hcall)
126 HMT_MEDIUM 131 HMT_MEDIUM
127 132
128 mfcr r0 133 mfcr r0
129 stw r0,8(r1) 134 stw r0,8(r1)
130 135
131 HCALL_INST_PRECALL(R5) 136 HCALL_BRANCH(plpar_hcall_trace)
132 137
133 std r4,STK_PARAM(R4)(r1) /* Save ret buffer */ 138 std r4,STK_PARAM(R4)(r1) /* Save ret buffer */
134 139
@@ -147,12 +152,40 @@ _GLOBAL_TOC(plpar_hcall)
147 std r6, 16(r12) 152 std r6, 16(r12)
148 std r7, 24(r12) 153 std r7, 24(r12)
149 154
155 lwz r0,8(r1)
156 mtcrf 0xff,r0
157
158 blr /* return r3 = status */
159
160#ifdef CONFIG_TRACEPOINTS
161plpar_hcall_trace:
162 HCALL_INST_PRECALL(R5)
163
164 std r4,STK_PARAM(R4)(r1)
165 mr r0,r4
166
167 mr r4,r5
168 mr r5,r6
169 mr r6,r7
170 mr r7,r8
171 mr r8,r9
172 mr r9,r10
173
174 HVSC
175
176 ld r12,STK_PARAM(R4)(r1)
177 std r4,0(r12)
178 std r5,8(r12)
179 std r6,16(r12)
180 std r7,24(r12)
181
150 HCALL_INST_POSTCALL(r12) 182 HCALL_INST_POSTCALL(r12)
151 183
152 lwz r0,8(r1) 184 lwz r0,8(r1)
153 mtcrf 0xff,r0 185 mtcrf 0xff,r0
154 186
155 blr /* return r3 = status */ 187 blr
188#endif
156 189
157/* 190/*
158 * plpar_hcall_raw can be called in real mode. kexec/kdump need some 191 * plpar_hcall_raw can be called in real mode. kexec/kdump need some
@@ -194,7 +227,7 @@ _GLOBAL_TOC(plpar_hcall9)
194 mfcr r0 227 mfcr r0
195 stw r0,8(r1) 228 stw r0,8(r1)
196 229
197 HCALL_INST_PRECALL(R5) 230 HCALL_BRANCH(plpar_hcall9_trace)
198 231
199 std r4,STK_PARAM(R4)(r1) /* Save ret buffer */ 232 std r4,STK_PARAM(R4)(r1) /* Save ret buffer */
200 233
@@ -222,12 +255,49 @@ _GLOBAL_TOC(plpar_hcall9)
222 std r11,56(r12) 255 std r11,56(r12)
223 std r0, 64(r12) 256 std r0, 64(r12)
224 257
258 lwz r0,8(r1)
259 mtcrf 0xff,r0
260
261 blr /* return r3 = status */
262
263#ifdef CONFIG_TRACEPOINTS
264plpar_hcall9_trace:
265 HCALL_INST_PRECALL(R5)
266
267 std r4,STK_PARAM(R4)(r1)
268 mr r0,r4
269
270 mr r4,r5
271 mr r5,r6
272 mr r6,r7
273 mr r7,r8
274 mr r8,r9
275 mr r9,r10
276 ld r10,STACK_FRAME_OVERHEAD+STK_PARAM(R11)(r1)
277 ld r11,STACK_FRAME_OVERHEAD+STK_PARAM(R12)(r1)
278 ld r12,STACK_FRAME_OVERHEAD+STK_PARAM(R13)(r1)
279
280 HVSC
281
282 mr r0,r12
283 ld r12,STACK_FRAME_OVERHEAD+STK_PARAM(R4)(r1)
284 std r4,0(r12)
285 std r5,8(r12)
286 std r6,16(r12)
287 std r7,24(r12)
288 std r8,32(r12)
289 std r9,40(r12)
290 std r10,48(r12)
291 std r11,56(r12)
292 std r0,64(r12)
293
225 HCALL_INST_POSTCALL(r12) 294 HCALL_INST_POSTCALL(r12)
226 295
227 lwz r0,8(r1) 296 lwz r0,8(r1)
228 mtcrf 0xff,r0 297 mtcrf 0xff,r0
229 298
230 blr /* return r3 = status */ 299 blr
300#endif
231 301
232/* See plpar_hcall_raw to see why this is needed */ 302/* See plpar_hcall_raw to see why this is needed */
233_GLOBAL(plpar_hcall9_raw) 303_GLOBAL(plpar_hcall9_raw)
diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c
index cf4e7736e4f1..4575f0c9e521 100644
--- a/arch/powerpc/platforms/pseries/hvCall_inst.c
+++ b/arch/powerpc/platforms/pseries/hvCall_inst.c
@@ -27,6 +27,7 @@
27#include <asm/firmware.h> 27#include <asm/firmware.h>
28#include <asm/cputable.h> 28#include <asm/cputable.h>
29#include <asm/trace.h> 29#include <asm/trace.h>
30#include <asm/machdep.h>
30 31
31DEFINE_PER_CPU(struct hcall_stats[HCALL_STAT_ARRAY_SIZE], hcall_stats); 32DEFINE_PER_CPU(struct hcall_stats[HCALL_STAT_ARRAY_SIZE], hcall_stats);
32 33
@@ -162,4 +163,4 @@ static int __init hcall_inst_init(void)
162 163
163 return 0; 164 return 0;
164} 165}
165__initcall(hcall_inst_init); 166machine_device_initcall(pseries, hcall_inst_init);
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index b02af9ef3ff6..fbfcef514aa7 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -26,6 +26,7 @@
26#include <linux/dma-mapping.h> 26#include <linux/dma-mapping.h>
27#include <linux/console.h> 27#include <linux/console.h>
28#include <linux/export.h> 28#include <linux/export.h>
29#include <linux/static_key.h>
29#include <asm/processor.h> 30#include <asm/processor.h>
30#include <asm/mmu.h> 31#include <asm/mmu.h>
31#include <asm/page.h> 32#include <asm/page.h>
@@ -649,6 +650,19 @@ EXPORT_SYMBOL(arch_free_page);
649#endif 650#endif
650 651
651#ifdef CONFIG_TRACEPOINTS 652#ifdef CONFIG_TRACEPOINTS
653#ifdef CONFIG_JUMP_LABEL
654struct static_key hcall_tracepoint_key = STATIC_KEY_INIT;
655
656void hcall_tracepoint_regfunc(void)
657{
658 static_key_slow_inc(&hcall_tracepoint_key);
659}
660
661void hcall_tracepoint_unregfunc(void)
662{
663 static_key_slow_dec(&hcall_tracepoint_key);
664}
665#else
652/* 666/*
653 * We optimise our hcall path by placing hcall_tracepoint_refcount 667 * We optimise our hcall path by placing hcall_tracepoint_refcount
654 * directly in the TOC so we can check if the hcall tracepoints are 668 * directly in the TOC so we can check if the hcall tracepoints are
@@ -658,13 +672,6 @@ EXPORT_SYMBOL(arch_free_page);
658/* NB: reg/unreg are called while guarded with the tracepoints_mutex */ 672/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
659extern long hcall_tracepoint_refcount; 673extern long hcall_tracepoint_refcount;
660 674
661/*
662 * Since the tracing code might execute hcalls we need to guard against
663 * recursion. One example of this are spinlocks calling H_YIELD on
664 * shared processor partitions.
665 */
666static DEFINE_PER_CPU(unsigned int, hcall_trace_depth);
667
668void hcall_tracepoint_regfunc(void) 675void hcall_tracepoint_regfunc(void)
669{ 676{
670 hcall_tracepoint_refcount++; 677 hcall_tracepoint_refcount++;
@@ -674,6 +681,15 @@ void hcall_tracepoint_unregfunc(void)
674{ 681{
675 hcall_tracepoint_refcount--; 682 hcall_tracepoint_refcount--;
676} 683}
684#endif
685
686/*
687 * Since the tracing code might execute hcalls we need to guard against
688 * recursion. One example of this are spinlocks calling H_YIELD on
689 * shared processor partitions.
690 */
691static DEFINE_PER_CPU(unsigned int, hcall_trace_depth);
692
677 693
678void __trace_hcall_entry(unsigned long opcode, unsigned long *args) 694void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
679{ 695{
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index bde7ebad3949..d146fef038b8 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -18,6 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20 20
21#include <asm/machdep.h>
21#include <asm/rtas.h> 22#include <asm/rtas.h>
22#include "pseries.h" 23#include "pseries.h"
23 24
@@ -362,4 +363,4 @@ static int __init mobility_sysfs_init(void)
362 363
363 return rc; 364 return rc;
364} 365}
365device_initcall(mobility_sysfs_init); 366machine_device_initcall(pseries, mobility_sysfs_init);
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
index 0c882e83c4ce..18ff4626d74e 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -16,6 +16,7 @@
16#include <asm/rtas.h> 16#include <asm/rtas.h>
17#include <asm/hw_irq.h> 17#include <asm/hw_irq.h>
18#include <asm/ppc-pci.h> 18#include <asm/ppc-pci.h>
19#include <asm/machdep.h>
19 20
20static int query_token, change_token; 21static int query_token, change_token;
21 22
@@ -532,5 +533,4 @@ static int rtas_msi_init(void)
532 533
533 return 0; 534 return 0;
534} 535}
535arch_initcall(rtas_msi_init); 536machine_arch_initcall(pseries, rtas_msi_init);
536
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 203cbf0dc101..89e23811199c 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -118,10 +118,10 @@ int remove_phb_dynamic(struct pci_controller *phb)
118 } 118 }
119 } 119 }
120 120
121 /* Unregister the bridge device from sysfs and remove the PCI bus */ 121 /* Remove the PCI bus and unregister the bridge device from sysfs */
122 device_unregister(b->bridge);
123 phb->bus = NULL; 122 phb->bus = NULL;
124 pci_remove_bus(b); 123 pci_remove_bus(b);
124 device_unregister(b->bridge);
125 125
126 /* Now release the IO resource */ 126 /* Now release the IO resource */
127 if (res->flags & IORESOURCE_IO) 127 if (res->flags & IORESOURCE_IO)
diff --git a/arch/powerpc/platforms/pseries/power.c b/arch/powerpc/platforms/pseries/power.c
index 6d6266236446..c26eadde434c 100644
--- a/arch/powerpc/platforms/pseries/power.c
+++ b/arch/powerpc/platforms/pseries/power.c
@@ -25,6 +25,7 @@
25#include <linux/string.h> 25#include <linux/string.h>
26#include <linux/errno.h> 26#include <linux/errno.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <asm/machdep.h>
28 29
29unsigned long rtas_poweron_auto; /* default and normal state is 0 */ 30unsigned long rtas_poweron_auto; /* default and normal state is 0 */
30 31
@@ -71,11 +72,11 @@ static int __init pm_init(void)
71 return -ENOMEM; 72 return -ENOMEM;
72 return sysfs_create_group(power_kobj, &attr_group); 73 return sysfs_create_group(power_kobj, &attr_group);
73} 74}
74core_initcall(pm_init); 75machine_core_initcall(pseries, pm_init);
75#else 76#else
76static int __init apo_pm_init(void) 77static int __init apo_pm_init(void)
77{ 78{
78 return (sysfs_create_file(power_kobj, &auto_poweron_attr.attr)); 79 return (sysfs_create_file(power_kobj, &auto_poweron_attr.attr));
79} 80}
80__initcall(apo_pm_init); 81machine_device_initcall(pseries, apo_pm_init);
81#endif 82#endif
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 9c5778e6ed4b..dff05b9eb946 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -71,7 +71,7 @@ static int __init init_ras_IRQ(void)
71 71
72 return 0; 72 return 0;
73} 73}
74subsys_initcall(init_ras_IRQ); 74machine_subsys_initcall(pseries, init_ras_IRQ);
75 75
76#define EPOW_SHUTDOWN_NORMAL 1 76#define EPOW_SHUTDOWN_NORMAL 1
77#define EPOW_SHUTDOWN_ON_UPS 2 77#define EPOW_SHUTDOWN_ON_UPS 2
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 1c0a60d98867..0f319521e002 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -446,13 +446,10 @@ static int proc_ppc64_create_ofdt(void)
446{ 446{
447 struct proc_dir_entry *ent; 447 struct proc_dir_entry *ent;
448 448
449 if (!machine_is(pseries))
450 return 0;
451
452 ent = proc_create("powerpc/ofdt", S_IWUSR, NULL, &ofdt_fops); 449 ent = proc_create("powerpc/ofdt", S_IWUSR, NULL, &ofdt_fops);
453 if (ent) 450 if (ent)
454 proc_set_size(ent, 0); 451 proc_set_size(ent, 0);
455 452
456 return 0; 453 return 0;
457} 454}
458__initcall(proc_ppc64_create_ofdt); 455machine_device_initcall(pseries, proc_ppc64_create_ofdt);
diff --git a/arch/powerpc/platforms/pseries/rng.c b/arch/powerpc/platforms/pseries/rng.c
index 72a102758d4e..e09608770909 100644
--- a/arch/powerpc/platforms/pseries/rng.c
+++ b/arch/powerpc/platforms/pseries/rng.c
@@ -42,4 +42,4 @@ static __init int rng_init(void)
42 42
43 return 0; 43 return 0;
44} 44}
45subsys_initcall(rng_init); 45machine_subsys_initcall(pseries, rng_init);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index f2f40e64658f..cfe8a6389a51 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -351,7 +351,7 @@ static int alloc_dispatch_log_kmem_cache(void)
351 351
352 return alloc_dispatch_logs(); 352 return alloc_dispatch_logs();
353} 353}
354early_initcall(alloc_dispatch_log_kmem_cache); 354machine_early_initcall(pseries, alloc_dispatch_log_kmem_cache);
355 355
356static void pseries_lpar_idle(void) 356static void pseries_lpar_idle(void)
357{ 357{
diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c
index b87b97849d4c..e76aefae2aa2 100644
--- a/arch/powerpc/platforms/pseries/suspend.c
+++ b/arch/powerpc/platforms/pseries/suspend.c
@@ -265,7 +265,7 @@ static int __init pseries_suspend_init(void)
265{ 265{
266 int rc; 266 int rc;
267 267
268 if (!machine_is(pseries) || !firmware_has_feature(FW_FEATURE_LPAR)) 268 if (!firmware_has_feature(FW_FEATURE_LPAR))
269 return 0; 269 return 0;
270 270
271 suspend_data.token = rtas_token("ibm,suspend-me"); 271 suspend_data.token = rtas_token("ibm,suspend-me");
@@ -280,5 +280,4 @@ static int __init pseries_suspend_init(void)
280 suspend_set_ops(&pseries_suspend_ops); 280 suspend_set_ops(&pseries_suspend_ops);
281 return 0; 281 return 0;
282} 282}
283 283machine_device_initcall(pseries, pseries_suspend_init);
284__initcall(pseries_suspend_init);
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 4bd091a05583..c5077673bd94 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -853,8 +853,8 @@ u64 fsl_pci_immrbar_base(struct pci_controller *hose)
853 in = pcie->cfg_type0 + PEX_RC_INWIN_BASE; 853 in = pcie->cfg_type0 + PEX_RC_INWIN_BASE;
854 for (i = 0; i < 4; i++) { 854 for (i = 0; i < 4; i++) {
855 /* not enabled, skip */ 855 /* not enabled, skip */
856 if (!in_le32(&in[i].ar) & PEX_RCIWARn_EN) 856 if (!(in_le32(&in[i].ar) & PEX_RCIWARn_EN))
857 continue; 857 continue;
858 858
859 if (get_immrbase() == in_le32(&in[i].tar)) 859 if (get_immrbase() == in_le32(&in[i].tar))
860 return (u64)in_le32(&in[i].barh) << 32 | 860 return (u64)in_le32(&in[i].barh) << 32 |
diff --git a/arch/powerpc/sysdev/micropatch.c b/arch/powerpc/sysdev/micropatch.c
index c0bb76ef7242..6727dc54d549 100644
--- a/arch/powerpc/sysdev/micropatch.c
+++ b/arch/powerpc/sysdev/micropatch.c
@@ -13,7 +13,6 @@
13#include <linux/mm.h> 13#include <linux/mm.h>
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <asm/irq.h> 15#include <asm/irq.h>
16#include <asm/mpc8xx.h>
17#include <asm/page.h> 16#include <asm/page.h>
18#include <asm/pgtable.h> 17#include <asm/pgtable.h>
19#include <asm/8xx_immap.h> 18#include <asm/8xx_immap.h>
diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c
index 2c9b52aa266c..7bdf3cc741e4 100644
--- a/arch/powerpc/sysdev/mpic_msgr.c
+++ b/arch/powerpc/sysdev/mpic_msgr.c
@@ -184,7 +184,7 @@ static int mpic_msgr_probe(struct platform_device *dev)
184 dev_info(&dev->dev, "Found %d message registers\n", 184 dev_info(&dev->dev, "Found %d message registers\n",
185 mpic_msgr_count); 185 mpic_msgr_count);
186 186
187 mpic_msgrs = kzalloc(sizeof(struct mpic_msgr) * mpic_msgr_count, 187 mpic_msgrs = kcalloc(mpic_msgr_count, sizeof(*mpic_msgrs),
188 GFP_KERNEL); 188 GFP_KERNEL);
189 if (!mpic_msgrs) { 189 if (!mpic_msgrs) {
190 dev_err(&dev->dev, 190 dev_err(&dev->dev,
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index d199bfa2f1fa..8d198b5e9e0a 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -2058,10 +2058,6 @@ static void dump_one_paca(int cpu)
2058 DUMP(p, kernel_toc, "lx"); 2058 DUMP(p, kernel_toc, "lx");
2059 DUMP(p, kernelbase, "lx"); 2059 DUMP(p, kernelbase, "lx");
2060 DUMP(p, kernel_msr, "lx"); 2060 DUMP(p, kernel_msr, "lx");
2061#ifdef CONFIG_PPC_STD_MMU_64
2062 DUMP(p, stab_real, "lx");
2063 DUMP(p, stab_addr, "lx");
2064#endif
2065 DUMP(p, emergency_sp, "p"); 2061 DUMP(p, emergency_sp, "p");
2066#ifdef CONFIG_PPC_BOOK3S_64 2062#ifdef CONFIG_PPC_BOOK3S_64
2067 DUMP(p, mc_emergency_sp, "p"); 2063 DUMP(p, mc_emergency_sp, "p");
@@ -2694,7 +2690,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
2694} 2690}
2695 2691
2696#ifdef CONFIG_PPC_BOOK3S_64 2692#ifdef CONFIG_PPC_BOOK3S_64
2697static void dump_slb(void) 2693void dump_segments(void)
2698{ 2694{
2699 int i; 2695 int i;
2700 unsigned long esid,vsid,valid; 2696 unsigned long esid,vsid,valid;
@@ -2726,34 +2722,6 @@ static void dump_slb(void)
2726 } 2722 }
2727 } 2723 }
2728} 2724}
2729
2730static void dump_stab(void)
2731{
2732 int i;
2733 unsigned long *tmp = (unsigned long *)local_paca->stab_addr;
2734
2735 printf("Segment table contents of cpu 0x%x\n", smp_processor_id());
2736
2737 for (i = 0; i < PAGE_SIZE/16; i++) {
2738 unsigned long a, b;
2739
2740 a = *tmp++;
2741 b = *tmp++;
2742
2743 if (a || b) {
2744 printf("%03d %016lx ", i, a);
2745 printf("%016lx\n", b);
2746 }
2747 }
2748}
2749
2750void dump_segments(void)
2751{
2752 if (mmu_has_feature(MMU_FTR_SLB))
2753 dump_slb();
2754 else
2755 dump_stab();
2756}
2757#endif 2725#endif
2758 2726
2759#ifdef CONFIG_PPC_STD_MMU_32 2727#ifdef CONFIG_PPC_STD_MMU_32
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c
index bb1d08dc8cc8..379c0837f5a9 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -28,6 +28,7 @@
28#include <linux/of.h> 28#include <linux/of.h>
29 29
30#include <asm/cputhreads.h> 30#include <asm/cputhreads.h>
31#include <asm/firmware.h>
31#include <asm/reg.h> 32#include <asm/reg.h>
32#include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */ 33#include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */
33 34
@@ -98,7 +99,11 @@ static int init_powernv_pstates(void)
98 return -ENODEV; 99 return -ENODEV;
99 } 100 }
100 101
101 WARN_ON(len_ids != len_freqs); 102 if (len_ids != len_freqs) {
103 pr_warn("Entries in ibm,pstate-ids and "
104 "ibm,pstate-frequencies-mhz does not match\n");
105 }
106
102 nr_pstates = min(len_ids, len_freqs) / sizeof(u32); 107 nr_pstates = min(len_ids, len_freqs) / sizeof(u32);
103 if (!nr_pstates) { 108 if (!nr_pstates) {
104 pr_warn("No PStates found\n"); 109 pr_warn("No PStates found\n");
@@ -131,7 +136,12 @@ static unsigned int pstate_id_to_freq(int pstate_id)
131 int i; 136 int i;
132 137
133 i = powernv_pstate_info.max - pstate_id; 138 i = powernv_pstate_info.max - pstate_id;
134 BUG_ON(i >= powernv_pstate_info.nr_pstates || i < 0); 139 if (i >= powernv_pstate_info.nr_pstates || i < 0) {
140 pr_warn("PState id %d outside of PState table, "
141 "reporting nominal id %d instead\n",
142 pstate_id, powernv_pstate_info.nominal);
143 i = powernv_pstate_info.max - powernv_pstate_info.nominal;
144 }
135 145
136 return powernv_freqs[i].frequency; 146 return powernv_freqs[i].frequency;
137} 147}
@@ -321,6 +331,10 @@ static int __init powernv_cpufreq_init(void)
321{ 331{
322 int rc = 0; 332 int rc = 0;
323 333
334 /* Don't probe on pseries (guest) platforms */
335 if (!firmware_has_feature(FW_FEATURE_OPALv3))
336 return -ENODEV;
337
324 /* Discover pstates from device tree and init */ 338 /* Discover pstates from device tree and init */
325 rc = init_powernv_pstates(); 339 rc = init_powernv_pstates();
326 if (rc) { 340 if (rc) {
diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c
index 74f5788d50b1..a64be578dab2 100644
--- a/drivers/cpuidle/cpuidle-powernv.c
+++ b/drivers/cpuidle/cpuidle-powernv.c
@@ -160,10 +160,10 @@ static int powernv_cpuidle_driver_init(void)
160static int powernv_add_idle_states(void) 160static int powernv_add_idle_states(void)
161{ 161{
162 struct device_node *power_mgt; 162 struct device_node *power_mgt;
163 struct property *prop;
164 int nr_idle_states = 1; /* Snooze */ 163 int nr_idle_states = 1; /* Snooze */
165 int dt_idle_states; 164 int dt_idle_states;
166 u32 *flags; 165 const __be32 *idle_state_flags;
166 u32 len_flags, flags;
167 int i; 167 int i;
168 168
169 /* Currently we have snooze statically defined */ 169 /* Currently we have snooze statically defined */
@@ -174,18 +174,18 @@ static int powernv_add_idle_states(void)
174 return nr_idle_states; 174 return nr_idle_states;
175 } 175 }
176 176
177 prop = of_find_property(power_mgt, "ibm,cpu-idle-state-flags", NULL); 177 idle_state_flags = of_get_property(power_mgt, "ibm,cpu-idle-state-flags", &len_flags);
178 if (!prop) { 178 if (!idle_state_flags) {
179 pr_warn("DT-PowerMgmt: missing ibm,cpu-idle-state-flags\n"); 179 pr_warn("DT-PowerMgmt: missing ibm,cpu-idle-state-flags\n");
180 return nr_idle_states; 180 return nr_idle_states;
181 } 181 }
182 182
183 dt_idle_states = prop->length / sizeof(u32); 183 dt_idle_states = len_flags / sizeof(u32);
184 flags = (u32 *) prop->value;
185 184
186 for (i = 0; i < dt_idle_states; i++) { 185 for (i = 0; i < dt_idle_states; i++) {
187 186
188 if (flags[i] & IDLE_USE_INST_NAP) { 187 flags = be32_to_cpu(idle_state_flags[i]);
188 if (flags & IDLE_USE_INST_NAP) {
189 /* Add NAP state */ 189 /* Add NAP state */
190 strcpy(powernv_states[nr_idle_states].name, "Nap"); 190 strcpy(powernv_states[nr_idle_states].name, "Nap");
191 strcpy(powernv_states[nr_idle_states].desc, "Nap"); 191 strcpy(powernv_states[nr_idle_states].desc, "Nap");
@@ -196,7 +196,7 @@ static int powernv_add_idle_states(void)
196 nr_idle_states++; 196 nr_idle_states++;
197 } 197 }
198 198
199 if (flags[i] & IDLE_USE_INST_SLEEP) { 199 if (flags & IDLE_USE_INST_SLEEP) {
200 /* Add FASTSLEEP state */ 200 /* Add FASTSLEEP state */
201 strcpy(powernv_states[nr_idle_states].name, "FastSleep"); 201 strcpy(powernv_states[nr_idle_states].name, "FastSleep");
202 strcpy(powernv_states[nr_idle_states].desc, "FastSleep"); 202 strcpy(powernv_states[nr_idle_states].desc, "FastSleep");
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index c59e9c96e86d..fab81a143bd7 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -61,6 +61,16 @@ config TEGRA30_MC
61 analysis, especially for IOMMU/SMMU(System Memory Management 61 analysis, especially for IOMMU/SMMU(System Memory Management
62 Unit) module. 62 Unit) module.
63 63
64config FSL_CORENET_CF
65 tristate "Freescale CoreNet Error Reporting"
66 depends on FSL_SOC_BOOKE
67 help
68 Say Y for reporting of errors from the Freescale CoreNet
69 Coherency Fabric. Errors reported include accesses to
70 physical addresses that mapped by no local access window
71 (LAW) or an invalid LAW, as well as bad cache state that
72 represents a coherency violation.
73
64config FSL_IFC 74config FSL_IFC
65 bool 75 bool
66 depends on FSL_SOC 76 depends on FSL_SOC
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index 71160a2b7313..4055c47f45ab 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_OF) += of_memory.o
7endif 7endif
8obj-$(CONFIG_TI_AEMIF) += ti-aemif.o 8obj-$(CONFIG_TI_AEMIF) += ti-aemif.o
9obj-$(CONFIG_TI_EMIF) += emif.o 9obj-$(CONFIG_TI_EMIF) += emif.o
10obj-$(CONFIG_FSL_CORENET_CF) += fsl-corenet-cf.o
10obj-$(CONFIG_FSL_IFC) += fsl_ifc.o 11obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
11obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o 12obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o
12obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o 13obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o
diff --git a/drivers/memory/fsl-corenet-cf.c b/drivers/memory/fsl-corenet-cf.c
new file mode 100644
index 000000000000..c9443fc136db
--- /dev/null
+++ b/drivers/memory/fsl-corenet-cf.c
@@ -0,0 +1,251 @@
1/*
2 * CoreNet Coherency Fabric error reporting
3 *
4 * Copyright 2014 Freescale Semiconductor Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <linux/interrupt.h>
13#include <linux/io.h>
14#include <linux/irq.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/of_address.h>
18#include <linux/of_device.h>
19#include <linux/of_irq.h>
20#include <linux/platform_device.h>
21
22enum ccf_version {
23 CCF1,
24 CCF2,
25};
26
27struct ccf_info {
28 enum ccf_version version;
29 int err_reg_offs;
30};
31
32static const struct ccf_info ccf1_info = {
33 .version = CCF1,
34 .err_reg_offs = 0xa00,
35};
36
37static const struct ccf_info ccf2_info = {
38 .version = CCF2,
39 .err_reg_offs = 0xe40,
40};
41
42static const struct of_device_id ccf_matches[] = {
43 {
44 .compatible = "fsl,corenet1-cf",
45 .data = &ccf1_info,
46 },
47 {
48 .compatible = "fsl,corenet2-cf",
49 .data = &ccf2_info,
50 },
51 {}
52};
53
54struct ccf_err_regs {
55 u32 errdet; /* 0x00 Error Detect Register */
56 /* 0x04 Error Enable (ccf1)/Disable (ccf2) Register */
57 u32 errdis;
58 /* 0x08 Error Interrupt Enable Register (ccf2 only) */
59 u32 errinten;
60 u32 cecar; /* 0x0c Error Capture Attribute Register */
61 u32 cecaddrh; /* 0x10 Error Capture Address High */
62 u32 cecaddrl; /* 0x14 Error Capture Address Low */
63 u32 cecar2; /* 0x18 Error Capture Attribute Register 2 */
64};
65
66/* LAE/CV also valid for errdis and errinten */
67#define ERRDET_LAE (1 << 0) /* Local Access Error */
68#define ERRDET_CV (1 << 1) /* Coherency Violation */
69#define ERRDET_CTYPE_SHIFT 26 /* Capture Type (ccf2 only) */
70#define ERRDET_CTYPE_MASK (0x1f << ERRDET_CTYPE_SHIFT)
71#define ERRDET_CAP (1 << 31) /* Capture Valid (ccf2 only) */
72
73#define CECAR_VAL (1 << 0) /* Valid (ccf1 only) */
74#define CECAR_UVT (1 << 15) /* Unavailable target ID (ccf1) */
75#define CECAR_SRCID_SHIFT_CCF1 24
76#define CECAR_SRCID_MASK_CCF1 (0xff << CECAR_SRCID_SHIFT_CCF1)
77#define CECAR_SRCID_SHIFT_CCF2 18
78#define CECAR_SRCID_MASK_CCF2 (0xff << CECAR_SRCID_SHIFT_CCF2)
79
80#define CECADDRH_ADDRH 0xff
81
82struct ccf_private {
83 const struct ccf_info *info;
84 struct device *dev;
85 void __iomem *regs;
86 struct ccf_err_regs __iomem *err_regs;
87};
88
89static irqreturn_t ccf_irq(int irq, void *dev_id)
90{
91 struct ccf_private *ccf = dev_id;
92 static DEFINE_RATELIMIT_STATE(ratelimit, DEFAULT_RATELIMIT_INTERVAL,
93 DEFAULT_RATELIMIT_BURST);
94 u32 errdet, cecar, cecar2;
95 u64 addr;
96 u32 src_id;
97 bool uvt = false;
98 bool cap_valid = false;
99
100 errdet = ioread32be(&ccf->err_regs->errdet);
101 cecar = ioread32be(&ccf->err_regs->cecar);
102 cecar2 = ioread32be(&ccf->err_regs->cecar2);
103 addr = ioread32be(&ccf->err_regs->cecaddrl);
104 addr |= ((u64)(ioread32be(&ccf->err_regs->cecaddrh) &
105 CECADDRH_ADDRH)) << 32;
106
107 if (!__ratelimit(&ratelimit))
108 goto out;
109
110 switch (ccf->info->version) {
111 case CCF1:
112 if (cecar & CECAR_VAL) {
113 if (cecar & CECAR_UVT)
114 uvt = true;
115
116 src_id = (cecar & CECAR_SRCID_MASK_CCF1) >>
117 CECAR_SRCID_SHIFT_CCF1;
118 cap_valid = true;
119 }
120
121 break;
122 case CCF2:
123 if (errdet & ERRDET_CAP) {
124 src_id = (cecar & CECAR_SRCID_MASK_CCF2) >>
125 CECAR_SRCID_SHIFT_CCF2;
126 cap_valid = true;
127 }
128
129 break;
130 }
131
132 dev_crit(ccf->dev, "errdet 0x%08x cecar 0x%08x cecar2 0x%08x\n",
133 errdet, cecar, cecar2);
134
135 if (errdet & ERRDET_LAE) {
136 if (uvt)
137 dev_crit(ccf->dev, "LAW Unavailable Target ID\n");
138 else
139 dev_crit(ccf->dev, "Local Access Window Error\n");
140 }
141
142 if (errdet & ERRDET_CV)
143 dev_crit(ccf->dev, "Coherency Violation\n");
144
145 if (cap_valid) {
146 dev_crit(ccf->dev, "address 0x%09llx, src id 0x%x\n",
147 addr, src_id);
148 }
149
150out:
151 iowrite32be(errdet, &ccf->err_regs->errdet);
152 return errdet ? IRQ_HANDLED : IRQ_NONE;
153}
154
155static int ccf_probe(struct platform_device *pdev)
156{
157 struct ccf_private *ccf;
158 struct resource *r;
159 const struct of_device_id *match;
160 int ret, irq;
161
162 match = of_match_device(ccf_matches, &pdev->dev);
163 if (WARN_ON(!match))
164 return -ENODEV;
165
166 ccf = devm_kzalloc(&pdev->dev, sizeof(*ccf), GFP_KERNEL);
167 if (!ccf)
168 return -ENOMEM;
169
170 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
171 if (!r) {
172 dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
173 return -ENXIO;
174 }
175
176 ccf->regs = devm_ioremap_resource(&pdev->dev, r);
177 if (IS_ERR(ccf->regs)) {
178 dev_err(&pdev->dev, "%s: can't map mem resource\n", __func__);
179 return PTR_ERR(ccf->regs);
180 }
181
182 ccf->dev = &pdev->dev;
183 ccf->info = match->data;
184 ccf->err_regs = ccf->regs + ccf->info->err_reg_offs;
185
186 dev_set_drvdata(&pdev->dev, ccf);
187
188 irq = platform_get_irq(pdev, 0);
189 if (!irq) {
190 dev_err(&pdev->dev, "%s: no irq\n", __func__);
191 return -ENXIO;
192 }
193
194 ret = devm_request_irq(&pdev->dev, irq, ccf_irq, 0, pdev->name, ccf);
195 if (ret) {
196 dev_err(&pdev->dev, "%s: can't request irq\n", __func__);
197 return ret;
198 }
199
200 switch (ccf->info->version) {
201 case CCF1:
202 /* On CCF1 this register enables rather than disables. */
203 iowrite32be(ERRDET_LAE | ERRDET_CV, &ccf->err_regs->errdis);
204 break;
205
206 case CCF2:
207 iowrite32be(0, &ccf->err_regs->errdis);
208 iowrite32be(ERRDET_LAE | ERRDET_CV, &ccf->err_regs->errinten);
209 break;
210 }
211
212 return 0;
213}
214
215static int ccf_remove(struct platform_device *pdev)
216{
217 struct ccf_private *ccf = dev_get_drvdata(&pdev->dev);
218
219 switch (ccf->info->version) {
220 case CCF1:
221 iowrite32be(0, &ccf->err_regs->errdis);
222 break;
223
224 case CCF2:
225 /*
226 * We clear errdis on ccf1 because that's the only way to
227 * disable interrupts, but on ccf2 there's no need to disable
228 * detection.
229 */
230 iowrite32be(0, &ccf->err_regs->errinten);
231 break;
232 }
233
234 return 0;
235}
236
237static struct platform_driver ccf_driver = {
238 .driver = {
239 .name = KBUILD_MODNAME,
240 .owner = THIS_MODULE,
241 .of_match_table = ccf_matches,
242 },
243 .probe = ccf_probe,
244 .remove = ccf_remove,
245};
246
247module_platform_driver(ccf_driver);
248
249MODULE_LICENSE("GPL");
250MODULE_AUTHOR("Freescale Semiconductor");
251MODULE_DESCRIPTION("Freescale CoreNet Coherency Fabric error reporting");
diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
index fc5413488496..1eedfba2ad3c 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
@@ -41,7 +41,6 @@
41#ifdef CONFIG_8xx 41#ifdef CONFIG_8xx
42#include <asm/8xx_immap.h> 42#include <asm/8xx_immap.h>
43#include <asm/pgtable.h> 43#include <asm/pgtable.h>
44#include <asm/mpc8xx.h>
45#include <asm/cpm1.h> 44#include <asm/cpm1.h>
46#endif 45#endif
47 46
diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
index b4bf02f57d43..90b3b19b7cd3 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
@@ -40,7 +40,6 @@
40#ifdef CONFIG_8xx 40#ifdef CONFIG_8xx
41#include <asm/8xx_immap.h> 41#include <asm/8xx_immap.h>
42#include <asm/pgtable.h> 42#include <asm/pgtable.h>
43#include <asm/mpc8xx.h>
44#include <asm/cpm1.h> 43#include <asm/cpm1.h>
45#endif 44#endif
46 45
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 51cf8083b299..b0ce7cdee0c2 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -144,16 +144,6 @@ config TCIC
144 "Bridge" is the name used for the hardware inside your computer that 144 "Bridge" is the name used for the hardware inside your computer that
145 PCMCIA cards are plugged into. If unsure, say N. 145 PCMCIA cards are plugged into. If unsure, say N.
146 146
147config PCMCIA_M8XX
148 tristate "MPC8xx PCMCIA support"
149 depends on PCCARD && PPC && 8xx
150 select PCCARD_IODYN if PCMCIA != n
151 help
152 Say Y here to include support for PowerPC 8xx series PCMCIA
153 controller.
154
155 This driver is also available as a module called m8xx_pcmcia.
156
157config PCMCIA_ALCHEMY_DEVBOARD 147config PCMCIA_ALCHEMY_DEVBOARD
158 tristate "Alchemy Db/Pb1xxx PCMCIA socket services" 148 tristate "Alchemy Db/Pb1xxx PCMCIA socket services"
159 depends on MIPS_ALCHEMY && PCMCIA 149 depends on MIPS_ALCHEMY && PCMCIA
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index fd55a6951402..27e94b30cf96 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -23,7 +23,6 @@ obj-$(CONFIG_PD6729) += pd6729.o
23obj-$(CONFIG_I82365) += i82365.o 23obj-$(CONFIG_I82365) += i82365.o
24obj-$(CONFIG_I82092) += i82092.o 24obj-$(CONFIG_I82092) += i82092.o
25obj-$(CONFIG_TCIC) += tcic.o 25obj-$(CONFIG_TCIC) += tcic.o
26obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
27obj-$(CONFIG_PCMCIA_SOC_COMMON) += soc_common.o 26obj-$(CONFIG_PCMCIA_SOC_COMMON) += soc_common.o
28obj-$(CONFIG_PCMCIA_SA11XX_BASE) += sa11xx_base.o 27obj-$(CONFIG_PCMCIA_SA11XX_BASE) += sa11xx_base.o
29obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o 28obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
deleted file mode 100644
index 182034d2ef58..000000000000
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ /dev/null
@@ -1,1168 +0,0 @@
1/*
2 * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
3 *
4 * (C) 1999-2000 Magnus Damm <damm@opensource.se>
5 * (C) 2001-2002 Montavista Software, Inc.
6 * <mlocke@mvista.com>
7 *
8 * Support for two slots by Cyclades Corporation
9 * <oliver.kurth@cyclades.de>
10 * Further fixes, v2.6 kernel port
11 * <marcelo.tosatti@cyclades.com>
12 *
13 * Some fixes, additions (C) 2005-2007 Montavista Software, Inc.
14 * <vbordug@ru.mvista.com>
15 *
16 * "The ExCA standard specifies that socket controllers should provide
17 * two IO and five memory windows per socket, which can be independently
18 * configured and positioned in the host address space and mapped to
19 * arbitrary segments of card address space. " - David A Hinds. 1999
20 *
21 * This controller does _not_ meet the ExCA standard.
22 *
23 * m8xx pcmcia controller brief info:
24 * + 8 windows (attrib, mem, i/o)
25 * + up to two slots (SLOT_A and SLOT_B)
26 * + inputpins, outputpins, event and mask registers.
27 * - no offset register. sigh.
28 *
29 * Because of the lacking offset register we must map the whole card.
30 * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
31 * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
32 * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
33 * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
34 * They are maximum 64KByte each...
35 */
36
37#include <linux/module.h>
38#include <linux/init.h>
39#include <linux/types.h>
40#include <linux/fcntl.h>
41#include <linux/string.h>
42
43#include <linux/kernel.h>
44#include <linux/errno.h>
45#include <linux/timer.h>
46#include <linux/ioport.h>
47#include <linux/delay.h>
48#include <linux/interrupt.h>
49#include <linux/fsl_devices.h>
50#include <linux/bitops.h>
51#include <linux/of_address.h>
52#include <linux/of_device.h>
53#include <linux/of_irq.h>
54#include <linux/of_platform.h>
55
56#include <asm/io.h>
57#include <asm/time.h>
58#include <asm/mpc8xx.h>
59#include <asm/8xx_immap.h>
60#include <asm/irq.h>
61#include <asm/fs_pd.h>
62
63#include <pcmcia/ss.h>
64
65#define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
66#define pcmcia_error(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
67
68static const char *version = "Version 0.06, Aug 2005";
69MODULE_LICENSE("Dual MPL/GPL");
70
71#if !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B)
72
73/* The ADS board use SLOT_A */
74#ifdef CONFIG_ADS
75#define CONFIG_PCMCIA_SLOT_A
76#define CONFIG_BD_IS_MHZ
77#endif
78
79/* The FADS series are a mess */
80#ifdef CONFIG_FADS
81#if defined(CONFIG_MPC860T) || defined(CONFIG_MPC860) || defined(CONFIG_MPC821)
82#define CONFIG_PCMCIA_SLOT_A
83#else
84#define CONFIG_PCMCIA_SLOT_B
85#endif
86#endif
87
88#if defined(CONFIG_MPC885ADS)
89#define CONFIG_PCMCIA_SLOT_A
90#define PCMCIA_GLITCHY_CD
91#endif
92
93/* Cyclades ACS uses both slots */
94#ifdef CONFIG_PRxK
95#define CONFIG_PCMCIA_SLOT_A
96#define CONFIG_PCMCIA_SLOT_B
97#endif
98
99#endif /* !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B) */
100
101#if defined(CONFIG_PCMCIA_SLOT_A) && defined(CONFIG_PCMCIA_SLOT_B)
102
103#define PCMCIA_SOCKETS_NO 2
104/* We have only 8 windows, dualsocket support will be limited. */
105#define PCMCIA_MEM_WIN_NO 2
106#define PCMCIA_IO_WIN_NO 2
107#define PCMCIA_SLOT_MSG "SLOT_A and SLOT_B"
108
109#elif defined(CONFIG_PCMCIA_SLOT_A) || defined(CONFIG_PCMCIA_SLOT_B)
110
111#define PCMCIA_SOCKETS_NO 1
112/* full support for one slot */
113#define PCMCIA_MEM_WIN_NO 5
114#define PCMCIA_IO_WIN_NO 2
115
116/* define _slot_ to be able to optimize macros */
117
118#ifdef CONFIG_PCMCIA_SLOT_A
119#define _slot_ 0
120#define PCMCIA_SLOT_MSG "SLOT_A"
121#else
122#define _slot_ 1
123#define PCMCIA_SLOT_MSG "SLOT_B"
124#endif
125
126#else
127#error m8xx_pcmcia: Bad configuration!
128#endif
129
130/* ------------------------------------------------------------------------- */
131
132#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0 */
133#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte */
134#define PCMCIA_IO_WIN_BASE _IO_BASE /* base address for io window 0 */
135/* ------------------------------------------------------------------------- */
136
137static int pcmcia_schlvl;
138
139static DEFINE_SPINLOCK(events_lock);
140
141#define PCMCIA_SOCKET_KEY_5V 1
142#define PCMCIA_SOCKET_KEY_LV 2
143
144/* look up table for pgcrx registers */
145static u32 *m8xx_pgcrx[2];
146
147/*
148 * This structure is used to address each window in the PCMCIA controller.
149 *
150 * Keep in mind that we assume that pcmcia_win[n+1] is mapped directly
151 * after pcmcia_win[n]...
152 */
153
154struct pcmcia_win {
155 u32 br;
156 u32 or;
157};
158
159/*
160 * For some reason the hardware guys decided to make both slots share
161 * some registers.
162 *
163 * Could someone invent object oriented hardware ?
164 *
165 * The macros are used to get the right bit from the registers.
166 * SLOT_A : slot = 0
167 * SLOT_B : slot = 1
168 */
169
170#define M8XX_PCMCIA_VS1(slot) (0x80000000 >> (slot << 4))
171#define M8XX_PCMCIA_VS2(slot) (0x40000000 >> (slot << 4))
172#define M8XX_PCMCIA_VS_MASK(slot) (0xc0000000 >> (slot << 4))
173#define M8XX_PCMCIA_VS_SHIFT(slot) (30 - (slot << 4))
174
175#define M8XX_PCMCIA_WP(slot) (0x20000000 >> (slot << 4))
176#define M8XX_PCMCIA_CD2(slot) (0x10000000 >> (slot << 4))
177#define M8XX_PCMCIA_CD1(slot) (0x08000000 >> (slot << 4))
178#define M8XX_PCMCIA_BVD2(slot) (0x04000000 >> (slot << 4))
179#define M8XX_PCMCIA_BVD1(slot) (0x02000000 >> (slot << 4))
180#define M8XX_PCMCIA_RDY(slot) (0x01000000 >> (slot << 4))
181#define M8XX_PCMCIA_RDY_L(slot) (0x00800000 >> (slot << 4))
182#define M8XX_PCMCIA_RDY_H(slot) (0x00400000 >> (slot << 4))
183#define M8XX_PCMCIA_RDY_R(slot) (0x00200000 >> (slot << 4))
184#define M8XX_PCMCIA_RDY_F(slot) (0x00100000 >> (slot << 4))
185#define M8XX_PCMCIA_MASK(slot) (0xFFFF0000 >> (slot << 4))
186
187#define M8XX_PCMCIA_POR_VALID 0x00000001
188#define M8XX_PCMCIA_POR_WRPROT 0x00000002
189#define M8XX_PCMCIA_POR_ATTRMEM 0x00000010
190#define M8XX_PCMCIA_POR_IO 0x00000018
191#define M8XX_PCMCIA_POR_16BIT 0x00000040
192
193#define M8XX_PGCRX(slot) m8xx_pgcrx[slot]
194
195#define M8XX_PGCRX_CXOE 0x00000080
196#define M8XX_PGCRX_CXRESET 0x00000040
197
198/* we keep one lookup table per socket to check flags */
199
200#define PCMCIA_EVENTS_MAX 5 /* 4 max at a time + termination */
201
202struct event_table {
203 u32 regbit;
204 u32 eventbit;
205};
206
207static const char driver_name[] = "m8xx-pcmcia";
208
209struct socket_info {
210 void (*handler) (void *info, u32 events);
211 void *info;
212
213 u32 slot;
214 pcmconf8xx_t *pcmcia;
215 u32 bus_freq;
216 int hwirq;
217
218 socket_state_t state;
219 struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
220 struct pccard_io_map io_win[PCMCIA_IO_WIN_NO];
221 struct event_table events[PCMCIA_EVENTS_MAX];
222 struct pcmcia_socket socket;
223};
224
225static struct socket_info socket[PCMCIA_SOCKETS_NO];
226
227/*
228 * Search this table to see if the windowsize is
229 * supported...
230 */
231
232#define M8XX_SIZES_NO 32
233
234static const u32 m8xx_size_to_gray[M8XX_SIZES_NO] = {
235 0x00000001, 0x00000002, 0x00000008, 0x00000004,
236 0x00000080, 0x00000040, 0x00000010, 0x00000020,
237 0x00008000, 0x00004000, 0x00001000, 0x00002000,
238 0x00000100, 0x00000200, 0x00000800, 0x00000400,
239
240 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
241 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
242 0x00010000, 0x00020000, 0x00080000, 0x00040000,
243 0x00800000, 0x00400000, 0x00100000, 0x00200000
244};
245
246/* ------------------------------------------------------------------------- */
247
248static irqreturn_t m8xx_interrupt(int irq, void *dev);
249
250#define PCMCIA_BMT_LIMIT (15*4) /* Bus Monitor Timeout value */
251
252/* FADS Boards from Motorola */
253
254#if defined(CONFIG_FADS)
255
256#define PCMCIA_BOARD_MSG "FADS"
257
258static int voltage_set(int slot, int vcc, int vpp)
259{
260 u32 reg = 0;
261
262 switch (vcc) {
263 case 0:
264 break;
265 case 33:
266 reg |= BCSR1_PCCVCC0;
267 break;
268 case 50:
269 reg |= BCSR1_PCCVCC1;
270 break;
271 default:
272 return 1;
273 }
274
275 switch (vpp) {
276 case 0:
277 break;
278 case 33:
279 case 50:
280 if (vcc == vpp)
281 reg |= BCSR1_PCCVPP1;
282 else
283 return 1;
284 break;
285 case 120:
286 if ((vcc == 33) || (vcc == 50))
287 reg |= BCSR1_PCCVPP0;
288 else
289 return 1;
290 default:
291 return 1;
292 }
293
294 /* first, turn off all power */
295 out_be32((u32 *) BCSR1,
296 in_be32((u32 *) BCSR1) & ~(BCSR1_PCCVCC_MASK |
297 BCSR1_PCCVPP_MASK));
298
299 /* enable new powersettings */
300 out_be32((u32 *) BCSR1, in_be32((u32 *) BCSR1) | reg);
301
302 return 0;
303}
304
305#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
306
307static void hardware_enable(int slot)
308{
309 out_be32((u32 *) BCSR1, in_be32((u32 *) BCSR1) & ~BCSR1_PCCEN);
310}
311
312static void hardware_disable(int slot)
313{
314 out_be32((u32 *) BCSR1, in_be32((u32 *) BCSR1) | BCSR1_PCCEN);
315}
316
317#endif
318
319/* MPC885ADS Boards */
320
321#if defined(CONFIG_MPC885ADS)
322
323#define PCMCIA_BOARD_MSG "MPC885ADS"
324#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
325
326static inline void hardware_enable(int slot)
327{
328 m8xx_pcmcia_ops.hw_ctrl(slot, 1);
329}
330
331static inline void hardware_disable(int slot)
332{
333 m8xx_pcmcia_ops.hw_ctrl(slot, 0);
334}
335
336static inline int voltage_set(int slot, int vcc, int vpp)
337{
338 return m8xx_pcmcia_ops.voltage_set(slot, vcc, vpp);
339}
340
341#endif
342
343#if defined(CONFIG_PRxK)
344#include <asm/cpld.h>
345extern volatile fpga_pc_regs *fpga_pc;
346
347#define PCMCIA_BOARD_MSG "MPC855T"
348
349static int voltage_set(int slot, int vcc, int vpp)
350{
351 u8 reg = 0;
352 u8 regread;
353 cpld_regs *ccpld = get_cpld();
354
355 switch (vcc) {
356 case 0:
357 break;
358 case 33:
359 reg |= PCMCIA_VCC_33;
360 break;
361 case 50:
362 reg |= PCMCIA_VCC_50;
363 break;
364 default:
365 return 1;
366 }
367
368 switch (vpp) {
369 case 0:
370 break;
371 case 33:
372 case 50:
373 if (vcc == vpp)
374 reg |= PCMCIA_VPP_VCC;
375 else
376 return 1;
377 break;
378 case 120:
379 if ((vcc == 33) || (vcc == 50))
380 reg |= PCMCIA_VPP_12;
381 else
382 return 1;
383 default:
384 return 1;
385 }
386
387 reg = reg >> (slot << 2);
388 regread = in_8(&ccpld->fpga_pc_ctl);
389 if (reg !=
390 (regread & ((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2)))) {
391 /* enable new powersettings */
392 regread =
393 regread & ~((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >>
394 (slot << 2));
395 out_8(&ccpld->fpga_pc_ctl, reg | regread);
396 msleep(100);
397 }
398
399 return 0;
400}
401
402#define socket_get(_slot_) PCMCIA_SOCKET_KEY_LV
403#define hardware_enable(_slot_) /* No hardware to enable */
404#define hardware_disable(_slot_) /* No hardware to disable */
405
406#endif /* CONFIG_PRxK */
407
408static u32 pending_events[PCMCIA_SOCKETS_NO];
409static DEFINE_SPINLOCK(pending_event_lock);
410
411static irqreturn_t m8xx_interrupt(int irq, void *dev)
412{
413 struct socket_info *s;
414 struct event_table *e;
415 unsigned int i, events, pscr, pipr, per;
416 pcmconf8xx_t *pcmcia = socket[0].pcmcia;
417
418 pr_debug("m8xx_pcmcia: Interrupt!\n");
419 /* get interrupt sources */
420
421 pscr = in_be32(&pcmcia->pcmc_pscr);
422 pipr = in_be32(&pcmcia->pcmc_pipr);
423 per = in_be32(&pcmcia->pcmc_per);
424
425 for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
426 s = &socket[i];
427 e = &s->events[0];
428 events = 0;
429
430 while (e->regbit) {
431 if (pscr & e->regbit)
432 events |= e->eventbit;
433
434 e++;
435 }
436
437 /*
438 * report only if both card detect signals are the same
439 * not too nice done,
440 * we depend on that CD2 is the bit to the left of CD1...
441 */
442 if (events & SS_DETECT)
443 if (((pipr & M8XX_PCMCIA_CD2(i)) >> 1) ^
444 (pipr & M8XX_PCMCIA_CD1(i))) {
445 events &= ~SS_DETECT;
446 }
447#ifdef PCMCIA_GLITCHY_CD
448 /*
449 * I've experienced CD problems with my ADS board.
450 * We make an extra check to see if there was a
451 * real change of Card detection.
452 */
453
454 if ((events & SS_DETECT) &&
455 ((pipr &
456 (M8XX_PCMCIA_CD2(i) | M8XX_PCMCIA_CD1(i))) == 0) &&
457 (s->state.Vcc | s->state.Vpp)) {
458 events &= ~SS_DETECT;
459 /*printk( "CD glitch workaround - CD = 0x%08x!\n",
460 (pipr & (M8XX_PCMCIA_CD2(i)
461 | M8XX_PCMCIA_CD1(i)))); */
462 }
463#endif
464
465 /* call the handler */
466
467 pr_debug("m8xx_pcmcia: slot %u: events = 0x%02x, pscr = 0x%08x, "
468 "pipr = 0x%08x\n", i, events, pscr, pipr);
469
470 if (events) {
471 spin_lock(&pending_event_lock);
472 pending_events[i] |= events;
473 spin_unlock(&pending_event_lock);
474 /*
475 * Turn off RDY_L bits in the PER mask on
476 * CD interrupt receival.
477 *
478 * They can generate bad interrupts on the
479 * ACS4,8,16,32. - marcelo
480 */
481 per &= ~M8XX_PCMCIA_RDY_L(0);
482 per &= ~M8XX_PCMCIA_RDY_L(1);
483
484 out_be32(&pcmcia->pcmc_per, per);
485
486 if (events)
487 pcmcia_parse_events(&socket[i].socket, events);
488 }
489 }
490
491 /* clear the interrupt sources */
492 out_be32(&pcmcia->pcmc_pscr, pscr);
493
494 pr_debug("m8xx_pcmcia: Interrupt done.\n");
495
496 return IRQ_HANDLED;
497}
498
499static u32 m8xx_get_graycode(u32 size)
500{
501 u32 k;
502
503 for (k = 0; k < M8XX_SIZES_NO; k++)
504 if (m8xx_size_to_gray[k] == size)
505 break;
506
507 if ((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
508 k = -1;
509
510 return k;
511}
512
513static u32 m8xx_get_speed(u32 ns, u32 is_io, u32 bus_freq)
514{
515 u32 reg, clocks, psst, psl, psht;
516
517 if (!ns) {
518
519 /*
520 * We get called with IO maps setup to 0ns
521 * if not specified by the user.
522 * They should be 255ns.
523 */
524
525 if (is_io)
526 ns = 255;
527 else
528 ns = 100; /* fast memory if 0 */
529 }
530
531 /*
532 * In PSST, PSL, PSHT fields we tell the controller
533 * timing parameters in CLKOUT clock cycles.
534 * CLKOUT is the same as GCLK2_50.
535 */
536
537/* how we want to adjust the timing - in percent */
538
539#define ADJ 180 /* 80 % longer accesstime - to be sure */
540
541 clocks = ((bus_freq / 1000) * ns) / 1000;
542 clocks = (clocks * ADJ) / (100 * 1000);
543 if (clocks >= PCMCIA_BMT_LIMIT) {
544 printk("Max access time limit reached\n");
545 clocks = PCMCIA_BMT_LIMIT - 1;
546 }
547
548 psst = clocks / 7; /* setup time */
549 psht = clocks / 7; /* hold time */
550 psl = (clocks * 5) / 7; /* strobe length */
551
552 psst += clocks - (psst + psht + psl);
553
554 reg = psst << 12;
555 reg |= psl << 7;
556 reg |= psht << 16;
557
558 return reg;
559}
560
561static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
562{
563 int lsock = container_of(sock, struct socket_info, socket)->slot;
564 struct socket_info *s = &socket[lsock];
565 unsigned int pipr, reg;
566 pcmconf8xx_t *pcmcia = s->pcmcia;
567
568 pipr = in_be32(&pcmcia->pcmc_pipr);
569
570 *value = ((pipr & (M8XX_PCMCIA_CD1(lsock)
571 | M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0;
572 *value |= (pipr & M8XX_PCMCIA_WP(lsock)) ? SS_WRPROT : 0;
573
574 if (s->state.flags & SS_IOCARD)
575 *value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_STSCHG : 0;
576 else {
577 *value |= (pipr & M8XX_PCMCIA_RDY(lsock)) ? SS_READY : 0;
578 *value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_BATDEAD : 0;
579 *value |= (pipr & M8XX_PCMCIA_BVD2(lsock)) ? SS_BATWARN : 0;
580 }
581
582 if (s->state.Vcc | s->state.Vpp)
583 *value |= SS_POWERON;
584
585 /*
586 * Voltage detection:
587 * This driver only supports 16-Bit pc-cards.
588 * Cardbus is not handled here.
589 *
590 * To determine what voltage to use we must read the VS1 and VS2 pin.
591 * Depending on what socket type is present,
592 * different combinations mean different things.
593 *
594 * Card Key Socket Key VS1 VS2 Card Vcc for CIS parse
595 *
596 * 5V 5V, LV* NC NC 5V only 5V (if available)
597 *
598 * 5V 5V, LV* GND NC 5 or 3.3V as low as possible
599 *
600 * 5V 5V, LV* GND GND 5, 3.3, x.xV as low as possible
601 *
602 * LV* 5V - - shall not fit into socket
603 *
604 * LV* LV* GND NC 3.3V only 3.3V
605 *
606 * LV* LV* NC GND x.xV x.xV (if avail.)
607 *
608 * LV* LV* GND GND 3.3 or x.xV as low as possible
609 *
610 * *LV means Low Voltage
611 *
612 *
613 * That gives us the following table:
614 *
615 * Socket VS1 VS2 Voltage
616 *
617 * 5V NC NC 5V
618 * 5V NC GND none (should not be possible)
619 * 5V GND NC >= 3.3V
620 * 5V GND GND >= x.xV
621 *
622 * LV NC NC 5V (if available)
623 * LV NC GND x.xV (if available)
624 * LV GND NC 3.3V
625 * LV GND GND >= x.xV
626 *
627 * So, how do I determine if I have a 5V or a LV
628 * socket on my board? Look at the socket!
629 *
630 *
631 * Socket with 5V key:
632 * ++--------------------------------------------+
633 * || |
634 * || ||
635 * || ||
636 * | |
637 * +---------------------------------------------+
638 *
639 * Socket with LV key:
640 * ++--------------------------------------------+
641 * || |
642 * | ||
643 * | ||
644 * | |
645 * +---------------------------------------------+
646 *
647 *
648 * With other words - LV only cards does not fit
649 * into the 5V socket!
650 */
651
652 /* read out VS1 and VS2 */
653
654 reg = (pipr & M8XX_PCMCIA_VS_MASK(lsock))
655 >> M8XX_PCMCIA_VS_SHIFT(lsock);
656
657 if (socket_get(lsock) == PCMCIA_SOCKET_KEY_LV) {
658 switch (reg) {
659 case 1:
660 *value |= SS_3VCARD;
661 break; /* GND, NC - 3.3V only */
662 case 2:
663 *value |= SS_XVCARD;
664 break; /* NC. GND - x.xV only */
665 };
666 }
667
668 pr_debug("m8xx_pcmcia: GetStatus(%d) = %#2.2x\n", lsock, *value);
669 return 0;
670}
671
672static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t * state)
673{
674 int lsock = container_of(sock, struct socket_info, socket)->slot;
675 struct socket_info *s = &socket[lsock];
676 struct event_table *e;
677 unsigned int reg;
678 unsigned long flags;
679 pcmconf8xx_t *pcmcia = socket[0].pcmcia;
680
681 pr_debug("m8xx_pcmcia: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
682 "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
683 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
684
685 /* First, set voltage - bail out if invalid */
686 if (voltage_set(lsock, state->Vcc, state->Vpp))
687 return -EINVAL;
688
689 /* Take care of reset... */
690 if (state->flags & SS_RESET)
691 out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXRESET); /* active high */
692 else
693 out_be32(M8XX_PGCRX(lsock),
694 in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXRESET);
695
696 /* ... and output enable. */
697
698 /* The CxOE signal is connected to a 74541 on the ADS.
699 I guess most other boards used the ADS as a reference.
700 I tried to control the CxOE signal with SS_OUTPUT_ENA,
701 but the reset signal seems connected via the 541.
702 If the CxOE is left high are some signals tristated and
703 no pullups are present -> the cards act weird.
704 So right now the buffers are enabled if the power is on. */
705
706 if (state->Vcc || state->Vpp)
707 out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXOE); /* active low */
708 else
709 out_be32(M8XX_PGCRX(lsock),
710 in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXOE);
711
712 /*
713 * We'd better turn off interrupts before
714 * we mess with the events-table..
715 */
716
717 spin_lock_irqsave(&events_lock, flags);
718
719 /*
720 * Play around with the interrupt mask to be able to
721 * give the events the generic pcmcia driver wants us to.
722 */
723
724 e = &s->events[0];
725 reg = 0;
726
727 if (state->csc_mask & SS_DETECT) {
728 e->eventbit = SS_DETECT;
729 reg |= e->regbit = (M8XX_PCMCIA_CD2(lsock)
730 | M8XX_PCMCIA_CD1(lsock));
731 e++;
732 }
733 if (state->flags & SS_IOCARD) {
734 /*
735 * I/O card
736 */
737 if (state->csc_mask & SS_STSCHG) {
738 e->eventbit = SS_STSCHG;
739 reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock);
740 e++;
741 }
742 /*
743 * If io_irq is non-zero we should enable irq.
744 */
745 if (state->io_irq) {
746 out_be32(M8XX_PGCRX(lsock),
747 in_be32(M8XX_PGCRX(lsock)) |
748 mk_int_int_mask(s->hwirq) << 24);
749 /*
750 * Strange thing here:
751 * The manual does not tell us which interrupt
752 * the sources generate.
753 * Anyhow, I found out that RDY_L generates IREQLVL.
754 *
755 * We use level triggerd interrupts, and they don't
756 * have to be cleared in PSCR in the interrupt handler.
757 */
758 reg |= M8XX_PCMCIA_RDY_L(lsock);
759 } else
760 out_be32(M8XX_PGCRX(lsock),
761 in_be32(M8XX_PGCRX(lsock)) & 0x00ffffff);
762 } else {
763 /*
764 * Memory card
765 */
766 if (state->csc_mask & SS_BATDEAD) {
767 e->eventbit = SS_BATDEAD;
768 reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock);
769 e++;
770 }
771 if (state->csc_mask & SS_BATWARN) {
772 e->eventbit = SS_BATWARN;
773 reg |= e->regbit = M8XX_PCMCIA_BVD2(lsock);
774 e++;
775 }
776 /* What should I trigger on - low/high,raise,fall? */
777 if (state->csc_mask & SS_READY) {
778 e->eventbit = SS_READY;
779 reg |= e->regbit = 0; //??
780 e++;
781 }
782 }
783
784 e->regbit = 0; /* terminate list */
785
786 /*
787 * Clear the status changed .
788 * Port A and Port B share the same port.
789 * Writing ones will clear the bits.
790 */
791
792 out_be32(&pcmcia->pcmc_pscr, reg);
793
794 /*
795 * Write the mask.
796 * Port A and Port B share the same port.
797 * Need for read-modify-write.
798 * Ones will enable the interrupt.
799 */
800
801 reg |=
802 in_be32(&pcmcia->
803 pcmc_per) & (M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
804 out_be32(&pcmcia->pcmc_per, reg);
805
806 spin_unlock_irqrestore(&events_lock, flags);
807
808 /* copy the struct and modify the copy */
809
810 s->state = *state;
811
812 return 0;
813}
814
815static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
816{
817 int lsock = container_of(sock, struct socket_info, socket)->slot;
818
819 struct socket_info *s = &socket[lsock];
820 struct pcmcia_win *w;
821 unsigned int reg, winnr;
822 pcmconf8xx_t *pcmcia = s->pcmcia;
823
824#define M8XX_SIZE (io->stop - io->start + 1)
825#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
826
827 pr_debug("m8xx_pcmcia: SetIOMap(%d, %d, %#2.2x, %d ns, "
828 "%#4.4llx-%#4.4llx)\n", lsock, io->map, io->flags,
829 io->speed, (unsigned long long)io->start,
830 (unsigned long long)io->stop);
831
832 if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff)
833 || (io->stop > 0xffff) || (io->stop < io->start))
834 return -EINVAL;
835
836 if ((reg = m8xx_get_graycode(M8XX_SIZE)) == -1)
837 return -EINVAL;
838
839 if (io->flags & MAP_ACTIVE) {
840
841 pr_debug("m8xx_pcmcia: io->flags & MAP_ACTIVE\n");
842
843 winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
844 + (lsock * PCMCIA_IO_WIN_NO) + io->map;
845
846 /* setup registers */
847
848 w = (void *)&pcmcia->pcmc_pbr0;
849 w += winnr;
850
851 out_be32(&w->or, 0); /* turn off window first */
852 out_be32(&w->br, M8XX_BASE);
853
854 reg <<= 27;
855 reg |= M8XX_PCMCIA_POR_IO | (lsock << 2);
856
857 reg |= m8xx_get_speed(io->speed, 1, s->bus_freq);
858
859 if (io->flags & MAP_WRPROT)
860 reg |= M8XX_PCMCIA_POR_WRPROT;
861
862 /*if(io->flags & (MAP_16BIT | MAP_AUTOSZ)) */
863 if (io->flags & MAP_16BIT)
864 reg |= M8XX_PCMCIA_POR_16BIT;
865
866 if (io->flags & MAP_ACTIVE)
867 reg |= M8XX_PCMCIA_POR_VALID;
868
869 out_be32(&w->or, reg);
870
871 pr_debug("m8xx_pcmcia: Socket %u: Mapped io window %u at "
872 "%#8.8x, OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
873 } else {
874 /* shutdown IO window */
875 winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
876 + (lsock * PCMCIA_IO_WIN_NO) + io->map;
877
878 /* setup registers */
879
880 w = (void *)&pcmcia->pcmc_pbr0;
881 w += winnr;
882
883 out_be32(&w->or, 0); /* turn off window */
884 out_be32(&w->br, 0); /* turn off base address */
885
886 pr_debug("m8xx_pcmcia: Socket %u: Unmapped io window %u at "
887 "%#8.8x, OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
888 }
889
890 /* copy the struct and modify the copy */
891 s->io_win[io->map] = *io;
892 s->io_win[io->map].flags &= (MAP_WRPROT | MAP_16BIT | MAP_ACTIVE);
893 pr_debug("m8xx_pcmcia: SetIOMap exit\n");
894
895 return 0;
896}
897
898static int m8xx_set_mem_map(struct pcmcia_socket *sock,
899 struct pccard_mem_map *mem)
900{
901 int lsock = container_of(sock, struct socket_info, socket)->slot;
902 struct socket_info *s = &socket[lsock];
903 struct pcmcia_win *w;
904 struct pccard_mem_map *old;
905 unsigned int reg, winnr;
906 pcmconf8xx_t *pcmcia = s->pcmcia;
907
908 pr_debug("m8xx_pcmcia: SetMemMap(%d, %d, %#2.2x, %d ns, "
909 "%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
910 mem->speed, (unsigned long long)mem->static_start,
911 mem->card_start);
912
913 if ((mem->map >= PCMCIA_MEM_WIN_NO)
914// || ((mem->s) >= PCMCIA_MEM_WIN_SIZE)
915 || (mem->card_start >= 0x04000000)
916 || (mem->static_start & 0xfff) /* 4KByte resolution */
917 ||(mem->card_start & 0xfff))
918 return -EINVAL;
919
920 if ((reg = m8xx_get_graycode(PCMCIA_MEM_WIN_SIZE)) == -1) {
921 printk("Cannot set size to 0x%08x.\n", PCMCIA_MEM_WIN_SIZE);
922 return -EINVAL;
923 }
924 reg <<= 27;
925
926 winnr = (lsock * PCMCIA_MEM_WIN_NO) + mem->map;
927
928 /* Setup the window in the pcmcia controller */
929
930 w = (void *)&pcmcia->pcmc_pbr0;
931 w += winnr;
932
933 reg |= lsock << 2;
934
935 reg |= m8xx_get_speed(mem->speed, 0, s->bus_freq);
936
937 if (mem->flags & MAP_ATTRIB)
938 reg |= M8XX_PCMCIA_POR_ATTRMEM;
939
940 if (mem->flags & MAP_WRPROT)
941 reg |= M8XX_PCMCIA_POR_WRPROT;
942
943 if (mem->flags & MAP_16BIT)
944 reg |= M8XX_PCMCIA_POR_16BIT;
945
946 if (mem->flags & MAP_ACTIVE)
947 reg |= M8XX_PCMCIA_POR_VALID;
948
949 out_be32(&w->or, reg);
950
951 pr_debug("m8xx_pcmcia: Socket %u: Mapped memory window %u at %#8.8x, "
952 "OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
953
954 if (mem->flags & MAP_ACTIVE) {
955 /* get the new base address */
956 mem->static_start = PCMCIA_MEM_WIN_BASE +
957 (PCMCIA_MEM_WIN_SIZE * winnr)
958 + mem->card_start;
959 }
960
961 pr_debug("m8xx_pcmcia: SetMemMap(%d, %d, %#2.2x, %d ns, "
962 "%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
963 mem->speed, (unsigned long long)mem->static_start,
964 mem->card_start);
965
966 /* copy the struct and modify the copy */
967
968 old = &s->mem_win[mem->map];
969
970 *old = *mem;
971 old->flags &= (MAP_ATTRIB | MAP_WRPROT | MAP_16BIT | MAP_ACTIVE);
972
973 return 0;
974}
975
976static int m8xx_sock_init(struct pcmcia_socket *sock)
977{
978 int i;
979 pccard_io_map io = { 0, 0, 0, 0, 1 };
980 pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
981
982 pr_debug("m8xx_pcmcia: sock_init(%d)\n", s);
983
984 m8xx_set_socket(sock, &dead_socket);
985 for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
986 io.map = i;
987 m8xx_set_io_map(sock, &io);
988 }
989 for (i = 0; i < PCMCIA_MEM_WIN_NO; i++) {
990 mem.map = i;
991 m8xx_set_mem_map(sock, &mem);
992 }
993
994 return 0;
995
996}
997
998static int m8xx_sock_suspend(struct pcmcia_socket *sock)
999{
1000 return m8xx_set_socket(sock, &dead_socket);
1001}
1002
1003static struct pccard_operations m8xx_services = {
1004 .init = m8xx_sock_init,
1005 .suspend = m8xx_sock_suspend,
1006 .get_status = m8xx_get_status,
1007 .set_socket = m8xx_set_socket,
1008 .set_io_map = m8xx_set_io_map,
1009 .set_mem_map = m8xx_set_mem_map,
1010};
1011
1012static int __init m8xx_probe(struct platform_device *ofdev)
1013{
1014 struct pcmcia_win *w;
1015 unsigned int i, m, hwirq;
1016 pcmconf8xx_t *pcmcia;
1017 int status;
1018 struct device_node *np = ofdev->dev.of_node;
1019
1020 pcmcia_info("%s\n", version);
1021
1022 pcmcia = of_iomap(np, 0);
1023 if (pcmcia == NULL)
1024 return -EINVAL;
1025
1026 pcmcia_schlvl = irq_of_parse_and_map(np, 0);
1027 hwirq = irq_map[pcmcia_schlvl].hwirq;
1028 if (pcmcia_schlvl < 0) {
1029 iounmap(pcmcia);
1030 return -EINVAL;
1031 }
1032
1033 m8xx_pgcrx[0] = &pcmcia->pcmc_pgcra;
1034 m8xx_pgcrx[1] = &pcmcia->pcmc_pgcrb;
1035
1036 pcmcia_info(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG
1037 " with IRQ %u (%d). \n", pcmcia_schlvl, hwirq);
1038
1039 /* Configure Status change interrupt */
1040
1041 if (request_irq(pcmcia_schlvl, m8xx_interrupt, IRQF_SHARED,
1042 driver_name, socket)) {
1043 pcmcia_error("Cannot allocate IRQ %u for SCHLVL!\n",
1044 pcmcia_schlvl);
1045 iounmap(pcmcia);
1046 return -1;
1047 }
1048
1049 w = (void *)&pcmcia->pcmc_pbr0;
1050
1051 out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
1052 clrbits32(&pcmcia->pcmc_per, M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
1053
1054 /* connect interrupt and disable CxOE */
1055
1056 out_be32(M8XX_PGCRX(0),
1057 M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
1058 out_be32(M8XX_PGCRX(1),
1059 M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
1060
1061 /* initialize the fixed memory windows */
1062
1063 for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
1064 for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
1065 out_be32(&w->br, PCMCIA_MEM_WIN_BASE +
1066 (PCMCIA_MEM_WIN_SIZE
1067 * (m + i * PCMCIA_MEM_WIN_NO)));
1068
1069 out_be32(&w->or, 0); /* set to not valid */
1070
1071 w++;
1072 }
1073 }
1074
1075 /* turn off voltage */
1076 voltage_set(0, 0, 0);
1077 voltage_set(1, 0, 0);
1078
1079 /* Enable external hardware */
1080 hardware_enable(0);
1081 hardware_enable(1);
1082
1083 for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
1084 socket[i].slot = i;
1085 socket[i].socket.owner = THIS_MODULE;
1086 socket[i].socket.features =
1087 SS_CAP_PCCARD | SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP;
1088 socket[i].socket.irq_mask = 0x000;
1089 socket[i].socket.map_size = 0x1000;
1090 socket[i].socket.io_offset = 0;
1091 socket[i].socket.pci_irq = pcmcia_schlvl;
1092 socket[i].socket.ops = &m8xx_services;
1093 socket[i].socket.resource_ops = &pccard_iodyn_ops;
1094 socket[i].socket.cb_dev = NULL;
1095 socket[i].socket.dev.parent = &ofdev->dev;
1096 socket[i].pcmcia = pcmcia;
1097 socket[i].bus_freq = ppc_proc_freq;
1098 socket[i].hwirq = hwirq;
1099
1100 }
1101
1102 for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
1103 status = pcmcia_register_socket(&socket[i].socket);
1104 if (status < 0)
1105 pcmcia_error("Socket register failed\n");
1106 }
1107
1108 return 0;
1109}
1110
1111static int m8xx_remove(struct platform_device *ofdev)
1112{
1113 u32 m, i;
1114 struct pcmcia_win *w;
1115 pcmconf8xx_t *pcmcia = socket[0].pcmcia;
1116
1117 for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
1118 w = (void *)&pcmcia->pcmc_pbr0;
1119
1120 out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(i));
1121 out_be32(&pcmcia->pcmc_per,
1122 in_be32(&pcmcia->pcmc_per) & ~M8XX_PCMCIA_MASK(i));
1123
1124 /* turn off interrupt and disable CxOE */
1125 out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE);
1126
1127 /* turn off memory windows */
1128 for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
1129 out_be32(&w->or, 0); /* set to not valid */
1130 w++;
1131 }
1132
1133 /* turn off voltage */
1134 voltage_set(i, 0, 0);
1135
1136 /* disable external hardware */
1137 hardware_disable(i);
1138 }
1139 for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
1140 pcmcia_unregister_socket(&socket[i].socket);
1141 iounmap(pcmcia);
1142
1143 free_irq(pcmcia_schlvl, NULL);
1144
1145 return 0;
1146}
1147
1148static const struct of_device_id m8xx_pcmcia_match[] = {
1149 {
1150 .type = "pcmcia",
1151 .compatible = "fsl,pq-pcmcia",
1152 },
1153 {},
1154};
1155
1156MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match);
1157
1158static struct platform_driver m8xx_pcmcia_driver = {
1159 .driver = {
1160 .name = driver_name,
1161 .owner = THIS_MODULE,
1162 .of_match_table = m8xx_pcmcia_match,
1163 },
1164 .probe = m8xx_probe,
1165 .remove = m8xx_remove,
1166};
1167
1168module_platform_driver(m8xx_pcmcia_driver);
diff --git a/drivers/vfio/Makefile b/drivers/vfio/Makefile
index 72bfabc8629e..50e30bc75e85 100644
--- a/drivers/vfio/Makefile
+++ b/drivers/vfio/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_VFIO) += vfio.o 1obj-$(CONFIG_VFIO) += vfio.o
2obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o 2obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o
3obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o 3obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o
4obj-$(CONFIG_EEH) += vfio_spapr_eeh.o
4obj-$(CONFIG_VFIO_PCI) += pci/ 5obj-$(CONFIG_VFIO_PCI) += pci/
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 010e0f8b8e4f..e2ee80f36e3e 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -157,8 +157,10 @@ static void vfio_pci_release(void *device_data)
157{ 157{
158 struct vfio_pci_device *vdev = device_data; 158 struct vfio_pci_device *vdev = device_data;
159 159
160 if (atomic_dec_and_test(&vdev->refcnt)) 160 if (atomic_dec_and_test(&vdev->refcnt)) {
161 vfio_spapr_pci_eeh_release(vdev->pdev);
161 vfio_pci_disable(vdev); 162 vfio_pci_disable(vdev);
163 }
162 164
163 module_put(THIS_MODULE); 165 module_put(THIS_MODULE);
164} 166}
@@ -166,19 +168,27 @@ static void vfio_pci_release(void *device_data)
166static int vfio_pci_open(void *device_data) 168static int vfio_pci_open(void *device_data)
167{ 169{
168 struct vfio_pci_device *vdev = device_data; 170 struct vfio_pci_device *vdev = device_data;
171 int ret;
169 172
170 if (!try_module_get(THIS_MODULE)) 173 if (!try_module_get(THIS_MODULE))
171 return -ENODEV; 174 return -ENODEV;
172 175
173 if (atomic_inc_return(&vdev->refcnt) == 1) { 176 if (atomic_inc_return(&vdev->refcnt) == 1) {
174 int ret = vfio_pci_enable(vdev); 177 ret = vfio_pci_enable(vdev);
178 if (ret)
179 goto error;
180
181 ret = vfio_spapr_pci_eeh_open(vdev->pdev);
175 if (ret) { 182 if (ret) {
176 module_put(THIS_MODULE); 183 vfio_pci_disable(vdev);
177 return ret; 184 goto error;
178 } 185 }
179 } 186 }
180 187
181 return 0; 188 return 0;
189error:
190 module_put(THIS_MODULE);
191 return ret;
182} 192}
183 193
184static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type) 194static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type)
diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c
index a84788ba662c..730b4ef3e0cc 100644
--- a/drivers/vfio/vfio_iommu_spapr_tce.c
+++ b/drivers/vfio/vfio_iommu_spapr_tce.c
@@ -156,7 +156,16 @@ static long tce_iommu_ioctl(void *iommu_data,
156 156
157 switch (cmd) { 157 switch (cmd) {
158 case VFIO_CHECK_EXTENSION: 158 case VFIO_CHECK_EXTENSION:
159 return (arg == VFIO_SPAPR_TCE_IOMMU) ? 1 : 0; 159 switch (arg) {
160 case VFIO_SPAPR_TCE_IOMMU:
161 ret = 1;
162 break;
163 default:
164 ret = vfio_spapr_iommu_eeh_ioctl(NULL, cmd, arg);
165 break;
166 }
167
168 return (ret < 0) ? 0 : ret;
160 169
161 case VFIO_IOMMU_SPAPR_TCE_GET_INFO: { 170 case VFIO_IOMMU_SPAPR_TCE_GET_INFO: {
162 struct vfio_iommu_spapr_tce_info info; 171 struct vfio_iommu_spapr_tce_info info;
@@ -283,6 +292,12 @@ static long tce_iommu_ioctl(void *iommu_data,
283 tce_iommu_disable(container); 292 tce_iommu_disable(container);
284 mutex_unlock(&container->lock); 293 mutex_unlock(&container->lock);
285 return 0; 294 return 0;
295 case VFIO_EEH_PE_OP:
296 if (!container->tbl || !container->tbl->it_group)
297 return -ENODEV;
298
299 return vfio_spapr_iommu_eeh_ioctl(container->tbl->it_group,
300 cmd, arg);
286 } 301 }
287 302
288 return -ENOTTY; 303 return -ENOTTY;
diff --git a/drivers/vfio/vfio_spapr_eeh.c b/drivers/vfio/vfio_spapr_eeh.c
new file mode 100644
index 000000000000..f834b4ce1431
--- /dev/null
+++ b/drivers/vfio/vfio_spapr_eeh.c
@@ -0,0 +1,87 @@
1/*
2 * EEH functionality support for VFIO devices. The feature is only
3 * available on sPAPR compatible platforms.
4 *
5 * Copyright Gavin Shan, IBM Corporation 2014.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/uaccess.h>
13#include <linux/vfio.h>
14#include <asm/eeh.h>
15
16/* We might build address mapping here for "fast" path later */
17int vfio_spapr_pci_eeh_open(struct pci_dev *pdev)
18{
19 return eeh_dev_open(pdev);
20}
21
22void vfio_spapr_pci_eeh_release(struct pci_dev *pdev)
23{
24 eeh_dev_release(pdev);
25}
26
27long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
28 unsigned int cmd, unsigned long arg)
29{
30 struct eeh_pe *pe;
31 struct vfio_eeh_pe_op op;
32 unsigned long minsz;
33 long ret = -EINVAL;
34
35 switch (cmd) {
36 case VFIO_CHECK_EXTENSION:
37 if (arg == VFIO_EEH)
38 ret = eeh_enabled() ? 1 : 0;
39 else
40 ret = 0;
41 break;
42 case VFIO_EEH_PE_OP:
43 pe = eeh_iommu_group_to_pe(group);
44 if (!pe)
45 return -ENODEV;
46
47 minsz = offsetofend(struct vfio_eeh_pe_op, op);
48 if (copy_from_user(&op, (void __user *)arg, minsz))
49 return -EFAULT;
50 if (op.argsz < minsz || op.flags)
51 return -EINVAL;
52
53 switch (op.op) {
54 case VFIO_EEH_PE_DISABLE:
55 ret = eeh_pe_set_option(pe, EEH_OPT_DISABLE);
56 break;
57 case VFIO_EEH_PE_ENABLE:
58 ret = eeh_pe_set_option(pe, EEH_OPT_ENABLE);
59 break;
60 case VFIO_EEH_PE_UNFREEZE_IO:
61 ret = eeh_pe_set_option(pe, EEH_OPT_THAW_MMIO);
62 break;
63 case VFIO_EEH_PE_UNFREEZE_DMA:
64 ret = eeh_pe_set_option(pe, EEH_OPT_THAW_DMA);
65 break;
66 case VFIO_EEH_PE_GET_STATE:
67 ret = eeh_pe_get_state(pe);
68 break;
69 case VFIO_EEH_PE_RESET_DEACTIVATE:
70 ret = eeh_pe_reset(pe, EEH_RESET_DEACTIVATE);
71 break;
72 case VFIO_EEH_PE_RESET_HOT:
73 ret = eeh_pe_reset(pe, EEH_RESET_HOT);
74 break;
75 case VFIO_EEH_PE_RESET_FUNDAMENTAL:
76 ret = eeh_pe_reset(pe, EEH_RESET_FUNDAMENTAL);
77 break;
78 case VFIO_EEH_PE_CONFIGURE:
79 ret = eeh_pe_configure(pe);
80 break;
81 default:
82 ret = -EINVAL;
83 }
84 }
85
86 return ret;
87}
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index 8ec980b5e3af..25a0fbd4b998 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -98,4 +98,27 @@ extern int vfio_external_user_iommu_id(struct vfio_group *group);
98extern long vfio_external_check_extension(struct vfio_group *group, 98extern long vfio_external_check_extension(struct vfio_group *group,
99 unsigned long arg); 99 unsigned long arg);
100 100
101#ifdef CONFIG_EEH
102extern int vfio_spapr_pci_eeh_open(struct pci_dev *pdev);
103extern void vfio_spapr_pci_eeh_release(struct pci_dev *pdev);
104extern long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
105 unsigned int cmd,
106 unsigned long arg);
107#else
108static inline int vfio_spapr_pci_eeh_open(struct pci_dev *pdev)
109{
110 return 0;
111}
112
113static inline void vfio_spapr_pci_eeh_release(struct pci_dev *pdev)
114{
115}
116
117static inline long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
118 unsigned int cmd,
119 unsigned long arg)
120{
121 return -ENOTTY;
122}
123#endif /* CONFIG_EEH */
101#endif /* VFIO_H */ 124#endif /* VFIO_H */
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index cb9023d4f063..6612974c64bf 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -30,6 +30,9 @@
30 */ 30 */
31#define VFIO_DMA_CC_IOMMU 4 31#define VFIO_DMA_CC_IOMMU 4
32 32
33/* Check if EEH is supported */
34#define VFIO_EEH 5
35
33/* 36/*
34 * The IOCTL interface is designed for extensibility by embedding the 37 * The IOCTL interface is designed for extensibility by embedding the
35 * structure length (argsz) and flags into structures passed between 38 * structure length (argsz) and flags into structures passed between
@@ -455,6 +458,37 @@ struct vfio_iommu_spapr_tce_info {
455 458
456#define VFIO_IOMMU_SPAPR_TCE_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12) 459#define VFIO_IOMMU_SPAPR_TCE_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12)
457 460
461/*
462 * EEH PE operation struct provides ways to:
463 * - enable/disable EEH functionality;
464 * - unfreeze IO/DMA for frozen PE;
465 * - read PE state;
466 * - reset PE;
467 * - configure PE.
468 */
469struct vfio_eeh_pe_op {
470 __u32 argsz;
471 __u32 flags;
472 __u32 op;
473};
474
475#define VFIO_EEH_PE_DISABLE 0 /* Disable EEH functionality */
476#define VFIO_EEH_PE_ENABLE 1 /* Enable EEH functionality */
477#define VFIO_EEH_PE_UNFREEZE_IO 2 /* Enable IO for frozen PE */
478#define VFIO_EEH_PE_UNFREEZE_DMA 3 /* Enable DMA for frozen PE */
479#define VFIO_EEH_PE_GET_STATE 4 /* PE state retrieval */
480#define VFIO_EEH_PE_STATE_NORMAL 0 /* PE in functional state */
481#define VFIO_EEH_PE_STATE_RESET 1 /* PE reset in progress */
482#define VFIO_EEH_PE_STATE_STOPPED 2 /* Stopped DMA and IO */
483#define VFIO_EEH_PE_STATE_STOPPED_DMA 4 /* Stopped DMA only */
484#define VFIO_EEH_PE_STATE_UNAVAIL 5 /* State unavailable */
485#define VFIO_EEH_PE_RESET_DEACTIVATE 5 /* Deassert PE reset */
486#define VFIO_EEH_PE_RESET_HOT 6 /* Assert hot reset */
487#define VFIO_EEH_PE_RESET_FUNDAMENTAL 7 /* Assert fundamental reset */
488#define VFIO_EEH_PE_CONFIGURE 8 /* PE configuration */
489
490#define VFIO_EEH_PE_OP _IO(VFIO_TYPE, VFIO_BASE + 21)
491
458/* ***************************************************************** */ 492/* ***************************************************************** */
459 493
460#endif /* _UAPIVFIO_H */ 494#endif /* _UAPIVFIO_H */
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index 54833a791a44..74a78cedce37 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -17,10 +17,10 @@ TARGETS = pmu copyloops mm tm
17 17
18endif 18endif
19 19
20all: 20all: $(TARGETS)
21 @for TARGET in $(TARGETS); do \ 21
22 $(MAKE) -C $$TARGET all; \ 22$(TARGETS):
23 done; 23 $(MAKE) -k -C $@ all
24 24
25run_tests: all 25run_tests: all
26 @for TARGET in $(TARGETS); do \ 26 @for TARGET in $(TARGETS); do \
@@ -36,4 +36,4 @@ clean:
36tags: 36tags:
37 find . -name '*.c' -o -name '*.h' | xargs ctags 37 find . -name '*.c' -o -name '*.h' | xargs ctags
38 38
39.PHONY: all run_tests clean tags 39.PHONY: all run_tests clean tags $(TARGETS)
diff --git a/tools/testing/selftests/powerpc/pmu/Makefile b/tools/testing/selftests/powerpc/pmu/Makefile
index b9ff0db42c79..c9f4263906a5 100644
--- a/tools/testing/selftests/powerpc/pmu/Makefile
+++ b/tools/testing/selftests/powerpc/pmu/Makefile
@@ -1,10 +1,12 @@
1noarg: 1noarg:
2 $(MAKE) -C ../ 2 $(MAKE) -C ../
3 3
4PROGS := count_instructions 4PROGS := count_instructions l3_bank_test per_event_excludes
5EXTRA_SOURCES := ../harness.c event.c 5EXTRA_SOURCES := ../harness.c event.c lib.c
6 6
7all: $(PROGS) sub_all 7SUB_TARGETS = ebb
8
9all: $(PROGS) $(SUB_TARGETS)
8 10
9$(PROGS): $(EXTRA_SOURCES) 11$(PROGS): $(EXTRA_SOURCES)
10 12
@@ -20,13 +22,8 @@ run_tests: all sub_run_tests
20clean: sub_clean 22clean: sub_clean
21 rm -f $(PROGS) loop.o 23 rm -f $(PROGS) loop.o
22 24
23 25$(SUB_TARGETS):
24SUB_TARGETS = ebb 26 $(MAKE) -k -C $@ all
25
26sub_all:
27 @for TARGET in $(SUB_TARGETS); do \
28 $(MAKE) -C $$TARGET all; \
29 done;
30 27
31sub_run_tests: all 28sub_run_tests: all
32 @for TARGET in $(SUB_TARGETS); do \ 29 @for TARGET in $(SUB_TARGETS); do \
@@ -38,4 +35,4 @@ sub_clean:
38 $(MAKE) -C $$TARGET clean; \ 35 $(MAKE) -C $$TARGET clean; \
39 done; 36 done;
40 37
41.PHONY: all run_tests clean sub_all sub_run_tests sub_clean 38.PHONY: all run_tests clean sub_run_tests sub_clean $(SUB_TARGETS)
diff --git a/tools/testing/selftests/powerpc/pmu/count_instructions.c b/tools/testing/selftests/powerpc/pmu/count_instructions.c
index 312b4f0fd27c..4622117b24c0 100644
--- a/tools/testing/selftests/powerpc/pmu/count_instructions.c
+++ b/tools/testing/selftests/powerpc/pmu/count_instructions.c
@@ -12,6 +12,7 @@
12 12
13#include "event.h" 13#include "event.h"
14#include "utils.h" 14#include "utils.h"
15#include "lib.h"
15 16
16extern void thirty_two_instruction_loop(u64 loops); 17extern void thirty_two_instruction_loop(u64 loops);
17 18
@@ -90,7 +91,7 @@ static u64 determine_overhead(struct event *events)
90 return overhead; 91 return overhead;
91} 92}
92 93
93static int count_instructions(void) 94static int test_body(void)
94{ 95{
95 struct event events[2]; 96 struct event events[2];
96 u64 overhead; 97 u64 overhead;
@@ -111,17 +112,23 @@ static int count_instructions(void)
111 overhead = determine_overhead(events); 112 overhead = determine_overhead(events);
112 printf("Overhead of null loop: %llu instructions\n", overhead); 113 printf("Overhead of null loop: %llu instructions\n", overhead);
113 114
114 /* Run for 1M instructions */ 115 /* Run for 1Mi instructions */
115 FAIL_IF(do_count_loop(events, 0x100000, overhead, true)); 116 FAIL_IF(do_count_loop(events, 1000000, overhead, true));
117
118 /* Run for 10Mi instructions */
119 FAIL_IF(do_count_loop(events, 10000000, overhead, true));
120
121 /* Run for 100Mi instructions */
122 FAIL_IF(do_count_loop(events, 100000000, overhead, true));
116 123
117 /* Run for 10M instructions */ 124 /* Run for 1Bi instructions */
118 FAIL_IF(do_count_loop(events, 0xa00000, overhead, true)); 125 FAIL_IF(do_count_loop(events, 1000000000, overhead, true));
119 126
120 /* Run for 100M instructions */ 127 /* Run for 16Bi instructions */
121 FAIL_IF(do_count_loop(events, 0x6400000, overhead, true)); 128 FAIL_IF(do_count_loop(events, 16000000000, overhead, true));
122 129
123 /* Run for 1G instructions */ 130 /* Run for 64Bi instructions */
124 FAIL_IF(do_count_loop(events, 0x40000000, overhead, true)); 131 FAIL_IF(do_count_loop(events, 64000000000, overhead, true));
125 132
126 event_close(&events[0]); 133 event_close(&events[0]);
127 event_close(&events[1]); 134 event_close(&events[1]);
@@ -129,6 +136,11 @@ static int count_instructions(void)
129 return 0; 136 return 0;
130} 137}
131 138
139static int count_instructions(void)
140{
141 return eat_cpu(test_body);
142}
143
132int main(void) 144int main(void)
133{ 145{
134 return test_harness(count_instructions, "count_instructions"); 146 return test_harness(count_instructions, "count_instructions");
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/Makefile b/tools/testing/selftests/powerpc/pmu/ebb/Makefile
index edbba2affc2c..3dc4332698cb 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/Makefile
+++ b/tools/testing/selftests/powerpc/pmu/ebb/Makefile
@@ -13,11 +13,12 @@ PROGS := reg_access_test event_attributes_test cycles_test \
13 close_clears_pmcc_test instruction_count_test \ 13 close_clears_pmcc_test instruction_count_test \
14 fork_cleanup_test ebb_on_child_test \ 14 fork_cleanup_test ebb_on_child_test \
15 ebb_on_willing_child_test back_to_back_ebbs_test \ 15 ebb_on_willing_child_test back_to_back_ebbs_test \
16 lost_exception_test no_handler_test 16 lost_exception_test no_handler_test \
17 cycles_with_mmcr2_test
17 18
18all: $(PROGS) 19all: $(PROGS)
19 20
20$(PROGS): ../../harness.c ../event.c ../lib.c ebb.c ebb_handler.S trace.c 21$(PROGS): ../../harness.c ../event.c ../lib.c ebb.c ebb_handler.S trace.c busy_loop.S
21 22
22instruction_count_test: ../loop.S 23instruction_count_test: ../loop.S
23 24
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/busy_loop.S b/tools/testing/selftests/powerpc/pmu/ebb/busy_loop.S
new file mode 100644
index 000000000000..c7e4093f1cd3
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/ebb/busy_loop.S
@@ -0,0 +1,271 @@
1/*
2 * Copyright 2014, Michael Ellerman, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#include <ppc-asm.h>
7
8 .text
9
10FUNC_START(core_busy_loop)
11 stdu %r1, -168(%r1)
12 std r14, 160(%r1)
13 std r15, 152(%r1)
14 std r16, 144(%r1)
15 std r17, 136(%r1)
16 std r18, 128(%r1)
17 std r19, 120(%r1)
18 std r20, 112(%r1)
19 std r21, 104(%r1)
20 std r22, 96(%r1)
21 std r23, 88(%r1)
22 std r24, 80(%r1)
23 std r25, 72(%r1)
24 std r26, 64(%r1)
25 std r27, 56(%r1)
26 std r28, 48(%r1)
27 std r29, 40(%r1)
28 std r30, 32(%r1)
29 std r31, 24(%r1)
30
31 li r3, 0x3030
32 std r3, -96(%r1)
33 li r4, 0x4040
34 std r4, -104(%r1)
35 li r5, 0x5050
36 std r5, -112(%r1)
37 li r6, 0x6060
38 std r6, -120(%r1)
39 li r7, 0x7070
40 std r7, -128(%r1)
41 li r8, 0x0808
42 std r8, -136(%r1)
43 li r9, 0x0909
44 std r9, -144(%r1)
45 li r10, 0x1010
46 std r10, -152(%r1)
47 li r11, 0x1111
48 std r11, -160(%r1)
49 li r14, 0x1414
50 std r14, -168(%r1)
51 li r15, 0x1515
52 std r15, -176(%r1)
53 li r16, 0x1616
54 std r16, -184(%r1)
55 li r17, 0x1717
56 std r17, -192(%r1)
57 li r18, 0x1818
58 std r18, -200(%r1)
59 li r19, 0x1919
60 std r19, -208(%r1)
61 li r20, 0x2020
62 std r20, -216(%r1)
63 li r21, 0x2121
64 std r21, -224(%r1)
65 li r22, 0x2222
66 std r22, -232(%r1)
67 li r23, 0x2323
68 std r23, -240(%r1)
69 li r24, 0x2424
70 std r24, -248(%r1)
71 li r25, 0x2525
72 std r25, -256(%r1)
73 li r26, 0x2626
74 std r26, -264(%r1)
75 li r27, 0x2727
76 std r27, -272(%r1)
77 li r28, 0x2828
78 std r28, -280(%r1)
79 li r29, 0x2929
80 std r29, -288(%r1)
81 li r30, 0x3030
82 li r31, 0x3131
83
84 li r3, 0
850: addi r3, r3, 1
86 cmpwi r3, 100
87 blt 0b
88
89 /* Return 1 (fail) unless we get through all the checks */
90 li r3, 1
91
92 /* Check none of our registers have been corrupted */
93 cmpwi r4, 0x4040
94 bne 1f
95 cmpwi r5, 0x5050
96 bne 1f
97 cmpwi r6, 0x6060
98 bne 1f
99 cmpwi r7, 0x7070
100 bne 1f
101 cmpwi r8, 0x0808
102 bne 1f
103 cmpwi r9, 0x0909
104 bne 1f
105 cmpwi r10, 0x1010
106 bne 1f
107 cmpwi r11, 0x1111
108 bne 1f
109 cmpwi r14, 0x1414
110 bne 1f
111 cmpwi r15, 0x1515
112 bne 1f
113 cmpwi r16, 0x1616
114 bne 1f
115 cmpwi r17, 0x1717
116 bne 1f
117 cmpwi r18, 0x1818
118 bne 1f
119 cmpwi r19, 0x1919
120 bne 1f
121 cmpwi r20, 0x2020
122 bne 1f
123 cmpwi r21, 0x2121
124 bne 1f
125 cmpwi r22, 0x2222
126 bne 1f
127 cmpwi r23, 0x2323
128 bne 1f
129 cmpwi r24, 0x2424
130 bne 1f
131 cmpwi r25, 0x2525
132 bne 1f
133 cmpwi r26, 0x2626
134 bne 1f
135 cmpwi r27, 0x2727
136 bne 1f
137 cmpwi r28, 0x2828
138 bne 1f
139 cmpwi r29, 0x2929
140 bne 1f
141 cmpwi r30, 0x3030
142 bne 1f
143 cmpwi r31, 0x3131
144 bne 1f
145
146 /* Load junk into all our registers before we reload them from the stack. */
147 li r3, 0xde
148 li r4, 0xad
149 li r5, 0xbe
150 li r6, 0xef
151 li r7, 0xde
152 li r8, 0xad
153 li r9, 0xbe
154 li r10, 0xef
155 li r11, 0xde
156 li r14, 0xad
157 li r15, 0xbe
158 li r16, 0xef
159 li r17, 0xde
160 li r18, 0xad
161 li r19, 0xbe
162 li r20, 0xef
163 li r21, 0xde
164 li r22, 0xad
165 li r23, 0xbe
166 li r24, 0xef
167 li r25, 0xde
168 li r26, 0xad
169 li r27, 0xbe
170 li r28, 0xef
171 li r29, 0xdd
172
173 ld r3, -96(%r1)
174 cmpwi r3, 0x3030
175 bne 1f
176 ld r4, -104(%r1)
177 cmpwi r4, 0x4040
178 bne 1f
179 ld r5, -112(%r1)
180 cmpwi r5, 0x5050
181 bne 1f
182 ld r6, -120(%r1)
183 cmpwi r6, 0x6060
184 bne 1f
185 ld r7, -128(%r1)
186 cmpwi r7, 0x7070
187 bne 1f
188 ld r8, -136(%r1)
189 cmpwi r8, 0x0808
190 bne 1f
191 ld r9, -144(%r1)
192 cmpwi r9, 0x0909
193 bne 1f
194 ld r10, -152(%r1)
195 cmpwi r10, 0x1010
196 bne 1f
197 ld r11, -160(%r1)
198 cmpwi r11, 0x1111
199 bne 1f
200 ld r14, -168(%r1)
201 cmpwi r14, 0x1414
202 bne 1f
203 ld r15, -176(%r1)
204 cmpwi r15, 0x1515
205 bne 1f
206 ld r16, -184(%r1)
207 cmpwi r16, 0x1616
208 bne 1f
209 ld r17, -192(%r1)
210 cmpwi r17, 0x1717
211 bne 1f
212 ld r18, -200(%r1)
213 cmpwi r18, 0x1818
214 bne 1f
215 ld r19, -208(%r1)
216 cmpwi r19, 0x1919
217 bne 1f
218 ld r20, -216(%r1)
219 cmpwi r20, 0x2020
220 bne 1f
221 ld r21, -224(%r1)
222 cmpwi r21, 0x2121
223 bne 1f
224 ld r22, -232(%r1)
225 cmpwi r22, 0x2222
226 bne 1f
227 ld r23, -240(%r1)
228 cmpwi r23, 0x2323
229 bne 1f
230 ld r24, -248(%r1)
231 cmpwi r24, 0x2424
232 bne 1f
233 ld r25, -256(%r1)
234 cmpwi r25, 0x2525
235 bne 1f
236 ld r26, -264(%r1)
237 cmpwi r26, 0x2626
238 bne 1f
239 ld r27, -272(%r1)
240 cmpwi r27, 0x2727
241 bne 1f
242 ld r28, -280(%r1)
243 cmpwi r28, 0x2828
244 bne 1f
245 ld r29, -288(%r1)
246 cmpwi r29, 0x2929
247 bne 1f
248
249 /* Load 0 (success) to return */
250 li r3, 0
251
2521: ld r14, 160(%r1)
253 ld r15, 152(%r1)
254 ld r16, 144(%r1)
255 ld r17, 136(%r1)
256 ld r18, 128(%r1)
257 ld r19, 120(%r1)
258 ld r20, 112(%r1)
259 ld r21, 104(%r1)
260 ld r22, 96(%r1)
261 ld r23, 88(%r1)
262 ld r24, 80(%r1)
263 ld r25, 72(%r1)
264 ld r26, 64(%r1)
265 ld r27, 56(%r1)
266 ld r28, 48(%r1)
267 ld r29, 40(%r1)
268 ld r30, 32(%r1)
269 ld r31, 24(%r1)
270 addi %r1, %r1, 168
271 blr
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c b/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c
new file mode 100644
index 000000000000..d43029b0800c
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c
@@ -0,0 +1,91 @@
1/*
2 * Copyright 2014, Michael Ellerman, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <stdbool.h>
9
10#include "ebb.h"
11
12
13/*
14 * Test of counting cycles while manipulating the user accessible bits in MMCR2.
15 */
16
17/* We use two values because the first freezes PMC1 and so we would get no EBBs */
18#define MMCR2_EXPECTED_1 0x4020100804020000UL /* (FC1P|FC2P|FC3P|FC4P|FC5P|FC6P) */
19#define MMCR2_EXPECTED_2 0x0020100804020000UL /* ( FC2P|FC3P|FC4P|FC5P|FC6P) */
20
21
22int cycles_with_mmcr2(void)
23{
24 struct event event;
25 uint64_t val, expected[2], actual;
26 int i;
27 bool bad_mmcr2;
28
29 event_init_named(&event, 0x1001e, "cycles");
30 event_leader_ebb_init(&event);
31
32 event.attr.exclude_kernel = 1;
33 event.attr.exclude_hv = 1;
34 event.attr.exclude_idle = 1;
35
36 FAIL_IF(event_open(&event));
37
38 ebb_enable_pmc_counting(1);
39 setup_ebb_handler(standard_ebb_callee);
40 ebb_global_enable();
41
42 FAIL_IF(ebb_event_enable(&event));
43
44 mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
45
46 /* XXX Set of MMCR2 must be after enable */
47 expected[0] = MMCR2_EXPECTED_1;
48 expected[1] = MMCR2_EXPECTED_2;
49 i = 0;
50 bad_mmcr2 = false;
51
52 /* Make sure we loop until we take at least one EBB */
53 while ((ebb_state.stats.ebb_count < 20 && !bad_mmcr2) ||
54 ebb_state.stats.ebb_count < 1)
55 {
56 mtspr(SPRN_MMCR2, expected[i % 2]);
57
58 FAIL_IF(core_busy_loop());
59
60 val = mfspr(SPRN_MMCR2);
61 if (val != expected[i % 2]) {
62 bad_mmcr2 = true;
63 actual = val;
64 }
65
66 i++;
67 }
68
69 ebb_global_disable();
70 ebb_freeze_pmcs();
71
72 count_pmc(1, sample_period);
73
74 dump_ebb_state();
75
76 event_close(&event);
77
78 FAIL_IF(ebb_state.stats.ebb_count == 0);
79
80 if (bad_mmcr2)
81 printf("Bad MMCR2 value seen is 0x%lx\n", actual);
82
83 FAIL_IF(bad_mmcr2);
84
85 return 0;
86}
87
88int main(void)
89{
90 return test_harness(cycles_with_mmcr2, "cycles_with_mmcr2");
91}
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb.c b/tools/testing/selftests/powerpc/pmu/ebb/ebb.c
index 1b46be94b64c..d7a72ce696b5 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/ebb.c
+++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb.c
@@ -224,6 +224,7 @@ void dump_ebb_hw_state(void)
224 224
225 printf("HW state:\n" \ 225 printf("HW state:\n" \
226 "MMCR0 0x%016x %s\n" \ 226 "MMCR0 0x%016x %s\n" \
227 "MMCR2 0x%016lx\n" \
227 "EBBHR 0x%016lx\n" \ 228 "EBBHR 0x%016lx\n" \
228 "BESCR 0x%016llx %s\n" \ 229 "BESCR 0x%016llx %s\n" \
229 "PMC1 0x%016lx\n" \ 230 "PMC1 0x%016lx\n" \
@@ -233,10 +234,11 @@ void dump_ebb_hw_state(void)
233 "PMC5 0x%016lx\n" \ 234 "PMC5 0x%016lx\n" \
234 "PMC6 0x%016lx\n" \ 235 "PMC6 0x%016lx\n" \
235 "SIAR 0x%016lx\n", 236 "SIAR 0x%016lx\n",
236 mmcr0, decode_mmcr0(mmcr0), mfspr(SPRN_EBBHR), bescr, 237 mmcr0, decode_mmcr0(mmcr0), mfspr(SPRN_MMCR2),
237 decode_bescr(bescr), mfspr(SPRN_PMC1), mfspr(SPRN_PMC2), 238 mfspr(SPRN_EBBHR), bescr, decode_bescr(bescr),
238 mfspr(SPRN_PMC3), mfspr(SPRN_PMC4), mfspr(SPRN_PMC5), 239 mfspr(SPRN_PMC1), mfspr(SPRN_PMC2), mfspr(SPRN_PMC3),
239 mfspr(SPRN_PMC6), mfspr(SPRN_SIAR)); 240 mfspr(SPRN_PMC4), mfspr(SPRN_PMC5), mfspr(SPRN_PMC6),
241 mfspr(SPRN_SIAR));
240} 242}
241 243
242void dump_ebb_state(void) 244void dump_ebb_state(void)
@@ -335,257 +337,6 @@ void event_leader_ebb_init(struct event *e)
335 e->attr.pinned = 1; 337 e->attr.pinned = 1;
336} 338}
337 339
338int core_busy_loop(void)
339{
340 int rc;
341
342 asm volatile (
343 "li 3, 0x3030\n"
344 "std 3, -96(1)\n"
345 "li 4, 0x4040\n"
346 "std 4, -104(1)\n"
347 "li 5, 0x5050\n"
348 "std 5, -112(1)\n"
349 "li 6, 0x6060\n"
350 "std 6, -120(1)\n"
351 "li 7, 0x7070\n"
352 "std 7, -128(1)\n"
353 "li 8, 0x0808\n"
354 "std 8, -136(1)\n"
355 "li 9, 0x0909\n"
356 "std 9, -144(1)\n"
357 "li 10, 0x1010\n"
358 "std 10, -152(1)\n"
359 "li 11, 0x1111\n"
360 "std 11, -160(1)\n"
361 "li 14, 0x1414\n"
362 "std 14, -168(1)\n"
363 "li 15, 0x1515\n"
364 "std 15, -176(1)\n"
365 "li 16, 0x1616\n"
366 "std 16, -184(1)\n"
367 "li 17, 0x1717\n"
368 "std 17, -192(1)\n"
369 "li 18, 0x1818\n"
370 "std 18, -200(1)\n"
371 "li 19, 0x1919\n"
372 "std 19, -208(1)\n"
373 "li 20, 0x2020\n"
374 "std 20, -216(1)\n"
375 "li 21, 0x2121\n"
376 "std 21, -224(1)\n"
377 "li 22, 0x2222\n"
378 "std 22, -232(1)\n"
379 "li 23, 0x2323\n"
380 "std 23, -240(1)\n"
381 "li 24, 0x2424\n"
382 "std 24, -248(1)\n"
383 "li 25, 0x2525\n"
384 "std 25, -256(1)\n"
385 "li 26, 0x2626\n"
386 "std 26, -264(1)\n"
387 "li 27, 0x2727\n"
388 "std 27, -272(1)\n"
389 "li 28, 0x2828\n"
390 "std 28, -280(1)\n"
391 "li 29, 0x2929\n"
392 "std 29, -288(1)\n"
393 "li 30, 0x3030\n"
394 "li 31, 0x3131\n"
395
396 "li 3, 0\n"
397 "0: "
398 "addi 3, 3, 1\n"
399 "cmpwi 3, 100\n"
400 "blt 0b\n"
401
402 /* Return 1 (fail) unless we get through all the checks */
403 "li 0, 1\n"
404
405 /* Check none of our registers have been corrupted */
406 "cmpwi 4, 0x4040\n"
407 "bne 1f\n"
408 "cmpwi 5, 0x5050\n"
409 "bne 1f\n"
410 "cmpwi 6, 0x6060\n"
411 "bne 1f\n"
412 "cmpwi 7, 0x7070\n"
413 "bne 1f\n"
414 "cmpwi 8, 0x0808\n"
415 "bne 1f\n"
416 "cmpwi 9, 0x0909\n"
417 "bne 1f\n"
418 "cmpwi 10, 0x1010\n"
419 "bne 1f\n"
420 "cmpwi 11, 0x1111\n"
421 "bne 1f\n"
422 "cmpwi 14, 0x1414\n"
423 "bne 1f\n"
424 "cmpwi 15, 0x1515\n"
425 "bne 1f\n"
426 "cmpwi 16, 0x1616\n"
427 "bne 1f\n"
428 "cmpwi 17, 0x1717\n"
429 "bne 1f\n"
430 "cmpwi 18, 0x1818\n"
431 "bne 1f\n"
432 "cmpwi 19, 0x1919\n"
433 "bne 1f\n"
434 "cmpwi 20, 0x2020\n"
435 "bne 1f\n"
436 "cmpwi 21, 0x2121\n"
437 "bne 1f\n"
438 "cmpwi 22, 0x2222\n"
439 "bne 1f\n"
440 "cmpwi 23, 0x2323\n"
441 "bne 1f\n"
442 "cmpwi 24, 0x2424\n"
443 "bne 1f\n"
444 "cmpwi 25, 0x2525\n"
445 "bne 1f\n"
446 "cmpwi 26, 0x2626\n"
447 "bne 1f\n"
448 "cmpwi 27, 0x2727\n"
449 "bne 1f\n"
450 "cmpwi 28, 0x2828\n"
451 "bne 1f\n"
452 "cmpwi 29, 0x2929\n"
453 "bne 1f\n"
454 "cmpwi 30, 0x3030\n"
455 "bne 1f\n"
456 "cmpwi 31, 0x3131\n"
457 "bne 1f\n"
458
459 /* Load junk into all our registers before we reload them from the stack. */
460 "li 3, 0xde\n"
461 "li 4, 0xad\n"
462 "li 5, 0xbe\n"
463 "li 6, 0xef\n"
464 "li 7, 0xde\n"
465 "li 8, 0xad\n"
466 "li 9, 0xbe\n"
467 "li 10, 0xef\n"
468 "li 11, 0xde\n"
469 "li 14, 0xad\n"
470 "li 15, 0xbe\n"
471 "li 16, 0xef\n"
472 "li 17, 0xde\n"
473 "li 18, 0xad\n"
474 "li 19, 0xbe\n"
475 "li 20, 0xef\n"
476 "li 21, 0xde\n"
477 "li 22, 0xad\n"
478 "li 23, 0xbe\n"
479 "li 24, 0xef\n"
480 "li 25, 0xde\n"
481 "li 26, 0xad\n"
482 "li 27, 0xbe\n"
483 "li 28, 0xef\n"
484 "li 29, 0xdd\n"
485
486 "ld 3, -96(1)\n"
487 "cmpwi 3, 0x3030\n"
488 "bne 1f\n"
489 "ld 4, -104(1)\n"
490 "cmpwi 4, 0x4040\n"
491 "bne 1f\n"
492 "ld 5, -112(1)\n"
493 "cmpwi 5, 0x5050\n"
494 "bne 1f\n"
495 "ld 6, -120(1)\n"
496 "cmpwi 6, 0x6060\n"
497 "bne 1f\n"
498 "ld 7, -128(1)\n"
499 "cmpwi 7, 0x7070\n"
500 "bne 1f\n"
501 "ld 8, -136(1)\n"
502 "cmpwi 8, 0x0808\n"
503 "bne 1f\n"
504 "ld 9, -144(1)\n"
505 "cmpwi 9, 0x0909\n"
506 "bne 1f\n"
507 "ld 10, -152(1)\n"
508 "cmpwi 10, 0x1010\n"
509 "bne 1f\n"
510 "ld 11, -160(1)\n"
511 "cmpwi 11, 0x1111\n"
512 "bne 1f\n"
513 "ld 14, -168(1)\n"
514 "cmpwi 14, 0x1414\n"
515 "bne 1f\n"
516 "ld 15, -176(1)\n"
517 "cmpwi 15, 0x1515\n"
518 "bne 1f\n"
519 "ld 16, -184(1)\n"
520 "cmpwi 16, 0x1616\n"
521 "bne 1f\n"
522 "ld 17, -192(1)\n"
523 "cmpwi 17, 0x1717\n"
524 "bne 1f\n"
525 "ld 18, -200(1)\n"
526 "cmpwi 18, 0x1818\n"
527 "bne 1f\n"
528 "ld 19, -208(1)\n"
529 "cmpwi 19, 0x1919\n"
530 "bne 1f\n"
531 "ld 20, -216(1)\n"
532 "cmpwi 20, 0x2020\n"
533 "bne 1f\n"
534 "ld 21, -224(1)\n"
535 "cmpwi 21, 0x2121\n"
536 "bne 1f\n"
537 "ld 22, -232(1)\n"
538 "cmpwi 22, 0x2222\n"
539 "bne 1f\n"
540 "ld 23, -240(1)\n"
541 "cmpwi 23, 0x2323\n"
542 "bne 1f\n"
543 "ld 24, -248(1)\n"
544 "cmpwi 24, 0x2424\n"
545 "bne 1f\n"
546 "ld 25, -256(1)\n"
547 "cmpwi 25, 0x2525\n"
548 "bne 1f\n"
549 "ld 26, -264(1)\n"
550 "cmpwi 26, 0x2626\n"
551 "bne 1f\n"
552 "ld 27, -272(1)\n"
553 "cmpwi 27, 0x2727\n"
554 "bne 1f\n"
555 "ld 28, -280(1)\n"
556 "cmpwi 28, 0x2828\n"
557 "bne 1f\n"
558 "ld 29, -288(1)\n"
559 "cmpwi 29, 0x2929\n"
560 "bne 1f\n"
561
562 /* Load 0 (success) to return */
563 "li 0, 0\n"
564
565 "1: mr %0, 0\n"
566
567 : "=r" (rc)
568 : /* no inputs */
569 : "3", "4", "5", "6", "7", "8", "9", "10", "11", "14",
570 "15", "16", "17", "18", "19", "20", "21", "22", "23",
571 "24", "25", "26", "27", "28", "29", "30", "31",
572 "memory"
573 );
574
575 return rc;
576}
577
578int core_busy_loop_with_freeze(void)
579{
580 int rc;
581
582 mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_FC);
583 rc = core_busy_loop();
584 mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_FC);
585
586 return rc;
587}
588
589int ebb_child(union pipe read_pipe, union pipe write_pipe) 340int ebb_child(union pipe read_pipe, union pipe write_pipe)
590{ 341{
591 struct event event; 342 struct event event;
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb.h b/tools/testing/selftests/powerpc/pmu/ebb/ebb.h
index e62bde05bf78..e44eee5d97ca 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/ebb.h
+++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb.h
@@ -70,7 +70,6 @@ int ebb_check_mmcr0(void);
70extern u64 sample_period; 70extern u64 sample_period;
71 71
72int core_busy_loop(void); 72int core_busy_loop(void);
73int core_busy_loop_with_freeze(void);
74int ebb_child(union pipe read_pipe, union pipe write_pipe); 73int ebb_child(union pipe read_pipe, union pipe write_pipe);
75int catch_sigill(void (*func)(void)); 74int catch_sigill(void (*func)(void));
76void write_pmc1(void); 75void write_pmc1(void);
diff --git a/tools/testing/selftests/powerpc/pmu/l3_bank_test.c b/tools/testing/selftests/powerpc/pmu/l3_bank_test.c
new file mode 100644
index 000000000000..77472f31441e
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/l3_bank_test.c
@@ -0,0 +1,48 @@
1/*
2 * Copyright 2014, Michael Ellerman, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8
9#include "event.h"
10#include "utils.h"
11
12#define MALLOC_SIZE (0x10000 * 10) /* Ought to be enough .. */
13
14/*
15 * Tests that the L3 bank handling is correct. We fixed it in commit e9aaac1.
16 */
17static int l3_bank_test(void)
18{
19 struct event event;
20 char *p;
21 int i;
22
23 p = malloc(MALLOC_SIZE);
24 FAIL_IF(!p);
25
26 event_init(&event, 0x84918F);
27
28 FAIL_IF(event_open(&event));
29
30 for (i = 0; i < MALLOC_SIZE; i += 0x10000)
31 p[i] = i;
32
33 event_read(&event);
34 event_report(&event);
35
36 FAIL_IF(event.result.running == 0);
37 FAIL_IF(event.result.enabled == 0);
38
39 event_close(&event);
40 free(p);
41
42 return 0;
43}
44
45int main(void)
46{
47 return test_harness(l3_bank_test, "l3_bank_test");
48}
diff --git a/tools/testing/selftests/powerpc/pmu/lib.c b/tools/testing/selftests/powerpc/pmu/lib.c
index 0f6a4731d546..9768dea37bf3 100644
--- a/tools/testing/selftests/powerpc/pmu/lib.c
+++ b/tools/testing/selftests/powerpc/pmu/lib.c
@@ -5,10 +5,15 @@
5 5
6#define _GNU_SOURCE /* For CPU_ZERO etc. */ 6#define _GNU_SOURCE /* For CPU_ZERO etc. */
7 7
8#include <elf.h>
8#include <errno.h> 9#include <errno.h>
10#include <fcntl.h>
11#include <link.h>
9#include <sched.h> 12#include <sched.h>
10#include <setjmp.h> 13#include <setjmp.h>
11#include <stdlib.h> 14#include <stdlib.h>
15#include <sys/stat.h>
16#include <sys/types.h>
12#include <sys/wait.h> 17#include <sys/wait.h>
13 18
14#include "utils.h" 19#include "utils.h"
@@ -177,8 +182,8 @@ struct addr_range libc, vdso;
177 182
178int parse_proc_maps(void) 183int parse_proc_maps(void)
179{ 184{
185 unsigned long start, end;
180 char execute, name[128]; 186 char execute, name[128];
181 uint64_t start, end;
182 FILE *f; 187 FILE *f;
183 int rc; 188 int rc;
184 189
@@ -250,3 +255,46 @@ out_close:
250out: 255out:
251 return rc; 256 return rc;
252} 257}
258
259static char auxv[4096];
260
261void *get_auxv_entry(int type)
262{
263 ElfW(auxv_t) *p;
264 void *result;
265 ssize_t num;
266 int fd;
267
268 fd = open("/proc/self/auxv", O_RDONLY);
269 if (fd == -1) {
270 perror("open");
271 return NULL;
272 }
273
274 result = NULL;
275
276 num = read(fd, auxv, sizeof(auxv));
277 if (num < 0) {
278 perror("read");
279 goto out;
280 }
281
282 if (num > sizeof(auxv)) {
283 printf("Overflowed auxv buffer\n");
284 goto out;
285 }
286
287 p = (ElfW(auxv_t) *)auxv;
288
289 while (p->a_type != AT_NULL) {
290 if (p->a_type == type) {
291 result = (void *)p->a_un.a_val;
292 break;
293 }
294
295 p++;
296 }
297out:
298 close(fd);
299 return result;
300}
diff --git a/tools/testing/selftests/powerpc/pmu/lib.h b/tools/testing/selftests/powerpc/pmu/lib.h
index ca5d72ae3be6..0f0339c8a6f6 100644
--- a/tools/testing/selftests/powerpc/pmu/lib.h
+++ b/tools/testing/selftests/powerpc/pmu/lib.h
@@ -29,6 +29,7 @@ extern int notify_parent(union pipe write_pipe);
29extern int notify_parent_of_error(union pipe write_pipe); 29extern int notify_parent_of_error(union pipe write_pipe);
30extern pid_t eat_cpu(int (test_function)(void)); 30extern pid_t eat_cpu(int (test_function)(void));
31extern bool require_paranoia_below(int level); 31extern bool require_paranoia_below(int level);
32extern void *get_auxv_entry(int type);
32 33
33struct addr_range { 34struct addr_range {
34 uint64_t first, last; 35 uint64_t first, last;
diff --git a/tools/testing/selftests/powerpc/pmu/per_event_excludes.c b/tools/testing/selftests/powerpc/pmu/per_event_excludes.c
new file mode 100644
index 000000000000..fddbbc9cae2f
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/per_event_excludes.c
@@ -0,0 +1,114 @@
1/*
2 * Copyright 2014, Michael Ellerman, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#define _GNU_SOURCE
7
8#include <elf.h>
9#include <limits.h>
10#include <stdio.h>
11#include <stdbool.h>
12#include <string.h>
13#include <sys/prctl.h>
14
15#include "event.h"
16#include "lib.h"
17#include "utils.h"
18
19/*
20 * Test that per-event excludes work.
21 */
22
23static int per_event_excludes(void)
24{
25 struct event *e, events[4];
26 char *platform;
27 int i;
28
29 platform = (char *)get_auxv_entry(AT_BASE_PLATFORM);
30 FAIL_IF(!platform);
31 SKIP_IF(strcmp(platform, "power8") != 0);
32
33 /*
34 * We need to create the events disabled, otherwise the running/enabled
35 * counts don't match up.
36 */
37 e = &events[0];
38 event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
39 PERF_TYPE_HARDWARE, "instructions");
40 e->attr.disabled = 1;
41
42 e = &events[1];
43 event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
44 PERF_TYPE_HARDWARE, "instructions(k)");
45 e->attr.disabled = 1;
46 e->attr.exclude_user = 1;
47 e->attr.exclude_hv = 1;
48
49 e = &events[2];
50 event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
51 PERF_TYPE_HARDWARE, "instructions(h)");
52 e->attr.disabled = 1;
53 e->attr.exclude_user = 1;
54 e->attr.exclude_kernel = 1;
55
56 e = &events[3];
57 event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
58 PERF_TYPE_HARDWARE, "instructions(u)");
59 e->attr.disabled = 1;
60 e->attr.exclude_hv = 1;
61 e->attr.exclude_kernel = 1;
62
63 FAIL_IF(event_open(&events[0]));
64
65 /*
66 * The open here will fail if we don't have per event exclude support,
67 * because the second event has an incompatible set of exclude settings
68 * and we're asking for the events to be in a group.
69 */
70 for (i = 1; i < 4; i++)
71 FAIL_IF(event_open_with_group(&events[i], events[0].fd));
72
73 /*
74 * Even though the above will fail without per-event excludes we keep
75 * testing in order to be thorough.
76 */
77 prctl(PR_TASK_PERF_EVENTS_ENABLE);
78
79 /* Spin for a while */
80 for (i = 0; i < INT_MAX; i++)
81 asm volatile("" : : : "memory");
82
83 prctl(PR_TASK_PERF_EVENTS_DISABLE);
84
85 for (i = 0; i < 4; i++) {
86 FAIL_IF(event_read(&events[i]));
87 event_report(&events[i]);
88 }
89
90 /*
91 * We should see that all events have enabled == running. That
92 * shows that they were all on the PMU at once.
93 */
94 for (i = 0; i < 4; i++)
95 FAIL_IF(events[i].result.running != events[i].result.enabled);
96
97 /*
98 * We can also check that the result for instructions is >= all the
99 * other counts. That's because it is counting all instructions while
100 * the others are counting a subset.
101 */
102 for (i = 1; i < 4; i++)
103 FAIL_IF(events[0].result.value < events[i].result.value);
104
105 for (i = 0; i < 4; i++)
106 event_close(&events[i]);
107
108 return 0;
109}
110
111int main(void)
112{
113 return test_harness(per_event_excludes, "per_event_excludes");
114}