aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-03-19 18:38:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-19 18:38:41 -0400
commitd5e2d00898bdfed9586472679760fc81a2ca2d02 (patch)
tree55ac781983bf7144230ad8a5a995ce02b6ac39a1
parent31e182363b39d84031eadf0caf6d99fd9eb056f0 (diff)
parent6e669f085d595cb6053920832c89f1a13067db44 (diff)
Merge tag 'powerpc-4.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc updates from Michael Ellerman: "This was delayed a day or two by some build-breakage on old toolchains which we've now fixed. There's two PCI commits both acked by Bjorn. There's one commit to mm/hugepage.c which is (co)authored by Kirill. Highlights: - Restructure Linux PTE on Book3S/64 to Radix format from Paul Mackerras - Book3s 64 MMU cleanup in preparation for Radix MMU from Aneesh Kumar K.V - Add POWER9 cputable entry from Michael Neuling - FPU/Altivec/VSX save/restore optimisations from Cyril Bur - Add support for new ftrace ABI on ppc64le from Torsten Duwe Various cleanups & minor fixes from: - Adam Buchbinder, Andrew Donnellan, Balbir Singh, Christophe Leroy, Cyril Bur, Luis Henriques, Madhavan Srinivasan, Pan Xinhui, Russell Currey, Sukadev Bhattiprolu, Suraj Jitindar Singh. General: - atomics: Allow architectures to define their own __atomic_op_* helpers from Boqun Feng - Implement atomic{, 64}_*_return_* variants and acquire/release/ relaxed variants for (cmp)xchg from Boqun Feng - Add powernv_defconfig from Jeremy Kerr - Fix BUG_ON() reporting in real mode from Balbir Singh - Add xmon command to dump OPAL msglog from Andrew Donnellan - Add xmon command to dump process/task similar to ps(1) from Douglas Miller - Clean up memory hotplug failure paths from David Gibson pci/eeh: - Redesign SR-IOV on PowerNV to give absolute isolation between VFs from Wei Yang. - EEH Support for SRIOV VFs from Wei Yang and Gavin Shan. - PCI/IOV: Rename and export virtfn_{add, remove} from Wei Yang - PCI: Add pcibios_bus_add_device() weak function from Wei Yang - MAINTAINERS: Update EEH details and maintainership from Russell Currey cxl: - Support added to the CXL driver for running on both bare-metal and hypervisor systems, from Christophe Lombard and Frederic Barrat. - Ignore probes for virtual afu pci devices from Vaibhav Jain perf: - Export Power8 generic and cache events to sysfs from Sukadev Bhattiprolu - hv-24x7: Fix usage with chip events, display change in counter values, display domain indices in sysfs, eliminate domain suffix in event names, from Sukadev Bhattiprolu Freescale: - Updates from Scott: "Highlights include 8xx optimizations, 32-bit checksum optimizations, 86xx consolidation, e5500/e6500 cpu hotplug, more fman and other dt bits, and minor fixes/cleanup" * tag 'powerpc-4.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (179 commits) powerpc: Fix unrecoverable SLB miss during restore_math() powerpc/8xx: Fix do_mtspr_cpu6() build on older compilers powerpc/rcpm: Fix build break when SMP=n powerpc/book3e-64: Use hardcoded mttmr opcode powerpc/fsl/dts: Add "jedec,spi-nor" flash compatible powerpc/T104xRDB: add tdm riser card node to device tree powerpc32: PAGE_EXEC required for inittext powerpc/mpc85xx: Add pcsphy nodes to FManV3 device tree powerpc/mpc85xx: Add MDIO bus muxing support to the board device tree(s) powerpc/86xx: Introduce and use common dtsi powerpc/86xx: Update device tree powerpc/86xx: Move dts files to fsl directory powerpc/86xx: Switch to kconfig fragments approach powerpc/86xx: Update defconfigs powerpc/86xx: Consolidate common platform code powerpc32: Remove one insn in mulhdu powerpc32: small optimisation in flush_icache_range() powerpc: Simplify test in __dma_sync() powerpc32: move xxxxx_dcache_range() functions inline powerpc32: Remove clear_pages() and define clear_page() inline ...
-rw-r--r--Documentation/ABI/testing/sysfs-class-cxl10
-rw-r--r--Documentation/devicetree/bindings/powerpc/fsl/fman.txt40
-rw-r--r--Documentation/devicetree/bindings/soc/fsl/rcpm.txt63
-rw-r--r--Documentation/kernel-parameters.txt2
-rw-r--r--Documentation/powerpc/cxl.txt55
-rw-r--r--MAINTAINERS16
-rw-r--r--arch/powerpc/Kconfig23
-rw-r--r--arch/powerpc/Makefile25
-rw-r--r--arch/powerpc/boot/dts/fsl/b4860qds.dts60
-rw-r--r--arch/powerpc/boot/dts/fsl/b4qds.dtsi53
-rw-r--r--arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/c293pcie.dts2
-rw-r--r--arch/powerpc/boot/dts/fsl/gef_ppc9a.dts216
-rw-r--r--arch/powerpc/boot/dts/fsl/gef_sbc310.dts260
-rw-r--r--arch/powerpc/boot/dts/fsl/gef_sbc610.dts214
-rw-r--r--arch/powerpc/boot/dts/fsl/kmcoge4.dts4
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi8
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8641_hpcn.dts (renamed from arch/powerpc/boot/dts/mpc8641_hpcn.dts)347
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8641_hpcn_36b.dts (renamed from arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts)330
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8641si-post.dtsi120
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8641si-pre.dtsi58
-rw-r--r--arch/powerpc/boot/dts/fsl/mvme2500.dts4
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010rdb.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts2
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020rdb.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/p1021mds.dts2
-rw-r--r--arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/p1022ds.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/p1022rdk.dts2
-rw-r--r--arch/powerpc/boot/dts/fsl/p1024rdb.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/p1025rdb.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/p2020rdb.dts2
-rw-r--r--arch/powerpc/boot/dts/fsl/p2041rdb.dts94
-rw-r--r--arch/powerpc/boot/dts/fsl/p3041ds.dts114
-rw-r--r--arch/powerpc/boot/dts/fsl/p4080ds.dts186
-rw-r--r--arch/powerpc/boot/dts/fsl/p5020ds.dts114
-rw-r--r--arch/powerpc/boot/dts/fsl/p5040ds.dts236
-rw-r--r--arch/powerpc/boot/dts/fsl/p5040si-post.dtsi1
-rw-r--r--arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi6
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi5
-rw-r--r--arch/powerpc/boot/dts/fsl/sbc8641d.dts203
-rw-r--r--arch/powerpc/boot/dts/fsl/t1023rdb.dts43
-rw-r--r--arch/powerpc/boot/dts/fsl/t1024qds.dts6
-rw-r--r--arch/powerpc/boot/dts/fsl/t1024rdb.dts47
-rw-r--r--arch/powerpc/boot/dts/fsl/t1040rdb.dts32
-rw-r--r--arch/powerpc/boot/dts/fsl/t1042rdb.dts30
-rw-r--r--arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts18
-rw-r--r--arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/t104xqds.dtsi180
-rw-r--r--arch/powerpc/boot/dts/fsl/t104xrdb.dtsi40
-rw-r--r--arch/powerpc/boot/dts/fsl/t2080qds.dts158
-rw-r--r--arch/powerpc/boot/dts/fsl/t2080rdb.dts67
-rw-r--r--arch/powerpc/boot/dts/fsl/t2081qds.dts221
-rw-r--r--arch/powerpc/boot/dts/fsl/t208xqds.dtsi6
-rw-r--r--arch/powerpc/boot/dts/fsl/t208xrdb.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/t4240qds.dts402
-rw-r--r--arch/powerpc/boot/dts/fsl/t4240rdb.dts151
-rw-r--r--arch/powerpc/boot/dts/gef_ppc9a.dts425
-rw-r--r--arch/powerpc/boot/dts/gef_sbc310.dts459
-rw-r--r--arch/powerpc/boot/dts/gef_sbc610.dts423
-rw-r--r--arch/powerpc/boot/dts/sbc8641d.dts447
-rw-r--r--arch/powerpc/boot/rs6000.h2
-rw-r--r--arch/powerpc/boot/treeboot-akebono.c2
-rw-r--r--arch/powerpc/boot/treeboot-currituck.c2
-rw-r--r--arch/powerpc/boot/treeboot-iss4xx.c2
-rw-r--r--arch/powerpc/configs/83xx/mpc834x_itx_defconfig1
-rw-r--r--arch/powerpc/configs/85xx/ksi8560_defconfig1
-rw-r--r--arch/powerpc/configs/85xx/stx_gp3_defconfig2
-rw-r--r--arch/powerpc/configs/86xx-hw.config104
-rw-r--r--arch/powerpc/configs/86xx-smp.config2
-rw-r--r--arch/powerpc/configs/86xx/gef_ppc9a_defconfig216
-rw-r--r--arch/powerpc/configs/86xx/gef_sbc310_defconfig214
-rw-r--r--arch/powerpc/configs/86xx/gef_sbc610_defconfig273
-rw-r--r--arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig110
-rw-r--r--arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig156
-rw-r--r--arch/powerpc/configs/86xx/sbc8641d_defconfig246
-rw-r--r--arch/powerpc/configs/mpc86xx_basic_defconfig10
-rw-r--r--arch/powerpc/configs/mpc86xx_defconfig162
-rw-r--r--arch/powerpc/configs/powernv_defconfig313
-rw-r--r--arch/powerpc/crypto/aes-spe-core.S4
-rw-r--r--arch/powerpc/crypto/aes-spe-glue.c2
-rw-r--r--arch/powerpc/include/asm/atomic.h159
-rw-r--r--arch/powerpc/include/asm/book3s/32/mmu-hash.h (renamed from arch/powerpc/include/asm/mmu-hash32.h)0
-rw-r--r--arch/powerpc/include/asm/book3s/64/hash-4k.h36
-rw-r--r--arch/powerpc/include/asm/book3s/64/hash-64k.h57
-rw-r--r--arch/powerpc/include/asm/book3s/64/hash.h68
-rw-r--r--arch/powerpc/include/asm/book3s/64/mmu-hash.h (renamed from arch/powerpc/include/asm/mmu-hash64.h)4
-rw-r--r--arch/powerpc/include/asm/book3s/64/pgtable.h36
-rw-r--r--arch/powerpc/include/asm/book3s/64/tlbflush-hash.h94
-rw-r--r--arch/powerpc/include/asm/cache.h19
-rw-r--r--arch/powerpc/include/asm/cacheflush.h54
-rw-r--r--arch/powerpc/include/asm/checksum.h141
-rw-r--r--arch/powerpc/include/asm/cmpxchg.h237
-rw-r--r--arch/powerpc/include/asm/code-patching.h21
-rw-r--r--arch/powerpc/include/asm/cputable.h28
-rw-r--r--arch/powerpc/include/asm/cputhreads.h15
-rw-r--r--arch/powerpc/include/asm/eeh.h5
-rw-r--r--arch/powerpc/include/asm/fsl_pm.h51
-rw-r--r--arch/powerpc/include/asm/ftrace.h5
-rw-r--r--arch/powerpc/include/asm/hugetlb.h2
-rw-r--r--arch/powerpc/include/asm/hvcall.h1
-rw-r--r--arch/powerpc/include/asm/hydra.h2
-rw-r--r--arch/powerpc/include/asm/io.h2
-rw-r--r--arch/powerpc/include/asm/machdep.h6
-rw-r--r--arch/powerpc/include/asm/mmu-8xx.h4
-rw-r--r--arch/powerpc/include/asm/mmu.h5
-rw-r--r--arch/powerpc/include/asm/module.h14
-rw-r--r--arch/powerpc/include/asm/nohash/32/pgtable.h5
-rw-r--r--arch/powerpc/include/asm/nohash/64/pgtable.h3
-rw-r--r--arch/powerpc/include/asm/opal.h3
-rw-r--r--arch/powerpc/include/asm/page.h111
-rw-r--r--arch/powerpc/include/asm/page_32.h17
-rw-r--r--arch/powerpc/include/asm/pci-bridge.h9
-rw-r--r--arch/powerpc/include/asm/perf_event_server.h10
-rw-r--r--arch/powerpc/include/asm/pgalloc-64.h42
-rw-r--r--arch/powerpc/include/asm/pgtable-types.h103
-rw-r--r--arch/powerpc/include/asm/pmac_feature.h2
-rw-r--r--arch/powerpc/include/asm/processor.h2
-rw-r--r--arch/powerpc/include/asm/reg.h18
-rw-r--r--arch/powerpc/include/asm/reg_8xx.h93
-rw-r--r--arch/powerpc/include/asm/reg_booke.h2
-rw-r--r--arch/powerpc/include/asm/sections.h12
-rw-r--r--arch/powerpc/include/asm/smp.h4
-rw-r--r--arch/powerpc/include/asm/smu.h2
-rw-r--r--arch/powerpc/include/asm/switch_to.h13
-rw-r--r--arch/powerpc/include/asm/time.h6
-rw-r--r--arch/powerpc/include/asm/tlbflush.h92
-rw-r--r--arch/powerpc/include/asm/uninorth.h2
-rw-r--r--arch/powerpc/include/asm/xics.h2
-rw-r--r--arch/powerpc/include/uapi/asm/epapr_hcalls.h4
-rw-r--r--arch/powerpc/kernel/Makefile12
-rw-r--r--arch/powerpc/kernel/asm-offsets.c3
-rw-r--r--arch/powerpc/kernel/cpu_setup_fsl_booke.S112
-rw-r--r--arch/powerpc/kernel/cpu_setup_power.S49
-rw-r--r--arch/powerpc/kernel/cputable.c31
-rw-r--r--arch/powerpc/kernel/eeh.c39
-rw-r--r--arch/powerpc/kernel/eeh_cache.c11
-rw-r--r--arch/powerpc/kernel/eeh_dev.c1
-rw-r--r--arch/powerpc/kernel/eeh_driver.c150
-rw-r--r--arch/powerpc/kernel/eeh_pe.c38
-rw-r--r--arch/powerpc/kernel/entry_64.S196
-rw-r--r--arch/powerpc/kernel/fpu.S25
-rw-r--r--arch/powerpc/kernel/ftrace.c132
-rw-r--r--arch/powerpc/kernel/head_44x.S2
-rw-r--r--arch/powerpc/kernel/head_64.S98
-rw-r--r--arch/powerpc/kernel/head_8xx.S108
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S74
-rw-r--r--arch/powerpc/kernel/idle_power7.S2
-rw-r--r--arch/powerpc/kernel/kgdb.c4
-rw-r--r--arch/powerpc/kernel/mce_power.c17
-rw-r--r--arch/powerpc/kernel/misc_32.S107
-rw-r--r--arch/powerpc/kernel/module.c5
-rw-r--r--arch/powerpc/kernel/module_32.c20
-rw-r--r--arch/powerpc/kernel/module_64.c214
-rw-r--r--arch/powerpc/kernel/paca.c11
-rw-r--r--arch/powerpc/kernel/pci-hotplug.c2
-rw-r--r--arch/powerpc/kernel/pci_dn.c19
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c6
-rw-r--r--arch/powerpc/kernel/ppc_ksyms_32.c1
-rw-r--r--arch/powerpc/kernel/process.c168
-rw-r--r--arch/powerpc/kernel/signal.c4
-rw-r--r--arch/powerpc/kernel/signal.h2
-rw-r--r--arch/powerpc/kernel/smp.c7
-rw-r--r--arch/powerpc/kernel/traps.c12
-rw-r--r--arch/powerpc/kernel/vector.S45
-rw-r--r--arch/powerpc/kvm/book3s_32_mmu_host.c2
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu.c2
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_host.c2
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_hv.c2
-rw-r--r--arch/powerpc/kvm/book3s_64_vio.c2
-rw-r--r--arch/powerpc/kvm/book3s_64_vio_hv.c2
-rw-r--r--arch/powerpc/kvm/book3s_hv_rm_mmu.c2
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S2
-rw-r--r--arch/powerpc/kvm/book3s_xics.c2
-rw-r--r--arch/powerpc/kvm/booke.c2
-rw-r--r--arch/powerpc/kvm/e500mc.c2
-rw-r--r--arch/powerpc/lib/Makefile7
-rw-r--r--arch/powerpc/lib/checksum_32.S398
-rw-r--r--arch/powerpc/lib/checksum_64.S31
-rw-r--r--arch/powerpc/lib/checksum_wrappers.c (renamed from arch/powerpc/lib/checksum_wrappers_64.c)0
-rw-r--r--arch/powerpc/lib/ppc_ksyms.c4
-rw-r--r--arch/powerpc/mm/8xx_mmu.c141
-rw-r--r--arch/powerpc/mm/Makefile1
-rw-r--r--arch/powerpc/mm/dma-noncoherent.c2
-rw-r--r--arch/powerpc/mm/fsl_booke_mmu.c6
-rw-r--r--arch/powerpc/mm/hash64_4k.c4
-rw-r--r--arch/powerpc/mm/hash64_64k.c7
-rw-r--r--arch/powerpc/mm/hash_utils_64.c87
-rw-r--r--arch/powerpc/mm/hugetlbpage-hash64.c5
-rw-r--r--arch/powerpc/mm/hugetlbpage.c3
-rw-r--r--arch/powerpc/mm/init_32.c23
-rw-r--r--arch/powerpc/mm/init_64.c68
-rw-r--r--arch/powerpc/mm/mem.c10
-rw-r--r--arch/powerpc/mm/mmu_decl.h29
-rw-r--r--arch/powerpc/mm/pgtable_32.c52
-rw-r--r--arch/powerpc/mm/pgtable_64.c11
-rw-r--r--arch/powerpc/mm/ppc_mmu_32.c4
-rw-r--r--arch/powerpc/mm/tlb_low_64e.S2
-rw-r--r--arch/powerpc/mm/tlb_nohash.c4
-rw-r--r--arch/powerpc/mm/tlb_nohash_low.S4
-rw-r--r--arch/powerpc/oprofile/op_model_cell.c4
-rw-r--r--arch/powerpc/perf/core-book3s.c2
-rw-r--r--arch/powerpc/perf/hv-24x7.c225
-rw-r--r--arch/powerpc/perf/hv-24x7.h3
-rw-r--r--arch/powerpc/perf/hv-gpci.c43
-rw-r--r--arch/powerpc/perf/power7-pmu.c18
-rw-r--r--arch/powerpc/perf/power8-events-list.h51
-rw-r--r--arch/powerpc/perf/power8-pmu.c112
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pci.c2
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig1
-rw-r--r--arch/powerpc/platforms/85xx/Makefile1
-rw-r--r--arch/powerpc/platforms/85xx/common.c3
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_cds.c2
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c106
-rw-r--r--arch/powerpc/platforms/85xx/smp.c312
-rw-r--r--arch/powerpc/platforms/85xx/smp.h1
-rw-r--r--arch/powerpc/platforms/86xx/Makefile2
-rw-r--r--arch/powerpc/platforms/86xx/common.c43
-rw-r--r--arch/powerpc/platforms/86xx/gef_ppc9a.c32
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc310.c32
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc610.c32
-rw-r--r--arch/powerpc/platforms/86xx/mpc8610_hpcd.c20
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx.h2
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c21
-rw-r--r--arch/powerpc/platforms/86xx/sbc8641d.c32
-rw-r--r--arch/powerpc/platforms/embedded6xx/mpc10x.h10
-rw-r--r--arch/powerpc/platforms/powermac/Makefile2
-rw-r--r--arch/powerpc/platforms/powermac/cache.S2
-rw-r--r--arch/powerpc/platforms/powermac/feature.c6
-rw-r--r--arch/powerpc/platforms/powernv/Makefile2
-rw-r--r--arch/powerpc/platforms/powernv/eeh-powernv.c298
-rw-r--r--arch/powerpc/platforms/powernv/idle.c6
-rw-r--r--arch/powerpc/platforms/powernv/npu-dma.c2
-rw-r--r--arch/powerpc/platforms/powernv/opal-msglog.c34
-rw-r--r--arch/powerpc/platforms/powernv/opal.c7
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c347
-rw-r--r--arch/powerpc/platforms/powernv/pci-p5ioc2.c271
-rw-r--r--arch/powerpc/platforms/powernv/pci.c17
-rw-r--r--arch/powerpc/platforms/powernv/pci.h152
-rw-r--r--arch/powerpc/platforms/powernv/subcore.c2
-rw-r--r--arch/powerpc/platforms/ps3/gelic_udbg.c72
-rw-r--r--arch/powerpc/platforms/ps3/interrupt.c2
-rw-r--r--arch/powerpc/platforms/pseries/hvconsole.c2
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c9
-rw-r--r--arch/powerpc/platforms/pseries/setup.c2
-rwxr-xr-xarch/powerpc/scripts/gcc-check-mprofile-kernel.sh23
-rw-r--r--arch/powerpc/sysdev/Kconfig5
-rw-r--r--arch/powerpc/sysdev/Makefile1
-rw-r--r--arch/powerpc/sysdev/cpm1.c5
-rw-r--r--arch/powerpc/sysdev/fsl_lbc.c49
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c2
-rw-r--r--arch/powerpc/sysdev/fsl_rcpm.c386
-rw-r--r--arch/powerpc/sysdev/fsl_rmu.c2
-rw-r--r--arch/powerpc/sysdev/i8259.c2
-rw-r--r--arch/powerpc/sysdev/mpic.c4
-rw-r--r--arch/powerpc/xmon/xmon.c120
-rw-r--r--drivers/misc/cxl/Makefile1
-rw-r--r--drivers/misc/cxl/api.c83
-rw-r--r--drivers/misc/cxl/base.c32
-rw-r--r--drivers/misc/cxl/context.c11
-rw-r--r--drivers/misc/cxl/cxl.h288
-rw-r--r--drivers/misc/cxl/debugfs.c4
-rw-r--r--drivers/misc/cxl/fault.c25
-rw-r--r--drivers/misc/cxl/file.c28
-rw-r--r--drivers/misc/cxl/flash.c538
-rw-r--r--drivers/misc/cxl/guest.c1177
-rw-r--r--drivers/misc/cxl/hcalls.c647
-rw-r--r--drivers/misc/cxl/hcalls.h204
-rw-r--r--drivers/misc/cxl/irq.c309
-rw-r--r--drivers/misc/cxl/main.c122
-rw-r--r--drivers/misc/cxl/native.c469
-rw-r--r--drivers/misc/cxl/of.c513
-rw-r--r--drivers/misc/cxl/pci.c267
-rw-r--r--drivers/misc/cxl/sysfs.c123
-rw-r--r--drivers/misc/cxl/trace.h193
-rw-r--r--drivers/misc/cxl/vphb.c167
-rw-r--r--drivers/pci/bus.c3
-rw-r--r--drivers/pci/iov.c10
-rw-r--r--drivers/scsi/cxlflash/common.h1
-rw-r--r--drivers/scsi/cxlflash/main.c18
-rw-r--r--drivers/soc/fsl/qe/qe_common.c66
-rw-r--r--drivers/soc/fsl/qe/qe_ic.c11
-rw-r--r--include/linux/atomic.h10
-rw-r--r--include/linux/bug.h9
-rw-r--r--include/linux/fsl/guts.h105
-rw-r--r--include/linux/huge_mm.h3
-rw-r--r--include/linux/pci.h9
-rw-r--r--include/misc/cxl.h8
-rw-r--r--include/soc/fsl/qe/qe.h2
-rw-r--r--include/uapi/misc/cxl.h24
-rw-r--r--mm/huge_memory.c17
-rw-r--r--tools/testing/selftests/powerpc/Makefile5
-rw-r--r--tools/testing/selftests/powerpc/basic_asm.h70
-rw-r--r--tools/testing/selftests/powerpc/math/.gitignore6
-rw-r--r--tools/testing/selftests/powerpc/math/Makefile19
-rw-r--r--tools/testing/selftests/powerpc/math/fpu_asm.S198
-rw-r--r--tools/testing/selftests/powerpc/math/fpu_preempt.c113
-rw-r--r--tools/testing/selftests/powerpc/math/fpu_signal.c135
-rw-r--r--tools/testing/selftests/powerpc/math/fpu_syscall.c90
-rw-r--r--tools/testing/selftests/powerpc/math/vmx_asm.S235
-rw-r--r--tools/testing/selftests/powerpc/math/vmx_preempt.c112
-rw-r--r--tools/testing/selftests/powerpc/math/vmx_signal.c156
-rw-r--r--tools/testing/selftests/powerpc/math/vmx_syscall.c91
-rw-r--r--tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c2
324 files changed, 14760 insertions, 7155 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl
index b07e86d4597f..7fd737eed38a 100644
--- a/Documentation/ABI/testing/sysfs-class-cxl
+++ b/Documentation/ABI/testing/sysfs-class-cxl
@@ -159,7 +159,7 @@ Description: read only
159 Decimal value of the Per Process MMIO space length. 159 Decimal value of the Per Process MMIO space length.
160Users: https://github.com/ibm-capi/libcxl 160Users: https://github.com/ibm-capi/libcxl
161 161
162What: /sys/class/cxl/<afu>m/pp_mmio_off 162What: /sys/class/cxl/<afu>m/pp_mmio_off (not in a guest)
163Date: September 2014 163Date: September 2014
164Contact: linuxppc-dev@lists.ozlabs.org 164Contact: linuxppc-dev@lists.ozlabs.org
165Description: read only 165Description: read only
@@ -183,7 +183,7 @@ Description: read only
183 Identifies the revision level of the PSL. 183 Identifies the revision level of the PSL.
184Users: https://github.com/ibm-capi/libcxl 184Users: https://github.com/ibm-capi/libcxl
185 185
186What: /sys/class/cxl/<card>/base_image 186What: /sys/class/cxl/<card>/base_image (not in a guest)
187Date: September 2014 187Date: September 2014
188Contact: linuxppc-dev@lists.ozlabs.org 188Contact: linuxppc-dev@lists.ozlabs.org
189Description: read only 189Description: read only
@@ -193,7 +193,7 @@ Description: read only
193 during the initial program load. 193 during the initial program load.
194Users: https://github.com/ibm-capi/libcxl 194Users: https://github.com/ibm-capi/libcxl
195 195
196What: /sys/class/cxl/<card>/image_loaded 196What: /sys/class/cxl/<card>/image_loaded (not in a guest)
197Date: September 2014 197Date: September 2014
198Contact: linuxppc-dev@lists.ozlabs.org 198Contact: linuxppc-dev@lists.ozlabs.org
199Description: read only 199Description: read only
@@ -201,7 +201,7 @@ Description: read only
201 onto the card. 201 onto the card.
202Users: https://github.com/ibm-capi/libcxl 202Users: https://github.com/ibm-capi/libcxl
203 203
204What: /sys/class/cxl/<card>/load_image_on_perst 204What: /sys/class/cxl/<card>/load_image_on_perst (not in a guest)
205Date: December 2014 205Date: December 2014
206Contact: linuxppc-dev@lists.ozlabs.org 206Contact: linuxppc-dev@lists.ozlabs.org
207Description: read/write 207Description: read/write
@@ -224,7 +224,7 @@ Description: write only
224 to reload the FPGA depending on load_image_on_perst. 224 to reload the FPGA depending on load_image_on_perst.
225Users: https://github.com/ibm-capi/libcxl 225Users: https://github.com/ibm-capi/libcxl
226 226
227What: /sys/class/cxl/<card>/perst_reloads_same_image 227What: /sys/class/cxl/<card>/perst_reloads_same_image (not in a guest)
228Date: July 2015 228Date: July 2015
229Contact: linuxppc-dev@lists.ozlabs.org 229Contact: linuxppc-dev@lists.ozlabs.org
230Description: read/write 230Description: read/write
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt
index 1fc5328c0651..55c2c03fc81e 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt
+++ b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt
@@ -315,6 +315,16 @@ PROPERTIES
315 Value type: <phandle> 315 Value type: <phandle>
316 Definition: A phandle for 1EEE1588 timer. 316 Definition: A phandle for 1EEE1588 timer.
317 317
318- pcsphy-handle
319 Usage required for "fsl,fman-memac" MACs
320 Value type: <phandle>
321 Definition: A phandle for pcsphy.
322
323- tbi-handle
324 Usage required for "fsl,fman-dtsec" MACs
325 Value type: <phandle>
326 Definition: A phandle for tbiphy.
327
318EXAMPLE 328EXAMPLE
319 329
320fman1_tx28: port@a8000 { 330fman1_tx28: port@a8000 {
@@ -340,6 +350,7 @@ ethernet@e0000 {
340 reg = <0xe0000 0x1000>; 350 reg = <0xe0000 0x1000>;
341 fsl,fman-ports = <&fman1_rx8 &fman1_tx28>; 351 fsl,fman-ports = <&fman1_rx8 &fman1_tx28>;
342 ptp-timer = <&ptp-timer>; 352 ptp-timer = <&ptp-timer>;
353 tbi-handle = <&tbi0>;
343}; 354};
344 355
345============================================================================ 356============================================================================
@@ -415,6 +426,13 @@ PROPERTIES
415 The settings and programming routines for internal/external 426 The settings and programming routines for internal/external
416 MDIO are different. Must be included for internal MDIO. 427 MDIO are different. Must be included for internal MDIO.
417 428
429For internal PHY device on internal mdio bus, a PHY node should be created.
430See the definition of the PHY node in booting-without-of.txt for an
431example of how to define a PHY (Internal PHY has no interrupt line).
432- For "fsl,fman-mdio" compatible internal mdio bus, the PHY is TBI PHY.
433- For "fsl,fman-memac-mdio" compatible internal mdio bus, the PHY is PCS PHY,
434 PCS PHY addr must be '0'.
435
418EXAMPLE 436EXAMPLE
419 437
420Example for FMan v2 external MDIO: 438Example for FMan v2 external MDIO:
@@ -425,12 +443,29 @@ mdio@f1000 {
425 interrupts = <101 2 0 0>; 443 interrupts = <101 2 0 0>;
426}; 444};
427 445
446Example for FMan v2 internal MDIO:
447
448mdio@e3120 {
449 compatible = "fsl,fman-mdio";
450 reg = <0xe3120 0xee0>;
451 fsl,fman-internal-mdio;
452
453 tbi1: tbi-phy@8 {
454 reg = <0x8>;
455 device_type = "tbi-phy";
456 };
457};
458
428Example for FMan v3 internal MDIO: 459Example for FMan v3 internal MDIO:
429 460
430mdio@f1000 { 461mdio@f1000 {
431 compatible = "fsl,fman-memac-mdio"; 462 compatible = "fsl,fman-memac-mdio";
432 reg = <0xf1000 0x1000>; 463 reg = <0xf1000 0x1000>;
433 fsl,fman-internal-mdio; 464 fsl,fman-internal-mdio;
465
466 pcsphy6: ethernet-phy@0 {
467 reg = <0x0>;
468 };
434}; 469};
435 470
436============================================================================= 471=============================================================================
@@ -568,6 +603,7 @@ fman@400000 {
568 cell-index = <0>; 603 cell-index = <0>;
569 reg = <0xe0000 0x1000>; 604 reg = <0xe0000 0x1000>;
570 fsl,fman-ports = <&fman1_rx_0x8 &fman1_tx_0x28>; 605 fsl,fman-ports = <&fman1_rx_0x8 &fman1_tx_0x28>;
606 tbi-handle = <&tbi5>;
571 }; 607 };
572 608
573 ethernet@e2000 { 609 ethernet@e2000 {
@@ -575,6 +611,7 @@ fman@400000 {
575 cell-index = <1>; 611 cell-index = <1>;
576 reg = <0xe2000 0x1000>; 612 reg = <0xe2000 0x1000>;
577 fsl,fman-ports = <&fman1_rx_0x9 &fman1_tx_0x29>; 613 fsl,fman-ports = <&fman1_rx_0x9 &fman1_tx_0x29>;
614 tbi-handle = <&tbi6>;
578 }; 615 };
579 616
580 ethernet@e4000 { 617 ethernet@e4000 {
@@ -582,6 +619,7 @@ fman@400000 {
582 cell-index = <2>; 619 cell-index = <2>;
583 reg = <0xe4000 0x1000>; 620 reg = <0xe4000 0x1000>;
584 fsl,fman-ports = <&fman1_rx_0xa &fman1_tx_0x2a>; 621 fsl,fman-ports = <&fman1_rx_0xa &fman1_tx_0x2a>;
622 tbi-handle = <&tbi7>;
585 }; 623 };
586 624
587 ethernet@e6000 { 625 ethernet@e6000 {
@@ -589,6 +627,7 @@ fman@400000 {
589 cell-index = <3>; 627 cell-index = <3>;
590 reg = <0xe6000 0x1000>; 628 reg = <0xe6000 0x1000>;
591 fsl,fman-ports = <&fman1_rx_0xb &fman1_tx_0x2b>; 629 fsl,fman-ports = <&fman1_rx_0xb &fman1_tx_0x2b>;
630 tbi-handle = <&tbi8>;
592 }; 631 };
593 632
594 ethernet@e8000 { 633 ethernet@e8000 {
@@ -596,6 +635,7 @@ fman@400000 {
596 cell-index = <4>; 635 cell-index = <4>;
597 reg = <0xf0000 0x1000>; 636 reg = <0xf0000 0x1000>;
598 fsl,fman-ports = <&fman1_rx_0xc &fman1_tx_0x2c>; 637 fsl,fman-ports = <&fman1_rx_0xc &fman1_tx_0x2c>;
638 tbi-handle = <&tbi9>;
599 639
600 ethernet@f0000 { 640 ethernet@f0000 {
601 cell-index = <8>; 641 cell-index = <8>;
diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt
new file mode 100644
index 000000000000..e284e4e1ccd5
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt
@@ -0,0 +1,63 @@
1* Run Control and Power Management
2-------------------------------------------
3The RCPM performs all device-level tasks associated with device run control
4and power management.
5
6Required properites:
7 - reg : Offset and length of the register set of the RCPM block.
8 - fsl,#rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the
9 fsl,rcpm-wakeup property.
10 - compatible : Must contain a chip-specific RCPM block compatible string
11 and (if applicable) may contain a chassis-version RCPM compatible
12 string. Chip-specific strings are of the form "fsl,<chip>-rcpm",
13 such as:
14 * "fsl,p2041-rcpm"
15 * "fsl,p5020-rcpm"
16 * "fsl,t4240-rcpm"
17
18 Chassis-version strings are of the form "fsl,qoriq-rcpm-<version>",
19 such as:
20 * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm
21 * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm
22 * "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm
23
24All references to "1.0" and "2.0" refer to the QorIQ chassis version to
25which the chip complies.
26Chassis Version Example Chips
27--------------- -------------------------------
281.0 p4080, p5020, p5040, p2041, p3041
292.0 t4240, b4860, b4420
302.1 t1040, ls1021
31
32Example:
33The RCPM node for T4240:
34 rcpm: global-utilities@e2000 {
35 compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0";
36 reg = <0xe2000 0x1000>;
37 fsl,#rcpm-wakeup-cells = <2>;
38 };
39
40* Freescale RCPM Wakeup Source Device Tree Bindings
41-------------------------------------------
42Required fsl,rcpm-wakeup property should be added to a device node if the device
43can be used as a wakeup source.
44
45 - fsl,rcpm-wakeup: Consists of a phandle to the rcpm node and the IPPDEXPCR
46 register cells. The number of IPPDEXPCR register cells is defined in
47 "fsl,#rcpm-wakeup-cells" in the rcpm node. The first register cell is
48 the bit mask that should be set in IPPDEXPCR0, and the second register
49 cell is for IPPDEXPCR1, and so on.
50
51 Note: IPPDEXPCR(IP Powerdown Exception Control Register) provides a
52 mechanism for keeping certain blocks awake during STANDBY and MEM, in
53 order to use them as wake-up sources.
54
55Example:
56 lpuart0: serial@2950000 {
57 compatible = "fsl,ls1021a-lpuart";
58 reg = <0x0 0x2950000 0x0 0x1000>;
59 interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
60 clocks = <&sysclk>;
61 clock-names = "ipg";
62 fsl,rcpm-wakeup = <&rcpm 0x0 0x40000000>;
63 };
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index eef242ee576b..1f780d907718 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2620,7 +2620,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
2620 nolapic_timer [X86-32,APIC] Do not use the local APIC timer. 2620 nolapic_timer [X86-32,APIC] Do not use the local APIC timer.
2621 2621
2622 noltlbs [PPC] Do not use large page/tlb entries for kernel 2622 noltlbs [PPC] Do not use large page/tlb entries for kernel
2623 lowmem mapping on PPC40x. 2623 lowmem mapping on PPC40x and PPC8xx
2624 2624
2625 nomca [IA-64] Disable machine check abort handling 2625 nomca [IA-64] Disable machine check abort handling
2626 2626
diff --git a/Documentation/powerpc/cxl.txt b/Documentation/powerpc/cxl.txt
index 205c1b81625c..d5506ba0fef7 100644
--- a/Documentation/powerpc/cxl.txt
+++ b/Documentation/powerpc/cxl.txt
@@ -116,6 +116,8 @@ Work Element Descriptor (WED)
116User API 116User API
117======== 117========
118 118
1191. AFU character devices
120
119 For AFUs operating in AFU directed mode, two character device 121 For AFUs operating in AFU directed mode, two character device
120 files will be created. /dev/cxl/afu0.0m will correspond to a 122 files will be created. /dev/cxl/afu0.0m will correspond to a
121 master context and /dev/cxl/afu0.0s will correspond to a slave 123 master context and /dev/cxl/afu0.0s will correspond to a slave
@@ -362,6 +364,59 @@ read
362 reserved fields: 364 reserved fields:
363 For future extensions and padding 365 For future extensions and padding
364 366
367
3682. Card character device (powerVM guest only)
369
370 In a powerVM guest, an extra character device is created for the
371 card. The device is only used to write (flash) a new image on the
372 FPGA accelerator. Once the image is written and verified, the
373 device tree is updated and the card is reset to reload the updated
374 image.
375
376open
377----
378
379 Opens the device and allocates a file descriptor to be used with
380 the rest of the API. The device can only be opened once.
381
382ioctl
383-----
384
385CXL_IOCTL_DOWNLOAD_IMAGE:
386CXL_IOCTL_VALIDATE_IMAGE:
387 Starts and controls flashing a new FPGA image. Partial
388 reconfiguration is not supported (yet), so the image must contain
389 a copy of the PSL and AFU(s). Since an image can be quite large,
390 the caller may have to iterate, splitting the image in smaller
391 chunks.
392
393 Takes a pointer to a struct cxl_adapter_image:
394 struct cxl_adapter_image {
395 __u64 flags;
396 __u64 data;
397 __u64 len_data;
398 __u64 len_image;
399 __u64 reserved1;
400 __u64 reserved2;
401 __u64 reserved3;
402 __u64 reserved4;
403 };
404
405 flags:
406 These flags indicate which optional fields are present in
407 this struct. Currently all fields are mandatory.
408
409 data:
410 Pointer to a buffer with part of the image to write to the
411 card.
412
413 len_data:
414 Size of the buffer pointed to by data.
415
416 len_image:
417 Full size of the image.
418
419
365Sysfs Class 420Sysfs Class
366=========== 421===========
367 422
diff --git a/MAINTAINERS b/MAINTAINERS
index 74acd99f19c4..0cbfc69a2303 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4250,13 +4250,6 @@ M: Maxim Levitsky <maximlevitsky@gmail.com>
4250S: Maintained 4250S: Maintained
4251F: drivers/media/rc/ene_ir.* 4251F: drivers/media/rc/ene_ir.*
4252 4252
4253ENHANCED ERROR HANDLING (EEH)
4254M: Gavin Shan <shangw@linux.vnet.ibm.com>
4255L: linuxppc-dev@lists.ozlabs.org
4256S: Supported
4257F: Documentation/powerpc/eeh-pci-error-recovery.txt
4258F: arch/powerpc/kernel/eeh*.c
4259
4260EPSON S1D13XXX FRAMEBUFFER DRIVER 4253EPSON S1D13XXX FRAMEBUFFER DRIVER
4261M: Kristoffer Ericson <kristoffer.ericson@gmail.com> 4254M: Kristoffer Ericson <kristoffer.ericson@gmail.com>
4262S: Maintained 4255S: Maintained
@@ -8315,6 +8308,15 @@ L: linux-pci@vger.kernel.org
8315S: Supported 8308S: Supported
8316F: Documentation/PCI/pci-error-recovery.txt 8309F: Documentation/PCI/pci-error-recovery.txt
8317 8310
8311PCI ENHANCED ERROR HANDLING (EEH) FOR POWERPC
8312M: Russell Currey <ruscur@russell.cc>
8313L: linuxppc-dev@lists.ozlabs.org
8314S: Supported
8315F: Documentation/powerpc/eeh-pci-error-recovery.txt
8316F: arch/powerpc/kernel/eeh*.c
8317F: arch/powerpc/platforms/*/eeh*.c
8318F: arch/powerpc/include/*/eeh*.h
8319
8318PCI SUBSYSTEM 8320PCI SUBSYSTEM
8319M: Bjorn Helgaas <bhelgaas@google.com> 8321M: Bjorn Helgaas <bhelgaas@google.com>
8320L: linux-pci@vger.kernel.org 8322L: linux-pci@vger.kernel.org
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a030e5ecb10b..7cd32c038286 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -94,6 +94,7 @@ config PPC
94 select OF_RESERVED_MEM 94 select OF_RESERVED_MEM
95 select HAVE_FTRACE_MCOUNT_RECORD 95 select HAVE_FTRACE_MCOUNT_RECORD
96 select HAVE_DYNAMIC_FTRACE 96 select HAVE_DYNAMIC_FTRACE
97 select HAVE_DYNAMIC_FTRACE_WITH_REGS if MPROFILE_KERNEL
97 select HAVE_FUNCTION_TRACER 98 select HAVE_FUNCTION_TRACER
98 select HAVE_FUNCTION_GRAPH_TRACER 99 select HAVE_FUNCTION_GRAPH_TRACER
99 select SYSCTL_EXCEPTION_TRACE 100 select SYSCTL_EXCEPTION_TRACE
@@ -304,7 +305,7 @@ config ZONE_DMA32
304config PGTABLE_LEVELS 305config PGTABLE_LEVELS
305 int 306 int
306 default 2 if !PPC64 307 default 2 if !PPC64
307 default 3 if PPC_64K_PAGES 308 default 3 if PPC_64K_PAGES && !PPC_BOOK3S_64
308 default 4 309 default 4
309 310
310source "init/Kconfig" 311source "init/Kconfig"
@@ -374,6 +375,24 @@ config PPC_TRANSACTIONAL_MEM
374 ---help--- 375 ---help---
375 Support user-mode Transactional Memory on POWERPC. 376 Support user-mode Transactional Memory on POWERPC.
376 377
378config DISABLE_MPROFILE_KERNEL
379 bool "Disable use of mprofile-kernel for kernel tracing"
380 depends on PPC64 && CPU_LITTLE_ENDIAN
381 default y
382 help
383 Selecting this options disables use of the mprofile-kernel ABI for
384 kernel tracing. That will cause options such as live patching
385 (CONFIG_LIVEPATCH) which depend on CONFIG_DYNAMIC_FTRACE_WITH_REGS to
386 be disabled also.
387
388 If you have a toolchain which supports mprofile-kernel, then you can
389 enable this. Otherwise leave it disabled. If you're not sure, say
390 "N".
391
392config MPROFILE_KERNEL
393 depends on PPC64 && CPU_LITTLE_ENDIAN
394 def_bool !DISABLE_MPROFILE_KERNEL
395
377config IOMMU_HELPER 396config IOMMU_HELPER
378 def_bool PPC64 397 def_bool PPC64
379 398
@@ -390,7 +409,7 @@ config SWIOTLB
390config HOTPLUG_CPU 409config HOTPLUG_CPU
391 bool "Support for enabling/disabling CPUs" 410 bool "Support for enabling/disabling CPUs"
392 depends on SMP && (PPC_PSERIES || \ 411 depends on SMP && (PPC_PSERIES || \
393 PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC)) 412 PPC_PMAC || PPC_POWERNV || FSL_SOC_BOOKE)
394 ---help--- 413 ---help---
395 Say Y here to be able to disable and re-enable individual 414 Say Y here to be able to disable and re-enable individual
396 CPUs at runtime on SMP machines. 415 CPUs at runtime on SMP machines.
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 96efd8213c1c..709a22a3e824 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -133,6 +133,21 @@ else
133CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64 133CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64
134endif 134endif
135 135
136ifdef CONFIG_MPROFILE_KERNEL
137 ifeq ($(shell $(srctree)/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh $(CC) -I$(srctree)/include -D__KERNEL__),OK)
138 CC_FLAGS_FTRACE := -pg -mprofile-kernel
139 KBUILD_CPPFLAGS += -DCC_USING_MPROFILE_KERNEL
140 else
141 # If the user asked for mprofile-kernel but the toolchain doesn't
142 # support it, emit a warning and deliberately break the build later
143 # with mprofile-kernel-not-supported. We would prefer to make this an
144 # error right here, but then the user would never be able to run
145 # oldconfig to change their configuration.
146 $(warning Compiler does not support mprofile-kernel, set CONFIG_DISABLE_MPROFILE_KERNEL)
147 CC_FLAGS_FTRACE := -mprofile-kernel-not-supported
148 endif
149endif
150
136CFLAGS-$(CONFIG_CELL_CPU) += $(call cc-option,-mcpu=cell) 151CFLAGS-$(CONFIG_CELL_CPU) += $(call cc-option,-mcpu=cell)
137CFLAGS-$(CONFIG_POWER4_CPU) += $(call cc-option,-mcpu=power4) 152CFLAGS-$(CONFIG_POWER4_CPU) += $(call cc-option,-mcpu=power4)
138CFLAGS-$(CONFIG_POWER5_CPU) += $(call cc-option,-mcpu=power5) 153CFLAGS-$(CONFIG_POWER5_CPU) += $(call cc-option,-mcpu=power5)
@@ -310,6 +325,16 @@ corenet64_smp_defconfig:
310 $(call merge_into_defconfig,corenet_basic_defconfig,\ 325 $(call merge_into_defconfig,corenet_basic_defconfig,\
311 85xx-64bit 85xx-smp altivec 85xx-hw fsl-emb-nonhw) 326 85xx-64bit 85xx-smp altivec 85xx-hw fsl-emb-nonhw)
312 327
328PHONY += mpc86xx_defconfig
329mpc86xx_defconfig:
330 $(call merge_into_defconfig,mpc86xx_basic_defconfig,\
331 86xx-hw fsl-emb-nonhw)
332
333PHONY += mpc86xx_smp_defconfig
334mpc86xx_smp_defconfig:
335 $(call merge_into_defconfig,mpc86xx_basic_defconfig,\
336 86xx-smp 86xx-hw fsl-emb-nonhw)
337
313define archhelp 338define archhelp
314 @echo '* zImage - Build default images selected by kernel config' 339 @echo '* zImage - Build default images selected by kernel config'
315 @echo ' zImage.* - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)' 340 @echo ' zImage.* - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)'
diff --git a/arch/powerpc/boot/dts/fsl/b4860qds.dts b/arch/powerpc/boot/dts/fsl/b4860qds.dts
index ba8c9bea33ac..a8bc419959ca 100644
--- a/arch/powerpc/boot/dts/fsl/b4860qds.dts
+++ b/arch/powerpc/boot/dts/fsl/b4860qds.dts
@@ -1,7 +1,7 @@
1/* 1/*
2 * B4860DS Device Tree Source 2 * B4860DS Device Tree Source
3 * 3 *
4 * Copyright 2012 Freescale Semiconductor Inc. 4 * Copyright 2012 - 2015 Freescale Semiconductor Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -39,12 +39,69 @@
39 model = "fsl,B4860QDS"; 39 model = "fsl,B4860QDS";
40 compatible = "fsl,B4860QDS"; 40 compatible = "fsl,B4860QDS";
41 41
42 aliases {
43 phy_sgmii_1e = &phy_sgmii_1e;
44 phy_sgmii_1f = &phy_sgmii_1f;
45 phy_xaui_slot1 = &phy_xaui_slot1;
46 phy_xaui_slot2 = &phy_xaui_slot2;
47 };
48
42 ifc: localbus@ffe124000 { 49 ifc: localbus@ffe124000 {
43 board-control@3,0 { 50 board-control@3,0 {
44 compatible = "fsl,b4860qds-fpga", "fsl,fpga-qixis"; 51 compatible = "fsl,b4860qds-fpga", "fsl,fpga-qixis";
45 }; 52 };
46 }; 53 };
47 54
55 soc@ffe000000 {
56 fman@400000 {
57 ethernet@e8000 {
58 phy-handle = <&phy_sgmii_1e>;
59 phy-connection-type = "sgmii";
60 };
61
62 ethernet@ea000 {
63 phy-handle = <&phy_sgmii_1f>;
64 phy-connection-type = "sgmii";
65 };
66
67 ethernet@f0000 {
68 phy-handle = <&phy_xaui_slot1>;
69 phy-connection-type = "xgmii";
70 };
71
72 ethernet@f2000 {
73 phy-handle = <&phy_xaui_slot2>;
74 phy-connection-type = "xgmii";
75 };
76
77 mdio@fc000 {
78 phy_sgmii_1e: ethernet-phy@1e {
79 reg = <0x1e>;
80 status = "disabled";
81 };
82
83 phy_sgmii_1f: ethernet-phy@1f {
84 reg = <0x1f>;
85 status = "disabled";
86 };
87 };
88
89 mdio@fd000 {
90 phy_xaui_slot1: xaui-phy@slot1 {
91 compatible = "ethernet-phy-ieee802.3-c45";
92 reg = <0x7>;
93 status = "disabled";
94 };
95
96 phy_xaui_slot2: xaui-phy@slot2 {
97 compatible = "ethernet-phy-ieee802.3-c45";
98 reg = <0x6>;
99 status = "disabled";
100 };
101 };
102 };
103 };
104
48 rio: rapidio@ffe0c0000 { 105 rio: rapidio@ffe0c0000 {
49 reg = <0xf 0xfe0c0000 0 0x11000>; 106 reg = <0xf 0xfe0c0000 0 0x11000>;
50 107
@@ -55,7 +112,6 @@
55 ranges = <0 0 0xc 0x30000000 0 0x10000000>; 112 ranges = <0 0 0xc 0x30000000 0 0x10000000>;
56 }; 113 };
57 }; 114 };
58
59}; 115};
60 116
61/include/ "b4860si-post.dtsi" 117/include/ "b4860si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/b4qds.dtsi b/arch/powerpc/boot/dts/fsl/b4qds.dtsi
index 64557742fb99..3785ef826d07 100644
--- a/arch/powerpc/boot/dts/fsl/b4qds.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4qds.dtsi
@@ -1,7 +1,7 @@
1/* 1/*
2 * B4420DS Device Tree Source 2 * B4420DS Device Tree Source
3 * 3 *
4 * Copyright 2012 - 2014 Freescale Semiconductor, Inc. 4 * Copyright 2012 - 2015 Freescale Semiconductor, Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -39,6 +39,13 @@
39 #size-cells = <2>; 39 #size-cells = <2>;
40 interrupt-parent = <&mpic>; 40 interrupt-parent = <&mpic>;
41 41
42 aliases {
43 phy_sgmii_10 = &phy_sgmii_10;
44 phy_sgmii_11 = &phy_sgmii_11;
45 phy_sgmii_1c = &phy_sgmii_1c;
46 phy_sgmii_1d = &phy_sgmii_1d;
47 };
48
42 ifc: localbus@ffe124000 { 49 ifc: localbus@ffe124000 {
43 reg = <0xf 0xfe124000 0 0x2000>; 50 reg = <0xf 0xfe124000 0 0x2000>;
44 ranges = <0 0 0xf 0xe8000000 0x08000000 51 ranges = <0 0 0xf 0xe8000000 0x08000000
@@ -135,7 +142,7 @@
135 flash@0 { 142 flash@0 {
136 #address-cells = <1>; 143 #address-cells = <1>;
137 #size-cells = <1>; 144 #size-cells = <1>;
138 compatible = "sst,sst25wf040"; 145 compatible = "sst,sst25wf040", "jedec,spi-nor";
139 reg = <0>; 146 reg = <0>;
140 spi-max-frequency = <40000000>; /* input clock */ 147 spi-max-frequency = <40000000>; /* input clock */
141 }; 148 };
@@ -210,6 +217,47 @@
210 phy_type = "ulpi"; 217 phy_type = "ulpi";
211 }; 218 };
212 219
220 fman@400000 {
221 ethernet@e0000 {
222 phy-handle = <&phy_sgmii_10>;
223 phy-connection-type = "sgmii";
224 };
225
226 ethernet@e2000 {
227 phy-handle = <&phy_sgmii_11>;
228 phy-connection-type = "sgmii";
229 };
230
231 ethernet@e4000 {
232 phy-handle = <&phy_sgmii_1c>;
233 phy-connection-type = "sgmii";
234 };
235
236 ethernet@e6000 {
237 phy-handle = <&phy_sgmii_1d>;
238 phy-connection-type = "sgmii";
239 };
240
241 mdio@fc000 {
242 phy_sgmii_10: ethernet-phy@10 {
243 reg = <0x10>;
244 };
245
246 phy_sgmii_11: ethernet-phy@11 {
247 reg = <0x11>;
248 };
249
250 phy_sgmii_1c: ethernet-phy@1c {
251 reg = <0x1c>;
252 status = "disabled";
253 };
254
255 phy_sgmii_1d: ethernet-phy@1d {
256 reg = <0x1d>;
257 status = "disabled";
258 };
259 };
260 };
213 }; 261 };
214 262
215 pci0: pcie@ffe200000 { 263 pci0: pcie@ffe200000 {
@@ -226,7 +274,6 @@
226 0 0x00010000>; 274 0 0x00010000>;
227 }; 275 };
228 }; 276 };
229
230}; 277};
231 278
232/include/ "b4si-post.dtsi" 279/include/ "b4si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi b/arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi
index f4d96d277ed5..53f8b956340f 100644
--- a/arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi
+++ b/arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi
@@ -53,7 +53,7 @@
53 flash@0 { 53 flash@0 {
54 #address-cells = <1>; 54 #address-cells = <1>;
55 #size-cells = <1>; 55 #size-cells = <1>;
56 compatible = "spansion,s25sl12801"; 56 compatible = "spansion,s25sl12801", "jedec,spi-nor";
57 reg = <0>; 57 reg = <0>;
58 spi-max-frequency = <50000000>; 58 spi-max-frequency = <50000000>;
59 59
diff --git a/arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi b/arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi
index 7a13bf2aa439..fead484a8180 100644
--- a/arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi
+++ b/arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi
@@ -55,7 +55,7 @@
55 flash@0 { 55 flash@0 {
56 #address-cells = <1>; 56 #address-cells = <1>;
57 #size-cells = <1>; 57 #size-cells = <1>;
58 compatible = "spansion,s25sl12801"; 58 compatible = "spansion,s25sl12801", "jedec,spi-nor";
59 reg = <0>; 59 reg = <0>;
60 spi-max-frequency = <30000000>; 60 spi-max-frequency = <30000000>;
61 }; 61 };
diff --git a/arch/powerpc/boot/dts/fsl/c293pcie.dts b/arch/powerpc/boot/dts/fsl/c293pcie.dts
index 53ab4db9e79c..66709788429d 100644
--- a/arch/powerpc/boot/dts/fsl/c293pcie.dts
+++ b/arch/powerpc/boot/dts/fsl/c293pcie.dts
@@ -167,7 +167,7 @@
167 flash@0 { 167 flash@0 {
168 #address-cells = <1>; 168 #address-cells = <1>;
169 #size-cells = <1>; 169 #size-cells = <1>;
170 compatible = "spansion,s25sl12801"; 170 compatible = "spansion,s25sl12801", "jedec,spi-nor";
171 reg = <0>; 171 reg = <0>;
172 spi-max-frequency = <50000000>; 172 spi-max-frequency = <50000000>;
173 173
diff --git a/arch/powerpc/boot/dts/fsl/gef_ppc9a.dts b/arch/powerpc/boot/dts/fsl/gef_ppc9a.dts
new file mode 100644
index 000000000000..0424fc2bd0e0
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/gef_ppc9a.dts
@@ -0,0 +1,216 @@
1/*
2 * GE PPC9A Device Tree Source
3 *
4 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * Based on: SBS CM6 Device Tree Source
12 * Copyright 2007 SBS Technologies GmbH & Co. KG
13 * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
14 * Copyright 2006 Freescale Semiconductor Inc.
15 */
16
17/*
18 * Compiled with dtc -I dts -O dtb -o gef_ppc9a.dtb gef_ppc9a.dts
19 */
20
21/include/ "mpc8641si-pre.dtsi"
22
23/ {
24 model = "GEF_PPC9A";
25 compatible = "gef,ppc9a";
26
27 memory {
28 device_type = "memory";
29 reg = <0x0 0x40000000>; // set by uboot
30 };
31
32 lbc: localbus@fef05000 {
33 reg = <0xfef05000 0x1000>;
34
35 ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
36 1 0 0xe8000000 0x08000000 // Paged Flash 0
37 2 0 0xe0000000 0x08000000 // Paged Flash 1
38 3 0 0xfc100000 0x00020000 // NVRAM
39 4 0 0xfc000000 0x00008000 // FPGA
40 5 0 0xfc008000 0x00008000 // AFIX FPGA
41 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit)
42 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit)
43
44 /* flash@0,0 is a mirror of part of the memory in flash@1,0
45 flash@0,0 {
46 compatible = "gef,ppc9a-firmware-mirror", "cfi-flash";
47 reg = <0x0 0x0 0x1000000>;
48 bank-width = <4>;
49 device-width = <2>;
50 #address-cells = <1>;
51 #size-cells = <1>;
52 partition@0 {
53 label = "firmware";
54 reg = <0x0 0x1000000>;
55 read-only;
56 };
57 };
58 */
59
60 flash@1,0 {
61 compatible = "gef,ppc9a-paged-flash", "cfi-flash";
62 reg = <0x1 0x0 0x8000000>;
63 bank-width = <4>;
64 device-width = <2>;
65 #address-cells = <1>;
66 #size-cells = <1>;
67 partition@0 {
68 label = "user";
69 reg = <0x0 0x7800000>;
70 };
71 partition@7800000 {
72 label = "firmware";
73 reg = <0x7800000 0x800000>;
74 read-only;
75 };
76 };
77
78 nvram@3,0 {
79 device_type = "nvram";
80 compatible = "simtek,stk14ca8";
81 reg = <0x3 0x0 0x20000>;
82 };
83
84 fpga@4,0 {
85 compatible = "gef,ppc9a-fpga-regs";
86 reg = <0x4 0x0 0x40>;
87 };
88
89 wdt@4,2000 {
90 compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00",
91 "gef,fpga-wdt";
92 reg = <0x4 0x2000 0x8>;
93 interrupts = <0x1a 0x4>;
94 interrupt-parent = <&gef_pic>;
95 };
96 /* Second watchdog available, driver currently supports one.
97 wdt@4,2010 {
98 compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00",
99 "gef,fpga-wdt";
100 reg = <0x4 0x2010 0x8>;
101 interrupts = <0x1b 0x4>;
102 interrupt-parent = <&gef_pic>;
103 };
104 */
105 gef_pic: pic@4,4000 {
106 #interrupt-cells = <1>;
107 interrupt-controller;
108 compatible = "gef,ppc9a-fpga-pic", "gef,fpga-pic-1.00";
109 reg = <0x4 0x4000 0x20>;
110 interrupts = <0x8 0x9 0 0>;
111
112 };
113 gef_gpio: gpio@7,14000 {
114 #gpio-cells = <2>;
115 compatible = "gef,ppc9a-gpio", "gef,sbc610-gpio";
116 reg = <0x7 0x14000 0x24>;
117 gpio-controller;
118 };
119 };
120
121 soc: soc@fef00000 {
122 ranges = <0x0 0xfef00000 0x00100000>;
123
124 i2c@3000 {
125 hwmon@48 {
126 compatible = "national,lm92";
127 reg = <0x48>;
128 };
129
130 hwmon@4c {
131 compatible = "adi,adt7461";
132 reg = <0x4c>;
133 };
134
135 rtc@51 {
136 compatible = "epson,rx8581";
137 reg = <0x00000051>;
138 };
139
140 eti@6b {
141 compatible = "dallas,ds1682";
142 reg = <0x6b>;
143 };
144 };
145
146 enet0: ethernet@24000 {
147 tbi-handle = <&tbi0>;
148 phy-handle = <&phy0>;
149 phy-connection-type = "gmii";
150 };
151
152 mdio@24520 {
153 phy0: ethernet-phy@0 {
154 interrupt-parent = <&gef_pic>;
155 interrupts = <0x9 0x4>;
156 reg = <1>;
157 };
158 phy2: ethernet-phy@2 {
159 interrupt-parent = <&gef_pic>;
160 interrupts = <0x8 0x4>;
161 reg = <3>;
162 };
163 tbi0: tbi-phy@11 {
164 reg = <0x11>;
165 device_type = "tbi-phy";
166 };
167 };
168
169 enet1: ethernet@26000 {
170 tbi-handle = <&tbi2>;
171 phy-handle = <&phy2>;
172 phy-connection-type = "gmii";
173 };
174
175 mdio@26520 {
176 tbi2: tbi-phy@11 {
177 reg = <0x11>;
178 device_type = "tbi-phy";
179 };
180 };
181
182 enet2: ethernet@25000 {
183 status = "disabled";
184 };
185
186 mdio@25520 {
187 status = "disabled";
188 };
189
190 enet3: ethernet@27000 {
191 status = "disabled";
192 };
193
194 mdio@27520 {
195 status = "disabled";
196 };
197 };
198
199 pci0: pcie@fef08000 {
200 reg = <0xfef08000 0x1000>;
201 ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
202 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
203
204 pcie@0 {
205 ranges = <0x02000000 0x0 0x80000000
206 0x02000000 0x0 0x80000000
207 0x0 0x40000000
208
209 0x01000000 0x0 0x00000000
210 0x01000000 0x0 0x00000000
211 0x0 0x00400000>;
212 };
213 };
214};
215
216/include/ "mpc8641si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/gef_sbc310.dts b/arch/powerpc/boot/dts/fsl/gef_sbc310.dts
new file mode 100644
index 000000000000..84b3d38f880e
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/gef_sbc310.dts
@@ -0,0 +1,260 @@
1/*
2 * GE SBC310 Device Tree Source
3 *
4 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * Based on: SBS CM6 Device Tree Source
12 * Copyright 2007 SBS Technologies GmbH & Co. KG
13 * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
14 * Copyright 2006 Freescale Semiconductor Inc.
15 */
16
17/*
18 * Compiled with dtc -I dts -O dtb -o gef_sbc310.dtb gef_sbc310.dts
19 */
20
21/include/ "mpc8641si-pre.dtsi"
22
23/ {
24 model = "GEF_SBC310";
25 compatible = "gef,sbc310";
26
27 aliases {
28 pci1 = &pci1;
29 };
30
31 memory {
32 device_type = "memory";
33 reg = <0x0 0x40000000>; // set by uboot
34 };
35
36 lbc: localbus@fef05000 {
37 reg = <0xfef05000 0x1000>;
38
39 ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
40 1 0 0xe0000000 0x08000000 // Paged Flash 0
41 2 0 0xe8000000 0x08000000 // Paged Flash 1
42 3 0 0xfc100000 0x00020000 // NVRAM
43 4 0 0xfc000000 0x00010000>; // FPGA
44
45 /* flash@0,0 is a mirror of part of the memory in flash@1,0
46 flash@0,0 {
47 compatible = "gef,sbc310-firmware-mirror", "cfi-flash";
48 reg = <0x0 0x0 0x01000000>;
49 bank-width = <2>;
50 device-width = <2>;
51 #address-cells = <1>;
52 #size-cells = <1>;
53 partition@0 {
54 label = "firmware";
55 reg = <0x0 0x01000000>;
56 read-only;
57 };
58 };
59 */
60
61 flash@1,0 {
62 compatible = "gef,sbc310-paged-flash", "cfi-flash";
63 reg = <0x1 0x0 0x8000000>;
64 bank-width = <2>;
65 device-width = <2>;
66 #address-cells = <1>;
67 #size-cells = <1>;
68 partition@0 {
69 label = "user";
70 reg = <0x0 0x7800000>;
71 };
72 partition@7800000 {
73 label = "firmware";
74 reg = <0x7800000 0x800000>;
75 read-only;
76 };
77 };
78
79 nvram@3,0 {
80 device_type = "nvram";
81 compatible = "simtek,stk14ca8";
82 reg = <0x3 0x0 0x20000>;
83 };
84
85 fpga@4,0 {
86 compatible = "gef,fpga-regs";
87 reg = <0x4 0x0 0x40>;
88 };
89
90 wdt@4,2000 {
91 compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00",
92 "gef,fpga-wdt";
93 reg = <0x4 0x2000 0x8>;
94 interrupts = <0x1a 0x4>;
95 interrupt-parent = <&gef_pic>;
96 };
97/*
98 wdt@4,2010 {
99 compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00",
100 "gef,fpga-wdt";
101 reg = <0x4 0x2010 0x8>;
102 interrupts = <0x1b 0x4>;
103 interrupt-parent = <&gef_pic>;
104 };
105*/
106 gef_pic: pic@4,4000 {
107 #interrupt-cells = <1>;
108 interrupt-controller;
109 compatible = "gef,sbc310-fpga-pic", "gef,fpga-pic";
110 reg = <0x4 0x4000 0x20>;
111 interrupts = <0x8 0x9 0 0>;
112
113 };
114 gef_gpio: gpio@4,8000 {
115 #gpio-cells = <2>;
116 compatible = "gef,sbc310-gpio";
117 reg = <0x4 0x8000 0x24>;
118 gpio-controller;
119 };
120 };
121
122 soc: soc@fef00000 {
123 ranges = <0x0 0xfef00000 0x00100000>;
124
125 i2c@3000 {
126 rtc@51 {
127 compatible = "epson,rx8581";
128 reg = <0x00000051>;
129 };
130 };
131
132 i2c@3100 {
133 hwmon@48 {
134 compatible = "national,lm92";
135 reg = <0x48>;
136 };
137
138 hwmon@4c {
139 compatible = "adi,adt7461";
140 reg = <0x4c>;
141 };
142
143 eti@6b {
144 compatible = "dallas,ds1682";
145 reg = <0x6b>;
146 };
147 };
148
149 enet0: ethernet@24000 {
150 tbi-handle = <&tbi0>;
151 phy-handle = <&phy0>;
152 phy-connection-type = "gmii";
153 };
154
155 mdio@24520 {
156 phy0: ethernet-phy@0 {
157 interrupt-parent = <&gef_pic>;
158 interrupts = <0x9 0x4>;
159 reg = <1>;
160 };
161 phy2: ethernet-phy@2 {
162 interrupt-parent = <&gef_pic>;
163 interrupts = <0x8 0x4>;
164 reg = <3>;
165 };
166 tbi0: tbi-phy@11 {
167 reg = <0x11>;
168 device_type = "tbi-phy";
169 };
170 };
171
172 enet1: ethernet@26000 {
173 tbi-handle = <&tbi2>;
174 phy-handle = <&phy2>;
175 phy-connection-type = "gmii";
176 };
177
178 mdio@26520 {
179 tbi2: tbi-phy@11 {
180 reg = <0x11>;
181 device_type = "tbi-phy";
182 };
183 };
184
185 enet2: ethernet@25000 {
186 status = "disabled";
187 };
188
189 mdio@25520 {
190 status = "disabled";
191 };
192
193 enet3: ethernet@27000 {
194 status = "disabled";
195 };
196
197 mdio@27520 {
198 status = "disabled";
199 };
200 };
201
202 pci0: pcie@fef08000 {
203 reg = <0xfef08000 0x1000>;
204 ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
205 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
206 interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
207 interrupt-map = <
208 0x0000 0x0 0x0 0x1 &mpic 0x0 0x2
209 0x0000 0x0 0x0 0x2 &mpic 0x1 0x2
210 0x0000 0x0 0x0 0x3 &mpic 0x2 0x2
211 0x0000 0x0 0x0 0x4 &mpic 0x3 0x2
212 >;
213
214 pcie@0 {
215 ranges = <0x02000000 0x0 0x80000000
216 0x02000000 0x0 0x80000000
217 0x0 0x40000000
218
219 0x01000000 0x0 0x00000000
220 0x01000000 0x0 0x00000000
221 0x0 0x00400000>;
222 };
223 };
224
225 pci1: pcie@fef09000 {
226 compatible = "fsl,mpc8641-pcie";
227 device_type = "pci";
228 #size-cells = <2>;
229 #address-cells = <3>;
230 reg = <0xfef09000 0x1000>;
231 bus-range = <0x0 0xff>;
232 ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0x0 0x20000000
233 0x01000000 0x0 0x00000000 0xfe400000 0x0 0x00400000>;
234 clock-frequency = <100000000>;
235 interrupts = <0x19 0x2 0 0>;
236 interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
237 interrupt-map = <
238 0x0000 0x0 0x0 0x1 &mpic 0x4 0x2
239 0x0000 0x0 0x0 0x2 &mpic 0x5 0x2
240 0x0000 0x0 0x0 0x3 &mpic 0x6 0x2
241 0x0000 0x0 0x0 0x4 &mpic 0x7 0x2
242 >;
243
244 pcie@0 {
245 reg = <0 0 0 0 0>;
246 #size-cells = <2>;
247 #address-cells = <3>;
248 device_type = "pci";
249 ranges = <0x02000000 0x0 0xc0000000
250 0x02000000 0x0 0xc0000000
251 0x0 0x20000000
252
253 0x01000000 0x0 0x00000000
254 0x01000000 0x0 0x00000000
255 0x0 0x00400000>;
256 };
257 };
258};
259
260/include/ "mpc8641si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/gef_sbc610.dts b/arch/powerpc/boot/dts/fsl/gef_sbc610.dts
new file mode 100644
index 000000000000..974446acce23
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/gef_sbc610.dts
@@ -0,0 +1,214 @@
1/*
2 * GE SBC610 Device Tree Source
3 *
4 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * Based on: SBS CM6 Device Tree Source
12 * Copyright 2007 SBS Technologies GmbH & Co. KG
13 * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
14 * Copyright 2006 Freescale Semiconductor Inc.
15 */
16
17/*
18 * Compiled with dtc -I dts -O dtb -o gef_sbc610.dtb gef_sbc610.dts
19 */
20
21/include/ "mpc8641si-pre.dtsi"
22
23/ {
24 model = "GEF_SBC610";
25 compatible = "gef,sbc610";
26
27 memory {
28 device_type = "memory";
29 reg = <0x0 0x40000000>; // set by uboot
30 };
31
32 lbc: localbus@fef05000 {
33 reg = <0xfef05000 0x1000>;
34
35 ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
36 1 0 0xe8000000 0x08000000 // Paged Flash 0
37 2 0 0xe0000000 0x08000000 // Paged Flash 1
38 3 0 0xfc100000 0x00020000 // NVRAM
39 4 0 0xfc000000 0x00008000 // FPGA
40 5 0 0xfc008000 0x00008000 // AFIX FPGA
41 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit)
42 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit)
43
44 /* flash@0,0 is a mirror of part of the memory in flash@1,0
45 flash@0,0 {
46 compatible = "gef,sbc610-firmware-mirror", "cfi-flash";
47 reg = <0x0 0x0 0x1000000>;
48 bank-width = <4>;
49 device-width = <2>;
50 #address-cells = <1>;
51 #size-cells = <1>;
52 partition@0 {
53 label = "firmware";
54 reg = <0x0 0x1000000>;
55 read-only;
56 };
57 };
58 */
59
60 flash@1,0 {
61 compatible = "gef,sbc610-paged-flash", "cfi-flash";
62 reg = <0x1 0x0 0x8000000>;
63 bank-width = <4>;
64 device-width = <2>;
65 #address-cells = <1>;
66 #size-cells = <1>;
67 partition@0 {
68 label = "user";
69 reg = <0x0 0x7800000>;
70 };
71 partition@7800000 {
72 label = "firmware";
73 reg = <0x7800000 0x800000>;
74 read-only;
75 };
76 };
77
78 nvram@3,0 {
79 device_type = "nvram";
80 compatible = "simtek,stk14ca8";
81 reg = <0x3 0x0 0x20000>;
82 };
83
84 fpga@4,0 {
85 compatible = "gef,fpga-regs";
86 reg = <0x4 0x0 0x40>;
87 };
88
89 wdt@4,2000 {
90 compatible = "gef,fpga-wdt";
91 reg = <0x4 0x2000 0x8>;
92 interrupts = <0x1a 0x4>;
93 interrupt-parent = <&gef_pic>;
94 };
95 /* Second watchdog available, driver currently supports one.
96 wdt@4,2010 {
97 compatible = "gef,fpga-wdt";
98 reg = <0x4 0x2010 0x8>;
99 interrupts = <0x1b 0x4>;
100 interrupt-parent = <&gef_pic>;
101 };
102 */
103 gef_pic: pic@4,4000 {
104 #interrupt-cells = <1>;
105 interrupt-controller;
106 compatible = "gef,fpga-pic";
107 reg = <0x4 0x4000 0x20>;
108 interrupts = <0x8 0x9 0 0>;
109
110 };
111 gef_gpio: gpio@7,14000 {
112 #gpio-cells = <2>;
113 compatible = "gef,sbc610-gpio";
114 reg = <0x7 0x14000 0x24>;
115 gpio-controller;
116 };
117 };
118
119 soc: soc@fef00000 {
120 ranges = <0x0 0xfef00000 0x00100000>;
121
122 i2c@3000 {
123 hwmon@48 {
124 compatible = "national,lm92";
125 reg = <0x48>;
126 };
127
128 hwmon@4c {
129 compatible = "adi,adt7461";
130 reg = <0x4c>;
131 };
132
133 rtc@51 {
134 compatible = "epson,rx8581";
135 reg = <0x00000051>;
136 };
137
138 eti@6b {
139 compatible = "dallas,ds1682";
140 reg = <0x6b>;
141 };
142 };
143
144 enet0: ethernet@24000 {
145 tbi-handle = <&tbi0>;
146 phy-handle = <&phy0>;
147 phy-connection-type = "gmii";
148 };
149
150 mdio@24520 {
151 phy0: ethernet-phy@0 {
152 interrupt-parent = <&gef_pic>;
153 interrupts = <0x9 0x4>;
154 reg = <1>;
155 };
156 phy2: ethernet-phy@2 {
157 interrupt-parent = <&gef_pic>;
158 interrupts = <0x8 0x4>;
159 reg = <3>;
160 };
161 tbi0: tbi-phy@11 {
162 reg = <0x11>;
163 device_type = "tbi-phy";
164 };
165 };
166
167 enet1: ethernet@26000 {
168 tbi-handle = <&tbi2>;
169 phy-handle = <&phy2>;
170 phy-connection-type = "gmii";
171 };
172
173 mdio@26520 {
174 tbi2: tbi-phy@11 {
175 reg = <0x11>;
176 device_type = "tbi-phy";
177 };
178 };
179
180 enet2: ethernet@25000 {
181 status = "disabled";
182 };
183
184 mdio@25520 {
185 status = "disabled";
186 };
187
188 enet3: ethernet@27000 {
189 status = "disabled";
190 };
191
192 mdio@27520 {
193 status = "disabled";
194 };
195 };
196
197 pci0: pcie@fef08000 {
198 reg = <0xfef08000 0x1000>;
199 ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
200 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
201
202 pcie@0 {
203 ranges = <0x02000000 0x0 0x80000000
204 0x02000000 0x0 0x80000000
205 0x0 0x40000000
206
207 0x01000000 0x0 0x00000000
208 0x01000000 0x0 0x00000000
209 0x0 0x00400000>;
210 };
211 };
212};
213
214/include/ "mpc8641si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/kmcoge4.dts b/arch/powerpc/boot/dts/fsl/kmcoge4.dts
index 6858ec9ef295..2d4b64fcee88 100644
--- a/arch/powerpc/boot/dts/fsl/kmcoge4.dts
+++ b/arch/powerpc/boot/dts/fsl/kmcoge4.dts
@@ -63,7 +63,7 @@
63 flash@0 { 63 flash@0 {
64 #address-cells = <1>; 64 #address-cells = <1>;
65 #size-cells = <1>; 65 #size-cells = <1>;
66 compatible = "spansion,s25fl256s1"; 66 compatible = "spansion,s25fl256s1", "jedec,spi-nor";
67 reg = <0>; 67 reg = <0>;
68 spi-max-frequency = <20000000>; /* input clock */ 68 spi-max-frequency = <20000000>; /* input clock */
69 }; 69 };
@@ -77,7 +77,7 @@
77 flash@2 { 77 flash@2 {
78 #address-cells = <1>; 78 #address-cells = <1>;
79 #size-cells = <1>; 79 #size-cells = <1>;
80 compatible = "micron,m25p32"; 80 compatible = "micron,m25p32", "jedec,spi-nor";
81 reg = <2>; 81 reg = <2>;
82 spi-max-frequency = <15000000>; 82 spi-max-frequency = <15000000>;
83 }; 83 };
diff --git a/arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi b/arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi
index 937ad7e46119..a925fe49a73e 100644
--- a/arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi
@@ -142,7 +142,7 @@
142 flash@0 { 142 flash@0 {
143 #address-cells = <1>; 143 #address-cells = <1>;
144 #size-cells = <1>; 144 #size-cells = <1>;
145 compatible = "spansion,s25sl12801"; 145 compatible = "spansion,s25sl12801", "jedec,spi-nor";
146 reg = <0>; 146 reg = <0>;
147 spi-max-frequency = <40000000>; 147 spi-max-frequency = <40000000>;
148 partition@u-boot { 148 partition@u-boot {
@@ -166,17 +166,17 @@
166 }; 166 };
167 }; 167 };
168 flash@1 { 168 flash@1 {
169 compatible = "spansion,s25sl12801"; 169 compatible = "spansion,s25sl12801", "jedec,spi-nor";
170 reg = <1>; 170 reg = <1>;
171 spi-max-frequency = <40000000>; 171 spi-max-frequency = <40000000>;
172 }; 172 };
173 flash@2 { 173 flash@2 {
174 compatible = "spansion,s25sl12801"; 174 compatible = "spansion,s25sl12801", "jedec,spi-nor";
175 reg = <2>; 175 reg = <2>;
176 spi-max-frequency = <40000000>; 176 spi-max-frequency = <40000000>;
177 }; 177 };
178 flash@3 { 178 flash@3 {
179 compatible = "spansion,s25sl12801"; 179 compatible = "spansion,s25sl12801", "jedec,spi-nor";
180 reg = <3>; 180 reg = <3>;
181 spi-max-frequency = <40000000>; 181 spi-max-frequency = <40000000>;
182 }; 182 };
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/fsl/mpc8641_hpcn.dts
index 1c03060dd0b8..554001f2e96a 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/fsl/mpc8641_hpcn.dts
@@ -9,65 +9,23 @@
9 * option) any later version. 9 * option) any later version.
10 */ 10 */
11 11
12/dts-v1/; 12/include/ "mpc8641si-pre.dtsi"
13 13
14/ { 14/ {
15 model = "MPC8641HPCN"; 15 model = "MPC8641HPCN";
16 compatible = "fsl,mpc8641hpcn"; 16 compatible = "fsl,mpc8641hpcn";
17 #address-cells = <1>;
18 #size-cells = <1>;
19 17
20 aliases { 18 aliases {
21 ethernet0 = &enet0;
22 ethernet1 = &enet1;
23 ethernet2 = &enet2;
24 ethernet3 = &enet3;
25 serial0 = &serial0;
26 serial1 = &serial1;
27 pci0 = &pci0;
28 pci1 = &pci1; 19 pci1 = &pci1;
29 }; 20 };
30 21
31 cpus {
32 #address-cells = <1>;
33 #size-cells = <0>;
34
35 PowerPC,8641@0 {
36 device_type = "cpu";
37 reg = <0>;
38 d-cache-line-size = <32>;
39 i-cache-line-size = <32>;
40 d-cache-size = <32768>; // L1
41 i-cache-size = <32768>; // L1
42 timebase-frequency = <0>; // From uboot
43 bus-frequency = <0>; // From uboot
44 clock-frequency = <0>; // From uboot
45 };
46 PowerPC,8641@1 {
47 device_type = "cpu";
48 reg = <1>;
49 d-cache-line-size = <32>;
50 i-cache-line-size = <32>;
51 d-cache-size = <32768>;
52 i-cache-size = <32768>;
53 timebase-frequency = <0>; // From uboot
54 bus-frequency = <0>; // From uboot
55 clock-frequency = <0>; // From uboot
56 };
57 };
58
59 memory { 22 memory {
60 device_type = "memory"; 23 device_type = "memory";
61 reg = <0x00000000 0x40000000>; // 1G at 0x0 24 reg = <0x00000000 0x40000000>; // 1G at 0x0
62 }; 25 };
63 26
64 localbus@ffe05000 { 27 lbc: localbus@ffe05000 {
65 #address-cells = <2>;
66 #size-cells = <1>;
67 compatible = "fsl,mpc8641-localbus", "simple-bus";
68 reg = <0xffe05000 0x1000>; 28 reg = <0xffe05000 0x1000>;
69 interrupts = <19 2>;
70 interrupt-parent = <&mpic>;
71 29
72 ranges = <0 0 0xef800000 0x00800000 30 ranges = <0 0 0xef800000 0x00800000
73 2 0 0xffdf8000 0x00008000 31 2 0 0xffdf8000 0x00008000
@@ -101,253 +59,75 @@
101 }; 59 };
102 }; 60 };
103 61
104 soc8641@ffe00000 { 62 soc: soc8641@ffe00000 {
105 #address-cells = <1>;
106 #size-cells = <1>;
107 device_type = "soc";
108 compatible = "simple-bus";
109 ranges = <0x00000000 0xffe00000 0x00100000>; 63 ranges = <0x00000000 0xffe00000 0x00100000>;
110 bus-frequency = <0>;
111
112 mcm-law@0 {
113 compatible = "fsl,mcm-law";
114 reg = <0x0 0x1000>;
115 fsl,num-laws = <10>;
116 };
117
118 mcm@1000 {
119 compatible = "fsl,mpc8641-mcm", "fsl,mcm";
120 reg = <0x1000 0x1000>;
121 interrupts = <17 2>;
122 interrupt-parent = <&mpic>;
123 };
124 64
125 i2c@3000 { 65 enet0: ethernet@24000 {
126 #address-cells = <1>; 66 tbi-handle = <&tbi0>;
127 #size-cells = <0>; 67 phy-handle = <&phy0>;
128 cell-index = <0>; 68 phy-connection-type = "rgmii-id";
129 compatible = "fsl-i2c";
130 reg = <0x3000 0x100>;
131 interrupts = <43 2>;
132 interrupt-parent = <&mpic>;
133 dfsrr;
134 };
135
136 i2c@3100 {
137 #address-cells = <1>;
138 #size-cells = <0>;
139 cell-index = <1>;
140 compatible = "fsl-i2c";
141 reg = <0x3100 0x100>;
142 interrupts = <43 2>;
143 interrupt-parent = <&mpic>;
144 dfsrr;
145 }; 69 };
146 70
147 dma@21300 { 71 mdio@24520 {
148 #address-cells = <1>; 72 phy0: ethernet-phy@0 {
149 #size-cells = <1>; 73 interrupts = <10 1 0 0>;
150 compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; 74 reg = <0>;
151 reg = <0x21300 0x4>;
152 ranges = <0x0 0x21100 0x200>;
153 cell-index = <0>;
154 dma-channel@0 {
155 compatible = "fsl,mpc8641-dma-channel",
156 "fsl,eloplus-dma-channel";
157 reg = <0x0 0x80>;
158 cell-index = <0>;
159 interrupt-parent = <&mpic>;
160 interrupts = <20 2>;
161 }; 75 };
162 dma-channel@80 { 76 phy1: ethernet-phy@1 {
163 compatible = "fsl,mpc8641-dma-channel", 77 interrupts = <10 1 0 0>;
164 "fsl,eloplus-dma-channel"; 78 reg = <1>;
165 reg = <0x80 0x80>;
166 cell-index = <1>;
167 interrupt-parent = <&mpic>;
168 interrupts = <21 2>;
169 }; 79 };
170 dma-channel@100 { 80 phy2: ethernet-phy@2 {
171 compatible = "fsl,mpc8641-dma-channel", 81 interrupts = <10 1 0 0>;
172 "fsl,eloplus-dma-channel"; 82 reg = <2>;
173 reg = <0x100 0x80>;
174 cell-index = <2>;
175 interrupt-parent = <&mpic>;
176 interrupts = <22 2>;
177 }; 83 };
178 dma-channel@180 { 84 phy3: ethernet-phy@3 {
179 compatible = "fsl,mpc8641-dma-channel", 85 interrupts = <10 1 0 0>;
180 "fsl,eloplus-dma-channel"; 86 reg = <3>;
181 reg = <0x180 0x80>;
182 cell-index = <3>;
183 interrupt-parent = <&mpic>;
184 interrupts = <23 2>;
185 }; 87 };
186 }; 88 tbi0: tbi-phy@11 {
187 89 reg = <0x11>;
188 enet0: ethernet@24000 { 90 device_type = "tbi-phy";
189 #address-cells = <1>;
190 #size-cells = <1>;
191 cell-index = <0>;
192 device_type = "network";
193 model = "TSEC";
194 compatible = "gianfar";
195 reg = <0x24000 0x1000>;
196 ranges = <0x0 0x24000 0x1000>;
197 local-mac-address = [ 00 00 00 00 00 00 ];
198 interrupts = <29 2 30 2 34 2>;
199 interrupt-parent = <&mpic>;
200 tbi-handle = <&tbi0>;
201 phy-handle = <&phy0>;
202 phy-connection-type = "rgmii-id";
203
204 mdio@520 {
205 #address-cells = <1>;
206 #size-cells = <0>;
207 compatible = "fsl,gianfar-mdio";
208 reg = <0x520 0x20>;
209
210 phy0: ethernet-phy@0 {
211 interrupt-parent = <&mpic>;
212 interrupts = <10 1>;
213 reg = <0>;
214 };
215 phy1: ethernet-phy@1 {
216 interrupt-parent = <&mpic>;
217 interrupts = <10 1>;
218 reg = <1>;
219 };
220 phy2: ethernet-phy@2 {
221 interrupt-parent = <&mpic>;
222 interrupts = <10 1>;
223 reg = <2>;
224 };
225 phy3: ethernet-phy@3 {
226 interrupt-parent = <&mpic>;
227 interrupts = <10 1>;
228 reg = <3>;
229 };
230 tbi0: tbi-phy@11 {
231 reg = <0x11>;
232 device_type = "tbi-phy";
233 };
234 }; 91 };
235 }; 92 };
236 93
237 enet1: ethernet@25000 { 94 enet1: ethernet@25000 {
238 #address-cells = <1>;
239 #size-cells = <1>;
240 cell-index = <1>;
241 device_type = "network";
242 model = "TSEC";
243 compatible = "gianfar";
244 reg = <0x25000 0x1000>;
245 ranges = <0x0 0x25000 0x1000>;
246 local-mac-address = [ 00 00 00 00 00 00 ];
247 interrupts = <35 2 36 2 40 2>;
248 interrupt-parent = <&mpic>;
249 tbi-handle = <&tbi1>; 95 tbi-handle = <&tbi1>;
250 phy-handle = <&phy1>; 96 phy-handle = <&phy1>;
251 phy-connection-type = "rgmii-id"; 97 phy-connection-type = "rgmii-id";
98 };
252 99
253 mdio@520 { 100 mdio@25520 {
254 #address-cells = <1>; 101 tbi1: tbi-phy@11 {
255 #size-cells = <0>; 102 reg = <0x11>;
256 compatible = "fsl,gianfar-tbi"; 103 device_type = "tbi-phy";
257 reg = <0x520 0x20>;
258
259 tbi1: tbi-phy@11 {
260 reg = <0x11>;
261 device_type = "tbi-phy";
262 };
263 }; 104 };
264 }; 105 };
265 106
266 enet2: ethernet@26000 { 107 enet2: ethernet@26000 {
267 #address-cells = <1>;
268 #size-cells = <1>;
269 cell-index = <2>;
270 device_type = "network";
271 model = "TSEC";
272 compatible = "gianfar";
273 reg = <0x26000 0x1000>;
274 ranges = <0x0 0x26000 0x1000>;
275 local-mac-address = [ 00 00 00 00 00 00 ];
276 interrupts = <31 2 32 2 33 2>;
277 interrupt-parent = <&mpic>;
278 tbi-handle = <&tbi2>; 108 tbi-handle = <&tbi2>;
279 phy-handle = <&phy2>; 109 phy-handle = <&phy2>;
280 phy-connection-type = "rgmii-id"; 110 phy-connection-type = "rgmii-id";
111 };
281 112
282 mdio@520 { 113 mdio@26520 {
283 #address-cells = <1>; 114 tbi2: tbi-phy@11 {
284 #size-cells = <0>; 115 reg = <0x11>;
285 compatible = "fsl,gianfar-tbi"; 116 device_type = "tbi-phy";
286 reg = <0x520 0x20>;
287
288 tbi2: tbi-phy@11 {
289 reg = <0x11>;
290 device_type = "tbi-phy";
291 };
292 }; 117 };
293 }; 118 };
294 119
295 enet3: ethernet@27000 { 120 enet3: ethernet@27000 {
296 #address-cells = <1>;
297 #size-cells = <1>;
298 cell-index = <3>;
299 device_type = "network";
300 model = "TSEC";
301 compatible = "gianfar";
302 reg = <0x27000 0x1000>;
303 ranges = <0x0 0x27000 0x1000>;
304 local-mac-address = [ 00 00 00 00 00 00 ];
305 interrupts = <37 2 38 2 39 2>;
306 interrupt-parent = <&mpic>;
307 tbi-handle = <&tbi3>; 121 tbi-handle = <&tbi3>;
308 phy-handle = <&phy3>; 122 phy-handle = <&phy3>;
309 phy-connection-type = "rgmii-id"; 123 phy-connection-type = "rgmii-id";
310
311 mdio@520 {
312 #address-cells = <1>;
313 #size-cells = <0>;
314 compatible = "fsl,gianfar-tbi";
315 reg = <0x520 0x20>;
316
317 tbi3: tbi-phy@11 {
318 reg = <0x11>;
319 device_type = "tbi-phy";
320 };
321 };
322 }; 124 };
323 125
324 serial0: serial@4500 { 126 mdio@27520 {
325 cell-index = <0>; 127 tbi3: tbi-phy@11 {
326 device_type = "serial"; 128 reg = <0x11>;
327 compatible = "fsl,ns16550", "ns16550"; 129 device_type = "tbi-phy";
328 reg = <0x4500 0x100>; 130 };
329 clock-frequency = <0>;
330 interrupts = <42 2>;
331 interrupt-parent = <&mpic>;
332 };
333
334 serial1: serial@4600 {
335 cell-index = <1>;
336 device_type = "serial";
337 compatible = "fsl,ns16550", "ns16550";
338 reg = <0x4600 0x100>;
339 clock-frequency = <0>;
340 interrupts = <28 2>;
341 interrupt-parent = <&mpic>;
342 };
343
344 mpic: pic@40000 {
345 interrupt-controller;
346 #address-cells = <0>;
347 #interrupt-cells = <2>;
348 reg = <0x40000 0x40000>;
349 compatible = "chrp,open-pic";
350 device_type = "open-pic";
351 }; 131 };
352 132
353 rmu: rmu@d3000 { 133 rmu: rmu@d3000 {
@@ -361,50 +141,35 @@
361 compatible = "fsl,srio-msg-unit"; 141 compatible = "fsl,srio-msg-unit";
362 reg = <0x0 0x100>; 142 reg = <0x0 0x100>;
363 interrupts = < 143 interrupts = <
364 53 2 /* msg1_tx_irq */ 144 53 2 0 0 /* msg1_tx_irq */
365 54 2>;/* msg1_rx_irq */ 145 54 2 0 0>;/* msg1_rx_irq */
366 }; 146 };
367 message-unit@100 { 147 message-unit@100 {
368 compatible = "fsl,srio-msg-unit"; 148 compatible = "fsl,srio-msg-unit";
369 reg = <0x100 0x100>; 149 reg = <0x100 0x100>;
370 interrupts = < 150 interrupts = <
371 55 2 /* msg2_tx_irq */ 151 55 2 0 0 /* msg2_tx_irq */
372 56 2>;/* msg2_rx_irq */ 152 56 2 0 0>;/* msg2_rx_irq */
373 }; 153 };
374 doorbell-unit@400 { 154 doorbell-unit@400 {
375 compatible = "fsl,srio-dbell-unit"; 155 compatible = "fsl,srio-dbell-unit";
376 reg = <0x400 0x80>; 156 reg = <0x400 0x80>;
377 interrupts = < 157 interrupts = <
378 49 2 /* bell_outb_irq */ 158 49 2 0 0 /* bell_outb_irq */
379 50 2>;/* bell_inb_irq */ 159 50 2 0 0>;/* bell_inb_irq */
380 }; 160 };
381 port-write-unit@4e0 { 161 port-write-unit@4e0 {
382 compatible = "fsl,srio-port-write-unit"; 162 compatible = "fsl,srio-port-write-unit";
383 reg = <0x4e0 0x20>; 163 reg = <0x4e0 0x20>;
384 interrupts = <48 2>; 164 interrupts = <48 2 0 0>;
385 }; 165 };
386 }; 166 };
387
388 global-utilities@e0000 {
389 compatible = "fsl,mpc8641-guts";
390 reg = <0xe0000 0x1000>;
391 fsl,has-rstcr;
392 };
393 }; 167 };
394 168
395 pci0: pcie@ffe08000 { 169 pci0: pcie@ffe08000 {
396 compatible = "fsl,mpc8641-pcie";
397 device_type = "pci";
398 #interrupt-cells = <1>;
399 #size-cells = <2>;
400 #address-cells = <3>;
401 reg = <0xffe08000 0x1000>; 170 reg = <0xffe08000 0x1000>;
402 bus-range = <0x0 0xff>;
403 ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000 171 ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000
404 0x01000000 0x0 0x00000000 0xffc00000 0x0 0x00010000>; 172 0x01000000 0x0 0x00000000 0xffc00000 0x0 0x00010000>;
405 clock-frequency = <33333333>;
406 interrupt-parent = <&mpic>;
407 interrupts = <24 2>;
408 interrupt-map-mask = <0xff00 0 0 7>; 173 interrupt-map-mask = <0xff00 0 0 7>;
409 interrupt-map = < 174 interrupt-map = <
410 /* IDSEL 0x11 func 0 - PCI slot 1 */ 175 /* IDSEL 0x11 func 0 - PCI slot 1 */
@@ -522,10 +287,6 @@
522 >; 287 >;
523 288
524 pcie@0 { 289 pcie@0 {
525 reg = <0 0 0 0 0>;
526 #size-cells = <2>;
527 #address-cells = <3>;
528 device_type = "pci";
529 ranges = <0x02000000 0x0 0x80000000 290 ranges = <0x02000000 0x0 0x80000000
530 0x02000000 0x0 0x80000000 291 0x02000000 0x0 0x80000000
531 0x0 0x20000000 292 0x0 0x20000000
@@ -545,7 +306,6 @@
545 0x0 0x00010000>; 306 0x0 0x00010000>;
546 isa@1e { 307 isa@1e {
547 device_type = "isa"; 308 device_type = "isa";
548 #interrupt-cells = <2>;
549 #size-cells = <1>; 309 #size-cells = <1>;
550 #address-cells = <2>; 310 #address-cells = <2>;
551 reg = <0xf000 0 0 0 0>; 311 reg = <0xf000 0 0 0 0>;
@@ -562,8 +322,7 @@
562 #address-cells = <0>; 322 #address-cells = <0>;
563 #interrupt-cells = <2>; 323 #interrupt-cells = <2>;
564 compatible = "chrp,iic"; 324 compatible = "chrp,iic";
565 interrupts = <9 2>; 325 interrupts = <9 2 0 0>;
566 interrupt-parent = <&mpic>;
567 }; 326 };
568 327
569 i8042@60 { 328 i8042@60 {
@@ -571,8 +330,7 @@
571 #address-cells = <1>; 330 #address-cells = <1>;
572 reg = <1 0x60 1 1 0x64 1>; 331 reg = <1 0x60 1 1 0x64 1>;
573 interrupts = <1 3 12 3>; 332 interrupts = <1 3 12 3>;
574 interrupt-parent = 333 interrupt-parent = <&i8259>;
575 <&i8259>;
576 334
577 keyboard@0 { 335 keyboard@0 {
578 reg = <0>; 336 reg = <0>;
@@ -603,16 +361,14 @@
603 pci1: pcie@ffe09000 { 361 pci1: pcie@ffe09000 {
604 compatible = "fsl,mpc8641-pcie"; 362 compatible = "fsl,mpc8641-pcie";
605 device_type = "pci"; 363 device_type = "pci";
606 #interrupt-cells = <1>;
607 #size-cells = <2>; 364 #size-cells = <2>;
608 #address-cells = <3>; 365 #address-cells = <3>;
609 reg = <0xffe09000 0x1000>; 366 reg = <0xffe09000 0x1000>;
610 bus-range = <0 0xff>; 367 bus-range = <0 0xff>;
611 ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000 368 ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000
612 0x01000000 0x0 0x00000000 0xffc10000 0x0 0x00010000>; 369 0x01000000 0x0 0x00000000 0xffc10000 0x0 0x00010000>;
613 clock-frequency = <33333333>; 370 clock-frequency = <100000000>;
614 interrupt-parent = <&mpic>; 371 interrupts = <25 2 0 0>;
615 interrupts = <25 2>;
616 interrupt-map-mask = <0xf800 0 0 7>; 372 interrupt-map-mask = <0xf800 0 0 7>;
617 interrupt-map = < 373 interrupt-map = <
618 /* IDSEL 0x0 */ 374 /* IDSEL 0x0 */
@@ -644,8 +400,7 @@
644 rapidio@ffec0000 { 400 rapidio@ffec0000 {
645 reg = <0xffec0000 0x11000>; 401 reg = <0xffec0000 0x11000>;
646 compatible = "fsl,srio"; 402 compatible = "fsl,srio";
647 interrupt-parent = <&mpic>; 403 interrupts = <48 2 0 0>;
648 interrupts = <48 2>;
649 #address-cells = <2>; 404 #address-cells = <2>;
650 #size-cells = <2>; 405 #size-cells = <2>;
651 fsl,srio-rmu-handle = <&rmu>; 406 fsl,srio-rmu-handle = <&rmu>;
@@ -661,3 +416,5 @@
661*/ 416*/
662 417
663}; 418};
419
420/include/ "mpc8641si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts b/arch/powerpc/boot/dts/fsl/mpc8641_hpcn_36b.dts
index bb575e28042a..fec58671a6d6 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts
+++ b/arch/powerpc/boot/dts/fsl/mpc8641_hpcn_36b.dts
@@ -9,7 +9,7 @@
9 * option) any later version. 9 * option) any later version.
10 */ 10 */
11 11
12/dts-v1/; 12/include/ "mpc8641si-pre.dtsi"
13 13
14/ { 14/ {
15 model = "MPC8641HPCN"; 15 model = "MPC8641HPCN";
@@ -18,56 +18,16 @@
18 #size-cells = <2>; 18 #size-cells = <2>;
19 19
20 aliases { 20 aliases {
21 ethernet0 = &enet0;
22 ethernet1 = &enet1;
23 ethernet2 = &enet2;
24 ethernet3 = &enet3;
25 serial0 = &serial0;
26 serial1 = &serial1;
27 pci0 = &pci0;
28 pci1 = &pci1; 21 pci1 = &pci1;
29 }; 22 };
30 23
31 cpus {
32 #address-cells = <1>;
33 #size-cells = <0>;
34
35 PowerPC,8641@0 {
36 device_type = "cpu";
37 reg = <0>;
38 d-cache-line-size = <32>; // 32 bytes
39 i-cache-line-size = <32>; // 32 bytes
40 d-cache-size = <32768>; // L1, 32K
41 i-cache-size = <32768>; // L1, 32K
42 timebase-frequency = <0>; // 33 MHz, from uboot
43 bus-frequency = <0>; // From uboot
44 clock-frequency = <0>; // From uboot
45 };
46 PowerPC,8641@1 {
47 device_type = "cpu";
48 reg = <1>;
49 d-cache-line-size = <32>; // 32 bytes
50 i-cache-line-size = <32>; // 32 bytes
51 d-cache-size = <32768>; // L1, 32K
52 i-cache-size = <32768>; // L1, 32K
53 timebase-frequency = <0>; // 33 MHz, from uboot
54 bus-frequency = <0>; // From uboot
55 clock-frequency = <0>; // From uboot
56 };
57 };
58
59 memory { 24 memory {
60 device_type = "memory"; 25 device_type = "memory";
61 reg = <0x0 0x00000000 0x0 0x40000000>; // 1G at 0x0 26 reg = <0x0 0x00000000 0x0 0x40000000>; // 1G at 0x0
62 }; 27 };
63 28
64 localbus@fffe05000 { 29 lbc: localbus@fffe05000 {
65 #address-cells = <2>;
66 #size-cells = <1>;
67 compatible = "fsl,mpc8641-localbus", "simple-bus";
68 reg = <0x0f 0xffe05000 0x0 0x1000>; 30 reg = <0x0f 0xffe05000 0x0 0x1000>;
69 interrupts = <19 2>;
70 interrupt-parent = <&mpic>;
71 31
72 ranges = <0 0 0xf 0xef800000 0x00800000 32 ranges = <0 0 0xf 0xef800000 0x00800000
73 2 0 0xf 0xffdf8000 0x00008000 33 2 0 0xf 0xffdf8000 0x00008000
@@ -101,276 +61,82 @@
101 }; 61 };
102 }; 62 };
103 63
104 soc8641@fffe00000 { 64 soc: soc8641@fffe00000 {
105 #address-cells = <1>;
106 #size-cells = <1>;
107 device_type = "soc";
108 compatible = "simple-bus";
109 ranges = <0x00000000 0x0f 0xffe00000 0x00100000>; 65 ranges = <0x00000000 0x0f 0xffe00000 0x00100000>;
110 bus-frequency = <0>;
111 66
112 mcm-law@0 { 67 enet0: ethernet@24000 {
113 compatible = "fsl,mcm-law"; 68 tbi-handle = <&tbi0>;
114 reg = <0x0 0x1000>; 69 phy-handle = <&phy0>;
115 fsl,num-laws = <10>; 70 phy-connection-type = "rgmii-id";
116 };
117
118 mcm@1000 {
119 compatible = "fsl,mpc8641-mcm", "fsl,mcm";
120 reg = <0x1000 0x1000>;
121 interrupts = <17 2>;
122 interrupt-parent = <&mpic>;
123 };
124
125 i2c@3000 {
126 #address-cells = <1>;
127 #size-cells = <0>;
128 cell-index = <0>;
129 compatible = "fsl-i2c";
130 reg = <0x3000 0x100>;
131 interrupts = <43 2>;
132 interrupt-parent = <&mpic>;
133 dfsrr;
134 };
135
136 i2c@3100 {
137 #address-cells = <1>;
138 #size-cells = <0>;
139 cell-index = <1>;
140 compatible = "fsl-i2c";
141 reg = <0x3100 0x100>;
142 interrupts = <43 2>;
143 interrupt-parent = <&mpic>;
144 dfsrr;
145 }; 71 };
146 72
147 dma@21300 { 73 mdio@24520 {
148 #address-cells = <1>; 74 phy0: ethernet-phy@0 {
149 #size-cells = <1>; 75 interrupts = <10 1 0 0>;
150 compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; 76 reg = <0>;
151 reg = <0x21300 0x4>;
152 ranges = <0x0 0x21100 0x200>;
153 cell-index = <0>;
154 dma-channel@0 {
155 compatible = "fsl,mpc8641-dma-channel",
156 "fsl,eloplus-dma-channel";
157 reg = <0x0 0x80>;
158 cell-index = <0>;
159 interrupt-parent = <&mpic>;
160 interrupts = <20 2>;
161 }; 77 };
162 dma-channel@80 { 78 phy1: ethernet-phy@1 {
163 compatible = "fsl,mpc8641-dma-channel", 79 interrupts = <10 1 0 0>;
164 "fsl,eloplus-dma-channel"; 80 reg = <1>;
165 reg = <0x80 0x80>;
166 cell-index = <1>;
167 interrupt-parent = <&mpic>;
168 interrupts = <21 2>;
169 }; 81 };
170 dma-channel@100 { 82 phy2: ethernet-phy@2 {
171 compatible = "fsl,mpc8641-dma-channel", 83 interrupts = <10 1 0 0>;
172 "fsl,eloplus-dma-channel"; 84 reg = <2>;
173 reg = <0x100 0x80>;
174 cell-index = <2>;
175 interrupt-parent = <&mpic>;
176 interrupts = <22 2>;
177 }; 85 };
178 dma-channel@180 { 86 phy3: ethernet-phy@3 {
179 compatible = "fsl,mpc8641-dma-channel", 87 interrupts = <10 1 0 0>;
180 "fsl,eloplus-dma-channel"; 88 reg = <3>;
181 reg = <0x180 0x80>;
182 cell-index = <3>;
183 interrupt-parent = <&mpic>;
184 interrupts = <23 2>;
185 }; 89 };
186 }; 90 tbi0: tbi-phy@11 {
187 91 reg = <0x11>;
188 enet0: ethernet@24000 { 92 device_type = "tbi-phy";
189 #address-cells = <1>;
190 #size-cells = <1>;
191 cell-index = <0>;
192 device_type = "network";
193 model = "TSEC";
194 compatible = "gianfar";
195 reg = <0x24000 0x1000>;
196 ranges = <0x0 0x24000 0x1000>;
197 local-mac-address = [ 00 00 00 00 00 00 ];
198 interrupts = <29 2 30 2 34 2>;
199 interrupt-parent = <&mpic>;
200 tbi-handle = <&tbi0>;
201 phy-handle = <&phy0>;
202 phy-connection-type = "rgmii-id";
203
204 mdio@520 {
205 #address-cells = <1>;
206 #size-cells = <0>;
207 compatible = "fsl,gianfar-mdio";
208 reg = <0x520 0x20>;
209
210 phy0: ethernet-phy@0 {
211 interrupt-parent = <&mpic>;
212 interrupts = <10 1>;
213 reg = <0>;
214 };
215 phy1: ethernet-phy@1 {
216 interrupt-parent = <&mpic>;
217 interrupts = <10 1>;
218 reg = <1>;
219 };
220 phy2: ethernet-phy@2 {
221 interrupt-parent = <&mpic>;
222 interrupts = <10 1>;
223 reg = <2>;
224 };
225 phy3: ethernet-phy@3 {
226 interrupt-parent = <&mpic>;
227 interrupts = <10 1>;
228 reg = <3>;
229 };
230 tbi0: tbi-phy@11 {
231 reg = <0x11>;
232 device_type = "tbi-phy";
233 };
234 }; 93 };
235 }; 94 };
236 95
237 enet1: ethernet@25000 { 96 enet1: ethernet@25000 {
238 #address-cells = <1>;
239 #size-cells = <1>;
240 cell-index = <1>;
241 device_type = "network";
242 model = "TSEC";
243 compatible = "gianfar";
244 reg = <0x25000 0x1000>;
245 ranges = <0x0 0x25000 0x1000>;
246 local-mac-address = [ 00 00 00 00 00 00 ];
247 interrupts = <35 2 36 2 40 2>;
248 interrupt-parent = <&mpic>;
249 tbi-handle = <&tbi1>; 97 tbi-handle = <&tbi1>;
250 phy-handle = <&phy1>; 98 phy-handle = <&phy1>;
251 phy-connection-type = "rgmii-id"; 99 phy-connection-type = "rgmii-id";
100 };
252 101
253 mdio@520 { 102 mdio@25520 {
254 #address-cells = <1>; 103 tbi1: tbi-phy@11 {
255 #size-cells = <0>; 104 reg = <0x11>;
256 compatible = "fsl,gianfar-tbi"; 105 device_type = "tbi-phy";
257 reg = <0x520 0x20>;
258
259 tbi1: tbi-phy@11 {
260 reg = <0x11>;
261 device_type = "tbi-phy";
262 };
263 }; 106 };
264 }; 107 };
265 108
266 enet2: ethernet@26000 { 109 enet2: ethernet@26000 {
267 #address-cells = <1>;
268 #size-cells = <1>;
269 cell-index = <2>;
270 device_type = "network";
271 model = "TSEC";
272 compatible = "gianfar";
273 reg = <0x26000 0x1000>;
274 ranges = <0x0 0x26000 0x1000>;
275 local-mac-address = [ 00 00 00 00 00 00 ];
276 interrupts = <31 2 32 2 33 2>;
277 interrupt-parent = <&mpic>;
278 tbi-handle = <&tbi2>; 110 tbi-handle = <&tbi2>;
279 phy-handle = <&phy2>; 111 phy-handle = <&phy2>;
280 phy-connection-type = "rgmii-id"; 112 phy-connection-type = "rgmii-id";
113 };
281 114
282 mdio@520 { 115 mdio@26520 {
283 #address-cells = <1>; 116 tbi2: tbi-phy@11 {
284 #size-cells = <0>; 117 reg = <0x11>;
285 compatible = "fsl,gianfar-tbi"; 118 device_type = "tbi-phy";
286 reg = <0x520 0x20>;
287
288 tbi2: tbi-phy@11 {
289 reg = <0x11>;
290 device_type = "tbi-phy";
291 };
292 }; 119 };
293 }; 120 };
294 121
295 enet3: ethernet@27000 { 122 enet3: ethernet@27000 {
296 #address-cells = <1>;
297 #size-cells = <1>;
298 cell-index = <3>;
299 device_type = "network";
300 model = "TSEC";
301 compatible = "gianfar";
302 reg = <0x27000 0x1000>;
303 ranges = <0x0 0x27000 0x1000>;
304 local-mac-address = [ 00 00 00 00 00 00 ];
305 interrupts = <37 2 38 2 39 2>;
306 interrupt-parent = <&mpic>;
307 tbi-handle = <&tbi3>; 123 tbi-handle = <&tbi3>;
308 phy-handle = <&phy3>; 124 phy-handle = <&phy3>;
309 phy-connection-type = "rgmii-id"; 125 phy-connection-type = "rgmii-id";
310
311 mdio@520 {
312 #address-cells = <1>;
313 #size-cells = <0>;
314 compatible = "fsl,gianfar-tbi";
315 reg = <0x520 0x20>;
316
317 tbi3: tbi-phy@11 {
318 reg = <0x11>;
319 device_type = "tbi-phy";
320 };
321 };
322 }; 126 };
323 127
324 serial0: serial@4500 { 128 mdio@27520 {
325 cell-index = <0>; 129 tbi3: tbi-phy@11 {
326 device_type = "serial"; 130 reg = <0x11>;
327 compatible = "fsl,ns16550", "ns16550"; 131 device_type = "tbi-phy";
328 reg = <0x4500 0x100>; 132 };
329 clock-frequency = <0>;
330 interrupts = <42 2>;
331 interrupt-parent = <&mpic>;
332 };
333
334 serial1: serial@4600 {
335 cell-index = <1>;
336 device_type = "serial";
337 compatible = "fsl,ns16550", "ns16550";
338 reg = <0x4600 0x100>;
339 clock-frequency = <0>;
340 interrupts = <28 2>;
341 interrupt-parent = <&mpic>;
342 };
343
344 mpic: pic@40000 {
345 interrupt-controller;
346 #address-cells = <0>;
347 #interrupt-cells = <2>;
348 reg = <0x40000 0x40000>;
349 compatible = "chrp,open-pic";
350 device_type = "open-pic";
351 };
352
353 global-utilities@e0000 {
354 compatible = "fsl,mpc8641-guts";
355 reg = <0xe0000 0x1000>;
356 fsl,has-rstcr;
357 }; 133 };
358 }; 134 };
359 135
360 pci0: pcie@fffe08000 { 136 pci0: pcie@fffe08000 {
361 cell-index = <0>;
362 compatible = "fsl,mpc8641-pcie";
363 device_type = "pci";
364 #interrupt-cells = <1>;
365 #size-cells = <2>;
366 #address-cells = <3>;
367 reg = <0x0f 0xffe08000 0x0 0x1000>; 137 reg = <0x0f 0xffe08000 0x0 0x1000>;
368 bus-range = <0x0 0xff>;
369 ranges = <0x02000000 0x0 0xe0000000 0x0c 0x00000000 0x0 0x20000000 138 ranges = <0x02000000 0x0 0xe0000000 0x0c 0x00000000 0x0 0x20000000
370 0x01000000 0x0 0x00000000 0x0f 0xffc00000 0x0 0x00010000>; 139 0x01000000 0x0 0x00000000 0x0f 0xffc00000 0x0 0x00010000>;
371 clock-frequency = <33333333>;
372 interrupt-parent = <&mpic>;
373 interrupts = <24 2>;
374 interrupt-map-mask = <0xff00 0 0 7>; 140 interrupt-map-mask = <0xff00 0 0 7>;
375 interrupt-map = < 141 interrupt-map = <
376 /* IDSEL 0x11 func 0 - PCI slot 1 */ 142 /* IDSEL 0x11 func 0 - PCI slot 1 */
@@ -488,10 +254,6 @@
488 >; 254 >;
489 255
490 pcie@0 { 256 pcie@0 {
491 reg = <0 0 0 0 0>;
492 #size-cells = <2>;
493 #address-cells = <3>;
494 device_type = "pci";
495 ranges = <0x02000000 0x0 0xe0000000 257 ranges = <0x02000000 0x0 0xe0000000
496 0x02000000 0x0 0xe0000000 258 0x02000000 0x0 0xe0000000
497 0x0 0x20000000 259 0x0 0x20000000
@@ -511,7 +273,6 @@
511 0x0 0x00010000>; 273 0x0 0x00010000>;
512 isa@1e { 274 isa@1e {
513 device_type = "isa"; 275 device_type = "isa";
514 #interrupt-cells = <2>;
515 #size-cells = <1>; 276 #size-cells = <1>;
516 #address-cells = <2>; 277 #address-cells = <2>;
517 reg = <0xf000 0 0 0 0>; 278 reg = <0xf000 0 0 0 0>;
@@ -528,8 +289,7 @@
528 #address-cells = <0>; 289 #address-cells = <0>;
529 #interrupt-cells = <2>; 290 #interrupt-cells = <2>;
530 compatible = "chrp,iic"; 291 compatible = "chrp,iic";
531 interrupts = <9 2>; 292 interrupts = <9 2 0 0>;
532 interrupt-parent = <&mpic>;
533 }; 293 };
534 294
535 i8042@60 { 295 i8042@60 {
@@ -537,8 +297,7 @@
537 #address-cells = <1>; 297 #address-cells = <1>;
538 reg = <1 0x60 1 1 0x64 1>; 298 reg = <1 0x60 1 1 0x64 1>;
539 interrupts = <1 3 12 3>; 299 interrupts = <1 3 12 3>;
540 interrupt-parent = 300 interrupt-parent = <&i8259>;
541 <&i8259>;
542 301
543 keyboard@0 { 302 keyboard@0 {
544 reg = <0>; 303 reg = <0>;
@@ -567,19 +326,16 @@
567 }; 326 };
568 327
569 pci1: pcie@fffe09000 { 328 pci1: pcie@fffe09000 {
570 cell-index = <1>;
571 compatible = "fsl,mpc8641-pcie"; 329 compatible = "fsl,mpc8641-pcie";
572 device_type = "pci"; 330 device_type = "pci";
573 #interrupt-cells = <1>;
574 #size-cells = <2>; 331 #size-cells = <2>;
575 #address-cells = <3>; 332 #address-cells = <3>;
576 reg = <0x0f 0xffe09000 0x0 0x1000>; 333 reg = <0x0f 0xffe09000 0x0 0x1000>;
577 bus-range = <0x0 0xff>; 334 bus-range = <0x0 0xff>;
578 ranges = <0x02000000 0x0 0xe0000000 0x0c 0x20000000 0x0 0x20000000 335 ranges = <0x02000000 0x0 0xe0000000 0x0c 0x20000000 0x0 0x20000000
579 0x01000000 0x0 0x00000000 0x0f 0xffc10000 0x0 0x00010000>; 336 0x01000000 0x0 0x00000000 0x0f 0xffc10000 0x0 0x00010000>;
580 clock-frequency = <33333333>; 337 clock-frequency = <100000000>;
581 interrupt-parent = <&mpic>; 338 interrupts = <25 2 0 0>;
582 interrupts = <25 2>;
583 interrupt-map-mask = <0xf800 0 0 7>; 339 interrupt-map-mask = <0xf800 0 0 7>;
584 interrupt-map = < 340 interrupt-map = <
585 /* IDSEL 0x0 */ 341 /* IDSEL 0x0 */
@@ -603,3 +359,5 @@
603 }; 359 };
604 }; 360 };
605}; 361};
362
363/include/ "mpc8641si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/mpc8641si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8641si-post.dtsi
new file mode 100644
index 000000000000..70889d8e8850
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8641si-post.dtsi
@@ -0,0 +1,120 @@
1/*
2 * MPC8641 Silicon/SoC Device Tree Source (post include)
3 *
4 * Copyright 2016 Elettra-Sincrotrone Trieste S.C.p.A.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13&lbc {
14 #address-cells = <2>;
15 #size-cells = <1>;
16 compatible = "fsl,mpc8641-localbus", "simple-bus";
17 interrupts = <19 2 0 0>;
18};
19
20&soc {
21 #address-cells = <1>;
22 #size-cells = <1>;
23 device_type = "soc";
24 compatible = "fsl,mpc8641-soc", "simple-bus";
25 bus-frequency = <0>;
26
27 mcm-law@0 {
28 compatible = "fsl,mcm-law";
29 reg = <0x0 0x1000>;
30 fsl,num-laws = <10>;
31 };
32
33 mcm@1000 {
34 compatible = "fsl,mpc8641-mcm", "fsl,mcm";
35 reg = <0x1000 0x1000>;
36 interrupts = <17 2 0 0>;
37 };
38
39/include/ "pq3-i2c-0.dtsi"
40/include/ "pq3-i2c-1.dtsi"
41/include/ "pq3-duart-0.dtsi"
42 serial@4600 {
43 interrupts = <28 2 0 0>;
44 };
45/include/ "pq3-dma-0.dtsi"
46 dma@21300 {
47 compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
48 };
49 dma-channel@0 {
50 compatible = "fsl,mpc8641-dma-channel", "fsl,eloplus-dma-channel";
51 };
52 dma-channel@80 {
53 compatible = "fsl,mpc8641-dma-channel", "fsl,eloplus-dma-channel";
54 };
55 dma-channel@100 {
56 compatible = "fsl,mpc8641-dma-channel", "fsl,eloplus-dma-channel";
57 };
58 dma-channel@180 {
59 compatible = "fsl,mpc8641-dma-channel", "fsl,eloplus-dma-channel";
60 };
61
62/include/ "pq3-etsec1-0.dtsi"
63 ethernet@24000 {
64 model = "TSEC";
65 };
66/include/ "pq3-etsec1-1.dtsi"
67 ethernet@25000 {
68 model = "TSEC";
69 };
70/include/ "pq3-etsec1-2.dtsi"
71 ethernet@26000 {
72 model = "TSEC";
73 };
74/include/ "pq3-etsec1-3.dtsi"
75 ethernet@27000 {
76 model = "TSEC";
77 };
78
79/include/ "qoriq-mpic.dtsi"
80 msi@41600 {
81 compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
82 };
83 msi@41800 {
84 compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
85 };
86 msi@41a00 {
87 compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
88 };
89
90 global-utilities@e0000 {
91 compatible = "fsl,mpc8641-guts";
92 reg = <0xe0000 0x1000>;
93 fsl,has-rstcr;
94 };
95};
96
97&pci0 {
98 compatible = "fsl,mpc8641-pcie";
99 device_type = "pci";
100 #size-cells = <2>;
101 #address-cells = <3>;
102 bus-range = <0x0 0xff>;
103 clock-frequency = <100000000>;
104 interrupts = <24 2 0 0>;
105 interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
106
107 interrupt-map = <
108 0x0000 0x0 0x0 0x1 &mpic 0x0 0x1
109 0x0000 0x0 0x0 0x2 &mpic 0x1 0x1
110 0x0000 0x0 0x0 0x3 &mpic 0x2 0x1
111 0x0000 0x0 0x0 0x4 &mpic 0x3 0x1
112 >;
113
114 pcie@0 {
115 reg = <0 0 0 0 0>;
116 #size-cells = <2>;
117 #address-cells = <3>;
118 device_type = "pci";
119 };
120};
diff --git a/arch/powerpc/boot/dts/fsl/mpc8641si-pre.dtsi b/arch/powerpc/boot/dts/fsl/mpc8641si-pre.dtsi
new file mode 100644
index 000000000000..9e03328561d3
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8641si-pre.dtsi
@@ -0,0 +1,58 @@
1/*
2 * MPC8641 Silicon/SoC Device Tree Source (pre include)
3 *
4 * Copyright 2016 Elettra-Sincrotrone Trieste S.C.p.A.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13/dts-v1/;
14
15/ {
16 #address-cells = <1>;
17 #size-cells = <1>;
18 interrupt-parent = <&mpic>;
19
20 aliases {
21 ethernet0 = &enet0;
22 ethernet1 = &enet1;
23 ethernet2 = &enet2;
24 ethernet3 = &enet3;
25 serial0 = &serial0;
26 serial1 = &serial1;
27 pci0 = &pci0;
28 };
29
30 cpus {
31 #address-cells = <1>;
32 #size-cells = <0>;
33
34 PowerPC,8641@0 {
35 device_type = "cpu";
36 reg = <0>;
37 d-cache-line-size = <32>;
38 i-cache-line-size = <32>;
39 d-cache-size = <32768>;
40 i-cache-size = <32768>;
41 timebase-frequency = <0>;
42 bus-frequency = <0>;
43 clock-frequency = <0>;
44 };
45
46 PowerPC,8641@1 {
47 device_type = "cpu";
48 reg = <1>;
49 d-cache-line-size = <32>;
50 i-cache-line-size = <32>;
51 d-cache-size = <32768>;
52 i-cache-size = <32768>;
53 timebase-frequency = <0>;
54 bus-frequency = <0>;
55 clock-frequency = <0>;
56 };
57 };
58};
diff --git a/arch/powerpc/boot/dts/fsl/mvme2500.dts b/arch/powerpc/boot/dts/fsl/mvme2500.dts
index c7bc1a0c7194..69559e970e99 100644
--- a/arch/powerpc/boot/dts/fsl/mvme2500.dts
+++ b/arch/powerpc/boot/dts/fsl/mvme2500.dts
@@ -70,12 +70,12 @@
70 fsl,espi-num-chipselects = <2>; 70 fsl,espi-num-chipselects = <2>;
71 71
72 flash@0 { 72 flash@0 {
73 compatible = "atmel,at25df641"; 73 compatible = "atmel,at25df641", "jedec,spi-nor";
74 reg = <0>; 74 reg = <0>;
75 spi-max-frequency = <10000000>; 75 spi-max-frequency = <10000000>;
76 }; 76 };
77 flash@1 { 77 flash@1 {
78 compatible = "atmel,at25df641"; 78 compatible = "atmel,at25df641", "jedec,spi-nor";
79 reg = <1>; 79 reg = <1>;
80 spi-max-frequency = <10000000>; 80 spi-max-frequency = <10000000>;
81 }; 81 };
diff --git a/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi
index 14b629505038..a8e4ba070104 100644
--- a/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi
@@ -110,7 +110,7 @@
110 flash@0 { 110 flash@0 {
111 #address-cells = <1>; 111 #address-cells = <1>;
112 #size-cells = <1>; 112 #size-cells = <1>;
113 compatible = "spansion,s25sl12801"; 113 compatible = "spansion,s25sl12801", "jedec,spi-nor";
114 reg = <0>; 114 reg = <0>;
115 spi-max-frequency = <40000000>; 115 spi-max-frequency = <40000000>;
116 116
diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi b/arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi
index c952cd37cf6d..25f81eea60e0 100644
--- a/arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi
@@ -151,7 +151,7 @@
151 flash@0 { 151 flash@0 {
152 #address-cells = <1>; 152 #address-cells = <1>;
153 #size-cells = <1>; 153 #size-cells = <1>;
154 compatible = "spansion,s25sl12801"; 154 compatible = "spansion,s25sl12801", "jedec,spi-nor";
155 reg = <0>; 155 reg = <0>;
156 spi-max-frequency = <40000000>; /* input clock */ 156 spi-max-frequency = <40000000>; /* input clock */
157 157
diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts b/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts
index 740553c090a3..f2dc6c09be52 100644
--- a/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts
+++ b/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts
@@ -155,7 +155,7 @@
155 flash@0 { 155 flash@0 {
156 #address-cells = <1>; 156 #address-cells = <1>;
157 #size-cells = <1>; 157 #size-cells = <1>;
158 compatible = "spansion,s25sl12801"; 158 compatible = "spansion,s25sl12801", "jedec,spi-nor";
159 reg = <0>; 159 reg = <0>;
160 /* input clock */ 160 /* input clock */
161 spi-max-frequency = <40000000>; 161 spi-max-frequency = <40000000>;
diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1020rdb.dtsi
index 1fb7e0e0940f..703142ee6627 100644
--- a/arch/powerpc/boot/dts/fsl/p1020rdb.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1020rdb.dtsi
@@ -148,7 +148,7 @@
148 flash@0 { 148 flash@0 {
149 #address-cells = <1>; 149 #address-cells = <1>;
150 #size-cells = <1>; 150 #size-cells = <1>;
151 compatible = "spansion,s25sl12801"; 151 compatible = "spansion,s25sl12801", "jedec,spi-nor";
152 reg = <0>; 152 reg = <0>;
153 spi-max-frequency = <40000000>; /* input clock */ 153 spi-max-frequency = <40000000>; /* input clock */
154 154
diff --git a/arch/powerpc/boot/dts/fsl/p1021mds.dts b/arch/powerpc/boot/dts/fsl/p1021mds.dts
index 27fdfd7dc7c7..291454c75dda 100644
--- a/arch/powerpc/boot/dts/fsl/p1021mds.dts
+++ b/arch/powerpc/boot/dts/fsl/p1021mds.dts
@@ -123,7 +123,7 @@
123 flash@0 { 123 flash@0 {
124 #address-cells = <1>; 124 #address-cells = <1>;
125 #size-cells = <1>; 125 #size-cells = <1>;
126 compatible = "spansion,s25sl12801"; 126 compatible = "spansion,s25sl12801", "jedec,spi-nor";
127 reg = <0>; 127 reg = <0>;
128 spi-max-frequency = <40000000>; /* input clock */ 128 spi-max-frequency = <40000000>; /* input clock */
129 129
diff --git a/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi b/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi
index e8a0f95fb24a..18f9b31602d0 100644
--- a/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi
@@ -150,7 +150,7 @@
150 flash@0 { 150 flash@0 {
151 #address-cells = <1>; 151 #address-cells = <1>;
152 #size-cells = <1>; 152 #size-cells = <1>;
153 compatible = "spansion,s25sl12801"; 153 compatible = "spansion,s25sl12801", "jedec,spi-nor";
154 reg = <0>; 154 reg = <0>;
155 spi-max-frequency = <40000000>; /* input clock */ 155 spi-max-frequency = <40000000>; /* input clock */
156 156
diff --git a/arch/powerpc/boot/dts/fsl/p1022ds.dtsi b/arch/powerpc/boot/dts/fsl/p1022ds.dtsi
index 149da0f123ee..ddefbf64f7f8 100644
--- a/arch/powerpc/boot/dts/fsl/p1022ds.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1022ds.dtsi
@@ -160,7 +160,7 @@
160 flash@0 { 160 flash@0 {
161 #address-cells = <1>; 161 #address-cells = <1>;
162 #size-cells = <1>; 162 #size-cells = <1>;
163 compatible = "spansion,s25sl12801"; 163 compatible = "spansion,s25sl12801", "jedec,spi-nor";
164 reg = <0>; 164 reg = <0>;
165 spi-max-frequency = <40000000>; /* input clock */ 165 spi-max-frequency = <40000000>; /* input clock */
166 166
diff --git a/arch/powerpc/boot/dts/fsl/p1022rdk.dts b/arch/powerpc/boot/dts/fsl/p1022rdk.dts
index 04c16337268a..d505d7c51903 100644
--- a/arch/powerpc/boot/dts/fsl/p1022rdk.dts
+++ b/arch/powerpc/boot/dts/fsl/p1022rdk.dts
@@ -86,7 +86,7 @@
86 flash@0 { 86 flash@0 {
87 #address-cells = <1>; 87 #address-cells = <1>;
88 #size-cells = <1>; 88 #size-cells = <1>;
89 compatible = "spansion,m25p80"; 89 compatible = "spansion,m25p80", "jedec,spi-nor";
90 reg = <0>; 90 reg = <0>;
91 spi-max-frequency = <1000000>; 91 spi-max-frequency = <1000000>;
92 partition@0 { 92 partition@0 {
diff --git a/arch/powerpc/boot/dts/fsl/p1024rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1024rdb.dtsi
index b05dcb40f800..b4d05867f707 100644
--- a/arch/powerpc/boot/dts/fsl/p1024rdb.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1024rdb.dtsi
@@ -129,7 +129,7 @@
129 flash@0 { 129 flash@0 {
130 #address-cells = <1>; 130 #address-cells = <1>;
131 #size-cells = <1>; 131 #size-cells = <1>;
132 compatible = "spansion,m25p80"; 132 compatible = "spansion,m25p80", "jedec,spi-nor";
133 reg = <0>; 133 reg = <0>;
134 spi-max-frequency = <40000000>; 134 spi-max-frequency = <40000000>;
135 135
diff --git a/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi
index f50256482297..d44bb12debb0 100644
--- a/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi
@@ -137,7 +137,7 @@
137 flash@0 { 137 flash@0 {
138 #address-cells = <1>; 138 #address-cells = <1>;
139 #size-cells = <1>; 139 #size-cells = <1>;
140 compatible = "spansion,s25sl12801"; 140 compatible = "spansion,s25sl12801", "jedec,spi-nor";
141 reg = <0>; 141 reg = <0>;
142 spi-max-frequency = <40000000>; /* input clock */ 142 spi-max-frequency = <40000000>; /* input clock */
143 143
diff --git a/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi b/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi
index ad2e242365cc..03c9afc82436 100644
--- a/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi
@@ -151,7 +151,7 @@
151 flash@0 { 151 flash@0 {
152 #address-cells = <1>; 152 #address-cells = <1>;
153 #size-cells = <1>; 153 #size-cells = <1>;
154 compatible = "spansion,m25p80"; 154 compatible = "spansion,m25p80", "jedec,spi-nor";
155 reg = <0>; 155 reg = <0>;
156 spi-max-frequency = <40000000>; 156 spi-max-frequency = <40000000>;
157 157
diff --git a/arch/powerpc/boot/dts/fsl/p2020rdb.dts b/arch/powerpc/boot/dts/fsl/p2020rdb.dts
index 70cf09019ce5..435a319958cb 100644
--- a/arch/powerpc/boot/dts/fsl/p2020rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/p2020rdb.dts
@@ -155,7 +155,7 @@
155 flash@0 { 155 flash@0 {
156 #address-cells = <1>; 156 #address-cells = <1>;
157 #size-cells = <1>; 157 #size-cells = <1>;
158 compatible = "spansion,s25sl12801"; 158 compatible = "spansion,s25sl12801", "jedec,spi-nor";
159 reg = <0>; 159 reg = <0>;
160 spi-max-frequency = <40000000>; 160 spi-max-frequency = <40000000>;
161 161
diff --git a/arch/powerpc/boot/dts/fsl/p2041rdb.dts b/arch/powerpc/boot/dts/fsl/p2041rdb.dts
index e9bd89406c4c..e50fea95a853 100644
--- a/arch/powerpc/boot/dts/fsl/p2041rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/p2041rdb.dts
@@ -1,7 +1,7 @@
1/* 1/*
2 * P2041RDB Device Tree Source 2 * P2041RDB Device Tree Source
3 * 3 *
4 * Copyright 2011 - 2014 Freescale Semiconductor Inc. 4 * Copyright 2011 - 2015 Freescale Semiconductor Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -41,6 +41,19 @@
41 #size-cells = <2>; 41 #size-cells = <2>;
42 interrupt-parent = <&mpic>; 42 interrupt-parent = <&mpic>;
43 43
44 aliases {
45 phy_rgmii_0 = &phy_rgmii_0;
46 phy_rgmii_1 = &phy_rgmii_1;
47 phy_sgmii_2 = &phy_sgmii_2;
48 phy_sgmii_3 = &phy_sgmii_3;
49 phy_sgmii_4 = &phy_sgmii_4;
50 phy_sgmii_1c = &phy_sgmii_1c;
51 phy_sgmii_1d = &phy_sgmii_1d;
52 phy_sgmii_1e = &phy_sgmii_1e;
53 phy_sgmii_1f = &phy_sgmii_1f;
54 phy_xgmii_2 = &phy_xgmii_2;
55 };
56
44 memory { 57 memory {
45 device_type = "memory"; 58 device_type = "memory";
46 }; 59 };
@@ -83,7 +96,7 @@
83 flash@0 { 96 flash@0 {
84 #address-cells = <1>; 97 #address-cells = <1>;
85 #size-cells = <1>; 98 #size-cells = <1>;
86 compatible = "spansion,s25sl12801"; 99 compatible = "spansion,s25sl12801", "jedec,spi-nor";
87 reg = <0>; 100 reg = <0>;
88 spi-max-frequency = <40000000>; /* input clock */ 101 spi-max-frequency = <40000000>; /* input clock */
89 partition@u-boot { 102 partition@u-boot {
@@ -137,6 +150,83 @@
137 usb1: usb@211000 { 150 usb1: usb@211000 {
138 dr_mode = "host"; 151 dr_mode = "host";
139 }; 152 };
153
154 fman@400000 {
155 ethernet@e0000 {
156 phy-handle = <&phy_sgmii_2>;
157 phy-connection-type = "sgmii";
158 };
159
160 mdio@e1120 {
161 phy_rgmii_0: ethernet-phy@0 {
162 reg = <0x0>;
163 };
164
165 phy_rgmii_1: ethernet-phy@1 {
166 reg = <0x1>;
167 };
168
169 phy_sgmii_2: ethernet-phy@2 {
170 reg = <0x2>;
171 };
172
173 phy_sgmii_3: ethernet-phy@3 {
174 reg = <0x3>;
175 };
176
177 phy_sgmii_4: ethernet-phy@4 {
178 reg = <0x4>;
179 };
180
181 phy_sgmii_1c: ethernet-phy@1c {
182 reg = <0x1c>;
183 };
184
185 phy_sgmii_1d: ethernet-phy@1d {
186 reg = <0x1d>;
187 };
188
189 phy_sgmii_1e: ethernet-phy@1e {
190 reg = <0x1e>;
191 };
192
193 phy_sgmii_1f: ethernet-phy@1f {
194 reg = <0x1f>;
195 };
196 };
197
198 ethernet@e2000 {
199 phy-handle = <&phy_sgmii_3>;
200 phy-connection-type = "sgmii";
201 };
202
203 ethernet@e4000 {
204 phy-handle = <&phy_sgmii_4>;
205 phy-connection-type = "sgmii";
206 };
207
208 ethernet@e6000 {
209 phy-handle = <&phy_rgmii_1>;
210 phy-connection-type = "rgmii";
211 };
212
213 ethernet@e8000 {
214 phy-handle = <&phy_rgmii_0>;
215 phy-connection-type = "rgmii";
216 };
217
218 ethernet@f0000 {
219 phy-handle = <&phy_xgmii_2>;
220 phy-connection-type = "xgmii";
221 };
222
223 mdio@f1000 {
224 phy_xgmii_2: ethernet-phy@0 {
225 compatible = "ethernet-phy-ieee802.3-c45";
226 reg = <0x0>;
227 };
228 };
229 };
140 }; 230 };
141 231
142 rio: rapidio@ffe0c0000 { 232 rio: rapidio@ffe0c0000 {
diff --git a/arch/powerpc/boot/dts/fsl/p3041ds.dts b/arch/powerpc/boot/dts/fsl/p3041ds.dts
index f2b1d40334d4..40748e415adb 100644
--- a/arch/powerpc/boot/dts/fsl/p3041ds.dts
+++ b/arch/powerpc/boot/dts/fsl/p3041ds.dts
@@ -1,7 +1,7 @@
1/* 1/*
2 * P3041DS Device Tree Source 2 * P3041DS Device Tree Source
3 * 3 *
4 * Copyright 2010 - 2014 Freescale Semiconductor Inc. 4 * Copyright 2010 - 2015 Freescale Semiconductor Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -41,6 +41,20 @@
41 #size-cells = <2>; 41 #size-cells = <2>;
42 interrupt-parent = <&mpic>; 42 interrupt-parent = <&mpic>;
43 43
44 aliases{
45 phy_rgmii_0 = &phy_rgmii_0;
46 phy_rgmii_1 = &phy_rgmii_1;
47 phy_sgmii_1c = &phy_sgmii_1c;
48 phy_sgmii_1d = &phy_sgmii_1d;
49 phy_sgmii_1e = &phy_sgmii_1e;
50 phy_sgmii_1f = &phy_sgmii_1f;
51 phy_xgmii_1 = &phy_xgmii_1;
52 phy_xgmii_2 = &phy_xgmii_2;
53 emi1_rgmii = &hydra_mdio_rgmii;
54 emi1_sgmii = &hydra_mdio_sgmii;
55 emi2_xgmii = &hydra_mdio_xgmii;
56 };
57
44 memory { 58 memory {
45 device_type = "memory"; 59 device_type = "memory";
46 }; 60 };
@@ -83,7 +97,7 @@
83 flash@0 { 97 flash@0 {
84 #address-cells = <1>; 98 #address-cells = <1>;
85 #size-cells = <1>; 99 #size-cells = <1>;
86 compatible = "spansion,s25sl12801"; 100 compatible = "spansion,s25sl12801", "jedec,spi-nor";
87 reg = <0>; 101 reg = <0>;
88 spi-max-frequency = <35000000>; /* input clock */ 102 spi-max-frequency = <35000000>; /* input clock */
89 partition@u-boot { 103 partition@u-boot {
@@ -150,6 +164,52 @@
150 reg = <0x4c>; 164 reg = <0x4c>;
151 }; 165 };
152 }; 166 };
167
168 fman@400000{
169 ethernet@e0000 {
170 phy-handle = <&phy_sgmii_1c>;
171 phy-connection-type = "sgmii";
172 };
173
174 ethernet@e2000 {
175 phy-handle = <&phy_sgmii_1d>;
176 phy-connection-type = "sgmii";
177 };
178
179 ethernet@e4000 {
180 phy-handle = <&phy_sgmii_1e>;
181 phy-connection-type = "sgmii";
182 };
183
184 ethernet@e6000 {
185 phy-handle = <&phy_sgmii_1f>;
186 phy-connection-type = "sgmii";
187 };
188
189 ethernet@e8000 {
190 phy-handle = <&phy_rgmii_1>;
191 phy-connection-type = "rgmii";
192 };
193
194 ethernet@f0000 {
195 phy-handle = <&phy_xgmii_1>;
196 phy-connection-type = "xgmii";
197 };
198
199 hydra_mdio_xgmii: mdio@f1000 {
200 status = "disabled";
201
202 phy_xgmii_1: ethernet-phy@4 {
203 compatible = "ethernet-phy-ieee802.3-c45";
204 reg = <0x4>;
205 };
206
207 phy_xgmii_2: ethernet-phy@0 {
208 compatible = "ethernet-phy-ieee802.3-c45";
209 reg = <0x0>;
210 };
211 };
212 };
153 }; 213 };
154 214
155 rio: rapidio@ffe0c0000 { 215 rio: rapidio@ffe0c0000 {
@@ -215,8 +275,58 @@
215 }; 275 };
216 276
217 board-control@3,0 { 277 board-control@3,0 {
278 #address-cells = <1>;
279 #size-cells = <1>;
218 compatible = "fsl,p3041ds-fpga", "fsl,fpga-ngpixis"; 280 compatible = "fsl,p3041ds-fpga", "fsl,fpga-ngpixis";
219 reg = <3 0 0x30>; 281 reg = <3 0 0x30>;
282 ranges = <0 3 0 0x30>;
283
284 mdio-mux-emi1 {
285 #address-cells = <1>;
286 #size-cells = <0>;
287 compatible = "mdio-mux-mmioreg", "mdio-mux";
288 mdio-parent-bus = <&mdio0>;
289 reg = <9 1>;
290 mux-mask = <0x78>;
291
292 hydra_mdio_rgmii: rgmii-mdio@8 {
293 #address-cells = <1>;
294 #size-cells = <0>;
295 reg = <8>;
296 status = "disabled";
297
298 phy_rgmii_0: ethernet-phy@0 {
299 reg = <0x0>;
300 };
301
302 phy_rgmii_1: ethernet-phy@1 {
303 reg = <0x1>;
304 };
305 };
306
307 hydra_mdio_sgmii: sgmii-mdio@28 {
308 #address-cells = <1>;
309 #size-cells = <0>;
310 reg = <0x28>;
311 status = "disabled";
312
313 phy_sgmii_1c: ethernet-phy@1c {
314 reg = <0x1c>;
315 };
316
317 phy_sgmii_1d: ethernet-phy@1d {
318 reg = <0x1d>;
319 };
320
321 phy_sgmii_1e: ethernet-phy@1e {
322 reg = <0x1e>;
323 };
324
325 phy_sgmii_1f: ethernet-phy@1f {
326 reg = <0x1f>;
327 };
328 };
329 };
220 }; 330 };
221 }; 331 };
222 332
diff --git a/arch/powerpc/boot/dts/fsl/p4080ds.dts b/arch/powerpc/boot/dts/fsl/p4080ds.dts
index 28a55c5e7099..816b9788d5f6 100644
--- a/arch/powerpc/boot/dts/fsl/p4080ds.dts
+++ b/arch/powerpc/boot/dts/fsl/p4080ds.dts
@@ -1,7 +1,7 @@
1/* 1/*
2 * P4080DS Device Tree Source 2 * P4080DS Device Tree Source
3 * 3 *
4 * Copyright 2009 - 2014 Freescale Semiconductor Inc. 4 * Copyright 2009 - 2015 Freescale Semiconductor Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -41,6 +41,20 @@
41 #size-cells = <2>; 41 #size-cells = <2>;
42 interrupt-parent = <&mpic>; 42 interrupt-parent = <&mpic>;
43 43
44 aliases {
45 phy_rgmii = &phyrgmii;
46 phy5_slot3 = &phy5slot3;
47 phy6_slot3 = &phy6slot3;
48 phy7_slot3 = &phy7slot3;
49 phy8_slot3 = &phy8slot3;
50 emi1_slot3 = &p4080mdio2;
51 emi1_slot4 = &p4080mdio1;
52 emi1_slot5 = &p4080mdio3;
53 emi1_rgmii = &p4080mdio0;
54 emi2_slot4 = &p4080xmdio1;
55 emi2_slot5 = &p4080xmdio3;
56 };
57
44 memory { 58 memory {
45 device_type = "memory"; 59 device_type = "memory";
46 }; 60 };
@@ -84,7 +98,7 @@
84 flash@0 { 98 flash@0 {
85 #address-cells = <1>; 99 #address-cells = <1>;
86 #size-cells = <1>; 100 #size-cells = <1>;
87 compatible = "spansion,s25sl12801"; 101 compatible = "spansion,s25sl12801", "jedec,spi-nor";
88 reg = <0>; 102 reg = <0>;
89 spi-max-frequency = <40000000>; /* input clock */ 103 spi-max-frequency = <40000000>; /* input clock */
90 partition@u-boot { 104 partition@u-boot {
@@ -137,6 +151,60 @@
137 dr_mode = "host"; 151 dr_mode = "host";
138 phy_type = "ulpi"; 152 phy_type = "ulpi";
139 }; 153 };
154
155 fman@400000 {
156 ethernet@e0000 {
157 phy-handle = <&phy0>;
158 phy-connection-type = "sgmii";
159 };
160
161 ethernet@e2000 {
162 phy-handle = <&phy1>;
163 phy-connection-type = "sgmii";
164 };
165
166 ethernet@e4000 {
167 phy-handle = <&phy2>;
168 phy-connection-type = "sgmii";
169 };
170
171 ethernet@e6000 {
172 phy-handle = <&phy3>;
173 phy-connection-type = "sgmii";
174 };
175
176 ethernet@f0000 {
177 phy-handle = <&phy10>;
178 phy-connection-type = "xgmii";
179 };
180 };
181
182 fman@500000 {
183 ethernet@e0000 {
184 phy-handle = <&phy5>;
185 phy-connection-type = "sgmii";
186 };
187
188 ethernet@e2000 {
189 phy-handle = <&phy6>;
190 phy-connection-type = "sgmii";
191 };
192
193 ethernet@e4000 {
194 phy-handle = <&phy7>;
195 phy-connection-type = "sgmii";
196 };
197
198 ethernet@e6000 {
199 phy-handle = <&phy8>;
200 phy-connection-type = "sgmii";
201 };
202
203 ethernet@f0000 {
204 phy-handle = <&phy11>;
205 phy-connection-type = "xgmii";
206 };
207 };
140 }; 208 };
141 209
142 rio: rapidio@ffe0c0000 { 210 rio: rapidio@ffe0c0000 {
@@ -213,6 +281,120 @@
213 }; 281 };
214 }; 282 };
215 283
284 mdio-mux-emi1 {
285 #address-cells = <1>;
286 #size-cells = <0>;
287 compatible = "mdio-mux-gpio", "mdio-mux";
288 mdio-parent-bus = <&mdio0>;
289 gpios = <&gpio0 1 0>, <&gpio0 0 0>;
290
291 p4080mdio0: mdio@0 {
292 #address-cells = <1>;
293 #size-cells = <0>;
294 reg = <0>;
295
296 phyrgmii: ethernet-phy@0 {
297 reg = <0x0>;
298 };
299 };
300
301 p4080mdio1: mdio@1 {
302 #address-cells = <1>;
303 #size-cells = <0>;
304 reg = <1>;
305
306 phy5: ethernet-phy@1c {
307 reg = <0x1c>;
308 };
309
310 phy6: ethernet-phy@1d {
311 reg = <0x1d>;
312 };
313
314 phy7: ethernet-phy@1e {
315 reg = <0x1e>;
316 };
317
318 phy8: ethernet-phy@1f {
319 reg = <0x1f>;
320 };
321 };
322
323 p4080mdio2: mdio@2 {
324 #address-cells = <1>;
325 #size-cells = <0>;
326 reg = <2>;
327 status = "disabled";
328
329 phy5slot3: ethernet-phy@1c {
330 reg = <0x1c>;
331 };
332
333 phy6slot3: ethernet-phy@1d {
334 reg = <0x1d>;
335 };
336
337 phy7slot3: ethernet-phy@1e {
338 reg = <0x1e>;
339 };
340
341 phy8slot3: ethernet-phy@1f {
342 reg = <0x1f>;
343 };
344 };
345
346 p4080mdio3: mdio@3 {
347 #address-cells = <1>;
348 #size-cells = <0>;
349 reg = <3>;
350
351 phy0: ethernet-phy@1c {
352 reg = <0x1c>;
353 };
354
355 phy1: ethernet-phy@1d {
356 reg = <0x1d>;
357 };
358
359 phy2: ethernet-phy@1e {
360 reg = <0x1e>;
361 };
362
363 phy3: ethernet-phy@1f {
364 reg = <0x1f>;
365 };
366 };
367 };
368
369 mdio-mux-emi2 {
370 #address-cells = <1>;
371 #size-cells = <0>;
372 compatible = "mdio-mux-gpio", "mdio-mux";
373 mdio-parent-bus = <&xmdio0>;
374 gpios = <&gpio0 3 0>, <&gpio0 2 0>;
375
376 p4080xmdio1: mdio@1 {
377 #address-cells = <1>;
378 #size-cells = <0>;
379 reg = <1>;
380
381 phy11: ethernet-phy@0 {
382 compatible = "ethernet-phy-ieee802.3-c45";
383 reg = <0x0>;
384 };
385 };
386
387 p4080xmdio3: mdio@3 {
388 #address-cells = <1>;
389 #size-cells = <0>;
390 reg = <3>;
391
392 phy10: ethernet-phy@4 {
393 compatible = "ethernet-phy-ieee802.3-c45";
394 reg = <0x4>;
395 };
396 };
397 };
216}; 398};
217 399
218/include/ "p4080si-post.dtsi" 400/include/ "p4080si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p5020ds.dts b/arch/powerpc/boot/dts/fsl/p5020ds.dts
index 920dc77b9c43..cd6f37386111 100644
--- a/arch/powerpc/boot/dts/fsl/p5020ds.dts
+++ b/arch/powerpc/boot/dts/fsl/p5020ds.dts
@@ -1,7 +1,7 @@
1/* 1/*
2 * P5020DS Device Tree Source 2 * P5020DS Device Tree Source
3 * 3 *
4 * Copyright 2010 - 2014 Freescale Semiconductor Inc. 4 * Copyright 2010 - 2015 Freescale Semiconductor Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -41,6 +41,20 @@
41 #size-cells = <2>; 41 #size-cells = <2>;
42 interrupt-parent = <&mpic>; 42 interrupt-parent = <&mpic>;
43 43
44 aliases {
45 phy_rgmii_0 = &phy_rgmii_0;
46 phy_rgmii_1 = &phy_rgmii_1;
47 phy_sgmii_1c = &phy_sgmii_1c;
48 phy_sgmii_1d = &phy_sgmii_1d;
49 phy_sgmii_1e = &phy_sgmii_1e;
50 phy_sgmii_1f = &phy_sgmii_1f;
51 phy_xgmii_1 = &phy_xgmii_1;
52 phy_xgmii_2 = &phy_xgmii_2;
53 emi1_rgmii = &hydra_mdio_rgmii;
54 emi1_sgmii = &hydra_mdio_sgmii;
55 emi2_xgmii = &hydra_mdio_xgmii;
56 };
57
44 memory { 58 memory {
45 device_type = "memory"; 59 device_type = "memory";
46 }; 60 };
@@ -83,7 +97,7 @@
83 flash@0 { 97 flash@0 {
84 #address-cells = <1>; 98 #address-cells = <1>;
85 #size-cells = <1>; 99 #size-cells = <1>;
86 compatible = "spansion,s25sl12801"; 100 compatible = "spansion,s25sl12801", "jedec,spi-nor";
87 reg = <0>; 101 reg = <0>;
88 spi-max-frequency = <40000000>; /* input clock */ 102 spi-max-frequency = <40000000>; /* input clock */
89 partition@u-boot { 103 partition@u-boot {
@@ -150,6 +164,52 @@
150 reg = <0x4c>; 164 reg = <0x4c>;
151 }; 165 };
152 }; 166 };
167
168 fman@400000 {
169 ethernet@e0000 {
170 phy-handle = <&phy_sgmii_1c>;
171 phy-connection-type = "sgmii";
172 };
173
174 ethernet@e2000 {
175 phy-handle = <&phy_sgmii_1d>;
176 phy-connection-type = "sgmii";
177 };
178
179 ethernet@e4000 {
180 phy-handle = <&phy_sgmii_1e>;
181 phy-connection-type = "sgmii";
182 };
183
184 ethernet@e6000 {
185 phy-handle = <&phy_sgmii_1f>;
186 phy-connection-type = "sgmii";
187 };
188
189 ethernet@e8000 {
190 phy-handle = <&phy_rgmii_1>;
191 phy-connection-type = "rgmii";
192 };
193
194 ethernet@f0000 {
195 phy-handle = <&phy_xgmii_1>;
196 phy-connection-type = "xgmii";
197 };
198
199 hydra_mdio_xgmii: mdio@f1000 {
200 status = "disabled";
201
202 phy_xgmii_1: ethernet-phy@4 {
203 compatible = "ethernet-phy-ieee802.3-c45";
204 reg = <0x4>;
205 };
206
207 phy_xgmii_2: ethernet-phy@0 {
208 compatible = "ethernet-phy-ieee802.3-c45";
209 reg = <0x0>;
210 };
211 };
212 };
153 }; 213 };
154 214
155 rio: rapidio@ffe0c0000 { 215 rio: rapidio@ffe0c0000 {
@@ -215,8 +275,58 @@
215 }; 275 };
216 276
217 board-control@3,0 { 277 board-control@3,0 {
278 #address-cells = <1>;
279 #size-cells = <1>;
218 compatible = "fsl,p5020ds-fpga", "fsl,fpga-ngpixis"; 280 compatible = "fsl,p5020ds-fpga", "fsl,fpga-ngpixis";
219 reg = <3 0 0x30>; 281 reg = <3 0 0x30>;
282 ranges = <0 3 0 0x30>;
283
284 mdio-mux-emi1 {
285 #address-cells = <1>;
286 #size-cells = <0>;
287 compatible = "mdio-mux-mmioreg", "mdio-mux";
288 mdio-parent-bus = <&mdio0>;
289 reg = <9 1>;
290 mux-mask = <0x78>;
291
292 hydra_mdio_rgmii: rgmii-mdio@8 {
293 #address-cells = <1>;
294 #size-cells = <0>;
295 reg = <8>;
296 status = "disabled";
297
298 phy_rgmii_0: ethernet-phy@0 {
299 reg = <0x0>;
300 };
301
302 phy_rgmii_1: ethernet-phy@1 {
303 reg = <0x1>;
304 };
305 };
306
307 hydra_mdio_sgmii: sgmii-mdio@28 {
308 #address-cells = <1>;
309 #size-cells = <0>;
310 reg = <0x28>;
311 status = "disabled";
312
313 phy_sgmii_1c: ethernet-phy@1c {
314 reg = <0x1c>;
315 };
316
317 phy_sgmii_1d: ethernet-phy@1d {
318 reg = <0x1d>;
319 };
320
321 phy_sgmii_1e: ethernet-phy@1e {
322 reg = <0x1e>;
323 };
324
325 phy_sgmii_1f: ethernet-phy@1f {
326 reg = <0x1f>;
327 };
328 };
329 };
220 }; 330 };
221 }; 331 };
222 332
diff --git a/arch/powerpc/boot/dts/fsl/p5040ds.dts b/arch/powerpc/boot/dts/fsl/p5040ds.dts
index e169cc297ea3..45084738cf4e 100644
--- a/arch/powerpc/boot/dts/fsl/p5040ds.dts
+++ b/arch/powerpc/boot/dts/fsl/p5040ds.dts
@@ -1,7 +1,7 @@
1/* 1/*
2 * P5040DS Device Tree Source 2 * P5040DS Device Tree Source
3 * 3 *
4 * Copyright 2012 - 2014 Freescale Semiconductor Inc. 4 * Copyright 2012 - 2015 Freescale Semiconductor Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -41,6 +41,32 @@
41 #size-cells = <2>; 41 #size-cells = <2>;
42 interrupt-parent = <&mpic>; 42 interrupt-parent = <&mpic>;
43 43
44 aliases{
45 phy_sgmii_slot2_1c = &phy_sgmii_slot2_1c;
46 phy_sgmii_slot2_1d = &phy_sgmii_slot2_1d;
47 phy_sgmii_slot2_1e = &phy_sgmii_slot2_1e;
48 phy_sgmii_slot2_1f = &phy_sgmii_slot2_1f;
49 phy_sgmii_slot3_1c = &phy_sgmii_slot3_1c;
50 phy_sgmii_slot3_1d = &phy_sgmii_slot3_1d;
51 phy_sgmii_slot3_1e = &phy_sgmii_slot3_1e;
52 phy_sgmii_slot3_1f = &phy_sgmii_slot3_1f;
53 phy_sgmii_slot5_1c = &phy_sgmii_slot5_1c;
54 phy_sgmii_slot5_1d = &phy_sgmii_slot5_1d;
55 phy_sgmii_slot5_1e = &phy_sgmii_slot5_1e;
56 phy_sgmii_slot5_1f = &phy_sgmii_slot5_1f;
57 phy_sgmii_slot6_1c = &phy_sgmii_slot6_1c;
58 phy_sgmii_slot6_1d = &phy_sgmii_slot6_1d;
59 phy_sgmii_slot6_1e = &phy_sgmii_slot6_1e;
60 phy_sgmii_slot6_1f = &phy_sgmii_slot6_1f;
61 hydra_rg = &hydra_rg;
62 hydra_sg_slot2 = &hydra_sg_slot2;
63 hydra_sg_slot3 = &hydra_sg_slot3;
64 hydra_sg_slot5 = &hydra_sg_slot5;
65 hydra_sg_slot6 = &hydra_sg_slot6;
66 hydra_xg_slot1 = &hydra_xg_slot1;
67 hydra_xg_slot2 = &hydra_xg_slot2;
68 };
69
44 memory { 70 memory {
45 device_type = "memory"; 71 device_type = "memory";
46 }; 72 };
@@ -83,7 +109,7 @@
83 flash@0 { 109 flash@0 {
84 #address-cells = <1>; 110 #address-cells = <1>;
85 #size-cells = <1>; 111 #size-cells = <1>;
86 compatible = "spansion,s25sl12801"; 112 compatible = "spansion,s25sl12801", "jedec,spi-nor";
87 reg = <0>; 113 reg = <0>;
88 spi-max-frequency = <40000000>; /* input clock */ 114 spi-max-frequency = <40000000>; /* input clock */
89 partition@u-boot { 115 partition@u-boot {
@@ -147,6 +173,62 @@
147 reg = <0x4c>; 173 reg = <0x4c>;
148 }; 174 };
149 }; 175 };
176
177 fman@400000 {
178 ethernet@e0000 {
179 phy-connection-type = "sgmii";
180 };
181
182 ethernet@e2000 {
183 phy-connection-type = "sgmii";
184 };
185
186 ethernet@e4000 {
187 phy-connection-type = "sgmii";
188 };
189
190 ethernet@e6000 {
191 phy-connection-type = "sgmii";
192 };
193
194 ethernet@e8000 {
195 phy-handle = <&phy_rgmii_0>;
196 phy-connection-type = "rgmii";
197 };
198
199 ethernet@f0000 {
200 phy-handle = <&phy_xgmii_slot_2>;
201 phy-connection-type = "xgmii";
202 };
203 };
204
205 fman@500000 {
206 ethernet@e0000 {
207 phy-connection-type = "sgmii";
208 };
209
210 ethernet@e2000 {
211 phy-connection-type = "sgmii";
212 };
213
214 ethernet@e4000 {
215 phy-connection-type = "sgmii";
216 };
217
218 ethernet@e6000 {
219 phy-connection-type = "sgmii";
220 };
221
222 ethernet@e8000 {
223 phy-handle = <&phy_rgmii_1>;
224 phy-connection-type = "rgmii";
225 };
226
227 ethernet@f0000 {
228 phy-handle = <&phy_xgmii_slot_1>;
229 phy-connection-type = "xgmii";
230 };
231 };
150 }; 232 };
151 233
152 lbc: localbus@ffe124000 { 234 lbc: localbus@ffe124000 {
@@ -200,8 +282,158 @@
200 }; 282 };
201 283
202 board-control@3,0 { 284 board-control@3,0 {
285 #address-cells = <1>;
286 #size-cells = <1>;
203 compatible = "fsl,p5040ds-fpga", "fsl,fpga-ngpixis"; 287 compatible = "fsl,p5040ds-fpga", "fsl,fpga-ngpixis";
204 reg = <3 0 0x40>; 288 reg = <3 0 0x40>;
289 ranges = <0 3 0 0x40>;
290
291 mdio-mux-emi1 {
292 #address-cells = <1>;
293 #size-cells = <0>;
294 compatible = "mdio-mux-mmioreg", "mdio-mux";
295 mdio-parent-bus = <&mdio0>;
296 reg = <9 1>;
297 mux-mask = <0x78>;
298
299 hydra_rg:rgmii-mdio@8 {
300 #address-cells = <1>;
301 #size-cells = <0>;
302 reg = <8>;
303 status = "disabled";
304
305 phy_rgmii_0: ethernet-phy@0 {
306 reg = <0x0>;
307 };
308
309 phy_rgmii_1: ethernet-phy@1 {
310 reg = <0x1>;
311 };
312 };
313
314 hydra_sg_slot2: sgmii-mdio@28 {
315 #address-cells = <1>;
316 #size-cells = <0>;
317 reg = <0x28>;
318 status = "disabled";
319
320 phy_sgmii_slot2_1c: ethernet-phy@1c {
321 reg = <0x1c>;
322 };
323
324 phy_sgmii_slot2_1d: ethernet-phy@1d {
325 reg = <0x1d>;
326 };
327
328 phy_sgmii_slot2_1e: ethernet-phy@1e {
329 reg = <0x1e>;
330 };
331
332 phy_sgmii_slot2_1f: ethernet-phy@1f {
333 reg = <0x1f>;
334 };
335 };
336
337 hydra_sg_slot3: sgmii-mdio@68 {
338 #address-cells = <1>;
339 #size-cells = <0>;
340 reg = <0x68>;
341 status = "disabled";
342
343 phy_sgmii_slot3_1c: ethernet-phy@1c {
344 reg = <0x1c>;
345 };
346
347 phy_sgmii_slot3_1d: ethernet-phy@1d {
348 reg = <0x1d>;
349 };
350
351 phy_sgmii_slot3_1e: ethernet-phy@1e {
352 reg = <0x1e>;
353 };
354
355 phy_sgmii_slot3_1f: ethernet-phy@1f {
356 reg = <0x1f>;
357 };
358 };
359
360 hydra_sg_slot5: sgmii-mdio@38 {
361 #address-cells = <1>;
362 #size-cells = <0>;
363 reg = <0x38>;
364 status = "disabled";
365
366 phy_sgmii_slot5_1c: ethernet-phy@1c {
367 reg = <0x1c>;
368 };
369
370 phy_sgmii_slot5_1d: ethernet-phy@1d {
371 reg = <0x1d>;
372 };
373
374 phy_sgmii_slot5_1e: ethernet-phy@1e {
375 reg = <0x1e>;
376 };
377
378 phy_sgmii_slot5_1f: ethernet-phy@1f {
379 reg = <0x1f>;
380 };
381 };
382 hydra_sg_slot6: sgmii-mdio@48 {
383 #address-cells = <1>;
384 #size-cells = <0>;
385 reg = <0x48>;
386 status = "disabled";
387
388 phy_sgmii_slot6_1c: ethernet-phy@1c {
389 reg = <0x1c>;
390 };
391
392 phy_sgmii_slot6_1d: ethernet-phy@1d {
393 reg = <0x1d>;
394 };
395
396 phy_sgmii_slot6_1e: ethernet-phy@1e {
397 reg = <0x1e>;
398 };
399
400 phy_sgmii_slot6_1f: ethernet-phy@1f {
401 reg = <0x1f>;
402 };
403 };
404 };
405
406 mdio-mux-emi2 {
407 #address-cells = <1>;
408 #size-cells = <0>;
409 compatible = "mdio-mux-mmioreg", "mdio-mux";
410 mdio-parent-bus = <&xmdio0>;
411 reg = <9 1>;
412 mux-mask = <0x06>;
413
414 hydra_xg_slot1: hydra-xg-slot1@0 {
415 #address-cells = <1>;
416 #size-cells = <0>;
417 reg = <0>;
418 status = "disabled";
419
420 phy_xgmii_slot_1: ethernet-phy@0 {
421 compatible = "ethernet-phy-ieee802.3-c45";
422 reg = <4>;
423 };
424 };
425
426 hydra_xg_slot2: hydra-xg-slot2@2 {
427 #address-cells = <1>;
428 #size-cells = <0>;
429 reg = <2>;
430
431 phy_xgmii_slot_2: ethernet-phy@4 {
432 compatible = "ethernet-phy-ieee802.3-c45";
433 reg = <0>;
434 };
435 };
436 };
205 }; 437 };
206 }; 438 };
207 439
diff --git a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi
index 2f227b1345ad..e2bd9313e632 100644
--- a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi
@@ -420,6 +420,7 @@
420 fsl,iommu-parent = <&pamu4>; 420 fsl,iommu-parent = <&pamu4>;
421 }; 421 };
422 422
423/include/ "qoriq-raid1.0-0.dtsi"
423/include/ "qoriq-qman1.dtsi" 424/include/ "qoriq-qman1.dtsi"
424/include/ "qoriq-bman1.dtsi" 425/include/ "qoriq-bman1.dtsi"
425 426
diff --git a/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi
index 0659d5bb69b8..dbd57750fc02 100644
--- a/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi
@@ -73,6 +73,12 @@
73 rtic_d = &rtic_d; 73 rtic_d = &rtic_d;
74 sec_mon = &sec_mon; 74 sec_mon = &sec_mon;
75 75
76 raideng = &raideng;
77 raideng_jr0 = &raideng_jr0;
78 raideng_jr1 = &raideng_jr1;
79 raideng_jr2 = &raideng_jr2;
80 raideng_jr3 = &raideng_jr3;
81
76 fman0 = &fman0; 82 fman0 = &fman0;
77 fman1 = &fman1; 83 fman1 = &fman1;
78 ethernet0 = &enet0; 84 ethernet0 = &enet0;
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi
index 2e441fab6d8f..e1a961f05dcd 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi
@@ -55,6 +55,7 @@ fman@400000 {
55 reg = <0xe0000 0x1000>; 55 reg = <0xe0000 0x1000>;
56 fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>; 56 fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>;
57 ptp-timer = <&ptp_timer0>; 57 ptp-timer = <&ptp_timer0>;
58 pcsphy-handle = <&pcsphy0>;
58 }; 59 };
59 60
60 mdio@e1000 { 61 mdio@e1000 {
@@ -62,5 +63,9 @@ fman@400000 {
62 #size-cells = <0>; 63 #size-cells = <0>;
63 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 64 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
64 reg = <0xe1000 0x1000>; 65 reg = <0xe1000 0x1000>;
66
67 pcsphy0: ethernet-phy@0 {
68 reg = <0x0>;
69 };
65 }; 70 };
66}; 71};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi
index 0b8f87f79d15..c288f3c6c637 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi
@@ -52,6 +52,7 @@ fman@400000 {
52 compatible = "fsl,fman-memac"; 52 compatible = "fsl,fman-memac";
53 reg = <0xf0000 0x1000>; 53 reg = <0xf0000 0x1000>;
54 fsl,fman-ports = <&fman0_rx_0x10 &fman0_tx_0x30>; 54 fsl,fman-ports = <&fman0_rx_0x10 &fman0_tx_0x30>;
55 pcsphy-handle = <&pcsphy6>;
55 }; 56 };
56 57
57 mdio@f1000 { 58 mdio@f1000 {
@@ -59,5 +60,9 @@ fman@400000 {
59 #size-cells = <0>; 60 #size-cells = <0>;
60 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 61 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
61 reg = <0xf1000 0x1000>; 62 reg = <0xf1000 0x1000>;
63
64 pcsphy6: ethernet-phy@0 {
65 reg = <0x0>;
66 };
62 }; 67 };
63}; 68};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi
index ba6f2275d3f6..94f3e7175012 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi
@@ -55,6 +55,7 @@ fman@400000 {
55 reg = <0xe2000 0x1000>; 55 reg = <0xe2000 0x1000>;
56 fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>; 56 fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>;
57 ptp-timer = <&ptp_timer0>; 57 ptp-timer = <&ptp_timer0>;
58 pcsphy-handle = <&pcsphy1>;
58 }; 59 };
59 60
60 mdio@e3000 { 61 mdio@e3000 {
@@ -62,5 +63,9 @@ fman@400000 {
62 #size-cells = <0>; 63 #size-cells = <0>;
63 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 64 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
64 reg = <0xe3000 0x1000>; 65 reg = <0xe3000 0x1000>;
66
67 pcsphy1: ethernet-phy@0 {
68 reg = <0x0>;
69 };
65 }; 70 };
66}; 71};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi
index 886003805592..94a76982d214 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi
@@ -52,6 +52,7 @@ fman@400000 {
52 compatible = "fsl,fman-memac"; 52 compatible = "fsl,fman-memac";
53 reg = <0xf2000 0x1000>; 53 reg = <0xf2000 0x1000>;
54 fsl,fman-ports = <&fman0_rx_0x11 &fman0_tx_0x31>; 54 fsl,fman-ports = <&fman0_rx_0x11 &fman0_tx_0x31>;
55 pcsphy-handle = <&pcsphy7>;
55 }; 56 };
56 57
57 mdio@f3000 { 58 mdio@f3000 {
@@ -59,5 +60,9 @@ fman@400000 {
59 #size-cells = <0>; 60 #size-cells = <0>;
60 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 61 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
61 reg = <0xf3000 0x1000>; 62 reg = <0xf3000 0x1000>;
63
64 pcsphy7: ethernet-phy@0 {
65 reg = <0x0>;
66 };
62 }; 67 };
63}; 68};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi
index ace9c13648ce..b5ff5f71c6b8 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi
@@ -51,6 +51,7 @@ fman@400000 {
51 reg = <0xe0000 0x1000>; 51 reg = <0xe0000 0x1000>;
52 fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>; 52 fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>;
53 ptp-timer = <&ptp_timer0>; 53 ptp-timer = <&ptp_timer0>;
54 pcsphy-handle = <&pcsphy0>;
54 }; 55 };
55 56
56 mdio@e1000 { 57 mdio@e1000 {
@@ -58,5 +59,9 @@ fman@400000 {
58 #size-cells = <0>; 59 #size-cells = <0>;
59 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 60 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
60 reg = <0xe1000 0x1000>; 61 reg = <0xe1000 0x1000>;
62
63 pcsphy0: ethernet-phy@0 {
64 reg = <0x0>;
65 };
61 }; 66 };
62}; 67};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi
index a4fc28654b31..ee44182c6348 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi
@@ -51,6 +51,7 @@ fman@400000 {
51 reg = <0xe2000 0x1000>; 51 reg = <0xe2000 0x1000>;
52 fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>; 52 fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>;
53 ptp-timer = <&ptp_timer0>; 53 ptp-timer = <&ptp_timer0>;
54 pcsphy-handle = <&pcsphy1>;
54 }; 55 };
55 56
56 mdio@e3000 { 57 mdio@e3000 {
@@ -58,5 +59,9 @@ fman@400000 {
58 #size-cells = <0>; 59 #size-cells = <0>;
59 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 60 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
60 reg = <0xe3000 0x1000>; 61 reg = <0xe3000 0x1000>;
62
63 pcsphy1: ethernet-phy@0 {
64 reg = <0x0>;
65 };
61 }; 66 };
62}; 67};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi
index 78596faadf99..f05f0d775039 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi
@@ -51,6 +51,7 @@ fman@400000 {
51 reg = <0xe4000 0x1000>; 51 reg = <0xe4000 0x1000>;
52 fsl,fman-ports = <&fman0_rx_0x0a &fman0_tx_0x2a>; 52 fsl,fman-ports = <&fman0_rx_0x0a &fman0_tx_0x2a>;
53 ptp-timer = <&ptp_timer0>; 53 ptp-timer = <&ptp_timer0>;
54 pcsphy-handle = <&pcsphy2>;
54 }; 55 };
55 56
56 mdio@e5000 { 57 mdio@e5000 {
@@ -58,5 +59,9 @@ fman@400000 {
58 #size-cells = <0>; 59 #size-cells = <0>;
59 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 60 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
60 reg = <0xe5000 0x1000>; 61 reg = <0xe5000 0x1000>;
62
63 pcsphy2: ethernet-phy@0 {
64 reg = <0x0>;
65 };
61 }; 66 };
62}; 67};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi
index af93abd86d78..a9114ec51075 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi
@@ -51,6 +51,7 @@ fman@400000 {
51 reg = <0xe6000 0x1000>; 51 reg = <0xe6000 0x1000>;
52 fsl,fman-ports = <&fman0_rx_0x0b &fman0_tx_0x2b>; 52 fsl,fman-ports = <&fman0_rx_0x0b &fman0_tx_0x2b>;
53 ptp-timer = <&ptp_timer0>; 53 ptp-timer = <&ptp_timer0>;
54 pcsphy-handle = <&pcsphy3>;
54 }; 55 };
55 56
56 mdio@e7000 { 57 mdio@e7000 {
@@ -58,5 +59,9 @@ fman@400000 {
58 #size-cells = <0>; 59 #size-cells = <0>;
59 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 60 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
60 reg = <0xe7000 0x1000>; 61 reg = <0xe7000 0x1000>;
62
63 pcsphy3: ethernet-phy@0 {
64 reg = <0x0>;
65 };
61 }; 66 };
62}; 67};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi
index 97cffd74bf3d..44dd00ac7367 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi
@@ -51,6 +51,7 @@ fman@400000 {
51 reg = <0xe8000 0x1000>; 51 reg = <0xe8000 0x1000>;
52 fsl,fman-ports = <&fman0_rx_0x0c &fman0_tx_0x2c>; 52 fsl,fman-ports = <&fman0_rx_0x0c &fman0_tx_0x2c>;
53 ptp-timer = <&ptp_timer0>; 53 ptp-timer = <&ptp_timer0>;
54 pcsphy-handle = <&pcsphy4>;
54 }; 55 };
55 56
56 mdio@e9000 { 57 mdio@e9000 {
@@ -58,5 +59,9 @@ fman@400000 {
58 #size-cells = <0>; 59 #size-cells = <0>;
59 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 60 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
60 reg = <0xe9000 0x1000>; 61 reg = <0xe9000 0x1000>;
62
63 pcsphy4: ethernet-phy@0 {
64 reg = <0x0>;
65 };
61 }; 66 };
62}; 67};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi
index 232c5c277bdb..5b1b84b58602 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi
@@ -51,6 +51,7 @@ fman@400000 {
51 reg = <0xea000 0x1000>; 51 reg = <0xea000 0x1000>;
52 fsl,fman-ports = <&fman0_rx_0x0d &fman0_tx_0x2d>; 52 fsl,fman-ports = <&fman0_rx_0x0d &fman0_tx_0x2d>;
53 ptp-timer = <&ptp_timer0>; 53 ptp-timer = <&ptp_timer0>;
54 pcsphy-handle = <&pcsphy5>;
54 }; 55 };
55 56
56 mdio@eb000 { 57 mdio@eb000 {
@@ -58,5 +59,9 @@ fman@400000 {
58 #size-cells = <0>; 59 #size-cells = <0>;
59 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 60 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
60 reg = <0xeb000 0x1000>; 61 reg = <0xeb000 0x1000>;
62
63 pcsphy5: ethernet-phy@0 {
64 reg = <0x0>;
65 };
61 }; 66 };
62}; 67};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi
index 89d64ee282b0..0e1daaef9e74 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi
@@ -52,6 +52,7 @@ fman@500000 {
52 compatible = "fsl,fman-memac"; 52 compatible = "fsl,fman-memac";
53 reg = <0xf0000 0x1000>; 53 reg = <0xf0000 0x1000>;
54 fsl,fman-ports = <&fman1_rx_0x10 &fman1_tx_0x30>; 54 fsl,fman-ports = <&fman1_rx_0x10 &fman1_tx_0x30>;
55 pcsphy-handle = <&pcsphy14>;
55 }; 56 };
56 57
57 mdio@f1000 { 58 mdio@f1000 {
@@ -59,5 +60,9 @@ fman@500000 {
59 #size-cells = <0>; 60 #size-cells = <0>;
60 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 61 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
61 reg = <0xf1000 0x1000>; 62 reg = <0xf1000 0x1000>;
63
64 pcsphy14: ethernet-phy@0 {
65 reg = <0x0>;
66 };
62 }; 67 };
63}; 68};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi
index 7fa9260889c6..68c5ef779266 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi
@@ -52,6 +52,7 @@ fman@500000 {
52 compatible = "fsl,fman-memac"; 52 compatible = "fsl,fman-memac";
53 reg = <0xf2000 0x1000>; 53 reg = <0xf2000 0x1000>;
54 fsl,fman-ports = <&fman1_rx_0x11 &fman1_tx_0x31>; 54 fsl,fman-ports = <&fman1_rx_0x11 &fman1_tx_0x31>;
55 pcsphy-handle = <&pcsphy15>;
55 }; 56 };
56 57
57 mdio@f3000 { 58 mdio@f3000 {
@@ -59,5 +60,9 @@ fman@500000 {
59 #size-cells = <0>; 60 #size-cells = <0>;
60 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 61 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
61 reg = <0xf3000 0x1000>; 62 reg = <0xf3000 0x1000>;
63
64 pcsphy15: ethernet-phy@0 {
65 reg = <0x0>;
66 };
62 }; 67 };
63}; 68};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi
index 3d236662bf07..605363cc1117 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi
@@ -51,6 +51,7 @@ fman@500000 {
51 reg = <0xe0000 0x1000>; 51 reg = <0xe0000 0x1000>;
52 fsl,fman-ports = <&fman1_rx_0x08 &fman1_tx_0x28>; 52 fsl,fman-ports = <&fman1_rx_0x08 &fman1_tx_0x28>;
53 ptp-timer = <&ptp_timer1>; 53 ptp-timer = <&ptp_timer1>;
54 pcsphy-handle = <&pcsphy8>;
54 }; 55 };
55 56
56 mdio@e1000 { 57 mdio@e1000 {
@@ -58,5 +59,9 @@ fman@500000 {
58 #size-cells = <0>; 59 #size-cells = <0>;
59 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 60 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
60 reg = <0xe1000 0x1000>; 61 reg = <0xe1000 0x1000>;
62
63 pcsphy8: ethernet-phy@0 {
64 reg = <0x0>;
65 };
61 }; 66 };
62}; 67};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi
index 97dc2eedd462..1955dfa13634 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi
@@ -51,6 +51,7 @@ fman@500000 {
51 reg = <0xe2000 0x1000>; 51 reg = <0xe2000 0x1000>;
52 fsl,fman-ports = <&fman1_rx_0x09 &fman1_tx_0x29>; 52 fsl,fman-ports = <&fman1_rx_0x09 &fman1_tx_0x29>;
53 ptp-timer = <&ptp_timer1>; 53 ptp-timer = <&ptp_timer1>;
54 pcsphy-handle = <&pcsphy9>;
54 }; 55 };
55 56
56 mdio@e3000 { 57 mdio@e3000 {
@@ -58,5 +59,9 @@ fman@500000 {
58 #size-cells = <0>; 59 #size-cells = <0>;
59 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 60 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
60 reg = <0xe3000 0x1000>; 61 reg = <0xe3000 0x1000>;
62
63 pcsphy9: ethernet-phy@0 {
64 reg = <0x0>;
65 };
61 }; 66 };
62}; 67};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi
index f084dd2f0bec..2c1476454ee0 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi
@@ -51,6 +51,7 @@ fman@500000 {
51 reg = <0xe4000 0x1000>; 51 reg = <0xe4000 0x1000>;
52 fsl,fman-ports = <&fman1_rx_0x0a &fman1_tx_0x2a>; 52 fsl,fman-ports = <&fman1_rx_0x0a &fman1_tx_0x2a>;
53 ptp-timer = <&ptp_timer1>; 53 ptp-timer = <&ptp_timer1>;
54 pcsphy-handle = <&pcsphy10>;
54 }; 55 };
55 56
56 mdio@e5000 { 57 mdio@e5000 {
@@ -58,5 +59,9 @@ fman@500000 {
58 #size-cells = <0>; 59 #size-cells = <0>;
59 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 60 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
60 reg = <0xe5000 0x1000>; 61 reg = <0xe5000 0x1000>;
62
63 pcsphy10: ethernet-phy@0 {
64 reg = <0x0>;
65 };
61 }; 66 };
62}; 67};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi
index bb627b3bf3db..b8b541ff5fb0 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi
@@ -51,6 +51,7 @@ fman@500000 {
51 reg = <0xe6000 0x1000>; 51 reg = <0xe6000 0x1000>;
52 fsl,fman-ports = <&fman1_rx_0x0b &fman1_tx_0x2b>; 52 fsl,fman-ports = <&fman1_rx_0x0b &fman1_tx_0x2b>;
53 ptp-timer = <&ptp_timer1>; 53 ptp-timer = <&ptp_timer1>;
54 pcsphy-handle = <&pcsphy11>;
54 }; 55 };
55 56
56 mdio@e7000 { 57 mdio@e7000 {
@@ -58,5 +59,9 @@ fman@500000 {
58 #size-cells = <0>; 59 #size-cells = <0>;
59 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 60 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
60 reg = <0xe7000 0x1000>; 61 reg = <0xe7000 0x1000>;
62
63 pcsphy11: ethernet-phy@0 {
64 reg = <0x0>;
65 };
61 }; 66 };
62}; 67};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi
index 821ed12225d4..4b2cfddd1b15 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi
@@ -51,6 +51,7 @@ fman@500000 {
51 reg = <0xe8000 0x1000>; 51 reg = <0xe8000 0x1000>;
52 fsl,fman-ports = <&fman1_rx_0x0c &fman1_tx_0x2c>; 52 fsl,fman-ports = <&fman1_rx_0x0c &fman1_tx_0x2c>;
53 ptp-timer = <&ptp_timer1>; 53 ptp-timer = <&ptp_timer1>;
54 pcsphy-handle = <&pcsphy12>;
54 }; 55 };
55 56
56 mdio@e9000 { 57 mdio@e9000 {
@@ -58,5 +59,9 @@ fman@500000 {
58 #size-cells = <0>; 59 #size-cells = <0>;
59 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 60 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
60 reg = <0xe9000 0x1000>; 61 reg = <0xe9000 0x1000>;
62
63 pcsphy12: ethernet-phy@0 {
64 reg = <0x0>;
65 };
61 }; 66 };
62}; 67};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi
index e245f1a1e42a..0a52ddf7cc17 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi
@@ -51,6 +51,7 @@ fman@500000 {
51 reg = <0xea000 0x1000>; 51 reg = <0xea000 0x1000>;
52 fsl,fman-ports = <&fman1_rx_0x0d &fman1_tx_0x2d>; 52 fsl,fman-ports = <&fman1_rx_0x0d &fman1_tx_0x2d>;
53 ptp-timer = <&ptp_timer1>; 53 ptp-timer = <&ptp_timer1>;
54 pcsphy-handle = <&pcsphy13>;
54 }; 55 };
55 56
56 mdio@eb000 { 57 mdio@eb000 {
@@ -58,5 +59,9 @@ fman@500000 {
58 #size-cells = <0>; 59 #size-cells = <0>;
59 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; 60 compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
60 reg = <0xeb000 0x1000>; 61 reg = <0xeb000 0x1000>;
62
63 pcsphy13: ethernet-phy@0 {
64 reg = <0x0>;
65 };
61 }; 66 };
62}; 67};
diff --git a/arch/powerpc/boot/dts/fsl/sbc8641d.dts b/arch/powerpc/boot/dts/fsl/sbc8641d.dts
new file mode 100644
index 000000000000..0a9733cd418d
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/sbc8641d.dts
@@ -0,0 +1,203 @@
1/*
2 * SBC8641D Device Tree Source
3 *
4 * Copyright 2008 Wind River Systems Inc.
5 *
6 * Paul Gortmaker (see MAINTAINERS for contact information)
7 *
8 * Based largely on the mpc8641_hpcn.dts by Freescale Semiconductor Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16/include/ "mpc8641si-pre.dtsi"
17
18/ {
19 model = "SBC8641D";
20 compatible = "wind,sbc8641";
21
22 aliases {
23 pci1 = &pci1;
24 };
25
26 memory {
27 device_type = "memory";
28 reg = <0x00000000 0x20000000>; // 512M at 0x0
29 };
30
31 lbc: localbus@f8005000 {
32 reg = <0xf8005000 0x1000>;
33
34 ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
35 1 0 0xf0000000 0x00010000 // 64KB EEPROM
36 2 0 0xf1000000 0x00100000 // EPLD (1MB)
37 3 0 0xe0000000 0x04000000 // 64MB LB SDRAM (CS3)
38 4 0 0xe4000000 0x04000000 // 64MB LB SDRAM (CS4)
39 6 0 0xf4000000 0x00100000 // LCD display (1MB)
40 7 0 0xe8000000 0x04000000>; // 64MB OneNAND
41
42 flash@0,0 {
43 compatible = "cfi-flash";
44 reg = <0 0 0x01000000>;
45 bank-width = <2>;
46 device-width = <2>;
47 #address-cells = <1>;
48 #size-cells = <1>;
49 partition@0 {
50 label = "dtb";
51 reg = <0x00000000 0x00100000>;
52 read-only;
53 };
54 partition@300000 {
55 label = "kernel";
56 reg = <0x00100000 0x00400000>;
57 read-only;
58 };
59 partition@400000 {
60 label = "fs";
61 reg = <0x00500000 0x00a00000>;
62 };
63 partition@700000 {
64 label = "firmware";
65 reg = <0x00f00000 0x00100000>;
66 read-only;
67 };
68 };
69
70 epld@2,0 {
71 compatible = "wrs,epld-localbus";
72 #address-cells = <2>;
73 #size-cells = <1>;
74 reg = <2 0 0x100000>;
75 ranges = <0 0 5 0 1 // User switches
76 1 0 5 1 1 // Board ID/Rev
77 3 0 5 3 1>; // LEDs
78 };
79 };
80
81 soc: soc@f8000000 {
82 ranges = <0x00000000 0xf8000000 0x00100000>;
83
84 enet0: ethernet@24000 {
85 tbi-handle = <&tbi0>;
86 phy-handle = <&phy0>;
87 phy-connection-type = "rgmii-id";
88 };
89
90 mdio@24520 {
91 phy0: ethernet-phy@1f {
92 reg = <0x1f>;
93 };
94 phy1: ethernet-phy@0 {
95 reg = <0>;
96 };
97 phy2: ethernet-phy@1 {
98 reg = <1>;
99 };
100 phy3: ethernet-phy@2 {
101 reg = <2>;
102 };
103 tbi0: tbi-phy@11 {
104 reg = <0x11>;
105 device_type = "tbi-phy";
106 };
107 };
108
109 enet1: ethernet@25000 {
110 tbi-handle = <&tbi1>;
111 phy-handle = <&phy1>;
112 phy-connection-type = "rgmii-id";
113 };
114
115 mdio@25520 {
116 tbi1: tbi-phy@11 {
117 reg = <0x11>;
118 device_type = "tbi-phy";
119 };
120 };
121
122 enet2: ethernet@26000 {
123 tbi-handle = <&tbi2>;
124 phy-handle = <&phy2>;
125 phy-connection-type = "rgmii-id";
126 };
127
128 mdio@26520 {
129 tbi2: tbi-phy@11 {
130 reg = <0x11>;
131 device_type = "tbi-phy";
132 };
133 };
134
135 enet3: ethernet@27000 {
136 tbi-handle = <&tbi3>;
137 phy-handle = <&phy3>;
138 phy-connection-type = "rgmii-id";
139 };
140
141 mdio@27520 {
142 tbi3: tbi-phy@11 {
143 reg = <0x11>;
144 device_type = "tbi-phy";
145 };
146 };
147 };
148
149 pci0: pcie@f8008000 {
150 reg = <0xf8008000 0x1000>;
151 ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000
152 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
153 interrupt-map-mask = <0xff00 0 0 7>;
154
155 pcie@0 {
156 ranges = <0x02000000 0x0 0x80000000
157 0x02000000 0x0 0x80000000
158 0x0 0x20000000
159
160 0x01000000 0x0 0x00000000
161 0x01000000 0x0 0x00000000
162 0x0 0x00100000>;
163 };
164
165 };
166
167 pci1: pcie@f8009000 {
168 compatible = "fsl,mpc8641-pcie";
169 device_type = "pci";
170 #size-cells = <2>;
171 #address-cells = <3>;
172 reg = <0xf8009000 0x1000>;
173 bus-range = <0 0xff>;
174 ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000
175 0x01000000 0x0 0x00000000 0xe3000000 0x0 0x00100000>;
176 clock-frequency = <100000000>;
177 interrupts = <25 2 0 0>;
178 interrupt-map-mask = <0xf800 0 0 7>;
179 interrupt-map = <
180 /* IDSEL 0x0 */
181 0x0000 0 0 1 &mpic 4 1
182 0x0000 0 0 2 &mpic 5 1
183 0x0000 0 0 3 &mpic 6 1
184 0x0000 0 0 4 &mpic 7 1
185 >;
186
187 pcie@0 {
188 reg = <0 0 0 0 0>;
189 #size-cells = <2>;
190 #address-cells = <3>;
191 device_type = "pci";
192 ranges = <0x02000000 0x0 0xa0000000
193 0x02000000 0x0 0xa0000000
194 0x0 0x20000000
195
196 0x01000000 0x0 0x00000000
197 0x01000000 0x0 0x00000000
198 0x0 0x00100000>;
199 };
200 };
201};
202
203/include/ "mpc8641si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t1023rdb.dts b/arch/powerpc/boot/dts/fsl/t1023rdb.dts
index 6bd842beb1dc..29757623e5ba 100644
--- a/arch/powerpc/boot/dts/fsl/t1023rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/t1023rdb.dts
@@ -79,7 +79,7 @@
79 flash@0 { 79 flash@0 {
80 #address-cells = <1>; 80 #address-cells = <1>;
81 #size-cells = <1>; 81 #size-cells = <1>;
82 compatible = "spansion,s25fl512s"; 82 compatible = "spansion,s25fl512s", "jedec,spi-nor";
83 reg = <0>; 83 reg = <0>;
84 spi-max-frequency = <10000000>; /* input clk */ 84 spi-max-frequency = <10000000>; /* input clk */
85 }; 85 };
@@ -111,6 +111,47 @@
111 shunt-resistor = <1000>; 111 shunt-resistor = <1000>;
112 }; 112 };
113 }; 113 };
114
115 fman@400000 {
116 fm1mac1: ethernet@e0000 {
117 phy-handle = <&sgmii_rtk_phy2>;
118 phy-connection-type = "sgmii";
119 sleep = <&rcpm 0x80000000>;
120 };
121
122 fm1mac2: ethernet@e2000 {
123 sleep = <&rcpm 0x40000000>;
124 };
125
126 fm1mac3: ethernet@e4000 {
127 phy-handle = <&sgmii_aqr_phy3>;
128 phy-connection-type = "sgmii-2500";
129 sleep = <&rcpm 0x20000000>;
130 };
131
132 fm1mac4: ethernet@e6000 {
133 phy-handle = <&rgmii_rtk_phy1>;
134 phy-connection-type = "rgmii";
135 sleep = <&rcpm 0x10000000>;
136 };
137
138
139 mdio0: mdio@fc000 {
140 rgmii_rtk_phy1: ethernet-phy@1 {
141 reg = <0x1>;
142 };
143 sgmii_rtk_phy2: ethernet-phy@3 {
144 reg = <0x3>;
145 };
146 };
147
148 xmdio0: mdio@fd000 {
149 sgmii_aqr_phy3: ethernet-phy@2 {
150 compatible = "ethernet-phy-ieee802.3-c45";
151 reg = <0x2>;
152 };
153 };
154 };
114 }; 155 };
115 156
116 pci0: pcie@ffe240000 { 157 pci0: pcie@ffe240000 {
diff --git a/arch/powerpc/boot/dts/fsl/t1024qds.dts b/arch/powerpc/boot/dts/fsl/t1024qds.dts
index 6a3581b8e1f8..772143da367f 100644
--- a/arch/powerpc/boot/dts/fsl/t1024qds.dts
+++ b/arch/powerpc/boot/dts/fsl/t1024qds.dts
@@ -87,7 +87,7 @@
87 flash@0 { 87 flash@0 {
88 #address-cells = <1>; 88 #address-cells = <1>;
89 #size-cells = <1>; 89 #size-cells = <1>;
90 compatible = "micron,n25q128a11"; /* 16MB */ 90 compatible = "micron,n25q128a11", "jedec,spi-nor"; /* 16MB */
91 reg = <0>; 91 reg = <0>;
92 spi-max-frequency = <10000000>; 92 spi-max-frequency = <10000000>;
93 }; 93 };
@@ -95,7 +95,7 @@
95 flash@1 { 95 flash@1 {
96 #address-cells = <1>; 96 #address-cells = <1>;
97 #size-cells = <1>; 97 #size-cells = <1>;
98 compatible = "sst,sst25wf040"; /* 512KB */ 98 compatible = "sst,sst25wf040", "jedec,spi-nor"; /* 512KB */
99 reg = <1>; 99 reg = <1>;
100 spi-max-frequency = <10000000>; 100 spi-max-frequency = <10000000>;
101 }; 101 };
@@ -103,7 +103,7 @@
103 flash@2 { 103 flash@2 {
104 #address-cells = <1>; 104 #address-cells = <1>;
105 #size-cells = <1>; 105 #size-cells = <1>;
106 compatible = "eon,en25s64"; /* 8MB */ 106 compatible = "eon,en25s64", "jedec,spi-nor"; /* 8MB */
107 reg = <2>; 107 reg = <2>;
108 spi-max-frequency = <10000000>; 108 spi-max-frequency = <10000000>;
109 }; 109 };
diff --git a/arch/powerpc/boot/dts/fsl/t1024rdb.dts b/arch/powerpc/boot/dts/fsl/t1024rdb.dts
index 0ccc7d03335e..302cdd22b4bb 100644
--- a/arch/powerpc/boot/dts/fsl/t1024rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/t1024rdb.dts
@@ -89,7 +89,7 @@
89 flash@0 { 89 flash@0 {
90 #address-cells = <1>; 90 #address-cells = <1>;
91 #size-cells = <1>; 91 #size-cells = <1>;
92 compatible = "micron,n25q512ax3"; 92 compatible = "micron,n25q512ax3", "jedec,spi-nor";
93 reg = <0>; 93 reg = <0>;
94 spi-max-frequency = <10000000>; /* input clk */ 94 spi-max-frequency = <10000000>; /* input clk */
95 }; 95 };
@@ -140,6 +140,51 @@
140 #size-cells = <0>; 140 #size-cells = <0>;
141 }; 141 };
142 }; 142 };
143
144 fman@400000 {
145 fm1mac1: ethernet@e0000 {
146 phy-handle = <&xg_aqr105_phy3>;
147 phy-connection-type = "xgmii";
148 sleep = <&rcpm 0x80000000>;
149 };
150
151 fm1mac2: ethernet@e2000 {
152 sleep = <&rcpm 0x40000000>;
153 };
154
155 fm1mac3: ethernet@e4000 {
156 phy-handle = <&rgmii_phy2>;
157 phy-connection-type = "rgmii";
158 sleep = <&rcpm 0x20000000>;
159 };
160
161 fm1mac4: ethernet@e6000 {
162 phy-handle = <&rgmii_phy1>;
163 phy-connection-type = "rgmii";
164 sleep = <&rcpm 0x10000000>;
165 };
166
167
168 mdio0: mdio@fc000 {
169 rgmii_phy1: ethernet-phy@2 {
170 reg = <0x2>;
171 };
172 rgmii_phy2: ethernet-phy@6 {
173 reg = <0x6>;
174 };
175 };
176
177 xmdio0: mdio@fd000 {
178 xg_aqr105_phy3: ethernet-phy@1 {
179 compatible = "ethernet-phy-ieee802.3-c45";
180 reg = <0x1>;
181 };
182 sg_2500_aqr105_phy4: ethernet-phy@2 {
183 compatible = "ethernet-phy-ieee802.3-c45";
184 reg = <0x2>;
185 };
186 };
187 };
143 }; 188 };
144 189
145 pci0: pcie@ffe240000 { 190 pci0: pcie@ffe240000 {
diff --git a/arch/powerpc/boot/dts/fsl/t1040rdb.dts b/arch/powerpc/boot/dts/fsl/t1040rdb.dts
index cf194154bbdc..621f2c6ee6ad 100644
--- a/arch/powerpc/boot/dts/fsl/t1040rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/t1040rdb.dts
@@ -1,7 +1,7 @@
1/* 1/*
2 * T1040RDB Device Tree Source 2 * T1040RDB Device Tree Source
3 * 3 *
4 * Copyright 2014 Freescale Semiconductor Inc. 4 * Copyright 2014 - 2015 Freescale Semiconductor Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -38,6 +38,36 @@
38/ { 38/ {
39 model = "fsl,T1040RDB"; 39 model = "fsl,T1040RDB";
40 compatible = "fsl,T1040RDB"; 40 compatible = "fsl,T1040RDB";
41
42 aliases {
43 phy_sgmii_2 = &phy_sgmii_2;
44 };
45
46 soc@ffe000000 {
47 fman@400000 {
48 ethernet@e0000 {
49 fixed-link = <0 1 1000 0 0>;
50 phy-connection-type = "sgmii";
51 };
52
53 ethernet@e2000 {
54 fixed-link = <1 1 1000 0 0>;
55 phy-connection-type = "sgmii";
56 };
57
58 ethernet@e4000 {
59 phy-handle = <&phy_sgmii_2>;
60 phy-connection-type = "sgmii";
61 };
62
63 mdio@fc000 {
64 phy_sgmii_2: ethernet-phy@03 {
65 reg = <0x03>;
66 };
67 };
68 };
69 };
70
41 ifc: localbus@ffe124000 { 71 ifc: localbus@ffe124000 {
42 cpld@3,0 { 72 cpld@3,0 {
43 compatible = "fsl,t1040rdb-cpld"; 73 compatible = "fsl,t1040rdb-cpld";
diff --git a/arch/powerpc/boot/dts/fsl/t1042rdb.dts b/arch/powerpc/boot/dts/fsl/t1042rdb.dts
index 8d908e795e4d..2c138627b1b4 100644
--- a/arch/powerpc/boot/dts/fsl/t1042rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/t1042rdb.dts
@@ -1,7 +1,7 @@
1/* 1/*
2 * T1042RDB Device Tree Source 2 * T1042RDB Device Tree Source
3 * 3 *
4 * Copyright 2014 Freescale Semiconductor Inc. 4 * Copyright 2014 - 2015 Freescale Semiconductor Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -38,6 +38,34 @@
38/ { 38/ {
39 model = "fsl,T1042RDB"; 39 model = "fsl,T1042RDB";
40 compatible = "fsl,T1042RDB"; 40 compatible = "fsl,T1042RDB";
41
42 aliases {
43 phy_sgmii_2 = &phy_sgmii_2;
44 };
45
46 soc@ffe000000 {
47 fman@400000 {
48 ethernet@e0000 {
49 status = "disabled";
50 };
51
52 ethernet@e2000 {
53 status = "disabled";
54 };
55
56 ethernet@e4000 {
57 phy-handle = <&phy_sgmii_2>;
58 phy-connection-type = "sgmii";
59 };
60
61 mdio@fc000 {
62 phy_sgmii_2: ethernet-phy@03 {
63 reg = <0x03>;
64 };
65 };
66 };
67 };
68
41 ifc: localbus@ffe124000 { 69 ifc: localbus@ffe124000 {
42 cpld@3,0 { 70 cpld@3,0 {
43 compatible = "fsl,t1042rdb-cpld"; 71 compatible = "fsl,t1042rdb-cpld";
diff --git a/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts b/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts
index 98c001019d6a..8ec3ff45e6fc 100644
--- a/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts
+++ b/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts
@@ -1,7 +1,7 @@
1/* 1/*
2 * T1042RDB_PI Device Tree Source 2 * T1042RDB_PI Device Tree Source
3 * 3 *
4 * Copyright 2014 Freescale Semiconductor Inc. 4 * Copyright 2014 - 2015 Freescale Semiconductor Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -38,11 +38,13 @@
38/ { 38/ {
39 model = "fsl,T1042RDB_PI"; 39 model = "fsl,T1042RDB_PI";
40 compatible = "fsl,T1042RDB_PI"; 40 compatible = "fsl,T1042RDB_PI";
41
41 ifc: localbus@ffe124000 { 42 ifc: localbus@ffe124000 {
42 cpld@3,0 { 43 cpld@3,0 {
43 compatible = "fsl,t1042rdb_pi-cpld"; 44 compatible = "fsl,t1042rdb_pi-cpld";
44 }; 45 };
45 }; 46 };
47
46 soc: soc@ffe000000 { 48 soc: soc@ffe000000 {
47 i2c@118000 { 49 i2c@118000 {
48 rtc@68 { 50 rtc@68 {
@@ -51,6 +53,20 @@
51 interrupts = <0x2 0x1 0 0>; 53 interrupts = <0x2 0x1 0 0>;
52 }; 54 };
53 }; 55 };
56
57 fman@400000 {
58 ethernet@e0000 {
59 status = "disabled";
60 };
61
62 ethernet@e2000 {
63 status = "disabled";
64 };
65
66 ethernet@e4000 {
67 status = "disabled";
68 };
69 };
54 }; 70 };
55}; 71};
56 72
diff --git a/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi b/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi
index 3f6d7c6a106b..8c7ea6c05de9 100644
--- a/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi
@@ -104,7 +104,7 @@
104 flash@0 { 104 flash@0 {
105 #address-cells = <1>; 105 #address-cells = <1>;
106 #size-cells = <1>; 106 #size-cells = <1>;
107 compatible = "micron,n25q512ax3"; 107 compatible = "micron,n25q512ax3", "jedec,spi-nor";
108 reg = <0>; 108 reg = <0>;
109 /* input clock */ 109 /* input clock */
110 spi-max-frequency = <10000000>; 110 spi-max-frequency = <10000000>;
diff --git a/arch/powerpc/boot/dts/fsl/t104xqds.dtsi b/arch/powerpc/boot/dts/fsl/t104xqds.dtsi
index 1498d1e4aecf..977af355b388 100644
--- a/arch/powerpc/boot/dts/fsl/t104xqds.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t104xqds.dtsi
@@ -1,7 +1,7 @@
1/* 1/*
2 * T104xQDS Device Tree Source 2 * T104xQDS Device Tree Source
3 * 3 *
4 * Copyright 2013 - 2014 Freescale Semiconductor Inc. 4 * Copyright 2013 - 2015 Freescale Semiconductor Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -38,6 +38,33 @@
38 #size-cells = <2>; 38 #size-cells = <2>;
39 interrupt-parent = <&mpic>; 39 interrupt-parent = <&mpic>;
40 40
41 aliases {
42 emi1_rgmii0 = &t1040mdio0;
43 emi1_rgmii1 = &t1040mdio1;
44 emi1_slot3 = &t1040mdio3;
45 emi1_slot5 = &t1040mdio5;
46 emi1_slot6 = &t1040mdio6;
47 emi1_slot7 = &t1040mdio7;
48 rgmii_phy1 = &rgmii_phy1;
49 rgmii_phy2 = &rgmii_phy2;
50 phy_s3_01 = &phy_s3_01;
51 phy_s3_02 = &phy_s3_02;
52 phy_s3_03 = &phy_s3_03;
53 phy_s3_04 = &phy_s3_04;
54 phy_s5_01 = &phy_s5_01;
55 phy_s5_02 = &phy_s5_02;
56 phy_s5_03 = &phy_s5_03;
57 phy_s5_04 = &phy_s5_04;
58 phy_s6_01 = &phy_s6_01;
59 phy_s6_02 = &phy_s6_02;
60 phy_s6_03 = &phy_s6_03;
61 phy_s6_04 = &phy_s6_04;
62 phy_s7_01 = &phy_s7_01;
63 phy_s7_02 = &phy_s7_02;
64 phy_s7_03 = &phy_s7_03;
65 phy_s7_04 = &phy_s7_04;
66 };
67
41 reserved-memory { 68 reserved-memory {
42 #address-cells = <2>; 69 #address-cells = <2>;
43 #size-cells = <2>; 70 #size-cells = <2>;
@@ -85,6 +112,128 @@
85 #size-cells = <1>; 112 #size-cells = <1>;
86 compatible = "fsl,fpga-qixis"; 113 compatible = "fsl,fpga-qixis";
87 reg = <3 0 0x300>; 114 reg = <3 0 0x300>;
115 ranges = <0 3 0 0x300>;
116
117 mdio-mux-emi1 {
118 #address-cells = <1>;
119 #size-cells = <0>;
120 compatible = "mdio-mux-mmioreg", "mdio-mux";
121 mdio-parent-bus = <&mdio0>;
122 reg = <0x54 1>;
123 mux-mask = <0xe0>;
124
125 t1040mdio0: mdio@0 {
126 #address-cells = <1>;
127 #size-cells = <0>;
128 reg = <0x00>;
129 status = "disabled";
130
131 rgmii_phy1: ethernet-phy@1 {
132 reg = <0x1>;
133 };
134 };
135
136 t1040mdio1: mdio@20 {
137 #address-cells = <1>;
138 #size-cells = <0>;
139 reg = <0x20>;
140 status = "disabled";
141
142 rgmii_phy2: ethernet-phy@2 {
143 reg = <0x2>;
144 };
145 };
146
147 t1040mdio3: mdio@60 {
148 #address-cells = <1>;
149 #size-cells = <0>;
150 reg = <0x60>;
151 status = "disabled";
152
153 phy_s3_01: ethernet-phy@1c {
154 reg = <0x1c>;
155 };
156
157 phy_s3_02: ethernet-phy@1d {
158 reg = <0x1d>;
159 };
160
161 phy_s3_03: ethernet-phy@1e {
162 reg = <0x1e>;
163 };
164
165 phy_s3_04: ethernet-phy@1f {
166 reg = <0x1f>;
167 };
168 };
169
170 t1040mdio5: mdio@a0 {
171 #address-cells = <1>;
172 #size-cells = <0>;
173 reg = <0xa0>;
174
175 phy_s5_01: ethernet-phy@1c {
176 reg = <0x14>;
177 };
178
179 phy_s5_02: ethernet-phy@1d {
180 reg = <0x15>;
181 };
182
183 phy_s5_03: ethernet-phy@1e {
184 reg = <0x16>;
185 };
186
187 phy_s5_04: ethernet-phy@1f {
188 reg = <0x17>;
189 };
190 };
191
192 t1040mdio6: mdio@c0 {
193 #address-cells = <1>;
194 #size-cells = <0>;
195 reg = <0xc0>;
196
197 phy_s6_01: ethernet-phy@1c {
198 reg = <0x18>;
199 };
200
201 phy_s6_02: ethernet-phy@1d {
202 reg = <0x19>;
203 };
204
205 phy_s6_03: ethernet-phy@1e {
206 reg = <0x1a>;
207 };
208
209 phy_s6_04: ethernet-phy@1f {
210 reg = <0x1b>;
211 };
212 };
213
214 t1040mdio7: mdio@e0 {
215 #address-cells = <1>;
216 #size-cells = <0>;
217 reg = <0xe0>;
218 status = "disabled";
219
220 phy_s7_01: ethernet-phy@1c {
221 reg = <0x1c>;
222 };
223
224 phy_s7_02: ethernet-phy@1d {
225 reg = <0x1d>;
226 };
227
228 phy_s7_03: ethernet-phy@1e {
229 reg = <0x1e>;
230 };
231
232 phy_s7_04: ethernet-phy@1f {
233 reg = <0x1f>;
234 };
235 };
236 };
88 }; 237 };
89 }; 238 };
90 239
@@ -112,7 +261,7 @@
112 flash@0 { 261 flash@0 {
113 #address-cells = <1>; 262 #address-cells = <1>;
114 #size-cells = <1>; 263 #size-cells = <1>;
115 compatible = "micron,n25q128a11"; 264 compatible = "micron,n25q128a11", "jedec,spi-nor";
116 reg = <0>; 265 reg = <0>;
117 spi-max-frequency = <10000000>; /* input clock */ 266 spi-max-frequency = <10000000>; /* input clock */
118 }; 267 };
@@ -129,6 +278,33 @@
129 interrupts = <0x1 0x1 0 0>; 278 interrupts = <0x1 0x1 0 0>;
130 }; 279 };
131 }; 280 };
281
282 fman@400000 {
283 ethernet@e0000 {
284 fixed-link = <0 1 1000 0 0>;
285 phy-connection-type = "sgmii";
286 };
287
288 ethernet@e2000 {
289 fixed-link = <1 1 1000 0 0>;
290 phy-connection-type = "sgmii";
291 };
292
293 ethernet@e4000 {
294 phy-handle = <&phy_s7_03>;
295 phy-connection-type = "sgmii";
296 };
297
298 ethernet@e6000 {
299 phy-handle = <&rgmii_phy1>;
300 phy-connection-type = "rgmii";
301 };
302
303 ethernet@e8000 {
304 phy-handle = <&rgmii_phy2>;
305 phy-connection-type = "rgmii";
306 };
307 };
132 }; 308 };
133 309
134 pci0: pcie@ffe240000 { 310 pci0: pcie@ffe240000 {
diff --git a/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi b/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi
index 830ea484295b..72691ef102ee 100644
--- a/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi
@@ -1,7 +1,7 @@
1/* 1/*
2 * T1040RDB/T1042RDB Device Tree Source 2 * T1040RDB/T1042RDB Device Tree Source
3 * 3 *
4 * Copyright 2014 Freescale Semiconductor Inc. 4 * Copyright 2014 - 2015 Freescale Semiconductor Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -33,6 +33,12 @@
33 */ 33 */
34 34
35/ { 35/ {
36 aliases {
37 phy_rgmii_0 = &phy_rgmii_0;
38 phy_rgmii_1 = &phy_rgmii_1;
39 phy_sgmii_2 = &phy_sgmii_2;
40 };
41
36 reserved-memory { 42 reserved-memory {
37 #address-cells = <2>; 43 #address-cells = <2>;
38 #size-cells = <2>; 44 #size-cells = <2>;
@@ -103,10 +109,15 @@
103 flash@0 { 109 flash@0 {
104 #address-cells = <1>; 110 #address-cells = <1>;
105 #size-cells = <1>; 111 #size-cells = <1>;
106 compatible = "micron,n25q512a"; 112 compatible = "micron,n25q512a", "jedec,spi-nor";
107 reg = <0>; 113 reg = <0>;
108 spi-max-frequency = <10000000>; /* input clock */ 114 spi-max-frequency = <10000000>; /* input clock */
109 }; 115 };
116 slic@3 {
117 compatible = "maxim,ds26522";
118 reg = <3>;
119 spi-max-frequency = <2000000>; /* input clock */
120 };
110 }; 121 };
111 122
112 i2c@118000 { 123 i2c@118000 {
@@ -125,6 +136,31 @@
125 }; 136 };
126 }; 137 };
127 138
139 fman@400000 {
140 ethernet@e6000 {
141 phy-handle = <&phy_rgmii_0>;
142 phy-connection-type = "rgmii";
143 };
144
145 ethernet@e8000 {
146 phy-handle = <&phy_rgmii_1>;
147 phy-connection-type = "rgmii";
148 };
149
150 mdio0: mdio@fc000 {
151 phy_sgmii_2: ethernet-phy@03 {
152 reg = <0x03>;
153 };
154
155 phy_rgmii_0: ethernet-phy@01 {
156 reg = <0x01>;
157 };
158
159 phy_rgmii_1: ethernet-phy@02 {
160 reg = <0x02>;
161 };
162 };
163 };
128 }; 164 };
129 165
130 pci0: pcie@ffe240000 { 166 pci0: pcie@ffe240000 {
diff --git a/arch/powerpc/boot/dts/fsl/t2080qds.dts b/arch/powerpc/boot/dts/fsl/t2080qds.dts
index 9c8e10fe04cb..8d190e8c62ce 100644
--- a/arch/powerpc/boot/dts/fsl/t2080qds.dts
+++ b/arch/powerpc/boot/dts/fsl/t2080qds.dts
@@ -1,7 +1,7 @@
1/* 1/*
2 * T2080QDS Device Tree Source 2 * T2080QDS Device Tree Source
3 * 3 *
4 * Copyright 2013 Freescale Semiconductor Inc. 4 * Copyright 2013 - 2015 Freescale Semiconductor Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -42,6 +42,12 @@
42 #size-cells = <2>; 42 #size-cells = <2>;
43 interrupt-parent = <&mpic>; 43 interrupt-parent = <&mpic>;
44 44
45 aliases {
46 emi1_slot1 = &t2080mdio2;
47 emi1_slot2 = &t2080mdio3;
48 emi1_slot3 = &t2080mdio4;
49 };
50
45 rio: rapidio@ffe0c0000 { 51 rio: rapidio@ffe0c0000 {
46 reg = <0xf 0xfe0c0000 0 0x11000>; 52 reg = <0xf 0xfe0c0000 0 0x11000>;
47 53
@@ -54,4 +60,154 @@
54 }; 60 };
55}; 61};
56 62
63&soc {
64 fman@400000 {
65 ethernet@e0000 {
66 phy-handle = <&phy_sgmii_s3_1e>;
67 phy-connection-type = "xgmii";
68 };
69
70 ethernet@e2000 {
71 phy-handle = <&phy_sgmii_s3_1f>;
72 phy-connection-type = "xgmii";
73 };
74
75 ethernet@e4000 {
76 phy-handle = <&rgmii_phy1>;
77 phy-connection-type = "rgmii";
78 };
79
80 ethernet@e6000 {
81 phy-handle = <&rgmii_phy2>;
82 phy-connection-type = "rgmii";
83 };
84
85 ethernet@e8000 {
86 phy-handle = <&phy_sgmii_s2_1e>;
87 phy-connection-type = "sgmii";
88 };
89
90 ethernet@ea000 {
91 phy-handle = <&phy_sgmii_s2_1d>;
92 phy-connection-type = "sgmii";
93 };
94
95 ethernet@f0000 {
96 phy-handle = <&phy_xaui_slot3>;
97 phy-connection-type = "xgmii";
98 };
99
100 ethernet@f2000 {
101 phy-handle = <&phy_sgmii_s3_1f>;
102 phy-connection-type = "xgmii";
103 };
104
105 mdio@fd000 {
106 phy_xaui_slot3: ethernet-phy@3 {
107 compatible = "ethernet-phy-ieee802.3-c45";
108 reg = <0x3>;
109 };
110 };
111 };
112};
113
114&boardctrl {
115 mdio-mux-emi1 {
116 compatible = "mdio-mux-mmioreg", "mdio-mux";
117 mdio-parent-bus = <&mdio0>;
118 #address-cells = <1>;
119 #size-cells = <0>;
120 reg = <0x54 1>;
121 mux-mask = <0xe0>;
122
123 t2080mdio0: mdio@0 {
124 #address-cells = <1>;
125 #size-cells = <0>;
126 reg = <0>;
127
128 rgmii_phy1: ethernet-phy@1 {
129 reg = <0x1>;
130 };
131 };
132
133 t2080mdio1: mdio@20 {
134 #address-cells = <1>;
135 #size-cells = <0>;
136 reg = <0x20>;
137
138 rgmii_phy2: ethernet-phy@2 {
139 reg = <0x2>;
140 };
141 };
142
143 t2080mdio2: mdio@40 {
144 #address-cells = <1>;
145 #size-cells = <0>;
146 reg = <0x40>;
147 status = "disabled";
148
149 phy_sgmii_s1_1c: ethernet-phy@1c {
150 reg = <0x1c>;
151 };
152
153 phy_sgmii_s1_1d: ethernet-phy@1d {
154 reg = <0x1d>;
155 };
156
157 phy_sgmii_s1_1e: ethernet-phy@1e {
158 reg = <0x1e>;
159 };
160
161 phy_sgmii_s1_1f: ethernet-phy@1f {
162 reg = <0x1f>;
163 };
164 };
165
166 t2080mdio3: mdio@c0 {
167 #address-cells = <1>;
168 #size-cells = <0>;
169 reg = <0xc0>;
170
171 phy_sgmii_s2_1c: ethernet-phy@1c {
172 reg = <0x1c>;
173 };
174
175 phy_sgmii_s2_1d: ethernet-phy@1d {
176 reg = <0x1d>;
177 };
178
179 phy_sgmii_s2_1e: ethernet-phy@1e {
180 reg = <0x1e>;
181 };
182
183 phy_sgmii_s2_1f: ethernet-phy@1f {
184 reg = <0x1f>;
185 };
186 };
187
188 t2080mdio4: mdio@60 {
189 #address-cells = <1>;
190 #size-cells = <0>;
191 reg = <0x60>;
192 status = "disabled";
193
194 phy_sgmii_s3_1c: ethernet-phy@1c {
195 reg = <0x1c>;
196 };
197
198 phy_sgmii_s3_1d: ethernet-phy@1d {
199 reg = <0x1d>;
200 };
201
202 phy_sgmii_s3_1e: ethernet-phy@1e {
203 reg = <0x1e>;
204 };
205
206 phy_sgmii_s3_1f: ethernet-phy@1f {
207 reg = <0x1f>;
208 };
209 };
210 };
211};
212
57/include/ "t2080si-post.dtsi" 213/include/ "t2080si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t2080rdb.dts b/arch/powerpc/boot/dts/fsl/t2080rdb.dts
index 33205bf08919..836e4c965b22 100644
--- a/arch/powerpc/boot/dts/fsl/t2080rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/t2080rdb.dts
@@ -1,7 +1,7 @@
1/* 1/*
2 * T2080PCIe-RDB Board Device Tree Source 2 * T2080PCIe-RDB Board Device Tree Source
3 * 3 *
4 * Copyright 2014 Freescale Semiconductor Inc. 4 * Copyright 2014 - 2015 Freescale Semiconductor Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -54,4 +54,69 @@
54 }; 54 };
55}; 55};
56 56
57&soc {
58 fman@400000 {
59 ethernet@e0000 {
60 phy-handle = <&xg_aq1202_phy3>;
61 phy-connection-type = "xgmii";
62 };
63
64 ethernet@e2000 {
65 phy-handle = <&xg_aq1202_phy4>;
66 phy-connection-type = "xgmii";
67 };
68
69 ethernet@e4000 {
70 phy-handle = <&rgmii_phy1>;
71 phy-connection-type = "rgmii";
72 };
73
74 ethernet@e6000 {
75 phy-handle = <&rgmii_phy2>;
76 phy-connection-type = "rgmii";
77 };
78
79 ethernet@f0000 {
80 phy-handle = <&xg_cs4315_phy1>;
81 phy-connection-type = "xgmii";
82 };
83
84 ethernet@f2000 {
85 phy-handle = <&xg_cs4315_phy2>;
86 phy-connection-type = "xgmii";
87 };
88
89 mdio@fc000 {
90 rgmii_phy1: ethernet-phy@1 {
91 reg = <0x1>;
92 };
93 rgmii_phy2: ethernet-phy@2 {
94 reg = <0x2>;
95 };
96 };
97
98 mdio@fd000 {
99 xg_cs4315_phy1: ethernet-phy@c {
100 compatible = "ethernet-phy-ieee802.3-c45";
101 reg = <0xc>;
102 };
103
104 xg_cs4315_phy2: ethernet-phy@d {
105 compatible = "ethernet-phy-ieee802.3-c45";
106 reg = <0xd>;
107 };
108
109 xg_aq1202_phy3: ethernet-phy@0 {
110 compatible = "ethernet-phy-ieee802.3-c45";
111 reg = <0x0>;
112 };
113
114 xg_aq1202_phy4: ethernet-phy@1 {
115 compatible = "ethernet-phy-ieee802.3-c45";
116 reg = <0x1>;
117 };
118 };
119 };
120};
121
57/include/ "t2080si-post.dtsi" 122/include/ "t2080si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t2081qds.dts b/arch/powerpc/boot/dts/fsl/t2081qds.dts
index b81213596dbf..fc5c4a30f7ad 100644
--- a/arch/powerpc/boot/dts/fsl/t2081qds.dts
+++ b/arch/powerpc/boot/dts/fsl/t2081qds.dts
@@ -1,7 +1,7 @@
1/* 1/*
2 * T2081QDS Device Tree Source 2 * T2081QDS Device Tree Source
3 * 3 *
4 * Copyright 2013 Freescale Semiconductor Inc. 4 * Copyright 2013 - 2015 Freescale Semiconductor Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -41,6 +41,225 @@
41 #address-cells = <2>; 41 #address-cells = <2>;
42 #size-cells = <2>; 42 #size-cells = <2>;
43 interrupt-parent = <&mpic>; 43 interrupt-parent = <&mpic>;
44
45 aliases {
46 emi1_slot1 = &t2081mdio2;
47 emi1_slot2 = &t2081mdio3;
48 emi1_slot3 = &t2081mdio4;
49 emi1_slot5 = &t2081mdio5;
50 emi1_slot6 = &t2081mdio6;
51 emi1_slot7 = &t2081mdio7;
52 };
53};
54
55&soc {
56 fman@400000 {
57 ethernet@e0000 {
58 phy-handle = <&phy_sgmii_s7_1c>;
59 phy-connection-type = "sgmii";
60 };
61
62 ethernet@e2000 {
63 phy-handle = <&phy_sgmii_s7_1d>;
64 phy-connection-type = "sgmii";
65 };
66
67 ethernet@e4000 {
68 phy-handle = <&rgmii_phy1>;
69 phy-connection-type = "rgmii";
70 };
71
72 ethernet@e6000 {
73 phy-handle = <&rgmii_phy2>;
74 phy-connection-type = "rgmii";
75 };
76
77 ethernet@e8000 {
78 phy-handle = <&phy_sgmii_s3_1c>;
79 phy-connection-type = "sgmii";
80 };
81
82 ethernet@ea000 {
83 phy-handle = <&phy_sgmii_s7_1f>;
84 phy-connection-type = "sgmii";
85 };
86
87 ethernet@f0000 {
88 phy-handle = <&phy_sgmii_s2_1c>;
89 phy-connection-type = "xgmii";
90 };
91
92 ethernet@f2000 {
93 phy-handle = <&phy_sgmii_s7_1e>;
94 phy-connection-type = "xgmii";
95 };
96 };
97};
98
99&boardctrl {
100 mdio-mux-emi1 {
101 compatible = "mdio-mux-mmioreg", "mdio-mux";
102 mdio-parent-bus = <&mdio0>;
103 #address-cells = <1>;
104 #size-cells = <0>;
105 reg = <0x54 1>;
106 mux-mask = <0xe0>;
107
108 t2081mdio0: mdio@0 {
109 #address-cells = <1>;
110 #size-cells = <0>;
111 reg = <0>;
112
113 rgmii_phy1: ethernet-phy@1 {
114 reg = <0x1>;
115 };
116 };
117
118 t2081mdio1: mdio@20 {
119 #address-cells = <1>;
120 #size-cells = <0>;
121 reg = <0x20>;
122
123 rgmii_phy2: ethernet-phy@2 {
124 reg = <0x2>;
125 };
126 };
127
128 t2081mdio2: mdio@40 {
129 #address-cells = <1>;
130 #size-cells = <0>;
131 reg = <0x40>;
132
133 phy_sgmii_s1_1c: ethernet-phy@1c {
134 reg = <0x1c>;
135 };
136
137 phy_sgmii_s1_1d: ethernet-phy@1d {
138 reg = <0x1d>;
139 };
140
141 phy_sgmii_s1_1e: ethernet-phy@1e {
142 reg = <0x1e>;
143 };
144
145 phy_sgmii_s1_1f: ethernet-phy@1f {
146 reg = <0x1f>;
147 };
148 };
149
150 t2081mdio3: mdio@60 {
151 #address-cells = <1>;
152 #size-cells = <0>;
153 reg = <0x60>;
154
155 phy_sgmii_s2_1c: ethernet-phy@1c {
156 reg = <0x1c>;
157 };
158
159 phy_sgmii_s2_1d: ethernet-phy@1d {
160 reg = <0x1d>;
161 };
162
163 phy_sgmii_s2_1e: ethernet-phy@1e {
164 reg = <0x1e>;
165 };
166
167 phy_sgmii_s2_1f: ethernet-phy@1f {
168 reg = <0x1f>;
169 };
170 };
171
172 t2081mdio4: mdio@80 {
173 #address-cells = <1>;
174 #size-cells = <0>;
175 reg = <0x80>;
176 status = "disabled";
177
178 phy_sgmii_s3_1c: ethernet-phy@1c {
179 reg = <0x1c>;
180 };
181
182 phy_sgmii_s3_1d: ethernet-phy@1d {
183 reg = <0x1d>;
184 };
185
186 phy_sgmii_s3_1e: ethernet-phy@1e {
187 reg = <0x1e>;
188 };
189
190 phy_sgmii_s3_1f: ethernet-phy@1f {
191 reg = <0x1f>;
192 };
193 };
194
195 t2081mdio5: mdio@a0 {
196 #address-cells = <1>;
197 #size-cells = <0>;
198 reg = <0xa0>;
199 status = "disabled";
200
201 phy_sgmii_s5_1c: ethernet-phy@1c {
202 reg = <0x1c>;
203 };
204
205 phy_sgmii_s5_1d: ethernet-phy@1d {
206 reg = <0x1d>;
207 };
208
209 phy_sgmii_s5_1e: ethernet-phy@1e {
210 reg = <0x1e>;
211 };
212
213 phy_sgmii_s5_1f: ethernet-phy@1f {
214 reg = <0x1f>;
215 };
216 };
217
218 t2081mdio6: mdio@c0 {
219 #address-cells = <1>;
220 #size-cells = <0>;
221 reg = <0xc0>;
222 status = "disabled";
223
224 phy_sgmii_s6_1c: ethernet-phy@1c {
225 reg = <0x1c>;
226 };
227
228 phy_sgmii_s6_1d: ethernet-phy@1d {
229 reg = <0x1d>;
230 };
231
232 phy_sgmii_s6_1e: ethernet-phy@1e {
233 reg = <0x1e>;
234 };
235
236 phy_sgmii_s6_1f: ethernet-phy@1f {
237 reg = <0x1f>;
238 };
239 };
240
241 t2081mdio7: mdio@e0 {
242 #address-cells = <1>;
243 #size-cells = <0>;
244 reg = <0xe0>;
245
246 phy_sgmii_s7_1c: ethernet-phy@1c {
247 reg = <0x1c>;
248 };
249
250 phy_sgmii_s7_1d: ethernet-phy@1d {
251 reg = <0x1d>;
252 };
253
254 phy_sgmii_s7_1e: ethernet-phy@1e {
255 reg = <0x1e>;
256 };
257
258 phy_sgmii_s7_1f: ethernet-phy@1f {
259 reg = <0x1f>;
260 };
261 };
262 };
44}; 263};
45 264
46/include/ "t2081si-post.dtsi" 265/include/ "t2081si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t208xqds.dtsi b/arch/powerpc/boot/dts/fsl/t208xqds.dtsi
index 869f9159b4d1..ec080bd01b09 100644
--- a/arch/powerpc/boot/dts/fsl/t208xqds.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t208xqds.dtsi
@@ -112,7 +112,7 @@
112 flash@0 { 112 flash@0 {
113 #address-cells = <1>; 113 #address-cells = <1>;
114 #size-cells = <1>; 114 #size-cells = <1>;
115 compatible = "micron,n25q128a11"; /* 16MB */ 115 compatible = "micron,n25q128a11", "jedec,spi-nor"; /* 16MB */
116 reg = <0>; 116 reg = <0>;
117 spi-max-frequency = <40000000>; /* input clock */ 117 spi-max-frequency = <40000000>; /* input clock */
118 }; 118 };
@@ -120,7 +120,7 @@
120 flash@1 { 120 flash@1 {
121 #address-cells = <1>; 121 #address-cells = <1>;
122 #size-cells = <1>; 122 #size-cells = <1>;
123 compatible = "sst,sst25wf040"; 123 compatible = "sst,sst25wf040", "jedec,spi-nor";
124 reg = <1>; 124 reg = <1>;
125 spi-max-frequency = <35000000>; 125 spi-max-frequency = <35000000>;
126 }; 126 };
@@ -128,7 +128,7 @@
128 flash@2 { 128 flash@2 {
129 #address-cells = <1>; 129 #address-cells = <1>;
130 #size-cells = <1>; 130 #size-cells = <1>;
131 compatible = "eon,en25s64"; 131 compatible = "eon,en25s64", "jedec,spi-nor";
132 reg = <2>; 132 reg = <2>;
133 spi-max-frequency = <35000000>; 133 spi-max-frequency = <35000000>;
134 }; 134 };
diff --git a/arch/powerpc/boot/dts/fsl/t208xrdb.dtsi b/arch/powerpc/boot/dts/fsl/t208xrdb.dtsi
index 693d2a8fa01c..dc9326875778 100644
--- a/arch/powerpc/boot/dts/fsl/t208xrdb.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t208xrdb.dtsi
@@ -113,7 +113,7 @@
113 flash@0 { 113 flash@0 {
114 #address-cells = <1>; 114 #address-cells = <1>;
115 #size-cells = <1>; 115 #size-cells = <1>;
116 compatible = "micron,n25q512a"; 116 compatible = "micron,n25q512a", "jedec,spi-nor";
117 reg = <0>; 117 reg = <0>;
118 spi-max-frequency = <10000000>; /* input clock */ 118 spi-max-frequency = <10000000>; /* input clock */
119 }; 119 };
diff --git a/arch/powerpc/boot/dts/fsl/t4240qds.dts b/arch/powerpc/boot/dts/fsl/t4240qds.dts
index c067a6533809..9573ceada07c 100644
--- a/arch/powerpc/boot/dts/fsl/t4240qds.dts
+++ b/arch/powerpc/boot/dts/fsl/t4240qds.dts
@@ -1,7 +1,7 @@
1/* 1/*
2 * T4240QDS Device Tree Source 2 * T4240QDS Device Tree Source
3 * 3 *
4 * Copyright 2012 - 2014 Freescale Semiconductor Inc. 4 * Copyright 2012 - 2015 Freescale Semiconductor Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -41,6 +41,44 @@
41 #size-cells = <2>; 41 #size-cells = <2>;
42 interrupt-parent = <&mpic>; 42 interrupt-parent = <&mpic>;
43 43
44 aliases{
45 phy_rgmii1 = &phyrgmii1;
46 phy_rgmii2 = &phyrgmii2;
47 phy_sgmii3 = &phy3;
48 phy_sgmii4 = &phy4;
49 phy_sgmii11 = &phy11;
50 phy_sgmii12 = &phy12;
51 sgmii_phy11 = &sgmiiphy11;
52 sgmii_phy12 = &sgmiiphy12;
53 sgmii_phy13 = &sgmiiphy13;
54 sgmii_phy14 = &sgmiiphy14;
55 sgmii_phy21 = &sgmiiphy21;
56 sgmii_phy22 = &sgmiiphy22;
57 sgmii_phy23 = &sgmiiphy23;
58 sgmii_phy24 = &sgmiiphy24;
59 sgmii_phy31 = &sgmiiphy31;
60 sgmii_phy32 = &sgmiiphy32;
61 sgmii_phy33 = &sgmiiphy33;
62 sgmii_phy34 = &sgmiiphy34;
63 sgmii_phy41 = &sgmiiphy41;
64 sgmii_phy42 = &sgmiiphy42;
65 sgmii_phy43 = &sgmiiphy43;
66 sgmii_phy44 = &sgmiiphy44;
67 phy_xfi1 = &xfiphy1;
68 phy_xfi2 = &xfiphy2;
69 phy_xfi3 = &xfiphy3;
70 phy_xfi4 = &xfiphy4;
71 xfi_pcs_mdio1 = &xfimdio0;
72 xfi_pcs_mdio2 = &xfimdio1;
73 xfi_pcs_mdio3 = &xfimdio2;
74 xfi_pcs_mdio4 = &xfimdio3;
75 emi1_rgmii = &t4240mdio0;
76 emi1_slot1 = &t4240mdio1;
77 emi1_slot2 = &t4240mdio2;
78 emi1_slot3 = &t4240mdio3;
79 emi1_slot4 = &t4240mdio4;
80 };
81
44 ifc: localbus@ffe124000 { 82 ifc: localbus@ffe124000 {
45 reg = <0xf 0xfe124000 0 0x2000>; 83 reg = <0xf 0xfe124000 0 0x2000>;
46 ranges = <0 0 0xf 0xe8000000 0x08000000 84 ranges = <0 0 0xf 0xe8000000 0x08000000
@@ -91,8 +129,190 @@
91 }; 129 };
92 130
93 board-control@3,0 { 131 board-control@3,0 {
132 #address-cells = <1>;
133 #size-cells = <1>;
94 compatible = "fsl,t4240qds-fpga", "fsl,fpga-qixis"; 134 compatible = "fsl,t4240qds-fpga", "fsl,fpga-qixis";
95 reg = <3 0 0x300>; 135 reg = <3 0 0x300>;
136 ranges = <0 3 0 0x300>;
137
138 mdio-mux-emi1 {
139 #address-cells = <1>;
140 #size-cells = <0>;
141 compatible = "mdio-mux-mmioreg", "mdio-mux";
142 mdio-parent-bus = <&mdio1>;
143 reg = <0x54 1>;
144 mux-mask = <0xe0>;
145
146 t4240mdio0: mdio@0 {
147 #address-cells = <1>;
148 #size-cells = <0>;
149 reg = <0>;
150
151 phyrgmii1: ethernet-phy@1 {
152 reg = <0x1>;
153 };
154
155 phyrgmii2: ethernet-phy@2 {
156 reg = <0x2>;
157 };
158 };
159
160 t4240mdio1: mdio@20 {
161 #address-cells = <1>;
162 #size-cells = <0>;
163 reg = <0x20>;
164 status = "disabled";
165
166 phy1: ethernet-phy@0 {
167 reg = <0x0>;
168 };
169
170 phy2: ethernet-phy@1 {
171 reg = <0x1>;
172 };
173
174 phy3: ethernet-phy@2 {
175 reg = <0x2>;
176 };
177
178 phy4: ethernet-phy@3 {
179 reg = <0x3>;
180 };
181
182 sgmiiphy11: ethernet-phy@1c {
183 reg = <0x1c>;
184 };
185
186 sgmiiphy12: ethernet-phy@1d {
187 reg = <0x1d>;
188 };
189
190 sgmiiphy13: ethernet-phy@1e {
191 reg = <0x1e>;
192 };
193
194 sgmiiphy14: ethernet-phy@1f {
195 reg = <0x1f>;
196 };
197 };
198
199 t4240mdio2: mdio@40 {
200 #address-cells = <1>;
201 #size-cells = <0>;
202 reg = <0x40>;
203 status = "disabled";
204
205 phy5: ethernet-phy@4 {
206 reg = <0x4>;
207 };
208
209 phy6: ethernet-phy@5 {
210 reg = <0x5>;
211 };
212
213 phy7: ethernet-phy@6 {
214 reg = <0x6>;
215 };
216
217 phy8: ethernet-phy@7 {
218 reg = <0x7>;
219 };
220
221 sgmiiphy21: ethernet-phy@1c {
222 reg = <0x1c>;
223 };
224
225 sgmiiphy22: ethernet-phy@1d {
226 reg = <0x1d>;
227 };
228
229 sgmiiphy23: ethernet-phy@1e {
230 reg = <0x1e>;
231 };
232
233 sgmiiphy24: ethernet-phy@1f {
234 reg = <0x1f>;
235 };
236 };
237
238 t4240mdio3: mdio@60 {
239 #address-cells = <1>;
240 #size-cells = <0>;
241 reg = <0x60>;
242 status = "disabled";
243
244 phy9: ethernet-phy@8 {
245 reg = <0x8>;
246 };
247
248 phy10: ethernet-phy@9 {
249 reg = <0x9>;
250 };
251
252 phy11: ethernet-phy@a {
253 reg = <0xa>;
254 };
255
256 phy12: ethernet-phy@b {
257 reg = <0xb>;
258 };
259
260 sgmiiphy31: ethernet-phy@1c {
261 reg = <0x1c>;
262 };
263
264 sgmiiphy32: ethernet-phy@1d {
265 reg = <0x1d>;
266 };
267
268 sgmiiphy33: ethernet-phy@1e {
269 reg = <0x1e>;
270 };
271
272 sgmiiphy34: ethernet-phy@1f {
273 reg = <0x1f>;
274 };
275 };
276
277 t4240mdio4: mdio@80 {
278 #address-cells = <1>;
279 #size-cells = <0>;
280 reg = <0x80>;
281 status = "disabled";
282
283 phy13: ethernet-phy@c {
284 reg = <0xc>;
285 };
286
287 phy14: ethernet-phy@d {
288 reg = <0xd>;
289 };
290
291 phy15: ethernet-phy@e {
292 reg = <0xe>;
293 };
294
295 phy16: ethernet-phy@f {
296 reg = <0xf>;
297 };
298
299 sgmiiphy41: ethernet-phy@1c {
300 reg = <0x1c>;
301 };
302
303 sgmiiphy42: ethernet-phy@1d {
304 reg = <0x1d>;
305 };
306
307 sgmiiphy43: ethernet-phy@1e {
308 reg = <0x1e>;
309 };
310
311 sgmiiphy44: ethernet-phy@1f {
312 reg = <0x1f>;
313 };
314 };
315 };
96 }; 316 };
97 }; 317 };
98 318
@@ -138,7 +358,7 @@
138 flash@0 { 358 flash@0 {
139 #address-cells = <1>; 359 #address-cells = <1>;
140 #size-cells = <1>; 360 #size-cells = <1>;
141 compatible = "sst,sst25wf040"; 361 compatible = "sst,sst25wf040", "jedec,spi-nor";
142 reg = <0>; 362 reg = <0>;
143 spi-max-frequency = <40000000>; /* input clock */ 363 spi-max-frequency = <40000000>; /* input clock */
144 }; 364 };
@@ -234,6 +454,184 @@
234 sdhc@114000 { 454 sdhc@114000 {
235 voltage-ranges = <1800 1800 3300 3300>; 455 voltage-ranges = <1800 1800 3300 3300>;
236 }; 456 };
457
458 fman@400000 {
459 port@83000 {
460 status = "disabled";
461 };
462
463 port@84000 {
464 status = "disabled";
465 };
466
467 port@85000 {
468 status = "disabled";
469 };
470
471 port@86000 {
472 status = "disabled";
473 };
474
475 port@87000 {
476 status = "disabled";
477 };
478
479 ethernet@e0000 {
480 phy-handle = <&phy5>;
481 phy-connection-type = "sgmii";
482 };
483
484 ethernet@e2000 {
485 phy-handle = <&phy6>;
486 phy-connection-type = "sgmii";
487 };
488
489 ethernet@e4000 {
490 phy-handle = <&phy7>;
491 phy-connection-type = "sgmii";
492 };
493
494 ethernet@e6000 {
495 phy-handle = <&phy8>;
496 phy-connection-type = "sgmii";
497 };
498
499 ethernet@e8000 {
500 phy-handle = <&phyrgmii2>;
501 phy-connection-type = "rgmii";
502 };
503
504 ethernet@ea000 {
505 phy-handle = <&phy2>;
506 phy-connection-type = "sgmii";
507 };
508
509 ethernet@f0000 {
510 phy-handle = <&xauiphy1>;
511 phy-connection-type = "xgmii";
512 };
513
514 ethernet@f2000 {
515 phy-handle = <&xauiphy2>;
516 phy-connection-type = "xgmii";
517 };
518
519 xfimdio0: mdio@f1000 {
520 status = "disabled";
521
522 xfiphy1: ethernet-phy@0 {
523 compatible = "ethernet-phy-ieee802.3-c45";
524 reg = <0x0>;
525 };
526 };
527
528 xfimdio1: mdio@f3000 {
529 status = "disabled";
530
531 xfiphy2: ethernet-phy@0 {
532 compatible = "ethernet-phy-ieee802.3-c45";
533 reg = <0x0>;
534 };
535 };
536 };
537
538 fman@500000 {
539 port@84000 {
540 status = "disabled";
541 };
542
543 port@85000 {
544 status = "disabled";
545 };
546
547 port@86000 {
548 status = "disabled";
549 };
550
551 port@87000 {
552 status = "disabled";
553 };
554
555 ethernet@e0000 {
556 phy-handle = <&phy13>;
557 phy-connection-type = "sgmii";
558 };
559
560 ethernet@e2000 {
561 phy-handle = <&phy14>;
562 phy-connection-type = "sgmii";
563 };
564
565 ethernet@e4000 {
566 phy-handle = <&phy15>;
567 phy-connection-type = "sgmii";
568 };
569
570 ethernet@e6000 {
571 phy-handle = <&phy16>;
572 phy-connection-type = "sgmii";
573 };
574
575 ethernet@e8000 {
576 phy-handle = <&phyrgmii1>;
577 phy-connection-type = "rgmii";
578 };
579
580 ethernet@ea000 {
581 phy-handle = <&phy10>;
582 phy-connection-type = "sgmii";
583 };
584
585 ethernet@f0000 {
586 phy-handle = <&xauiphy3>;
587 phy-connection-type = "xgmii";
588 };
589
590 ethernet@f2000 {
591 phy-handle = <&xauiphy4>;
592 phy-connection-type = "xgmii";
593 };
594
595 xfimdio2: mdio@f1000 {
596 status = "disabled";
597
598 xfiphy3: ethernet-phy@0 {
599 compatible = "ethernet-phy-ieee802.3-c45";
600 reg = <0x0>;
601 };
602 };
603
604 xfimdio3: mdio@f3000 {
605 status = "disabled";
606
607 xfiphy4: ethernet-phy@0 {
608 compatible = "ethernet-phy-ieee802.3-c45";
609 reg = <0x0>;
610 };
611 };
612
613 mdio@fd000 {
614 xauiphy1: ethernet-phy@0 {
615 compatible = "ethernet-phy-ieee802.3-c45";
616 reg = <0x0>;
617 };
618
619 xauiphy2: ethernet-phy@1 {
620 compatible = "ethernet-phy-ieee802.3-c45";
621 reg = <0x1>;
622 };
623
624 xauiphy3: ethernet-phy@2 {
625 compatible = "ethernet-phy-ieee802.3-c45";
626 reg = <0x2>;
627 };
628
629 xauiphy4: ethernet-phy@3 {
630 compatible = "ethernet-phy-ieee802.3-c45";
631 reg = <0x3>;
632 };
633 };
634 };
237 }; 635 };
238 636
239 pci0: pcie@ffe240000 { 637 pci0: pcie@ffe240000 {
diff --git a/arch/powerpc/boot/dts/fsl/t4240rdb.dts b/arch/powerpc/boot/dts/fsl/t4240rdb.dts
index 6e820a875621..cc0a264b8acb 100644
--- a/arch/powerpc/boot/dts/fsl/t4240rdb.dts
+++ b/arch/powerpc/boot/dts/fsl/t4240rdb.dts
@@ -1,7 +1,7 @@
1/* 1/*
2 * T4240RDB Device Tree Source 2 * T4240RDB Device Tree Source
3 * 3 *
4 * Copyright 2014 Freescale Semiconductor Inc. 4 * Copyright 2014 - 2015 Freescale Semiconductor Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
@@ -41,6 +41,17 @@
41 #size-cells = <2>; 41 #size-cells = <2>;
42 interrupt-parent = <&mpic>; 42 interrupt-parent = <&mpic>;
43 43
44 aliases {
45 sgmii_phy21 = &sgmiiphy21;
46 sgmii_phy22 = &sgmiiphy22;
47 sgmii_phy23 = &sgmiiphy23;
48 sgmii_phy24 = &sgmiiphy24;
49 sgmii_phy41 = &sgmiiphy41;
50 sgmii_phy42 = &sgmiiphy42;
51 sgmii_phy43 = &sgmiiphy43;
52 sgmii_phy44 = &sgmiiphy44;
53 };
54
44 ifc: localbus@ffe124000 { 55 ifc: localbus@ffe124000 {
45 reg = <0xf 0xfe124000 0 0x2000>; 56 reg = <0xf 0xfe124000 0 0x2000>;
46 ranges = <0 0 0xf 0xe8000000 0x08000000 57 ranges = <0 0 0xf 0xe8000000 0x08000000
@@ -107,7 +118,7 @@
107 flash@0 { 118 flash@0 {
108 #address-cells = <1>; 119 #address-cells = <1>;
109 #size-cells = <1>; 120 #size-cells = <1>;
110 compatible = "sst,sst25wf040"; 121 compatible = "sst,sst25wf040", "jedec,spi-nor";
111 reg = <0>; 122 reg = <0>;
112 spi-max-frequency = <40000000>; /* input clock */ 123 spi-max-frequency = <40000000>; /* input clock */
113 }; 124 };
@@ -136,6 +147,142 @@
136 sdhc@114000 { 147 sdhc@114000 {
137 voltage-ranges = <1800 1800 3300 3300>; 148 voltage-ranges = <1800 1800 3300 3300>;
138 }; 149 };
150
151 fman@400000 {
152 ethernet@e0000 {
153 phy-handle = <&sgmiiphy21>;
154 phy-connection-type = "sgmii";
155 };
156
157 ethernet@e2000 {
158 phy-handle = <&sgmiiphy22>;
159 phy-connection-type = "sgmii";
160 };
161
162 ethernet@e4000 {
163 phy-handle = <&sgmiiphy23>;
164 phy-connection-type = "sgmii";
165 };
166
167 ethernet@e6000 {
168 phy-handle = <&sgmiiphy24>;
169 phy-connection-type = "sgmii";
170 };
171
172 ethernet@e8000 {
173 status = "disabled";
174 };
175
176 ethernet@ea000 {
177 status = "disabled";
178 };
179
180 ethernet@f0000 {
181 phy-handle = <&xfiphy1>;
182 phy-connection-type = "xgmii";
183 };
184
185 ethernet@f2000 {
186 phy-handle = <&xfiphy2>;
187 phy-connection-type = "xgmii";
188 };
189 };
190
191 fman@500000 {
192 ethernet@e0000 {
193 phy-handle = <&sgmiiphy41>;
194 phy-connection-type = "sgmii";
195 };
196
197 ethernet@e2000 {
198 phy-handle = <&sgmiiphy42>;
199 phy-connection-type = "sgmii";
200 };
201
202 ethernet@e4000 {
203 phy-handle = <&sgmiiphy43>;
204 phy-connection-type = "sgmii";
205 };
206
207 ethernet@e6000 {
208 phy-handle = <&sgmiiphy44>;
209 phy-connection-type = "sgmii";
210 };
211
212 ethernet@e8000 {
213 status = "disabled";
214 };
215
216 ethernet@ea000 {
217 status = "disabled";
218 };
219
220 ethernet@f0000 {
221 phy-handle = <&xfiphy3>;
222 phy-connection-type = "xgmii";
223 };
224
225 ethernet@f2000 {
226 phy-handle = <&xfiphy4>;
227 phy-connection-type = "xgmii";
228 };
229
230 mdio@fc000 {
231 sgmiiphy21: ethernet-phy@0 {
232 reg = <0x0>;
233 };
234
235 sgmiiphy22: ethernet-phy@1 {
236 reg = <0x1>;
237 };
238
239 sgmiiphy23: ethernet-phy@2 {
240 reg = <0x2>;
241 };
242
243 sgmiiphy24: ethernet-phy@3 {
244 reg = <0x3>;
245 };
246
247 sgmiiphy41: ethernet-phy@4 {
248 reg = <0x4>;
249 };
250
251 sgmiiphy42: ethernet-phy@5 {
252 reg = <0x5>;
253 };
254
255 sgmiiphy43: ethernet-phy@6 {
256 reg = <0x6>;
257 };
258
259 sgmiiphy44: ethernet-phy@7 {
260 reg = <0x7>;
261 };
262 };
263
264 mdio@fd000 {
265 xfiphy1: ethernet-phy@10 {
266 compatible = "ethernet-phy-ieee802.3-c45";
267 reg = <0x10>;
268 };
269
270 xfiphy2: ethernet-phy@11 {
271 compatible = "ethernet-phy-ieee802.3-c45";
272 reg = <0x11>;
273 };
274
275 xfiphy3: ethernet-phy@13 {
276 compatible = "ethernet-phy-ieee802.3-c45";
277 reg = <0x13>;
278 };
279
280 xfiphy4: ethernet-phy@12 {
281 compatible = "ethernet-phy-ieee802.3-c45";
282 reg = <0x12>;
283 };
284 };
285 };
139 }; 286 };
140 287
141 pci0: pcie@ffe240000 { 288 pci0: pcie@ffe240000 {
diff --git a/arch/powerpc/boot/dts/gef_ppc9a.dts b/arch/powerpc/boot/dts/gef_ppc9a.dts
deleted file mode 100644
index 83eb0fda2666..000000000000
--- a/arch/powerpc/boot/dts/gef_ppc9a.dts
+++ /dev/null
@@ -1,425 +0,0 @@
1/*
2 * GE PPC9A Device Tree Source
3 *
4 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * Based on: SBS CM6 Device Tree Source
12 * Copyright 2007 SBS Technologies GmbH & Co. KG
13 * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
14 * Copyright 2006 Freescale Semiconductor Inc.
15 */
16
17/*
18 * Compiled with dtc -I dts -O dtb -o gef_ppc9a.dtb gef_ppc9a.dts
19 */
20
21/dts-v1/;
22
23/ {
24 model = "GEF_PPC9A";
25 compatible = "gef,ppc9a";
26 #address-cells = <1>;
27 #size-cells = <1>;
28
29 aliases {
30 ethernet0 = &enet0;
31 ethernet1 = &enet1;
32 serial0 = &serial0;
33 serial1 = &serial1;
34 pci0 = &pci0;
35 };
36
37 cpus {
38 #address-cells = <1>;
39 #size-cells = <0>;
40
41 PowerPC,8641@0 {
42 device_type = "cpu";
43 reg = <0>;
44 d-cache-line-size = <32>; // 32 bytes
45 i-cache-line-size = <32>; // 32 bytes
46 d-cache-size = <32768>; // L1, 32K
47 i-cache-size = <32768>; // L1, 32K
48 timebase-frequency = <0>; // From uboot
49 bus-frequency = <0>; // From uboot
50 clock-frequency = <0>; // From uboot
51 };
52 PowerPC,8641@1 {
53 device_type = "cpu";
54 reg = <1>;
55 d-cache-line-size = <32>; // 32 bytes
56 i-cache-line-size = <32>; // 32 bytes
57 d-cache-size = <32768>; // L1, 32K
58 i-cache-size = <32768>; // L1, 32K
59 timebase-frequency = <0>; // From uboot
60 bus-frequency = <0>; // From uboot
61 clock-frequency = <0>; // From uboot
62 };
63 };
64
65 memory {
66 device_type = "memory";
67 reg = <0x0 0x40000000>; // set by uboot
68 };
69
70 localbus@fef05000 {
71 #address-cells = <2>;
72 #size-cells = <1>;
73 compatible = "fsl,mpc8641-localbus", "simple-bus";
74 reg = <0xfef05000 0x1000>;
75 interrupts = <19 2>;
76 interrupt-parent = <&mpic>;
77
78 ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
79 1 0 0xe8000000 0x08000000 // Paged Flash 0
80 2 0 0xe0000000 0x08000000 // Paged Flash 1
81 3 0 0xfc100000 0x00020000 // NVRAM
82 4 0 0xfc000000 0x00008000 // FPGA
83 5 0 0xfc008000 0x00008000 // AFIX FPGA
84 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit)
85 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit)
86
87 /* flash@0,0 is a mirror of part of the memory in flash@1,0
88 flash@0,0 {
89 compatible = "gef,ppc9a-firmware-mirror", "cfi-flash";
90 reg = <0x0 0x0 0x1000000>;
91 bank-width = <4>;
92 device-width = <2>;
93 #address-cells = <1>;
94 #size-cells = <1>;
95 partition@0 {
96 label = "firmware";
97 reg = <0x0 0x1000000>;
98 read-only;
99 };
100 };
101 */
102
103 flash@1,0 {
104 compatible = "gef,ppc9a-paged-flash", "cfi-flash";
105 reg = <0x1 0x0 0x8000000>;
106 bank-width = <4>;
107 device-width = <2>;
108 #address-cells = <1>;
109 #size-cells = <1>;
110 partition@0 {
111 label = "user";
112 reg = <0x0 0x7800000>;
113 };
114 partition@7800000 {
115 label = "firmware";
116 reg = <0x7800000 0x800000>;
117 read-only;
118 };
119 };
120
121 nvram@3,0 {
122 device_type = "nvram";
123 compatible = "simtek,stk14ca8";
124 reg = <0x3 0x0 0x20000>;
125 };
126
127 fpga@4,0 {
128 compatible = "gef,ppc9a-fpga-regs";
129 reg = <0x4 0x0 0x40>;
130 };
131
132 wdt@4,2000 {
133 compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00",
134 "gef,fpga-wdt";
135 reg = <0x4 0x2000 0x8>;
136 interrupts = <0x1a 0x4>;
137 interrupt-parent = <&gef_pic>;
138 };
139 /* Second watchdog available, driver currently supports one.
140 wdt@4,2010 {
141 compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00",
142 "gef,fpga-wdt";
143 reg = <0x4 0x2010 0x8>;
144 interrupts = <0x1b 0x4>;
145 interrupt-parent = <&gef_pic>;
146 };
147 */
148 gef_pic: pic@4,4000 {
149 #interrupt-cells = <1>;
150 interrupt-controller;
151 compatible = "gef,ppc9a-fpga-pic", "gef,fpga-pic-1.00";
152 reg = <0x4 0x4000 0x20>;
153 interrupts = <0x8
154 0x9>;
155 interrupt-parent = <&mpic>;
156
157 };
158 gef_gpio: gpio@7,14000 {
159 #gpio-cells = <2>;
160 compatible = "gef,ppc9a-gpio", "gef,sbc610-gpio";
161 reg = <0x7 0x14000 0x24>;
162 gpio-controller;
163 };
164 };
165
166 soc@fef00000 {
167 #address-cells = <1>;
168 #size-cells = <1>;
169 #interrupt-cells = <2>;
170 device_type = "soc";
171 compatible = "fsl,mpc8641-soc", "simple-bus";
172 ranges = <0x0 0xfef00000 0x00100000>;
173 bus-frequency = <33333333>;
174
175 mcm-law@0 {
176 compatible = "fsl,mcm-law";
177 reg = <0x0 0x1000>;
178 fsl,num-laws = <10>;
179 };
180
181 mcm@1000 {
182 compatible = "fsl,mpc8641-mcm", "fsl,mcm";
183 reg = <0x1000 0x1000>;
184 interrupts = <17 2>;
185 interrupt-parent = <&mpic>;
186 };
187
188 i2c1: i2c@3000 {
189 #address-cells = <1>;
190 #size-cells = <0>;
191 compatible = "fsl-i2c";
192 reg = <0x3000 0x100>;
193 interrupts = <0x2b 0x2>;
194 interrupt-parent = <&mpic>;
195 dfsrr;
196
197 hwmon@48 {
198 compatible = "national,lm92";
199 reg = <0x48>;
200 };
201
202 hwmon@4c {
203 compatible = "adi,adt7461";
204 reg = <0x4c>;
205 };
206
207 rtc@51 {
208 compatible = "epson,rx8581";
209 reg = <0x00000051>;
210 };
211
212 eti@6b {
213 compatible = "dallas,ds1682";
214 reg = <0x6b>;
215 };
216 };
217
218 i2c2: i2c@3100 {
219 #address-cells = <1>;
220 #size-cells = <0>;
221 compatible = "fsl-i2c";
222 reg = <0x3100 0x100>;
223 interrupts = <0x2b 0x2>;
224 interrupt-parent = <&mpic>;
225 dfsrr;
226 };
227
228 dma@21300 {
229 #address-cells = <1>;
230 #size-cells = <1>;
231 compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
232 reg = <0x21300 0x4>;
233 ranges = <0x0 0x21100 0x200>;
234 cell-index = <0>;
235 dma-channel@0 {
236 compatible = "fsl,mpc8641-dma-channel",
237 "fsl,eloplus-dma-channel";
238 reg = <0x0 0x80>;
239 cell-index = <0>;
240 interrupt-parent = <&mpic>;
241 interrupts = <20 2>;
242 };
243 dma-channel@80 {
244 compatible = "fsl,mpc8641-dma-channel",
245 "fsl,eloplus-dma-channel";
246 reg = <0x80 0x80>;
247 cell-index = <1>;
248 interrupt-parent = <&mpic>;
249 interrupts = <21 2>;
250 };
251 dma-channel@100 {
252 compatible = "fsl,mpc8641-dma-channel",
253 "fsl,eloplus-dma-channel";
254 reg = <0x100 0x80>;
255 cell-index = <2>;
256 interrupt-parent = <&mpic>;
257 interrupts = <22 2>;
258 };
259 dma-channel@180 {
260 compatible = "fsl,mpc8641-dma-channel",
261 "fsl,eloplus-dma-channel";
262 reg = <0x180 0x80>;
263 cell-index = <3>;
264 interrupt-parent = <&mpic>;
265 interrupts = <23 2>;
266 };
267 };
268
269 enet0: ethernet@24000 {
270 #address-cells = <1>;
271 #size-cells = <1>;
272 cell-index = <0>;
273 device_type = "network";
274 model = "TSEC";
275 compatible = "gianfar";
276 reg = <0x24000 0x1000>;
277 ranges = <0x0 0x24000 0x1000>;
278 local-mac-address = [ 00 00 00 00 00 00 ];
279 interrupts = <29 2 30 2 34 2>;
280 interrupt-parent = <&mpic>;
281 tbi-handle = <&tbi0>;
282 phy-handle = <&phy0>;
283 phy-connection-type = "gmii";
284
285 mdio@520 {
286 #address-cells = <1>;
287 #size-cells = <0>;
288 compatible = "fsl,gianfar-mdio";
289 reg = <0x520 0x20>;
290
291 phy0: ethernet-phy@0 {
292 interrupt-parent = <&gef_pic>;
293 interrupts = <0x9 0x4>;
294 reg = <1>;
295 };
296 phy2: ethernet-phy@2 {
297 interrupt-parent = <&gef_pic>;
298 interrupts = <0x8 0x4>;
299 reg = <3>;
300 };
301 tbi0: tbi-phy@11 {
302 reg = <0x11>;
303 device_type = "tbi-phy";
304 };
305 };
306 };
307
308 enet1: ethernet@26000 {
309 #address-cells = <1>;
310 #size-cells = <1>;
311 cell-index = <2>;
312 device_type = "network";
313 model = "TSEC";
314 compatible = "gianfar";
315 reg = <0x26000 0x1000>;
316 ranges = <0x0 0x26000 0x1000>;
317 local-mac-address = [ 00 00 00 00 00 00 ];
318 interrupts = <31 2 32 2 33 2>;
319 interrupt-parent = <&mpic>;
320 tbi-handle = <&tbi2>;
321 phy-handle = <&phy2>;
322 phy-connection-type = "gmii";
323
324 mdio@520 {
325 #address-cells = <1>;
326 #size-cells = <0>;
327 compatible = "fsl,gianfar-tbi";
328 reg = <0x520 0x20>;
329
330 tbi2: tbi-phy@11 {
331 reg = <0x11>;
332 device_type = "tbi-phy";
333 };
334 };
335 };
336
337 serial0: serial@4500 {
338 cell-index = <0>;
339 device_type = "serial";
340 compatible = "fsl,ns16550", "ns16550";
341 reg = <0x4500 0x100>;
342 clock-frequency = <0>;
343 interrupts = <0x2a 0x2>;
344 interrupt-parent = <&mpic>;
345 };
346
347 serial1: serial@4600 {
348 cell-index = <1>;
349 device_type = "serial";
350 compatible = "fsl,ns16550", "ns16550";
351 reg = <0x4600 0x100>;
352 clock-frequency = <0>;
353 interrupts = <0x1c 0x2>;
354 interrupt-parent = <&mpic>;
355 };
356
357 mpic: pic@40000 {
358 clock-frequency = <0>;
359 interrupt-controller;
360 #address-cells = <0>;
361 #interrupt-cells = <2>;
362 reg = <0x40000 0x40000>;
363 compatible = "chrp,open-pic";
364 device_type = "open-pic";
365 };
366
367 msi@41600 {
368 compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
369 reg = <0x41600 0x80>;
370 msi-available-ranges = <0 0x100>;
371 interrupts = <
372 0xe0 0
373 0xe1 0
374 0xe2 0
375 0xe3 0
376 0xe4 0
377 0xe5 0
378 0xe6 0
379 0xe7 0>;
380 interrupt-parent = <&mpic>;
381 };
382
383 global-utilities@e0000 {
384 compatible = "fsl,mpc8641-guts";
385 reg = <0xe0000 0x1000>;
386 fsl,has-rstcr;
387 };
388 };
389
390 pci0: pcie@fef08000 {
391 compatible = "fsl,mpc8641-pcie";
392 device_type = "pci";
393 #interrupt-cells = <1>;
394 #size-cells = <2>;
395 #address-cells = <3>;
396 reg = <0xfef08000 0x1000>;
397 bus-range = <0x0 0xff>;
398 ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
399 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
400 clock-frequency = <33333333>;
401 interrupt-parent = <&mpic>;
402 interrupts = <0x18 0x2>;
403 interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
404 interrupt-map = <
405 0x0000 0x0 0x0 0x1 &mpic 0x0 0x1
406 0x0000 0x0 0x0 0x2 &mpic 0x1 0x1
407 0x0000 0x0 0x0 0x3 &mpic 0x2 0x1
408 0x0000 0x0 0x0 0x4 &mpic 0x3 0x1
409 >;
410
411 pcie@0 {
412 reg = <0 0 0 0 0>;
413 #size-cells = <2>;
414 #address-cells = <3>;
415 device_type = "pci";
416 ranges = <0x02000000 0x0 0x80000000
417 0x02000000 0x0 0x80000000
418 0x0 0x40000000
419
420 0x01000000 0x0 0x00000000
421 0x01000000 0x0 0x00000000
422 0x0 0x00400000>;
423 };
424 };
425};
diff --git a/arch/powerpc/boot/dts/gef_sbc310.dts b/arch/powerpc/boot/dts/gef_sbc310.dts
deleted file mode 100644
index d426dd3de9ef..000000000000
--- a/arch/powerpc/boot/dts/gef_sbc310.dts
+++ /dev/null
@@ -1,459 +0,0 @@
1/*
2 * GE SBC310 Device Tree Source
3 *
4 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * Based on: SBS CM6 Device Tree Source
12 * Copyright 2007 SBS Technologies GmbH & Co. KG
13 * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
14 * Copyright 2006 Freescale Semiconductor Inc.
15 */
16
17/*
18 * Compiled with dtc -I dts -O dtb -o gef_sbc310.dtb gef_sbc310.dts
19 */
20
21/dts-v1/;
22
23/ {
24 model = "GEF_SBC310";
25 compatible = "gef,sbc310";
26 #address-cells = <1>;
27 #size-cells = <1>;
28
29 aliases {
30 ethernet0 = &enet0;
31 ethernet1 = &enet1;
32 serial0 = &serial0;
33 serial1 = &serial1;
34 pci0 = &pci0;
35 pci1 = &pci1;
36 };
37
38 cpus {
39 #address-cells = <1>;
40 #size-cells = <0>;
41
42 PowerPC,8641@0 {
43 device_type = "cpu";
44 reg = <0>;
45 d-cache-line-size = <32>; // 32 bytes
46 i-cache-line-size = <32>; // 32 bytes
47 d-cache-size = <32768>; // L1, 32K
48 i-cache-size = <32768>; // L1, 32K
49 timebase-frequency = <0>; // From uboot
50 bus-frequency = <0>; // From uboot
51 clock-frequency = <0>; // From uboot
52 };
53 PowerPC,8641@1 {
54 device_type = "cpu";
55 reg = <1>;
56 d-cache-line-size = <32>; // 32 bytes
57 i-cache-line-size = <32>; // 32 bytes
58 d-cache-size = <32768>; // L1, 32K
59 i-cache-size = <32768>; // L1, 32K
60 timebase-frequency = <0>; // From uboot
61 bus-frequency = <0>; // From uboot
62 clock-frequency = <0>; // From uboot
63 };
64 };
65
66 memory {
67 device_type = "memory";
68 reg = <0x0 0x40000000>; // set by uboot
69 };
70
71 localbus@fef05000 {
72 #address-cells = <2>;
73 #size-cells = <1>;
74 compatible = "fsl,mpc8641-localbus", "simple-bus";
75 reg = <0xfef05000 0x1000>;
76 interrupts = <19 2>;
77 interrupt-parent = <&mpic>;
78
79 ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
80 1 0 0xe0000000 0x08000000 // Paged Flash 0
81 2 0 0xe8000000 0x08000000 // Paged Flash 1
82 3 0 0xfc100000 0x00020000 // NVRAM
83 4 0 0xfc000000 0x00010000>; // FPGA
84
85 /* flash@0,0 is a mirror of part of the memory in flash@1,0
86 flash@0,0 {
87 compatible = "gef,sbc310-firmware-mirror", "cfi-flash";
88 reg = <0x0 0x0 0x01000000>;
89 bank-width = <2>;
90 device-width = <2>;
91 #address-cells = <1>;
92 #size-cells = <1>;
93 partition@0 {
94 label = "firmware";
95 reg = <0x0 0x01000000>;
96 read-only;
97 };
98 };
99 */
100
101 flash@1,0 {
102 compatible = "gef,sbc310-paged-flash", "cfi-flash";
103 reg = <0x1 0x0 0x8000000>;
104 bank-width = <2>;
105 device-width = <2>;
106 #address-cells = <1>;
107 #size-cells = <1>;
108 partition@0 {
109 label = "user";
110 reg = <0x0 0x7800000>;
111 };
112 partition@7800000 {
113 label = "firmware";
114 reg = <0x7800000 0x800000>;
115 read-only;
116 };
117 };
118
119 nvram@3,0 {
120 device_type = "nvram";
121 compatible = "simtek,stk14ca8";
122 reg = <0x3 0x0 0x20000>;
123 };
124
125 fpga@4,0 {
126 compatible = "gef,fpga-regs";
127 reg = <0x4 0x0 0x40>;
128 };
129
130 wdt@4,2000 {
131 compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00",
132 "gef,fpga-wdt";
133 reg = <0x4 0x2000 0x8>;
134 interrupts = <0x1a 0x4>;
135 interrupt-parent = <&gef_pic>;
136 };
137/*
138 wdt@4,2010 {
139 compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00",
140 "gef,fpga-wdt";
141 reg = <0x4 0x2010 0x8>;
142 interrupts = <0x1b 0x4>;
143 interrupt-parent = <&gef_pic>;
144 };
145*/
146 gef_pic: pic@4,4000 {
147 #interrupt-cells = <1>;
148 interrupt-controller;
149 compatible = "gef,sbc310-fpga-pic", "gef,fpga-pic";
150 reg = <0x4 0x4000 0x20>;
151 interrupts = <0x8
152 0x9>;
153 interrupt-parent = <&mpic>;
154
155 };
156 gef_gpio: gpio@4,8000 {
157 #gpio-cells = <2>;
158 compatible = "gef,sbc310-gpio";
159 reg = <0x4 0x8000 0x24>;
160 gpio-controller;
161 };
162 };
163
164 soc@fef00000 {
165 #address-cells = <1>;
166 #size-cells = <1>;
167 #interrupt-cells = <2>;
168 device_type = "soc";
169 compatible = "fsl,mpc8641-soc", "simple-bus";
170 ranges = <0x0 0xfef00000 0x00100000>;
171 bus-frequency = <33333333>;
172
173 mcm-law@0 {
174 compatible = "fsl,mcm-law";
175 reg = <0x0 0x1000>;
176 fsl,num-laws = <10>;
177 };
178
179 mcm@1000 {
180 compatible = "fsl,mpc8641-mcm", "fsl,mcm";
181 reg = <0x1000 0x1000>;
182 interrupts = <17 2>;
183 interrupt-parent = <&mpic>;
184 };
185
186 i2c1: i2c@3000 {
187 #address-cells = <1>;
188 #size-cells = <0>;
189 compatible = "fsl-i2c";
190 reg = <0x3000 0x100>;
191 interrupts = <0x2b 0x2>;
192 interrupt-parent = <&mpic>;
193 dfsrr;
194
195 rtc@51 {
196 compatible = "epson,rx8581";
197 reg = <0x00000051>;
198 };
199 };
200
201 i2c2: i2c@3100 {
202 #address-cells = <1>;
203 #size-cells = <0>;
204 compatible = "fsl-i2c";
205 reg = <0x3100 0x100>;
206 interrupts = <0x2b 0x2>;
207 interrupt-parent = <&mpic>;
208 dfsrr;
209
210 hwmon@48 {
211 compatible = "national,lm92";
212 reg = <0x48>;
213 };
214
215 hwmon@4c {
216 compatible = "adi,adt7461";
217 reg = <0x4c>;
218 };
219
220 eti@6b {
221 compatible = "dallas,ds1682";
222 reg = <0x6b>;
223 };
224 };
225
226 dma@21300 {
227 #address-cells = <1>;
228 #size-cells = <1>;
229 compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
230 reg = <0x21300 0x4>;
231 ranges = <0x0 0x21100 0x200>;
232 cell-index = <0>;
233 dma-channel@0 {
234 compatible = "fsl,mpc8641-dma-channel",
235 "fsl,eloplus-dma-channel";
236 reg = <0x0 0x80>;
237 cell-index = <0>;
238 interrupt-parent = <&mpic>;
239 interrupts = <20 2>;
240 };
241 dma-channel@80 {
242 compatible = "fsl,mpc8641-dma-channel",
243 "fsl,eloplus-dma-channel";
244 reg = <0x80 0x80>;
245 cell-index = <1>;
246 interrupt-parent = <&mpic>;
247 interrupts = <21 2>;
248 };
249 dma-channel@100 {
250 compatible = "fsl,mpc8641-dma-channel",
251 "fsl,eloplus-dma-channel";
252 reg = <0x100 0x80>;
253 cell-index = <2>;
254 interrupt-parent = <&mpic>;
255 interrupts = <22 2>;
256 };
257 dma-channel@180 {
258 compatible = "fsl,mpc8641-dma-channel",
259 "fsl,eloplus-dma-channel";
260 reg = <0x180 0x80>;
261 cell-index = <3>;
262 interrupt-parent = <&mpic>;
263 interrupts = <23 2>;
264 };
265 };
266
267 enet0: ethernet@24000 {
268 #address-cells = <1>;
269 #size-cells = <1>;
270 cell-index = <0>;
271 device_type = "network";
272 model = "TSEC";
273 compatible = "gianfar";
274 reg = <0x24000 0x1000>;
275 ranges = <0x0 0x24000 0x1000>;
276 local-mac-address = [ 00 00 00 00 00 00 ];
277 interrupts = <29 2 30 2 34 2>;
278 interrupt-parent = <&mpic>;
279 tbi-handle = <&tbi0>;
280 phy-handle = <&phy0>;
281 phy-connection-type = "gmii";
282
283 mdio@520 {
284 #address-cells = <1>;
285 #size-cells = <0>;
286 compatible = "fsl,gianfar-mdio";
287 reg = <0x520 0x20>;
288
289 phy0: ethernet-phy@0 {
290 interrupt-parent = <&gef_pic>;
291 interrupts = <0x9 0x4>;
292 reg = <1>;
293 };
294 phy2: ethernet-phy@2 {
295 interrupt-parent = <&gef_pic>;
296 interrupts = <0x8 0x4>;
297 reg = <3>;
298 };
299 tbi0: tbi-phy@11 {
300 reg = <0x11>;
301 device_type = "tbi-phy";
302 };
303 };
304 };
305
306 enet1: ethernet@26000 {
307 #address-cells = <1>;
308 #size-cells = <1>;
309 cell-index = <2>;
310 device_type = "network";
311 model = "TSEC";
312 compatible = "gianfar";
313 reg = <0x26000 0x1000>;
314 ranges = <0x0 0x26000 0x1000>;
315 local-mac-address = [ 00 00 00 00 00 00 ];
316 interrupts = <31 2 32 2 33 2>;
317 interrupt-parent = <&mpic>;
318 tbi-handle = <&tbi2>;
319 phy-handle = <&phy2>;
320 phy-connection-type = "gmii";
321
322 mdio@520 {
323 #address-cells = <1>;
324 #size-cells = <0>;
325 compatible = "fsl,gianfar-tbi";
326 reg = <0x520 0x20>;
327
328 tbi2: tbi-phy@11 {
329 reg = <0x11>;
330 device_type = "tbi-phy";
331 };
332 };
333 };
334
335 serial0: serial@4500 {
336 cell-index = <0>;
337 device_type = "serial";
338 compatible = "fsl,ns16550", "ns16550";
339 reg = <0x4500 0x100>;
340 clock-frequency = <0>;
341 interrupts = <0x2a 0x2>;
342 interrupt-parent = <&mpic>;
343 };
344
345 serial1: serial@4600 {
346 cell-index = <1>;
347 device_type = "serial";
348 compatible = "fsl,ns16550", "ns16550";
349 reg = <0x4600 0x100>;
350 clock-frequency = <0>;
351 interrupts = <0x1c 0x2>;
352 interrupt-parent = <&mpic>;
353 };
354
355 mpic: pic@40000 {
356 clock-frequency = <0>;
357 interrupt-controller;
358 #address-cells = <0>;
359 #interrupt-cells = <2>;
360 reg = <0x40000 0x40000>;
361 compatible = "chrp,open-pic";
362 device_type = "open-pic";
363 };
364
365 msi@41600 {
366 compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
367 reg = <0x41600 0x80>;
368 msi-available-ranges = <0 0x100>;
369 interrupts = <
370 0xe0 0
371 0xe1 0
372 0xe2 0
373 0xe3 0
374 0xe4 0
375 0xe5 0
376 0xe6 0
377 0xe7 0>;
378 interrupt-parent = <&mpic>;
379 };
380
381 global-utilities@e0000 {
382 compatible = "fsl,mpc8641-guts";
383 reg = <0xe0000 0x1000>;
384 fsl,has-rstcr;
385 };
386 };
387
388 pci0: pcie@fef08000 {
389 compatible = "fsl,mpc8641-pcie";
390 device_type = "pci";
391 #interrupt-cells = <1>;
392 #size-cells = <2>;
393 #address-cells = <3>;
394 reg = <0xfef08000 0x1000>;
395 bus-range = <0x0 0xff>;
396 ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
397 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
398 clock-frequency = <33333333>;
399 interrupt-parent = <&mpic>;
400 interrupts = <0x18 0x2>;
401 interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
402 interrupt-map = <
403 0x0000 0x0 0x0 0x1 &mpic 0x0 0x2
404 0x0000 0x0 0x0 0x2 &mpic 0x1 0x2
405 0x0000 0x0 0x0 0x3 &mpic 0x2 0x2
406 0x0000 0x0 0x0 0x4 &mpic 0x3 0x2
407 >;
408
409 pcie@0 {
410 reg = <0 0 0 0 0>;
411 #size-cells = <2>;
412 #address-cells = <3>;
413 device_type = "pci";
414 ranges = <0x02000000 0x0 0x80000000
415 0x02000000 0x0 0x80000000
416 0x0 0x40000000
417
418 0x01000000 0x0 0x00000000
419 0x01000000 0x0 0x00000000
420 0x0 0x00400000>;
421 };
422 };
423
424 pci1: pcie@fef09000 {
425 compatible = "fsl,mpc8641-pcie";
426 device_type = "pci";
427 #interrupt-cells = <1>;
428 #size-cells = <2>;
429 #address-cells = <3>;
430 reg = <0xfef09000 0x1000>;
431 bus-range = <0x0 0xff>;
432 ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0x0 0x20000000
433 0x01000000 0x0 0x00000000 0xfe400000 0x0 0x00400000>;
434 clock-frequency = <33333333>;
435 interrupt-parent = <&mpic>;
436 interrupts = <0x19 0x2>;
437 interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
438 interrupt-map = <
439 0x0000 0x0 0x0 0x1 &mpic 0x4 0x2
440 0x0000 0x0 0x0 0x2 &mpic 0x5 0x2
441 0x0000 0x0 0x0 0x3 &mpic 0x6 0x2
442 0x0000 0x0 0x0 0x4 &mpic 0x7 0x2
443 >;
444
445 pcie@0 {
446 reg = <0 0 0 0 0>;
447 #size-cells = <2>;
448 #address-cells = <3>;
449 device_type = "pci";
450 ranges = <0x02000000 0x0 0xc0000000
451 0x02000000 0x0 0xc0000000
452 0x0 0x20000000
453
454 0x01000000 0x0 0x00000000
455 0x01000000 0x0 0x00000000
456 0x0 0x00400000>;
457 };
458 };
459};
diff --git a/arch/powerpc/boot/dts/gef_sbc610.dts b/arch/powerpc/boot/dts/gef_sbc610.dts
deleted file mode 100644
index 5db3399b76b7..000000000000
--- a/arch/powerpc/boot/dts/gef_sbc610.dts
+++ /dev/null
@@ -1,423 +0,0 @@
1/*
2 * GE SBC610 Device Tree Source
3 *
4 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * Based on: SBS CM6 Device Tree Source
12 * Copyright 2007 SBS Technologies GmbH & Co. KG
13 * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
14 * Copyright 2006 Freescale Semiconductor Inc.
15 */
16
17/*
18 * Compiled with dtc -I dts -O dtb -o gef_sbc610.dtb gef_sbc610.dts
19 */
20
21/dts-v1/;
22
23/ {
24 model = "GEF_SBC610";
25 compatible = "gef,sbc610";
26 #address-cells = <1>;
27 #size-cells = <1>;
28
29 aliases {
30 ethernet0 = &enet0;
31 ethernet1 = &enet1;
32 serial0 = &serial0;
33 serial1 = &serial1;
34 pci0 = &pci0;
35 };
36
37 cpus {
38 #address-cells = <1>;
39 #size-cells = <0>;
40
41 PowerPC,8641@0 {
42 device_type = "cpu";
43 reg = <0>;
44 d-cache-line-size = <32>; // 32 bytes
45 i-cache-line-size = <32>; // 32 bytes
46 d-cache-size = <32768>; // L1, 32K
47 i-cache-size = <32768>; // L1, 32K
48 timebase-frequency = <0>; // From uboot
49 bus-frequency = <0>; // From uboot
50 clock-frequency = <0>; // From uboot
51 };
52 PowerPC,8641@1 {
53 device_type = "cpu";
54 reg = <1>;
55 d-cache-line-size = <32>; // 32 bytes
56 i-cache-line-size = <32>; // 32 bytes
57 d-cache-size = <32768>; // L1, 32K
58 i-cache-size = <32768>; // L1, 32K
59 timebase-frequency = <0>; // From uboot
60 bus-frequency = <0>; // From uboot
61 clock-frequency = <0>; // From uboot
62 };
63 };
64
65 memory {
66 device_type = "memory";
67 reg = <0x0 0x40000000>; // set by uboot
68 };
69
70 localbus@fef05000 {
71 #address-cells = <2>;
72 #size-cells = <1>;
73 compatible = "fsl,mpc8641-localbus", "simple-bus";
74 reg = <0xfef05000 0x1000>;
75 interrupts = <19 2>;
76 interrupt-parent = <&mpic>;
77
78 ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
79 1 0 0xe8000000 0x08000000 // Paged Flash 0
80 2 0 0xe0000000 0x08000000 // Paged Flash 1
81 3 0 0xfc100000 0x00020000 // NVRAM
82 4 0 0xfc000000 0x00008000 // FPGA
83 5 0 0xfc008000 0x00008000 // AFIX FPGA
84 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit)
85 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit)
86
87 /* flash@0,0 is a mirror of part of the memory in flash@1,0
88 flash@0,0 {
89 compatible = "gef,sbc610-firmware-mirror", "cfi-flash";
90 reg = <0x0 0x0 0x1000000>;
91 bank-width = <4>;
92 device-width = <2>;
93 #address-cells = <1>;
94 #size-cells = <1>;
95 partition@0 {
96 label = "firmware";
97 reg = <0x0 0x1000000>;
98 read-only;
99 };
100 };
101 */
102
103 flash@1,0 {
104 compatible = "gef,sbc610-paged-flash", "cfi-flash";
105 reg = <0x1 0x0 0x8000000>;
106 bank-width = <4>;
107 device-width = <2>;
108 #address-cells = <1>;
109 #size-cells = <1>;
110 partition@0 {
111 label = "user";
112 reg = <0x0 0x7800000>;
113 };
114 partition@7800000 {
115 label = "firmware";
116 reg = <0x7800000 0x800000>;
117 read-only;
118 };
119 };
120
121 nvram@3,0 {
122 device_type = "nvram";
123 compatible = "simtek,stk14ca8";
124 reg = <0x3 0x0 0x20000>;
125 };
126
127 fpga@4,0 {
128 compatible = "gef,fpga-regs";
129 reg = <0x4 0x0 0x40>;
130 };
131
132 wdt@4,2000 {
133 compatible = "gef,fpga-wdt";
134 reg = <0x4 0x2000 0x8>;
135 interrupts = <0x1a 0x4>;
136 interrupt-parent = <&gef_pic>;
137 };
138 /* Second watchdog available, driver currently supports one.
139 wdt@4,2010 {
140 compatible = "gef,fpga-wdt";
141 reg = <0x4 0x2010 0x8>;
142 interrupts = <0x1b 0x4>;
143 interrupt-parent = <&gef_pic>;
144 };
145 */
146 gef_pic: pic@4,4000 {
147 #interrupt-cells = <1>;
148 interrupt-controller;
149 compatible = "gef,fpga-pic";
150 reg = <0x4 0x4000 0x20>;
151 interrupts = <0x8
152 0x9>;
153 interrupt-parent = <&mpic>;
154
155 };
156 gef_gpio: gpio@7,14000 {
157 #gpio-cells = <2>;
158 compatible = "gef,sbc610-gpio";
159 reg = <0x7 0x14000 0x24>;
160 gpio-controller;
161 };
162 };
163
164 soc@fef00000 {
165 #address-cells = <1>;
166 #size-cells = <1>;
167 #interrupt-cells = <2>;
168 device_type = "soc";
169 compatible = "simple-bus";
170 ranges = <0x0 0xfef00000 0x00100000>;
171 bus-frequency = <33333333>;
172
173 mcm-law@0 {
174 compatible = "fsl,mcm-law";
175 reg = <0x0 0x1000>;
176 fsl,num-laws = <10>;
177 };
178
179 mcm@1000 {
180 compatible = "fsl,mpc8641-mcm", "fsl,mcm";
181 reg = <0x1000 0x1000>;
182 interrupts = <17 2>;
183 interrupt-parent = <&mpic>;
184 };
185
186 i2c1: i2c@3000 {
187 #address-cells = <1>;
188 #size-cells = <0>;
189 compatible = "fsl-i2c";
190 reg = <0x3000 0x100>;
191 interrupts = <0x2b 0x2>;
192 interrupt-parent = <&mpic>;
193 dfsrr;
194
195 hwmon@48 {
196 compatible = "national,lm92";
197 reg = <0x48>;
198 };
199
200 hwmon@4c {
201 compatible = "adi,adt7461";
202 reg = <0x4c>;
203 };
204
205 rtc@51 {
206 compatible = "epson,rx8581";
207 reg = <0x00000051>;
208 };
209
210 eti@6b {
211 compatible = "dallas,ds1682";
212 reg = <0x6b>;
213 };
214 };
215
216 i2c2: i2c@3100 {
217 #address-cells = <1>;
218 #size-cells = <0>;
219 compatible = "fsl-i2c";
220 reg = <0x3100 0x100>;
221 interrupts = <0x2b 0x2>;
222 interrupt-parent = <&mpic>;
223 dfsrr;
224 };
225
226 dma@21300 {
227 #address-cells = <1>;
228 #size-cells = <1>;
229 compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
230 reg = <0x21300 0x4>;
231 ranges = <0x0 0x21100 0x200>;
232 cell-index = <0>;
233 dma-channel@0 {
234 compatible = "fsl,mpc8641-dma-channel",
235 "fsl,eloplus-dma-channel";
236 reg = <0x0 0x80>;
237 cell-index = <0>;
238 interrupt-parent = <&mpic>;
239 interrupts = <20 2>;
240 };
241 dma-channel@80 {
242 compatible = "fsl,mpc8641-dma-channel",
243 "fsl,eloplus-dma-channel";
244 reg = <0x80 0x80>;
245 cell-index = <1>;
246 interrupt-parent = <&mpic>;
247 interrupts = <21 2>;
248 };
249 dma-channel@100 {
250 compatible = "fsl,mpc8641-dma-channel",
251 "fsl,eloplus-dma-channel";
252 reg = <0x100 0x80>;
253 cell-index = <2>;
254 interrupt-parent = <&mpic>;
255 interrupts = <22 2>;
256 };
257 dma-channel@180 {
258 compatible = "fsl,mpc8641-dma-channel",
259 "fsl,eloplus-dma-channel";
260 reg = <0x180 0x80>;
261 cell-index = <3>;
262 interrupt-parent = <&mpic>;
263 interrupts = <23 2>;
264 };
265 };
266
267 enet0: ethernet@24000 {
268 #address-cells = <1>;
269 #size-cells = <1>;
270 cell-index = <0>;
271 device_type = "network";
272 model = "TSEC";
273 compatible = "gianfar";
274 reg = <0x24000 0x1000>;
275 ranges = <0x0 0x24000 0x1000>;
276 local-mac-address = [ 00 00 00 00 00 00 ];
277 interrupts = <29 2 30 2 34 2>;
278 interrupt-parent = <&mpic>;
279 tbi-handle = <&tbi0>;
280 phy-handle = <&phy0>;
281 phy-connection-type = "gmii";
282
283 mdio@520 {
284 #address-cells = <1>;
285 #size-cells = <0>;
286 compatible = "fsl,gianfar-mdio";
287 reg = <0x520 0x20>;
288
289 phy0: ethernet-phy@0 {
290 interrupt-parent = <&gef_pic>;
291 interrupts = <0x9 0x4>;
292 reg = <1>;
293 };
294 phy2: ethernet-phy@2 {
295 interrupt-parent = <&gef_pic>;
296 interrupts = <0x8 0x4>;
297 reg = <3>;
298 };
299 tbi0: tbi-phy@11 {
300 reg = <0x11>;
301 device_type = "tbi-phy";
302 };
303 };
304 };
305
306 enet1: ethernet@26000 {
307 #address-cells = <1>;
308 #size-cells = <1>;
309 cell-index = <2>;
310 device_type = "network";
311 model = "TSEC";
312 compatible = "gianfar";
313 reg = <0x26000 0x1000>;
314 ranges = <0x0 0x26000 0x1000>;
315 local-mac-address = [ 00 00 00 00 00 00 ];
316 interrupts = <31 2 32 2 33 2>;
317 interrupt-parent = <&mpic>;
318 tbi-handle = <&tbi2>;
319 phy-handle = <&phy2>;
320 phy-connection-type = "gmii";
321
322 mdio@520 {
323 #address-cells = <1>;
324 #size-cells = <0>;
325 compatible = "fsl,gianfar-tbi";
326 reg = <0x520 0x20>;
327
328 tbi2: tbi-phy@11 {
329 reg = <0x11>;
330 device_type = "tbi-phy";
331 };
332 };
333 };
334
335 serial0: serial@4500 {
336 cell-index = <0>;
337 device_type = "serial";
338 compatible = "fsl,ns16550", "ns16550";
339 reg = <0x4500 0x100>;
340 clock-frequency = <0>;
341 interrupts = <0x2a 0x2>;
342 interrupt-parent = <&mpic>;
343 };
344
345 serial1: serial@4600 {
346 cell-index = <1>;
347 device_type = "serial";
348 compatible = "fsl,ns16550", "ns16550";
349 reg = <0x4600 0x100>;
350 clock-frequency = <0>;
351 interrupts = <0x1c 0x2>;
352 interrupt-parent = <&mpic>;
353 };
354
355 mpic: pic@40000 {
356 clock-frequency = <0>;
357 interrupt-controller;
358 #address-cells = <0>;
359 #interrupt-cells = <2>;
360 reg = <0x40000 0x40000>;
361 compatible = "chrp,open-pic";
362 device_type = "open-pic";
363 };
364
365 msi@41600 {
366 compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
367 reg = <0x41600 0x80>;
368 msi-available-ranges = <0 0x100>;
369 interrupts = <
370 0xe0 0
371 0xe1 0
372 0xe2 0
373 0xe3 0
374 0xe4 0
375 0xe5 0
376 0xe6 0
377 0xe7 0>;
378 interrupt-parent = <&mpic>;
379 };
380
381 global-utilities@e0000 {
382 compatible = "fsl,mpc8641-guts";
383 reg = <0xe0000 0x1000>;
384 fsl,has-rstcr;
385 };
386 };
387
388 pci0: pcie@fef08000 {
389 compatible = "fsl,mpc8641-pcie";
390 device_type = "pci";
391 #interrupt-cells = <1>;
392 #size-cells = <2>;
393 #address-cells = <3>;
394 reg = <0xfef08000 0x1000>;
395 bus-range = <0x0 0xff>;
396 ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
397 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
398 clock-frequency = <33333333>;
399 interrupt-parent = <&mpic>;
400 interrupts = <0x18 0x2>;
401 interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
402 interrupt-map = <
403 0x0000 0x0 0x0 0x1 &mpic 0x0 0x1
404 0x0000 0x0 0x0 0x2 &mpic 0x1 0x1
405 0x0000 0x0 0x0 0x3 &mpic 0x2 0x1
406 0x0000 0x0 0x0 0x4 &mpic 0x3 0x1
407 >;
408
409 pcie@0 {
410 reg = <0 0 0 0 0>;
411 #size-cells = <2>;
412 #address-cells = <3>;
413 device_type = "pci";
414 ranges = <0x02000000 0x0 0x80000000
415 0x02000000 0x0 0x80000000
416 0x0 0x40000000
417
418 0x01000000 0x0 0x00000000
419 0x01000000 0x0 0x00000000
420 0x0 0x00400000>;
421 };
422 };
423};
diff --git a/arch/powerpc/boot/dts/sbc8641d.dts b/arch/powerpc/boot/dts/sbc8641d.dts
deleted file mode 100644
index 68f0ed7626bd..000000000000
--- a/arch/powerpc/boot/dts/sbc8641d.dts
+++ /dev/null
@@ -1,447 +0,0 @@
1/*
2 * SBC8641D Device Tree Source
3 *
4 * Copyright 2008 Wind River Systems Inc.
5 *
6 * Paul Gortmaker (see MAINTAINERS for contact information)
7 *
8 * Based largely on the mpc8641_hpcn.dts by Freescale Semiconductor Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16/dts-v1/;
17
18/ {
19 model = "SBC8641D";
20 compatible = "wind,sbc8641";
21 #address-cells = <1>;
22 #size-cells = <1>;
23
24 aliases {
25 ethernet0 = &enet0;
26 ethernet1 = &enet1;
27 ethernet2 = &enet2;
28 ethernet3 = &enet3;
29 serial0 = &serial0;
30 serial1 = &serial1;
31 pci0 = &pci0;
32 pci1 = &pci1;
33 };
34
35 cpus {
36 #address-cells = <1>;
37 #size-cells = <0>;
38
39 PowerPC,8641@0 {
40 device_type = "cpu";
41 reg = <0>;
42 d-cache-line-size = <32>;
43 i-cache-line-size = <32>;
44 d-cache-size = <32768>; // L1
45 i-cache-size = <32768>; // L1
46 timebase-frequency = <0>; // From uboot
47 bus-frequency = <0>; // From uboot
48 clock-frequency = <0>; // From uboot
49 };
50 PowerPC,8641@1 {
51 device_type = "cpu";
52 reg = <1>;
53 d-cache-line-size = <32>;
54 i-cache-line-size = <32>;
55 d-cache-size = <32768>;
56 i-cache-size = <32768>;
57 timebase-frequency = <0>; // From uboot
58 bus-frequency = <0>; // From uboot
59 clock-frequency = <0>; // From uboot
60 };
61 };
62
63 memory {
64 device_type = "memory";
65 reg = <0x00000000 0x20000000>; // 512M at 0x0
66 };
67
68 localbus@f8005000 {
69 #address-cells = <2>;
70 #size-cells = <1>;
71 compatible = "fsl,mpc8641-localbus", "simple-bus";
72 reg = <0xf8005000 0x1000>;
73 interrupts = <19 2>;
74 interrupt-parent = <&mpic>;
75
76 ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
77 1 0 0xf0000000 0x00010000 // 64KB EEPROM
78 2 0 0xf1000000 0x00100000 // EPLD (1MB)
79 3 0 0xe0000000 0x04000000 // 64MB LB SDRAM (CS3)
80 4 0 0xe4000000 0x04000000 // 64MB LB SDRAM (CS4)
81 6 0 0xf4000000 0x00100000 // LCD display (1MB)
82 7 0 0xe8000000 0x04000000>; // 64MB OneNAND
83
84 flash@0,0 {
85 compatible = "cfi-flash";
86 reg = <0 0 0x01000000>;
87 bank-width = <2>;
88 device-width = <2>;
89 #address-cells = <1>;
90 #size-cells = <1>;
91 partition@0 {
92 label = "dtb";
93 reg = <0x00000000 0x00100000>;
94 read-only;
95 };
96 partition@300000 {
97 label = "kernel";
98 reg = <0x00100000 0x00400000>;
99 read-only;
100 };
101 partition@400000 {
102 label = "fs";
103 reg = <0x00500000 0x00a00000>;
104 };
105 partition@700000 {
106 label = "firmware";
107 reg = <0x00f00000 0x00100000>;
108 read-only;
109 };
110 };
111
112 epld@2,0 {
113 compatible = "wrs,epld-localbus";
114 #address-cells = <2>;
115 #size-cells = <1>;
116 reg = <2 0 0x100000>;
117 ranges = <0 0 5 0 1 // User switches
118 1 0 5 1 1 // Board ID/Rev
119 3 0 5 3 1>; // LEDs
120 };
121 };
122
123 soc@f8000000 {
124 #address-cells = <1>;
125 #size-cells = <1>;
126 device_type = "soc";
127 compatible = "simple-bus";
128 ranges = <0x00000000 0xf8000000 0x00100000>;
129 bus-frequency = <0>;
130
131 mcm-law@0 {
132 compatible = "fsl,mcm-law";
133 reg = <0x0 0x1000>;
134 fsl,num-laws = <10>;
135 };
136
137 mcm@1000 {
138 compatible = "fsl,mpc8641-mcm", "fsl,mcm";
139 reg = <0x1000 0x1000>;
140 interrupts = <17 2>;
141 interrupt-parent = <&mpic>;
142 };
143
144 i2c@3000 {
145 #address-cells = <1>;
146 #size-cells = <0>;
147 cell-index = <0>;
148 compatible = "fsl-i2c";
149 reg = <0x3000 0x100>;
150 interrupts = <43 2>;
151 interrupt-parent = <&mpic>;
152 dfsrr;
153 };
154
155 i2c@3100 {
156 #address-cells = <1>;
157 #size-cells = <0>;
158 cell-index = <1>;
159 compatible = "fsl-i2c";
160 reg = <0x3100 0x100>;
161 interrupts = <43 2>;
162 interrupt-parent = <&mpic>;
163 dfsrr;
164 };
165
166 dma@21300 {
167 #address-cells = <1>;
168 #size-cells = <1>;
169 compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
170 reg = <0x21300 0x4>;
171 ranges = <0x0 0x21100 0x200>;
172 cell-index = <0>;
173 dma-channel@0 {
174 compatible = "fsl,mpc8641-dma-channel",
175 "fsl,eloplus-dma-channel";
176 reg = <0x0 0x80>;
177 cell-index = <0>;
178 interrupt-parent = <&mpic>;
179 interrupts = <20 2>;
180 };
181 dma-channel@80 {
182 compatible = "fsl,mpc8641-dma-channel",
183 "fsl,eloplus-dma-channel";
184 reg = <0x80 0x80>;
185 cell-index = <1>;
186 interrupt-parent = <&mpic>;
187 interrupts = <21 2>;
188 };
189 dma-channel@100 {
190 compatible = "fsl,mpc8641-dma-channel",
191 "fsl,eloplus-dma-channel";
192 reg = <0x100 0x80>;
193 cell-index = <2>;
194 interrupt-parent = <&mpic>;
195 interrupts = <22 2>;
196 };
197 dma-channel@180 {
198 compatible = "fsl,mpc8641-dma-channel",
199 "fsl,eloplus-dma-channel";
200 reg = <0x180 0x80>;
201 cell-index = <3>;
202 interrupt-parent = <&mpic>;
203 interrupts = <23 2>;
204 };
205 };
206
207 enet0: ethernet@24000 {
208 #address-cells = <1>;
209 #size-cells = <1>;
210 cell-index = <0>;
211 device_type = "network";
212 model = "TSEC";
213 compatible = "gianfar";
214 reg = <0x24000 0x1000>;
215 ranges = <0x0 0x24000 0x1000>;
216 local-mac-address = [ 00 00 00 00 00 00 ];
217 interrupts = <29 2 30 2 34 2>;
218 interrupt-parent = <&mpic>;
219 tbi-handle = <&tbi0>;
220 phy-handle = <&phy0>;
221 phy-connection-type = "rgmii-id";
222
223 mdio@520 {
224 #address-cells = <1>;
225 #size-cells = <0>;
226 compatible = "fsl,gianfar-mdio";
227 reg = <0x520 0x20>;
228
229 phy0: ethernet-phy@1f {
230 reg = <0x1f>;
231 };
232 phy1: ethernet-phy@0 {
233 reg = <0>;
234 };
235 phy2: ethernet-phy@1 {
236 reg = <1>;
237 };
238 phy3: ethernet-phy@2 {
239 reg = <2>;
240 };
241 tbi0: tbi-phy@11 {
242 reg = <0x11>;
243 device_type = "tbi-phy";
244 };
245 };
246 };
247
248 enet1: ethernet@25000 {
249 #address-cells = <1>;
250 #size-cells = <1>;
251 cell-index = <1>;
252 device_type = "network";
253 model = "TSEC";
254 compatible = "gianfar";
255 reg = <0x25000 0x1000>;
256 ranges = <0x0 0x25000 0x1000>;
257 local-mac-address = [ 00 00 00 00 00 00 ];
258 interrupts = <35 2 36 2 40 2>;
259 interrupt-parent = <&mpic>;
260 tbi-handle = <&tbi1>;
261 phy-handle = <&phy1>;
262 phy-connection-type = "rgmii-id";
263
264 mdio@520 {
265 #address-cells = <1>;
266 #size-cells = <0>;
267 compatible = "fsl,gianfar-tbi";
268 reg = <0x520 0x20>;
269
270 tbi1: tbi-phy@11 {
271 reg = <0x11>;
272 device_type = "tbi-phy";
273 };
274 };
275 };
276
277 enet2: ethernet@26000 {
278 #address-cells = <1>;
279 #size-cells = <1>;
280 cell-index = <2>;
281 device_type = "network";
282 model = "TSEC";
283 compatible = "gianfar";
284 reg = <0x26000 0x1000>;
285 ranges = <0x0 0x26000 0x1000>;
286 local-mac-address = [ 00 00 00 00 00 00 ];
287 interrupts = <31 2 32 2 33 2>;
288 interrupt-parent = <&mpic>;
289 tbi-handle = <&tbi2>;
290 phy-handle = <&phy2>;
291 phy-connection-type = "rgmii-id";
292
293 mdio@520 {
294 #address-cells = <1>;
295 #size-cells = <0>;
296 compatible = "fsl,gianfar-tbi";
297 reg = <0x520 0x20>;
298
299 tbi2: tbi-phy@11 {
300 reg = <0x11>;
301 device_type = "tbi-phy";
302 };
303 };
304 };
305
306 enet3: ethernet@27000 {
307 #address-cells = <1>;
308 #size-cells = <1>;
309 cell-index = <3>;
310 device_type = "network";
311 model = "TSEC";
312 compatible = "gianfar";
313 reg = <0x27000 0x1000>;
314 ranges = <0x0 0x27000 0x1000>;
315 local-mac-address = [ 00 00 00 00 00 00 ];
316 interrupts = <37 2 38 2 39 2>;
317 interrupt-parent = <&mpic>;
318 tbi-handle = <&tbi3>;
319 phy-handle = <&phy3>;
320 phy-connection-type = "rgmii-id";
321
322 mdio@520 {
323 #address-cells = <1>;
324 #size-cells = <0>;
325 compatible = "fsl,gianfar-tbi";
326 reg = <0x520 0x20>;
327
328 tbi3: tbi-phy@11 {
329 reg = <0x11>;
330 device_type = "tbi-phy";
331 };
332 };
333 };
334
335 serial0: serial@4500 {
336 cell-index = <0>;
337 device_type = "serial";
338 compatible = "fsl,ns16550", "ns16550";
339 reg = <0x4500 0x100>;
340 clock-frequency = <0>;
341 interrupts = <42 2>;
342 interrupt-parent = <&mpic>;
343 };
344
345 serial1: serial@4600 {
346 cell-index = <1>;
347 device_type = "serial";
348 compatible = "fsl,ns16550", "ns16550";
349 reg = <0x4600 0x100>;
350 clock-frequency = <0>;
351 interrupts = <28 2>;
352 interrupt-parent = <&mpic>;
353 };
354
355 mpic: pic@40000 {
356 clock-frequency = <0>;
357 interrupt-controller;
358 #address-cells = <0>;
359 #interrupt-cells = <2>;
360 reg = <0x40000 0x40000>;
361 compatible = "chrp,open-pic";
362 device_type = "open-pic";
363 big-endian;
364 };
365
366 global-utilities@e0000 {
367 compatible = "fsl,mpc8641-guts";
368 reg = <0xe0000 0x1000>;
369 fsl,has-rstcr;
370 };
371 };
372
373 pci0: pcie@f8008000 {
374 compatible = "fsl,mpc8641-pcie";
375 device_type = "pci";
376 #interrupt-cells = <1>;
377 #size-cells = <2>;
378 #address-cells = <3>;
379 reg = <0xf8008000 0x1000>;
380 bus-range = <0x0 0xff>;
381 ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000
382 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
383 clock-frequency = <33333333>;
384 interrupt-parent = <&mpic>;
385 interrupts = <24 2>;
386 interrupt-map-mask = <0xff00 0 0 7>;
387 interrupt-map = <
388 /* IDSEL 0x0 */
389 0x0000 0 0 1 &mpic 0 1
390 0x0000 0 0 2 &mpic 1 1
391 0x0000 0 0 3 &mpic 2 1
392 0x0000 0 0 4 &mpic 3 1
393 >;
394
395 pcie@0 {
396 reg = <0 0 0 0 0>;
397 #size-cells = <2>;
398 #address-cells = <3>;
399 device_type = "pci";
400 ranges = <0x02000000 0x0 0x80000000
401 0x02000000 0x0 0x80000000
402 0x0 0x20000000
403
404 0x01000000 0x0 0x00000000
405 0x01000000 0x0 0x00000000
406 0x0 0x00100000>;
407 };
408
409 };
410
411 pci1: pcie@f8009000 {
412 compatible = "fsl,mpc8641-pcie";
413 device_type = "pci";
414 #interrupt-cells = <1>;
415 #size-cells = <2>;
416 #address-cells = <3>;
417 reg = <0xf8009000 0x1000>;
418 bus-range = <0 0xff>;
419 ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000
420 0x01000000 0x0 0x00000000 0xe3000000 0x0 0x00100000>;
421 clock-frequency = <33333333>;
422 interrupt-parent = <&mpic>;
423 interrupts = <25 2>;
424 interrupt-map-mask = <0xf800 0 0 7>;
425 interrupt-map = <
426 /* IDSEL 0x0 */
427 0x0000 0 0 1 &mpic 4 1
428 0x0000 0 0 2 &mpic 5 1
429 0x0000 0 0 3 &mpic 6 1
430 0x0000 0 0 4 &mpic 7 1
431 >;
432
433 pcie@0 {
434 reg = <0 0 0 0 0>;
435 #size-cells = <2>;
436 #address-cells = <3>;
437 device_type = "pci";
438 ranges = <0x02000000 0x0 0xa0000000
439 0x02000000 0x0 0xa0000000
440 0x0 0x20000000
441
442 0x01000000 0x0 0x00000000
443 0x01000000 0x0 0x00000000
444 0x0 0x00100000>;
445 };
446 };
447};
diff --git a/arch/powerpc/boot/rs6000.h b/arch/powerpc/boot/rs6000.h
index 433f45084e41..d70517ccc0f7 100644
--- a/arch/powerpc/boot/rs6000.h
+++ b/arch/powerpc/boot/rs6000.h
@@ -239,5 +239,5 @@ struct external_reloc {
239#define DEFAULT_DATA_SECTION_ALIGNMENT 4 239#define DEFAULT_DATA_SECTION_ALIGNMENT 4
240#define DEFAULT_BSS_SECTION_ALIGNMENT 4 240#define DEFAULT_BSS_SECTION_ALIGNMENT 4
241#define DEFAULT_TEXT_SECTION_ALIGNMENT 4 241#define DEFAULT_TEXT_SECTION_ALIGNMENT 4
242/* For new sections we havn't heard of before */ 242/* For new sections we haven't heard of before */
243#define DEFAULT_SECTION_ALIGNMENT 4 243#define DEFAULT_SECTION_ALIGNMENT 4
diff --git a/arch/powerpc/boot/treeboot-akebono.c b/arch/powerpc/boot/treeboot-akebono.c
index b73174c34fe4..bcc5902f8462 100644
--- a/arch/powerpc/boot/treeboot-akebono.c
+++ b/arch/powerpc/boot/treeboot-akebono.c
@@ -38,7 +38,7 @@
38 38
39BSS_STACK(4096); 39BSS_STACK(4096);
40 40
41#define SPRN_PIR 0x11E /* Processor Indentification Register */ 41#define SPRN_PIR 0x11E /* Processor Identification Register */
42#define USERDATA_LEN 256 /* Length of userdata passed in by PIBS */ 42#define USERDATA_LEN 256 /* Length of userdata passed in by PIBS */
43#define MAX_RANKS 0x4 43#define MAX_RANKS 0x4
44#define DDR3_MR0CF 0x80010011U 44#define DDR3_MR0CF 0x80010011U
diff --git a/arch/powerpc/boot/treeboot-currituck.c b/arch/powerpc/boot/treeboot-currituck.c
index 925ae43b7467..303d2074ee56 100644
--- a/arch/powerpc/boot/treeboot-currituck.c
+++ b/arch/powerpc/boot/treeboot-currituck.c
@@ -80,7 +80,7 @@ static void ibm_currituck_fixups(void)
80 } 80 }
81} 81}
82 82
83#define SPRN_PIR 0x11E /* Processor Indentification Register */ 83#define SPRN_PIR 0x11E /* Processor Identification Register */
84void platform_init(void) 84void platform_init(void)
85{ 85{
86 unsigned long end_of_ram, avail_ram; 86 unsigned long end_of_ram, avail_ram;
diff --git a/arch/powerpc/boot/treeboot-iss4xx.c b/arch/powerpc/boot/treeboot-iss4xx.c
index 329e710feda2..733f8bf25184 100644
--- a/arch/powerpc/boot/treeboot-iss4xx.c
+++ b/arch/powerpc/boot/treeboot-iss4xx.c
@@ -59,7 +59,7 @@ static void *iss_4xx_vmlinux_alloc(unsigned long size)
59 return (void *)ibm4xx_memstart; 59 return (void *)ibm4xx_memstart;
60} 60}
61 61
62#define SPRN_PIR 0x11E /* Processor Indentification Register */ 62#define SPRN_PIR 0x11E /* Processor Identification Register */
63void platform_init(void) 63void platform_init(void)
64{ 64{
65 unsigned long end_of_ram = 0x08000000; 65 unsigned long end_of_ram = 0x08000000;
diff --git a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig
index 2a5fdcbabcdd..87fc15bce407 100644
--- a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig
+++ b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig
@@ -35,7 +35,6 @@ CONFIG_MTD_PHYSMAP=y
35CONFIG_BLK_DEV_LOOP=y 35CONFIG_BLK_DEV_LOOP=y
36CONFIG_BLK_DEV_RAM=y 36CONFIG_BLK_DEV_RAM=y
37CONFIG_BLK_DEV_RAM_SIZE=32768 37CONFIG_BLK_DEV_RAM_SIZE=32768
38CONFIG_IDE=y
39CONFIG_BLK_DEV_SD=y 38CONFIG_BLK_DEV_SD=y
40CONFIG_CHR_DEV_SG=y 39CONFIG_CHR_DEV_SG=y
41CONFIG_SCSI_SPI_ATTRS=y 40CONFIG_SCSI_SPI_ATTRS=y
diff --git a/arch/powerpc/configs/85xx/ksi8560_defconfig b/arch/powerpc/configs/85xx/ksi8560_defconfig
index 3be85c5f1a2a..6f753a71fe5d 100644
--- a/arch/powerpc/configs/85xx/ksi8560_defconfig
+++ b/arch/powerpc/configs/85xx/ksi8560_defconfig
@@ -34,7 +34,6 @@ CONFIG_MTD_PHYSMAP_OF=y
34CONFIG_BLK_DEV_LOOP=y 34CONFIG_BLK_DEV_LOOP=y
35CONFIG_BLK_DEV_RAM=y 35CONFIG_BLK_DEV_RAM=y
36CONFIG_BLK_DEV_RAM_SIZE=32768 36CONFIG_BLK_DEV_RAM_SIZE=32768
37CONFIG_IDE=y
38CONFIG_NETDEVICES=y 37CONFIG_NETDEVICES=y
39CONFIG_FS_ENET=y 38CONFIG_FS_ENET=y
40# CONFIG_FS_ENET_HAS_SCC is not set 39# CONFIG_FS_ENET_HAS_SCC is not set
diff --git a/arch/powerpc/configs/85xx/stx_gp3_defconfig b/arch/powerpc/configs/85xx/stx_gp3_defconfig
index f66d16ba8c58..b45190556c0c 100644
--- a/arch/powerpc/configs/85xx/stx_gp3_defconfig
+++ b/arch/powerpc/configs/85xx/stx_gp3_defconfig
@@ -31,8 +31,6 @@ CONFIG_BLK_DEV_LOOP=m
31CONFIG_BLK_DEV_NBD=m 31CONFIG_BLK_DEV_NBD=m
32CONFIG_BLK_DEV_RAM=y 32CONFIG_BLK_DEV_RAM=y
33CONFIG_BLK_DEV_RAM_SIZE=32768 33CONFIG_BLK_DEV_RAM_SIZE=32768
34CONFIG_IDE=y
35CONFIG_BLK_DEV_IDECD=m
36CONFIG_SCSI=m 34CONFIG_SCSI=m
37CONFIG_BLK_DEV_SD=m 35CONFIG_BLK_DEV_SD=m
38CONFIG_CHR_DEV_ST=m 36CONFIG_CHR_DEV_ST=m
diff --git a/arch/powerpc/configs/86xx-hw.config b/arch/powerpc/configs/86xx-hw.config
new file mode 100644
index 000000000000..f91f8895fc93
--- /dev/null
+++ b/arch/powerpc/configs/86xx-hw.config
@@ -0,0 +1,104 @@
1CONFIG_ATA=y
2CONFIG_BLK_DEV_SD=y
3CONFIG_BLK_DEV_SR=y
4CONFIG_BROADCOM_PHY=y
5# CONFIG_CARDBUS is not set
6CONFIG_CHR_DEV_SG=y
7CONFIG_CHR_DEV_ST=y
8CONFIG_CRC_T10DIF=y
9CONFIG_CRYPTO_HMAC=y
10CONFIG_DS1682=y
11CONFIG_EEPROM_LEGACY=y
12CONFIG_GEF_WDT=y
13CONFIG_GIANFAR=y
14CONFIG_GPIO_GE_FPGA=y
15CONFIG_GPIO_SYSFS=y
16CONFIG_HID_A4TECH=y
17CONFIG_HID_APPLE=y
18CONFIG_HID_BELKIN=y
19CONFIG_HID_CHERRY=y
20CONFIG_HID_CHICONY=y
21CONFIG_HID_CYPRESS=y
22CONFIG_HID_EZKEY=y
23CONFIG_HID_GYRATION=y
24CONFIG_HID_LOGITECH=y
25CONFIG_HID_MICROSOFT=y
26CONFIG_HID_MONTEREY=y
27CONFIG_HID_PANTHERLORD=y
28CONFIG_HID_PETALYNX=y
29CONFIG_HID_SAMSUNG=y
30CONFIG_HID_SUNPLUS=y
31CONFIG_HW_RANDOM=y
32CONFIG_HZ_1000=y
33CONFIG_I2C_MPC=y
34CONFIG_I2C=y
35# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
36# CONFIG_INET_XFRM_MODE_TUNNEL is not set
37CONFIG_INPUT_FF_MEMLESS=m
38# CONFIG_INPUT_KEYBOARD is not set
39# CONFIG_INPUT_MOUSEDEV is not set
40# CONFIG_INPUT_MOUSE is not set
41CONFIG_MTD_BLOCK=y
42CONFIG_MTD_CFI_ADV_OPTIONS=y
43CONFIG_MTD_CFI_AMDSTD=y
44CONFIG_MTD_CFI_INTELEXT=y
45CONFIG_MTD_CFI_LE_BYTE_SWAP=y
46CONFIG_MTD_CFI=y
47CONFIG_MTD_CMDLINE_PARTS=y
48CONFIG_MTD_JEDECPROBE=y
49CONFIG_MTD_NAND_FSL_ELBC=y
50CONFIG_MTD_NAND=y
51CONFIG_MTD_PHYSMAP_OF=y
52CONFIG_NETDEVICES=y
53CONFIG_NET_TULIP=y
54CONFIG_NVRAM=y
55CONFIG_PATA_ALI=y
56CONFIG_PCCARD=y
57CONFIG_PCI_DEBUG=y
58# CONFIG_PCIEASPM is not set
59CONFIG_PCIEPORTBUS=y
60CONFIG_PCI=y
61# CONFIG_PCMCIA_LOAD_CIS is not set
62# CONFIG_PPC_CHRP is not set
63# CONFIG_PPC_PMAC is not set
64CONFIG_RTC_CLASS=y
65CONFIG_RTC_DRV_CMOS=y
66CONFIG_RTC_DRV_RX8581=y
67CONFIG_SATA_AHCI=y
68CONFIG_SATA_SIL24=y
69CONFIG_SATA_SIL=y
70CONFIG_SCSI_LOGGING=y
71CONFIG_SENSORS_LM90=y
72CONFIG_SENSORS_LM92=y
73CONFIG_SERIAL_8250_CONSOLE=y
74CONFIG_SERIAL_8250_DETECT_IRQ=y
75CONFIG_SERIAL_8250_EXTENDED=y
76CONFIG_SERIAL_8250_MANY_PORTS=y
77CONFIG_SERIAL_8250_NR_UARTS=2
78CONFIG_SERIAL_8250_RSA=y
79CONFIG_SERIAL_8250_RUNTIME_UARTS=2
80CONFIG_SERIAL_8250_SHARE_IRQ=y
81CONFIG_SERIAL_8250=y
82CONFIG_SERIO_LIBPS2=y
83CONFIG_SND_INTEL8X0=y
84CONFIG_SND_MIXER_OSS=y
85CONFIG_SND_PCM_OSS=y
86# CONFIG_SND_SUPPORT_OLD_API is not set
87CONFIG_SND=y
88CONFIG_SOUND=y
89CONFIG_ULI526X=y
90CONFIG_USB_EHCI_HCD=y
91CONFIG_USB_MON=y
92CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
93CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
94CONFIG_USB_OHCI_HCD=y
95CONFIG_USB_STORAGE=y
96CONFIG_USB=y
97CONFIG_VITESSE_PHY=y
98CONFIG_VME_BUS=y
99CONFIG_VME_TSI148=y
100CONFIG_WATCHDOG=y
101# CONFIG_YENTA_O2 is not set
102# CONFIG_YENTA_RICOH is not set
103# CONFIG_YENTA_TOSHIBA is not set
104CONFIG_YENTA=y
diff --git a/arch/powerpc/configs/86xx-smp.config b/arch/powerpc/configs/86xx-smp.config
new file mode 100644
index 000000000000..40ac38d3038c
--- /dev/null
+++ b/arch/powerpc/configs/86xx-smp.config
@@ -0,0 +1,2 @@
1CONFIG_NR_CPUS=2
2CONFIG_SMP=y
diff --git a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
deleted file mode 100644
index 9792a2cb9b20..000000000000
--- a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
+++ /dev/null
@@ -1,216 +0,0 @@
1CONFIG_SMP=y
2CONFIG_NR_CPUS=2
3CONFIG_SYSVIPC=y
4CONFIG_POSIX_MQUEUE=y
5CONFIG_HIGH_RES_TIMERS=y
6CONFIG_BSD_PROCESS_ACCT=y
7CONFIG_BSD_PROCESS_ACCT_V3=y
8CONFIG_IKCONFIG=y
9CONFIG_IKCONFIG_PROC=y
10CONFIG_LOG_BUF_SHIFT=14
11CONFIG_RELAY=y
12CONFIG_BLK_DEV_INITRD=y
13CONFIG_EXPERT=y
14CONFIG_SLAB=y
15CONFIG_MODULES=y
16CONFIG_MODULE_UNLOAD=y
17# CONFIG_BLK_DEV_BSG is not set
18# CONFIG_PPC_CHRP is not set
19# CONFIG_PPC_PMAC is not set
20CONFIG_PPC_86xx=y
21CONFIG_GEF_PPC9A=y
22CONFIG_HIGHMEM=y
23CONFIG_HZ_1000=y
24CONFIG_PREEMPT=y
25CONFIG_BINFMT_MISC=m
26CONFIG_PCI=y
27CONFIG_PCIEPORTBUS=y
28# CONFIG_PCIEASPM is not set
29CONFIG_PCCARD=y
30# CONFIG_PCMCIA_LOAD_CIS is not set
31# CONFIG_CARDBUS is not set
32CONFIG_YENTA=y
33# CONFIG_YENTA_O2 is not set
34# CONFIG_YENTA_RICOH is not set
35# CONFIG_YENTA_TOSHIBA is not set
36CONFIG_NET=y
37CONFIG_PACKET=y
38CONFIG_UNIX=y
39CONFIG_XFRM_USER=m
40CONFIG_NET_KEY=m
41CONFIG_INET=y
42CONFIG_IP_MULTICAST=y
43CONFIG_IP_ADVANCED_ROUTER=y
44CONFIG_IP_MULTIPLE_TABLES=y
45CONFIG_IP_ROUTE_MULTIPATH=y
46CONFIG_IP_ROUTE_VERBOSE=y
47CONFIG_IP_PNP=y
48CONFIG_IP_PNP_DHCP=y
49CONFIG_IP_PNP_BOOTP=y
50CONFIG_IP_PNP_RARP=y
51CONFIG_NET_IPIP=m
52CONFIG_IP_MROUTE=y
53CONFIG_IP_PIMSM_V1=y
54CONFIG_IP_PIMSM_V2=y
55CONFIG_SYN_COOKIES=y
56CONFIG_INET_AH=m
57CONFIG_INET_ESP=m
58CONFIG_INET_IPCOMP=m
59# CONFIG_INET_XFRM_MODE_BEET is not set
60CONFIG_INET6_AH=m
61CONFIG_INET6_ESP=m
62CONFIG_INET6_IPCOMP=m
63CONFIG_IPV6_TUNNEL=m
64CONFIG_NET_PKTGEN=m
65CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
66CONFIG_MTD=y
67CONFIG_MTD_BLOCK=y
68CONFIG_MTD_CFI=y
69CONFIG_MTD_JEDECPROBE=y
70CONFIG_MTD_CFI_INTELEXT=y
71CONFIG_MTD_CFI_AMDSTD=y
72CONFIG_MTD_PHYSMAP_OF=y
73CONFIG_BLK_DEV_LOOP=m
74CONFIG_BLK_DEV_CRYPTOLOOP=m
75CONFIG_BLK_DEV_NBD=m
76CONFIG_BLK_DEV_RAM=y
77CONFIG_BLK_DEV_RAM_SIZE=131072
78CONFIG_DS1682=y
79CONFIG_IDE=y
80CONFIG_BLK_DEV_IDECS=y
81CONFIG_BLK_DEV_SD=y
82CONFIG_CHR_DEV_ST=y
83CONFIG_BLK_DEV_SR=y
84CONFIG_ATA=y
85CONFIG_SATA_SIL=y
86CONFIG_NETDEVICES=y
87CONFIG_BONDING=m
88CONFIG_DUMMY=m
89CONFIG_NETCONSOLE=y
90CONFIG_TUN=m
91CONFIG_GIANFAR=y
92CONFIG_PPP=m
93CONFIG_PPP_BSDCOMP=m
94CONFIG_PPP_DEFLATE=m
95CONFIG_PPP_FILTER=y
96CONFIG_PPP_MULTILINK=y
97CONFIG_PPPOE=m
98CONFIG_PPP_ASYNC=m
99CONFIG_PPP_SYNC_TTY=m
100CONFIG_SLIP=m
101CONFIG_SLIP_COMPRESSED=y
102CONFIG_SLIP_SMART=y
103CONFIG_SLIP_MODE_SLIP6=y
104# CONFIG_INPUT_KEYBOARD is not set
105# CONFIG_INPUT_MOUSE is not set
106# CONFIG_SERIO is not set
107# CONFIG_LEGACY_PTYS is not set
108CONFIG_SERIAL_8250=y
109CONFIG_SERIAL_8250_CONSOLE=y
110# CONFIG_SERIAL_8250_PCI is not set
111CONFIG_SERIAL_8250_NR_UARTS=2
112CONFIG_SERIAL_8250_RUNTIME_UARTS=2
113CONFIG_HW_RANDOM=y
114CONFIG_NVRAM=y
115CONFIG_I2C=y
116CONFIG_I2C_CHARDEV=y
117CONFIG_I2C_MPC=y
118CONFIG_GPIO_SYSFS=y
119CONFIG_GPIO_GE_FPGA=y
120CONFIG_SENSORS_LM90=y
121CONFIG_SENSORS_LM92=y
122CONFIG_WATCHDOG=y
123CONFIG_GEF_WDT=y
124CONFIG_HID_A4TECH=y
125CONFIG_HID_APPLE=y
126CONFIG_HID_BELKIN=y
127CONFIG_HID_CHERRY=y
128CONFIG_HID_CHICONY=y
129CONFIG_HID_CYPRESS=y
130CONFIG_HID_EZKEY=y
131CONFIG_HID_GYRATION=y
132CONFIG_HID_LOGITECH=y
133CONFIG_HID_MICROSOFT=y
134CONFIG_HID_MONTEREY=y
135CONFIG_HID_PANTHERLORD=y
136CONFIG_HID_PETALYNX=y
137CONFIG_HID_SAMSUNG=y
138CONFIG_HID_SUNPLUS=y
139CONFIG_USB=y
140CONFIG_USB_EHCI_HCD=y
141# CONFIG_USB_EHCI_HCD_PPC_OF is not set
142CONFIG_USB_OHCI_HCD=y
143CONFIG_USB_STORAGE=y
144CONFIG_RTC_CLASS=y
145# CONFIG_RTC_INTF_PROC is not set
146CONFIG_RTC_DRV_RX8581=y
147CONFIG_STAGING=y
148CONFIG_VME_BUS=y
149CONFIG_VME_TSI148=y
150CONFIG_EXT2_FS=y
151CONFIG_EXT2_FS_XATTR=y
152CONFIG_EXT2_FS_POSIX_ACL=y
153CONFIG_EXT3_FS=y
154# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
155CONFIG_EXT3_FS_POSIX_ACL=y
156CONFIG_ISO9660_FS=y
157CONFIG_JOLIET=y
158CONFIG_ZISOFS=y
159CONFIG_UDF_FS=y
160CONFIG_MSDOS_FS=y
161CONFIG_VFAT_FS=y
162CONFIG_FAT_DEFAULT_CODEPAGE=850
163CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
164CONFIG_PROC_KCORE=y
165CONFIG_TMPFS=y
166CONFIG_JFFS2_FS=y
167CONFIG_NFS_FS=y
168CONFIG_NFS_V4=y
169CONFIG_ROOT_NFS=y
170CONFIG_CIFS=m
171CONFIG_CIFS_XATTR=y
172CONFIG_CIFS_POSIX=y
173CONFIG_NLS_CODEPAGE_437=m
174CONFIG_NLS_CODEPAGE_737=m
175CONFIG_NLS_CODEPAGE_775=m
176CONFIG_NLS_CODEPAGE_850=m
177CONFIG_NLS_CODEPAGE_852=m
178CONFIG_NLS_CODEPAGE_855=m
179CONFIG_NLS_CODEPAGE_857=m
180CONFIG_NLS_CODEPAGE_860=m
181CONFIG_NLS_CODEPAGE_861=m
182CONFIG_NLS_CODEPAGE_862=m
183CONFIG_NLS_CODEPAGE_863=m
184CONFIG_NLS_CODEPAGE_864=m
185CONFIG_NLS_CODEPAGE_865=m
186CONFIG_NLS_CODEPAGE_866=m
187CONFIG_NLS_CODEPAGE_869=m
188CONFIG_NLS_CODEPAGE_936=m
189CONFIG_NLS_CODEPAGE_950=m
190CONFIG_NLS_CODEPAGE_932=m
191CONFIG_NLS_CODEPAGE_949=m
192CONFIG_NLS_CODEPAGE_874=m
193CONFIG_NLS_ISO8859_8=m
194CONFIG_NLS_CODEPAGE_1250=m
195CONFIG_NLS_CODEPAGE_1251=m
196CONFIG_NLS_ASCII=m
197CONFIG_NLS_ISO8859_1=m
198CONFIG_NLS_ISO8859_2=m
199CONFIG_NLS_ISO8859_3=m
200CONFIG_NLS_ISO8859_4=m
201CONFIG_NLS_ISO8859_5=m
202CONFIG_NLS_ISO8859_6=m
203CONFIG_NLS_ISO8859_7=m
204CONFIG_NLS_ISO8859_9=m
205CONFIG_NLS_ISO8859_13=m
206CONFIG_NLS_ISO8859_14=m
207CONFIG_NLS_ISO8859_15=m
208CONFIG_NLS_KOI8_R=m
209CONFIG_NLS_KOI8_U=m
210CONFIG_NLS_UTF8=m
211CONFIG_CRC_CCITT=y
212CONFIG_CRC_T10DIF=y
213CONFIG_LIBCRC32C=y
214CONFIG_MAGIC_SYSRQ=y
215# CONFIG_CRYPTO_ANSI_CPRNG is not set
216# CONFIG_CRYPTO_HW is not set
diff --git a/arch/powerpc/configs/86xx/gef_sbc310_defconfig b/arch/powerpc/configs/86xx/gef_sbc310_defconfig
deleted file mode 100644
index cadc36682bb4..000000000000
--- a/arch/powerpc/configs/86xx/gef_sbc310_defconfig
+++ /dev/null
@@ -1,214 +0,0 @@
1CONFIG_SMP=y
2CONFIG_NR_CPUS=2
3CONFIG_SYSVIPC=y
4CONFIG_POSIX_MQUEUE=y
5CONFIG_HIGH_RES_TIMERS=y
6CONFIG_BSD_PROCESS_ACCT=y
7CONFIG_BSD_PROCESS_ACCT_V3=y
8CONFIG_IKCONFIG=y
9CONFIG_IKCONFIG_PROC=y
10CONFIG_LOG_BUF_SHIFT=14
11CONFIG_RELAY=y
12CONFIG_BLK_DEV_INITRD=y
13CONFIG_EXPERT=y
14CONFIG_SLAB=y
15CONFIG_MODULES=y
16CONFIG_MODULE_UNLOAD=y
17# CONFIG_BLK_DEV_BSG is not set
18# CONFIG_PPC_CHRP is not set
19# CONFIG_PPC_PMAC is not set
20CONFIG_PPC_86xx=y
21CONFIG_GEF_SBC310=y
22CONFIG_HIGHMEM=y
23CONFIG_HZ_1000=y
24CONFIG_PREEMPT=y
25CONFIG_BINFMT_MISC=y
26CONFIG_PCI=y
27CONFIG_PCIEPORTBUS=y
28# CONFIG_PCIEASPM is not set
29CONFIG_PCCARD=y
30# CONFIG_PCMCIA_LOAD_CIS is not set
31# CONFIG_CARDBUS is not set
32CONFIG_YENTA=y
33# CONFIG_YENTA_O2 is not set
34# CONFIG_YENTA_RICOH is not set
35# CONFIG_YENTA_TOSHIBA is not set
36CONFIG_NET=y
37CONFIG_PACKET=y
38CONFIG_UNIX=y
39CONFIG_XFRM_USER=m
40CONFIG_NET_KEY=m
41CONFIG_INET=y
42CONFIG_IP_MULTICAST=y
43CONFIG_IP_ADVANCED_ROUTER=y
44CONFIG_IP_MULTIPLE_TABLES=y
45CONFIG_IP_ROUTE_MULTIPATH=y
46CONFIG_IP_ROUTE_VERBOSE=y
47CONFIG_IP_PNP=y
48CONFIG_IP_PNP_DHCP=y
49CONFIG_IP_PNP_BOOTP=y
50CONFIG_IP_PNP_RARP=y
51CONFIG_NET_IPIP=m
52CONFIG_IP_MROUTE=y
53CONFIG_IP_PIMSM_V1=y
54CONFIG_IP_PIMSM_V2=y
55CONFIG_SYN_COOKIES=y
56CONFIG_INET_AH=m
57CONFIG_INET_ESP=m
58CONFIG_INET_IPCOMP=m
59# CONFIG_INET_XFRM_MODE_BEET is not set
60CONFIG_INET6_AH=m
61CONFIG_INET6_ESP=m
62CONFIG_INET6_IPCOMP=m
63CONFIG_IPV6_TUNNEL=m
64CONFIG_NET_PKTGEN=m
65CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
66CONFIG_MTD=y
67CONFIG_MTD_BLOCK=y
68CONFIG_MTD_CFI=y
69CONFIG_MTD_JEDECPROBE=y
70CONFIG_MTD_CFI_INTELEXT=y
71CONFIG_MTD_CFI_AMDSTD=y
72CONFIG_MTD_PHYSMAP_OF=y
73CONFIG_BLK_DEV_LOOP=m
74CONFIG_BLK_DEV_CRYPTOLOOP=m
75CONFIG_BLK_DEV_NBD=m
76CONFIG_BLK_DEV_RAM=y
77CONFIG_BLK_DEV_RAM_SIZE=131072
78CONFIG_DS1682=y
79CONFIG_IDE=y
80CONFIG_BLK_DEV_IDECS=y
81CONFIG_BLK_DEV_SD=y
82CONFIG_CHR_DEV_ST=y
83CONFIG_BLK_DEV_SR=y
84CONFIG_ATA=y
85CONFIG_SATA_SIL24=y
86# CONFIG_ATA_SFF is not set
87CONFIG_NETDEVICES=y
88CONFIG_BONDING=m
89CONFIG_DUMMY=m
90CONFIG_NETCONSOLE=y
91CONFIG_TUN=m
92CONFIG_GIANFAR=y
93CONFIG_PPP=m
94CONFIG_PPP_BSDCOMP=m
95CONFIG_PPP_DEFLATE=m
96CONFIG_PPP_FILTER=y
97CONFIG_PPP_MULTILINK=y
98CONFIG_PPPOE=m
99CONFIG_PPP_ASYNC=m
100CONFIG_PPP_SYNC_TTY=m
101CONFIG_SLIP=m
102CONFIG_SLIP_COMPRESSED=y
103CONFIG_SLIP_SMART=y
104CONFIG_SLIP_MODE_SLIP6=y
105# CONFIG_INPUT_KEYBOARD is not set
106# CONFIG_INPUT_MOUSE is not set
107# CONFIG_SERIO is not set
108# CONFIG_LEGACY_PTYS is not set
109CONFIG_SERIAL_8250=y
110CONFIG_SERIAL_8250_CONSOLE=y
111# CONFIG_SERIAL_8250_PCI is not set
112CONFIG_SERIAL_8250_NR_UARTS=2
113CONFIG_SERIAL_8250_RUNTIME_UARTS=2
114CONFIG_HW_RANDOM=y
115CONFIG_NVRAM=y
116CONFIG_I2C=y
117CONFIG_I2C_CHARDEV=y
118CONFIG_I2C_MPC=y
119CONFIG_GPIO_SYSFS=y
120CONFIG_GPIO_GE_FPGA=y
121CONFIG_SENSORS_LM90=y
122CONFIG_SENSORS_LM92=y
123CONFIG_WATCHDOG=y
124CONFIG_GEF_WDT=y
125CONFIG_HID_A4TECH=y
126CONFIG_HID_APPLE=y
127CONFIG_HID_BELKIN=y
128CONFIG_HID_CHERRY=y
129CONFIG_HID_CHICONY=y
130CONFIG_HID_CYPRESS=y
131CONFIG_HID_EZKEY=y
132CONFIG_HID_GYRATION=y
133CONFIG_HID_LOGITECH=y
134CONFIG_HID_MICROSOFT=y
135CONFIG_HID_MONTEREY=y
136CONFIG_HID_PANTHERLORD=y
137CONFIG_HID_PETALYNX=y
138CONFIG_HID_SAMSUNG=y
139CONFIG_HID_SUNPLUS=y
140CONFIG_USB=y
141CONFIG_USB_EHCI_HCD=y
142# CONFIG_USB_EHCI_HCD_PPC_OF is not set
143CONFIG_USB_OHCI_HCD=y
144CONFIG_USB_STORAGE=y
145CONFIG_RTC_CLASS=y
146# CONFIG_RTC_INTF_PROC is not set
147CONFIG_RTC_DRV_RX8581=y
148CONFIG_EXT2_FS=y
149CONFIG_EXT2_FS_XATTR=y
150CONFIG_EXT2_FS_POSIX_ACL=y
151CONFIG_EXT3_FS=y
152# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
153CONFIG_EXT3_FS_POSIX_ACL=y
154CONFIG_ISO9660_FS=y
155CONFIG_JOLIET=y
156CONFIG_ZISOFS=y
157CONFIG_UDF_FS=y
158CONFIG_MSDOS_FS=y
159CONFIG_VFAT_FS=y
160CONFIG_FAT_DEFAULT_CODEPAGE=850
161CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
162CONFIG_PROC_KCORE=y
163CONFIG_TMPFS=y
164CONFIG_JFFS2_FS=y
165CONFIG_NFS_FS=y
166CONFIG_NFS_V4=y
167CONFIG_ROOT_NFS=y
168CONFIG_CIFS=m
169CONFIG_CIFS_XATTR=y
170CONFIG_CIFS_POSIX=y
171CONFIG_NLS_CODEPAGE_437=m
172CONFIG_NLS_CODEPAGE_737=m
173CONFIG_NLS_CODEPAGE_775=m
174CONFIG_NLS_CODEPAGE_850=m
175CONFIG_NLS_CODEPAGE_852=m
176CONFIG_NLS_CODEPAGE_855=m
177CONFIG_NLS_CODEPAGE_857=m
178CONFIG_NLS_CODEPAGE_860=m
179CONFIG_NLS_CODEPAGE_861=m
180CONFIG_NLS_CODEPAGE_862=m
181CONFIG_NLS_CODEPAGE_863=m
182CONFIG_NLS_CODEPAGE_864=m
183CONFIG_NLS_CODEPAGE_865=m
184CONFIG_NLS_CODEPAGE_866=m
185CONFIG_NLS_CODEPAGE_869=m
186CONFIG_NLS_CODEPAGE_936=m
187CONFIG_NLS_CODEPAGE_950=m
188CONFIG_NLS_CODEPAGE_932=m
189CONFIG_NLS_CODEPAGE_949=m
190CONFIG_NLS_CODEPAGE_874=m
191CONFIG_NLS_ISO8859_8=m
192CONFIG_NLS_CODEPAGE_1250=m
193CONFIG_NLS_CODEPAGE_1251=m
194CONFIG_NLS_ASCII=m
195CONFIG_NLS_ISO8859_1=m
196CONFIG_NLS_ISO8859_2=m
197CONFIG_NLS_ISO8859_3=m
198CONFIG_NLS_ISO8859_4=m
199CONFIG_NLS_ISO8859_5=m
200CONFIG_NLS_ISO8859_6=m
201CONFIG_NLS_ISO8859_7=m
202CONFIG_NLS_ISO8859_9=m
203CONFIG_NLS_ISO8859_13=m
204CONFIG_NLS_ISO8859_14=m
205CONFIG_NLS_ISO8859_15=m
206CONFIG_NLS_KOI8_R=m
207CONFIG_NLS_KOI8_U=m
208CONFIG_NLS_UTF8=m
209CONFIG_CRC_CCITT=y
210CONFIG_CRC_T10DIF=y
211CONFIG_LIBCRC32C=y
212CONFIG_MAGIC_SYSRQ=y
213# CONFIG_CRYPTO_ANSI_CPRNG is not set
214# CONFIG_CRYPTO_HW is not set
diff --git a/arch/powerpc/configs/86xx/gef_sbc610_defconfig b/arch/powerpc/configs/86xx/gef_sbc610_defconfig
deleted file mode 100644
index 2aa7d9737e43..000000000000
--- a/arch/powerpc/configs/86xx/gef_sbc610_defconfig
+++ /dev/null
@@ -1,273 +0,0 @@
1CONFIG_SMP=y
2CONFIG_NR_CPUS=2
3CONFIG_SYSVIPC=y
4CONFIG_POSIX_MQUEUE=y
5CONFIG_HIGH_RES_TIMERS=y
6CONFIG_BSD_PROCESS_ACCT=y
7CONFIG_BSD_PROCESS_ACCT_V3=y
8CONFIG_IKCONFIG=y
9CONFIG_IKCONFIG_PROC=y
10CONFIG_LOG_BUF_SHIFT=14
11CONFIG_RELAY=y
12CONFIG_BLK_DEV_INITRD=y
13CONFIG_EXPERT=y
14CONFIG_SLAB=y
15CONFIG_MODULES=y
16CONFIG_MODULE_UNLOAD=y
17# CONFIG_BLK_DEV_BSG is not set
18# CONFIG_PPC_CHRP is not set
19# CONFIG_PPC_PMAC is not set
20CONFIG_PPC_86xx=y
21CONFIG_GEF_SBC610=y
22CONFIG_HIGHMEM=y
23CONFIG_HZ_1000=y
24CONFIG_PREEMPT=y
25CONFIG_BINFMT_MISC=m
26CONFIG_PCI=y
27CONFIG_PCIEPORTBUS=y
28# CONFIG_PCIEASPM is not set
29CONFIG_PCI_DEBUG=y
30CONFIG_NET=y
31CONFIG_PACKET=y
32CONFIG_UNIX=y
33CONFIG_XFRM_USER=m
34CONFIG_NET_KEY=m
35CONFIG_INET=y
36CONFIG_IP_MULTICAST=y
37CONFIG_IP_ADVANCED_ROUTER=y
38CONFIG_IP_MULTIPLE_TABLES=y
39CONFIG_IP_ROUTE_MULTIPATH=y
40CONFIG_IP_ROUTE_VERBOSE=y
41CONFIG_IP_PNP=y
42CONFIG_IP_PNP_DHCP=y
43CONFIG_IP_PNP_BOOTP=y
44CONFIG_IP_PNP_RARP=y
45CONFIG_NET_IPIP=m
46CONFIG_IP_MROUTE=y
47CONFIG_IP_PIMSM_V1=y
48CONFIG_IP_PIMSM_V2=y
49CONFIG_SYN_COOKIES=y
50CONFIG_INET_AH=m
51CONFIG_INET_ESP=m
52CONFIG_INET_IPCOMP=m
53# CONFIG_INET_LRO is not set
54CONFIG_INET6_AH=m
55CONFIG_INET6_ESP=m
56CONFIG_INET6_IPCOMP=m
57CONFIG_IPV6_TUNNEL=m
58CONFIG_NETFILTER=y
59# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
60CONFIG_IP_NF_IPTABLES=m
61CONFIG_IP_NF_MATCH_ECN=m
62CONFIG_IP_NF_MATCH_TTL=m
63CONFIG_IP_NF_FILTER=m
64CONFIG_IP_NF_TARGET_REJECT=m
65CONFIG_IP_NF_MANGLE=m
66CONFIG_IP_NF_TARGET_ECN=m
67CONFIG_IP_NF_RAW=m
68CONFIG_IP_NF_ARPTABLES=m
69CONFIG_IP_NF_ARPFILTER=m
70CONFIG_IP_NF_ARP_MANGLE=m
71CONFIG_IP6_NF_IPTABLES=m
72CONFIG_IP6_NF_MATCH_EUI64=m
73CONFIG_IP6_NF_MATCH_FRAG=m
74CONFIG_IP6_NF_MATCH_OPTS=m
75CONFIG_IP6_NF_MATCH_HL=m
76CONFIG_IP6_NF_MATCH_IPV6HEADER=m
77CONFIG_IP6_NF_MATCH_RT=m
78CONFIG_IP6_NF_FILTER=m
79CONFIG_IP6_NF_MANGLE=m
80CONFIG_IP6_NF_RAW=m
81CONFIG_IP_SCTP=m
82CONFIG_TIPC=m
83CONFIG_ATM=m
84CONFIG_ATM_CLIP=m
85CONFIG_ATM_LANE=m
86CONFIG_ATM_MPOA=m
87CONFIG_ATM_BR2684=m
88CONFIG_BRIDGE=m
89CONFIG_VLAN_8021Q=m
90CONFIG_NET_SCHED=y
91CONFIG_NET_SCH_CBQ=m
92CONFIG_NET_SCH_HTB=m
93CONFIG_NET_SCH_HFSC=m
94CONFIG_NET_SCH_ATM=m
95CONFIG_NET_SCH_PRIO=m
96CONFIG_NET_SCH_RED=m
97CONFIG_NET_SCH_SFQ=m
98CONFIG_NET_SCH_TEQL=m
99CONFIG_NET_SCH_TBF=m
100CONFIG_NET_SCH_GRED=m
101CONFIG_NET_SCH_DSMARK=m
102CONFIG_NET_SCH_NETEM=m
103CONFIG_NET_CLS_TCINDEX=m
104CONFIG_NET_CLS_ROUTE4=m
105CONFIG_NET_CLS_FW=m
106CONFIG_NET_CLS_U32=m
107CONFIG_NET_CLS_RSVP=m
108CONFIG_NET_CLS_RSVP6=m
109CONFIG_NET_PKTGEN=m
110CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
111# CONFIG_FW_LOADER is not set
112CONFIG_MTD=y
113CONFIG_MTD_BLOCK=y
114CONFIG_MTD_CFI=y
115CONFIG_MTD_JEDECPROBE=y
116CONFIG_MTD_CFI_INTELEXT=y
117CONFIG_MTD_CFI_AMDSTD=y
118CONFIG_MTD_PHYSMAP_OF=y
119CONFIG_BLK_DEV_LOOP=m
120CONFIG_BLK_DEV_CRYPTOLOOP=m
121CONFIG_BLK_DEV_NBD=m
122CONFIG_BLK_DEV_RAM=y
123CONFIG_BLK_DEV_RAM_SIZE=131072
124CONFIG_DS1682=y
125CONFIG_BLK_DEV_SD=y
126CONFIG_CHR_DEV_ST=y
127CONFIG_BLK_DEV_SR=y
128CONFIG_ATA=y
129CONFIG_SATA_SIL=y
130CONFIG_NETDEVICES=y
131CONFIG_BONDING=m
132CONFIG_DUMMY=m
133CONFIG_NETCONSOLE=y
134CONFIG_TUN=m
135CONFIG_GIANFAR=y
136CONFIG_PPP=m
137CONFIG_PPP_BSDCOMP=m
138CONFIG_PPP_DEFLATE=m
139CONFIG_PPP_FILTER=y
140CONFIG_PPP_MULTILINK=y
141CONFIG_PPPOATM=m
142CONFIG_PPPOE=m
143CONFIG_PPP_ASYNC=m
144CONFIG_PPP_SYNC_TTY=m
145CONFIG_SLIP=m
146CONFIG_SLIP_COMPRESSED=y
147CONFIG_SLIP_SMART=y
148CONFIG_SLIP_MODE_SLIP6=y
149CONFIG_INPUT_FF_MEMLESS=m
150# CONFIG_INPUT_KEYBOARD is not set
151# CONFIG_INPUT_MOUSE is not set
152# CONFIG_SERIO is not set
153# CONFIG_LEGACY_PTYS is not set
154CONFIG_SERIAL_8250=y
155CONFIG_SERIAL_8250_CONSOLE=y
156# CONFIG_SERIAL_8250_PCI is not set
157CONFIG_SERIAL_8250_NR_UARTS=2
158CONFIG_SERIAL_8250_RUNTIME_UARTS=2
159CONFIG_HW_RANDOM=y
160CONFIG_NVRAM=y
161CONFIG_I2C=y
162CONFIG_I2C_CHARDEV=y
163CONFIG_I2C_MPC=y
164CONFIG_GPIO_SYSFS=y
165CONFIG_GPIO_GE_FPGA=y
166CONFIG_SENSORS_LM90=y
167CONFIG_SENSORS_LM92=y
168CONFIG_WATCHDOG=y
169CONFIG_GEF_WDT=y
170CONFIG_HID_A4TECH=y
171CONFIG_HID_APPLE=y
172CONFIG_HID_BELKIN=y
173CONFIG_HID_CHERRY=y
174CONFIG_HID_CHICONY=y
175CONFIG_HID_CYPRESS=y
176CONFIG_HID_EZKEY=y
177CONFIG_HID_GYRATION=y
178CONFIG_HID_LOGITECH=y
179CONFIG_HID_MICROSOFT=y
180CONFIG_HID_MONTEREY=y
181CONFIG_HID_PANTHERLORD=y
182CONFIG_HID_PETALYNX=y
183CONFIG_HID_SAMSUNG=y
184CONFIG_HID_SUNPLUS=y
185CONFIG_USB=y
186CONFIG_USB_EHCI_HCD=y
187# CONFIG_USB_EHCI_HCD_PPC_OF is not set
188CONFIG_USB_OHCI_HCD=y
189CONFIG_USB_STORAGE=y
190CONFIG_RTC_CLASS=y
191# CONFIG_RTC_INTF_PROC is not set
192CONFIG_RTC_DRV_RX8581=y
193CONFIG_STAGING=y
194CONFIG_VME_BUS=y
195CONFIG_VME_TSI148=y
196CONFIG_EXT2_FS=y
197CONFIG_EXT2_FS_XATTR=y
198CONFIG_EXT2_FS_POSIX_ACL=y
199CONFIG_EXT3_FS=y
200# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
201CONFIG_EXT3_FS_POSIX_ACL=y
202CONFIG_MSDOS_FS=y
203CONFIG_VFAT_FS=y
204CONFIG_PROC_KCORE=y
205CONFIG_TMPFS=y
206CONFIG_JFFS2_FS=y
207CONFIG_NFS_FS=y
208CONFIG_NFS_V4=y
209CONFIG_ROOT_NFS=y
210CONFIG_CIFS=m
211CONFIG_CIFS_XATTR=y
212CONFIG_CIFS_POSIX=y
213CONFIG_NLS_CODEPAGE_437=m
214CONFIG_NLS_CODEPAGE_737=m
215CONFIG_NLS_CODEPAGE_775=m
216CONFIG_NLS_CODEPAGE_850=m
217CONFIG_NLS_CODEPAGE_852=m
218CONFIG_NLS_CODEPAGE_855=m
219CONFIG_NLS_CODEPAGE_857=m
220CONFIG_NLS_CODEPAGE_860=m
221CONFIG_NLS_CODEPAGE_861=m
222CONFIG_NLS_CODEPAGE_862=m
223CONFIG_NLS_CODEPAGE_863=m
224CONFIG_NLS_CODEPAGE_864=m
225CONFIG_NLS_CODEPAGE_865=m
226CONFIG_NLS_CODEPAGE_866=m
227CONFIG_NLS_CODEPAGE_869=m
228CONFIG_NLS_CODEPAGE_936=m
229CONFIG_NLS_CODEPAGE_950=m
230CONFIG_NLS_CODEPAGE_932=m
231CONFIG_NLS_CODEPAGE_949=m
232CONFIG_NLS_CODEPAGE_874=m
233CONFIG_NLS_ISO8859_8=m
234CONFIG_NLS_CODEPAGE_1250=m
235CONFIG_NLS_CODEPAGE_1251=m
236CONFIG_NLS_ASCII=m
237CONFIG_NLS_ISO8859_1=m
238CONFIG_NLS_ISO8859_2=m
239CONFIG_NLS_ISO8859_3=m
240CONFIG_NLS_ISO8859_4=m
241CONFIG_NLS_ISO8859_5=m
242CONFIG_NLS_ISO8859_6=m
243CONFIG_NLS_ISO8859_7=m
244CONFIG_NLS_ISO8859_9=m
245CONFIG_NLS_ISO8859_13=m
246CONFIG_NLS_ISO8859_14=m
247CONFIG_NLS_ISO8859_15=m
248CONFIG_NLS_KOI8_R=m
249CONFIG_NLS_KOI8_U=m
250CONFIG_NLS_UTF8=m
251CONFIG_DEBUG_INFO=y
252CONFIG_MAGIC_SYSRQ=y
253CONFIG_DETECT_HUNG_TASK=y
254# CONFIG_DEBUG_BUGVERBOSE is not set
255CONFIG_SECURITY=y
256CONFIG_SECURITY_NETWORK=y
257CONFIG_CRYPTO_NULL=m
258CONFIG_CRYPTO_TEST=m
259CONFIG_CRYPTO_PCBC=m
260CONFIG_CRYPTO_HMAC=y
261CONFIG_CRYPTO_MICHAEL_MIC=m
262CONFIG_CRYPTO_SHA512=m
263CONFIG_CRYPTO_WP512=m
264CONFIG_CRYPTO_ANUBIS=m
265CONFIG_CRYPTO_BLOWFISH=m
266CONFIG_CRYPTO_CAST5=m
267CONFIG_CRYPTO_CAST6=m
268CONFIG_CRYPTO_KHAZAD=m
269CONFIG_CRYPTO_SERPENT=m
270CONFIG_CRYPTO_TEA=m
271CONFIG_CRYPTO_TWOFISH=m
272# CONFIG_CRYPTO_ANSI_CPRNG is not set
273# CONFIG_CRYPTO_HW is not set
diff --git a/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig b/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
deleted file mode 100644
index e32207de2b77..000000000000
--- a/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
+++ /dev/null
@@ -1,110 +0,0 @@
1# CONFIG_SWAP is not set
2CONFIG_SYSVIPC=y
3CONFIG_NO_HZ=y
4CONFIG_HIGH_RES_TIMERS=y
5CONFIG_IKCONFIG=y
6CONFIG_IKCONFIG_PROC=y
7CONFIG_LOG_BUF_SHIFT=14
8CONFIG_BLK_DEV_INITRD=y
9CONFIG_EXPERT=y
10# CONFIG_ELF_CORE is not set
11CONFIG_MODULES=y
12CONFIG_MODULE_UNLOAD=y
13# CONFIG_BLK_DEV_BSG is not set
14CONFIG_PARTITION_ADVANCED=y
15CONFIG_LDM_PARTITION=y
16# CONFIG_IOSCHED_CFQ is not set
17# CONFIG_PPC_CHRP is not set
18# CONFIG_PPC_PMAC is not set
19CONFIG_PPC_86xx=y
20CONFIG_MPC8610_HPCD=y
21CONFIG_HIGHMEM=y
22CONFIG_HZ_1000=y
23CONFIG_FORCE_MAX_ZONEORDER=12
24# CONFIG_SECCOMP is not set
25CONFIG_PCI=y
26CONFIG_PCIEPORTBUS=y
27# CONFIG_PCIEASPM is not set
28CONFIG_PCI_DEBUG=y
29CONFIG_NET=y
30CONFIG_PACKET=y
31CONFIG_UNIX=y
32CONFIG_XFRM_USER=y
33CONFIG_INET=y
34CONFIG_IP_PNP=y
35CONFIG_IP_PNP_DHCP=y
36CONFIG_IP_PNP_BOOTP=y
37CONFIG_IP_PNP_RARP=y
38# CONFIG_INET_LRO is not set
39CONFIG_IPV6=y
40CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
41CONFIG_MTD=y
42CONFIG_MTD_CMDLINE_PARTS=y
43CONFIG_MTD_BLOCK=y
44CONFIG_MTD_CFI=y
45CONFIG_MTD_CFI_AMDSTD=y
46CONFIG_MTD_PHYSMAP_OF=y
47CONFIG_MTD_NAND=y
48CONFIG_MTD_NAND_FSL_ELBC=y
49CONFIG_BLK_DEV_LOOP=y
50CONFIG_BLK_DEV_RAM=y
51CONFIG_BLK_DEV_RAM_SIZE=131072
52CONFIG_IDE=y
53CONFIG_BLK_DEV_SD=y
54CONFIG_CHR_DEV_SG=y
55CONFIG_ATA=y
56CONFIG_SATA_AHCI=y
57CONFIG_PATA_ALI=y
58CONFIG_NETDEVICES=y
59CONFIG_DUMMY=y
60CONFIG_NET_TULIP=y
61CONFIG_ULI526X=y
62# CONFIG_INPUT_MOUSEDEV is not set
63# CONFIG_INPUT_KEYBOARD is not set
64# CONFIG_INPUT_MOUSE is not set
65CONFIG_SERIO_LIBPS2=y
66# CONFIG_LEGACY_PTYS is not set
67CONFIG_SERIAL_8250=y
68CONFIG_SERIAL_8250_CONSOLE=y
69CONFIG_SERIAL_8250_NR_UARTS=2
70CONFIG_SERIAL_8250_RUNTIME_UARTS=2
71CONFIG_SERIAL_8250_EXTENDED=y
72CONFIG_SERIAL_8250_MANY_PORTS=y
73CONFIG_SERIAL_8250_SHARE_IRQ=y
74CONFIG_SERIAL_8250_DETECT_IRQ=y
75CONFIG_SERIAL_8250_RSA=y
76# CONFIG_HW_RANDOM is not set
77CONFIG_I2C=y
78CONFIG_I2C_MPC=y
79# CONFIG_HWMON is not set
80CONFIG_FB=y
81CONFIG_FB_FSL_DIU=y
82CONFIG_VGACON_SOFT_SCROLLBACK=y
83CONFIG_FRAMEBUFFER_CONSOLE=y
84CONFIG_SOUND=y
85CONFIG_SND=y
86CONFIG_SND_MIXER_OSS=y
87CONFIG_SND_PCM_OSS=y
88# CONFIG_SND_SUPPORT_OLD_API is not set
89CONFIG_SND_SOC=y
90CONFIG_SND_POWERPC_SOC=y
91CONFIG_RTC_CLASS=y
92CONFIG_RTC_DRV_CMOS=y
93CONFIG_EXT2_FS=y
94CONFIG_EXT3_FS=y
95# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
96# CONFIG_DNOTIFY is not set
97CONFIG_PROC_KCORE=y
98CONFIG_TMPFS=y
99CONFIG_NFS_FS=y
100CONFIG_ROOT_NFS=y
101CONFIG_NFSD=y
102CONFIG_NLS=y
103CONFIG_CRC_T10DIF=y
104CONFIG_FONTS=y
105CONFIG_FONT_8x8=y
106CONFIG_FONT_8x16=y
107CONFIG_DEBUG_INFO=y
108CONFIG_DEBUG_SHIRQ=y
109CONFIG_DETECT_HUNG_TASK=y
110# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig b/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
deleted file mode 100644
index a36e11ddaebd..000000000000
--- a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
+++ /dev/null
@@ -1,156 +0,0 @@
1CONFIG_SMP=y
2CONFIG_NR_CPUS=2
3CONFIG_SYSVIPC=y
4CONFIG_POSIX_MQUEUE=y
5CONFIG_AUDIT=y
6CONFIG_NO_HZ=y
7CONFIG_HIGH_RES_TIMERS=y
8CONFIG_BSD_PROCESS_ACCT=y
9CONFIG_IKCONFIG=y
10CONFIG_IKCONFIG_PROC=y
11CONFIG_LOG_BUF_SHIFT=14
12CONFIG_BLK_DEV_INITRD=y
13CONFIG_EXPERT=y
14CONFIG_KALLSYMS_ALL=y
15CONFIG_MODULES=y
16CONFIG_MODULE_UNLOAD=y
17CONFIG_MODULE_FORCE_UNLOAD=y
18CONFIG_MODVERSIONS=y
19# CONFIG_BLK_DEV_BSG is not set
20CONFIG_PARTITION_ADVANCED=y
21CONFIG_MAC_PARTITION=y
22# CONFIG_PPC_CHRP is not set
23# CONFIG_PPC_PMAC is not set
24CONFIG_PPC_86xx=y
25CONFIG_MPC8641_HPCN=y
26CONFIG_HIGHMEM=y
27CONFIG_HZ_1000=y
28CONFIG_BINFMT_MISC=m
29CONFIG_PCI=y
30CONFIG_NET=y
31CONFIG_PACKET=y
32CONFIG_UNIX=y
33CONFIG_XFRM_USER=y
34CONFIG_NET_KEY=m
35CONFIG_INET=y
36CONFIG_IP_MULTICAST=y
37CONFIG_IP_ADVANCED_ROUTER=y
38CONFIG_IP_MULTIPLE_TABLES=y
39CONFIG_IP_ROUTE_MULTIPATH=y
40CONFIG_IP_ROUTE_VERBOSE=y
41CONFIG_IP_PNP=y
42CONFIG_IP_PNP_DHCP=y
43CONFIG_IP_PNP_BOOTP=y
44CONFIG_IP_PNP_RARP=y
45CONFIG_NET_IPIP=y
46CONFIG_IP_MROUTE=y
47CONFIG_IP_PIMSM_V1=y
48CONFIG_IP_PIMSM_V2=y
49# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
50# CONFIG_INET_XFRM_MODE_TUNNEL is not set
51# CONFIG_INET_XFRM_MODE_BEET is not set
52# CONFIG_INET_LRO is not set
53CONFIG_IPV6=y
54CONFIG_IP_SCTP=m
55CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
56CONFIG_BLK_DEV_LOOP=y
57CONFIG_BLK_DEV_NBD=y
58CONFIG_BLK_DEV_RAM=y
59CONFIG_BLK_DEV_RAM_SIZE=131072
60CONFIG_EEPROM_LEGACY=y
61CONFIG_BLK_DEV_SD=y
62CONFIG_CHR_DEV_ST=y
63CONFIG_BLK_DEV_SR=y
64CONFIG_CHR_DEV_SG=y
65CONFIG_SCSI_LOGGING=y
66CONFIG_ATA=y
67CONFIG_SATA_AHCI=y
68CONFIG_PATA_ALI=y
69CONFIG_NETDEVICES=y
70CONFIG_DUMMY=y
71CONFIG_GIANFAR=y
72CONFIG_VITESSE_PHY=y
73CONFIG_INPUT_FF_MEMLESS=m
74# CONFIG_INPUT_MOUSEDEV is not set
75# CONFIG_INPUT_KEYBOARD is not set
76# CONFIG_INPUT_MOUSE is not set
77CONFIG_SERIO_LIBPS2=y
78CONFIG_SERIAL_8250=y
79CONFIG_SERIAL_8250_CONSOLE=y
80CONFIG_SERIAL_8250_NR_UARTS=2
81CONFIG_SERIAL_8250_RUNTIME_UARTS=2
82CONFIG_SERIAL_8250_EXTENDED=y
83CONFIG_SERIAL_8250_MANY_PORTS=y
84CONFIG_SERIAL_8250_SHARE_IRQ=y
85CONFIG_SERIAL_8250_DETECT_IRQ=y
86CONFIG_SERIAL_8250_RSA=y
87# CONFIG_HW_RANDOM is not set
88CONFIG_NVRAM=y
89CONFIG_I2C=y
90CONFIG_I2C_MPC=y
91# CONFIG_HWMON is not set
92CONFIG_SOUND=y
93CONFIG_SND=y
94CONFIG_SND_MIXER_OSS=y
95CONFIG_SND_PCM_OSS=y
96# CONFIG_SND_SUPPORT_OLD_API is not set
97CONFIG_SND_INTEL8X0=y
98CONFIG_HID_A4TECH=y
99CONFIG_HID_APPLE=y
100CONFIG_HID_BELKIN=y
101CONFIG_HID_CHERRY=y
102CONFIG_HID_CHICONY=y
103CONFIG_HID_CYPRESS=y
104CONFIG_HID_EZKEY=y
105CONFIG_HID_GYRATION=y
106CONFIG_HID_LOGITECH=y
107CONFIG_HID_MICROSOFT=y
108CONFIG_HID_MONTEREY=y
109CONFIG_HID_PANTHERLORD=y
110CONFIG_HID_PETALYNX=y
111CONFIG_HID_SAMSUNG=y
112CONFIG_HID_SUNPLUS=y
113CONFIG_USB=y
114CONFIG_USB_MON=y
115CONFIG_USB_EHCI_HCD=y
116CONFIG_USB_OHCI_HCD=y
117CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
118CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
119CONFIG_USB_STORAGE=y
120CONFIG_RTC_CLASS=y
121CONFIG_RTC_DRV_CMOS=y
122CONFIG_EXT2_FS=y
123CONFIG_EXT3_FS=y
124# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
125CONFIG_ISO9660_FS=m
126CONFIG_JOLIET=y
127CONFIG_ZISOFS=y
128CONFIG_UDF_FS=m
129CONFIG_MSDOS_FS=m
130CONFIG_VFAT_FS=y
131CONFIG_NTFS_FS=y
132CONFIG_PROC_KCORE=y
133CONFIG_TMPFS=y
134CONFIG_ADFS_FS=m
135CONFIG_AFFS_FS=m
136CONFIG_HFS_FS=m
137CONFIG_HFSPLUS_FS=m
138CONFIG_BEFS_FS=m
139CONFIG_BFS_FS=m
140CONFIG_EFS_FS=m
141CONFIG_CRAMFS=y
142CONFIG_VXFS_FS=m
143CONFIG_HPFS_FS=m
144CONFIG_QNX4FS_FS=m
145CONFIG_SYSV_FS=m
146CONFIG_UFS_FS=m
147CONFIG_NFS_FS=y
148CONFIG_NFS_V4=y
149CONFIG_ROOT_NFS=y
150CONFIG_NFSD=y
151CONFIG_CRC_T10DIF=y
152CONFIG_DEBUG_INFO=y
153CONFIG_DETECT_HUNG_TASK=y
154CONFIG_CRYPTO_PCBC=m
155CONFIG_CRYPTO_HMAC=y
156# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/powerpc/configs/86xx/sbc8641d_defconfig b/arch/powerpc/configs/86xx/sbc8641d_defconfig
deleted file mode 100644
index db79bdee844b..000000000000
--- a/arch/powerpc/configs/86xx/sbc8641d_defconfig
+++ /dev/null
@@ -1,246 +0,0 @@
1CONFIG_SMP=y
2CONFIG_NR_CPUS=2
3CONFIG_SYSVIPC=y
4CONFIG_POSIX_MQUEUE=y
5CONFIG_HIGH_RES_TIMERS=y
6CONFIG_BSD_PROCESS_ACCT=y
7CONFIG_BSD_PROCESS_ACCT_V3=y
8CONFIG_IKCONFIG=y
9CONFIG_IKCONFIG_PROC=y
10CONFIG_LOG_BUF_SHIFT=14
11CONFIG_RELAY=y
12CONFIG_BLK_DEV_INITRD=y
13CONFIG_EXPERT=y
14CONFIG_SLAB=y
15CONFIG_MODULES=y
16CONFIG_MODULE_UNLOAD=y
17# CONFIG_BLK_DEV_BSG is not set
18# CONFIG_PPC_CHRP is not set
19# CONFIG_PPC_PMAC is not set
20CONFIG_PPC_86xx=y
21CONFIG_SBC8641D=y
22CONFIG_PREEMPT=y
23CONFIG_BINFMT_MISC=m
24CONFIG_PCI=y
25CONFIG_PCIEPORTBUS=y
26# CONFIG_PCIEASPM is not set
27CONFIG_NET=y
28CONFIG_PACKET=y
29CONFIG_UNIX=y
30CONFIG_XFRM_USER=m
31CONFIG_NET_KEY=m
32CONFIG_INET=y
33CONFIG_IP_MULTICAST=y
34CONFIG_IP_ADVANCED_ROUTER=y
35CONFIG_IP_MULTIPLE_TABLES=y
36CONFIG_IP_ROUTE_MULTIPATH=y
37CONFIG_IP_ROUTE_VERBOSE=y
38CONFIG_IP_PNP=y
39CONFIG_IP_PNP_DHCP=y
40CONFIG_IP_PNP_BOOTP=y
41CONFIG_IP_PNP_RARP=y
42CONFIG_NET_IPIP=m
43CONFIG_IP_MROUTE=y
44CONFIG_IP_PIMSM_V1=y
45CONFIG_IP_PIMSM_V2=y
46CONFIG_SYN_COOKIES=y
47CONFIG_INET_AH=m
48CONFIG_INET_ESP=m
49CONFIG_INET_IPCOMP=m
50# CONFIG_INET_LRO is not set
51CONFIG_INET6_AH=m
52CONFIG_INET6_ESP=m
53CONFIG_INET6_IPCOMP=m
54CONFIG_IPV6_TUNNEL=m
55CONFIG_NETFILTER=y
56# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
57CONFIG_IP_NF_IPTABLES=m
58CONFIG_IP_NF_MATCH_ECN=m
59CONFIG_IP_NF_MATCH_TTL=m
60CONFIG_IP_NF_FILTER=m
61CONFIG_IP_NF_TARGET_REJECT=m
62CONFIG_IP_NF_MANGLE=m
63CONFIG_IP_NF_TARGET_ECN=m
64CONFIG_IP_NF_RAW=m
65CONFIG_IP_NF_ARPTABLES=m
66CONFIG_IP_NF_ARPFILTER=m
67CONFIG_IP_NF_ARP_MANGLE=m
68CONFIG_IP6_NF_IPTABLES=m
69CONFIG_IP6_NF_MATCH_EUI64=m
70CONFIG_IP6_NF_MATCH_FRAG=m
71CONFIG_IP6_NF_MATCH_OPTS=m
72CONFIG_IP6_NF_MATCH_HL=m
73CONFIG_IP6_NF_MATCH_IPV6HEADER=m
74CONFIG_IP6_NF_MATCH_RT=m
75CONFIG_IP6_NF_FILTER=m
76CONFIG_IP6_NF_MANGLE=m
77CONFIG_IP6_NF_RAW=m
78CONFIG_IP_SCTP=m
79CONFIG_TIPC=m
80CONFIG_ATM=m
81CONFIG_ATM_CLIP=m
82CONFIG_ATM_LANE=m
83CONFIG_ATM_MPOA=m
84CONFIG_ATM_BR2684=m
85CONFIG_BRIDGE=m
86CONFIG_VLAN_8021Q=m
87CONFIG_NET_SCHED=y
88CONFIG_NET_SCH_CBQ=m
89CONFIG_NET_SCH_HTB=m
90CONFIG_NET_SCH_HFSC=m
91CONFIG_NET_SCH_ATM=m
92CONFIG_NET_SCH_PRIO=m
93CONFIG_NET_SCH_RED=m
94CONFIG_NET_SCH_SFQ=m
95CONFIG_NET_SCH_TEQL=m
96CONFIG_NET_SCH_TBF=m
97CONFIG_NET_SCH_GRED=m
98CONFIG_NET_SCH_DSMARK=m
99CONFIG_NET_SCH_NETEM=m
100CONFIG_NET_CLS_TCINDEX=m
101CONFIG_NET_CLS_ROUTE4=m
102CONFIG_NET_CLS_FW=m
103CONFIG_NET_CLS_U32=m
104CONFIG_NET_CLS_RSVP=m
105CONFIG_NET_CLS_RSVP6=m
106CONFIG_NET_PKTGEN=m
107CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
108# CONFIG_FW_LOADER is not set
109CONFIG_MTD=y
110CONFIG_MTD_BLOCK=y
111CONFIG_MTD_CFI=y
112CONFIG_MTD_CFI_ADV_OPTIONS=y
113CONFIG_MTD_CFI_LE_BYTE_SWAP=y
114CONFIG_MTD_CFI_INTELEXT=y
115CONFIG_MTD_PHYSMAP_OF=y
116CONFIG_BLK_DEV_LOOP=m
117CONFIG_BLK_DEV_CRYPTOLOOP=m
118CONFIG_BLK_DEV_NBD=m
119CONFIG_BLK_DEV_RAM=y
120CONFIG_MD=y
121CONFIG_BLK_DEV_MD=y
122CONFIG_MD_LINEAR=y
123CONFIG_MD_RAID0=y
124CONFIG_MD_RAID1=y
125CONFIG_MD_RAID10=y
126CONFIG_MD_MULTIPATH=y
127CONFIG_MD_FAULTY=y
128CONFIG_BLK_DEV_DM=y
129CONFIG_DM_CRYPT=y
130CONFIG_DM_SNAPSHOT=y
131CONFIG_DM_MIRROR=y
132CONFIG_DM_ZERO=y
133CONFIG_NETDEVICES=y
134CONFIG_BONDING=m
135CONFIG_DUMMY=m
136CONFIG_NETCONSOLE=y
137CONFIG_TUN=m
138CONFIG_GIANFAR=y
139CONFIG_BROADCOM_PHY=y
140CONFIG_PPP=m
141CONFIG_PPP_BSDCOMP=m
142CONFIG_PPP_DEFLATE=m
143CONFIG_PPP_FILTER=y
144CONFIG_PPP_MULTILINK=y
145CONFIG_PPPOATM=m
146CONFIG_PPPOE=m
147CONFIG_PPP_ASYNC=m
148CONFIG_PPP_SYNC_TTY=m
149CONFIG_SLIP=m
150CONFIG_SLIP_COMPRESSED=y
151CONFIG_SLIP_SMART=y
152CONFIG_SLIP_MODE_SLIP6=y
153# CONFIG_INPUT_KEYBOARD is not set
154# CONFIG_INPUT_MOUSE is not set
155# CONFIG_SERIO is not set
156CONFIG_SERIAL_8250=y
157CONFIG_SERIAL_8250_CONSOLE=y
158# CONFIG_SERIAL_8250_PCI is not set
159CONFIG_SERIAL_8250_NR_UARTS=2
160CONFIG_SERIAL_8250_RUNTIME_UARTS=2
161CONFIG_I2C=y
162CONFIG_I2C_CHARDEV=y
163CONFIG_I2C_MPC=y
164CONFIG_WATCHDOG=y
165CONFIG_SOFT_WATCHDOG=m
166CONFIG_EXT2_FS=y
167CONFIG_EXT2_FS_XATTR=y
168CONFIG_EXT2_FS_POSIX_ACL=y
169CONFIG_EXT3_FS=y
170# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
171CONFIG_EXT3_FS_POSIX_ACL=y
172CONFIG_REISERFS_FS=m
173CONFIG_REISERFS_FS_XATTR=y
174CONFIG_REISERFS_FS_POSIX_ACL=y
175CONFIG_AUTOFS4_FS=m
176CONFIG_PROC_KCORE=y
177CONFIG_TMPFS=y
178CONFIG_MINIX_FS=m
179CONFIG_ROMFS_FS=m
180CONFIG_NFS_FS=y
181CONFIG_NFS_V4=y
182CONFIG_ROOT_NFS=y
183CONFIG_CIFS=m
184CONFIG_CIFS_XATTR=y
185CONFIG_CIFS_POSIX=y
186CONFIG_NLS_CODEPAGE_437=m
187CONFIG_NLS_CODEPAGE_737=m
188CONFIG_NLS_CODEPAGE_775=m
189CONFIG_NLS_CODEPAGE_850=m
190CONFIG_NLS_CODEPAGE_852=m
191CONFIG_NLS_CODEPAGE_855=m
192CONFIG_NLS_CODEPAGE_857=m
193CONFIG_NLS_CODEPAGE_860=m
194CONFIG_NLS_CODEPAGE_861=m
195CONFIG_NLS_CODEPAGE_862=m
196CONFIG_NLS_CODEPAGE_863=m
197CONFIG_NLS_CODEPAGE_864=m
198CONFIG_NLS_CODEPAGE_865=m
199CONFIG_NLS_CODEPAGE_866=m
200CONFIG_NLS_CODEPAGE_869=m
201CONFIG_NLS_CODEPAGE_936=m
202CONFIG_NLS_CODEPAGE_950=m
203CONFIG_NLS_CODEPAGE_932=m
204CONFIG_NLS_CODEPAGE_949=m
205CONFIG_NLS_CODEPAGE_874=m
206CONFIG_NLS_ISO8859_8=m
207CONFIG_NLS_CODEPAGE_1250=m
208CONFIG_NLS_CODEPAGE_1251=m
209CONFIG_NLS_ASCII=m
210CONFIG_NLS_ISO8859_1=m
211CONFIG_NLS_ISO8859_2=m
212CONFIG_NLS_ISO8859_3=m
213CONFIG_NLS_ISO8859_4=m
214CONFIG_NLS_ISO8859_5=m
215CONFIG_NLS_ISO8859_6=m
216CONFIG_NLS_ISO8859_7=m
217CONFIG_NLS_ISO8859_9=m
218CONFIG_NLS_ISO8859_13=m
219CONFIG_NLS_ISO8859_14=m
220CONFIG_NLS_ISO8859_15=m
221CONFIG_NLS_KOI8_R=m
222CONFIG_NLS_KOI8_U=m
223CONFIG_NLS_UTF8=m
224CONFIG_DEBUG_INFO=y
225CONFIG_DEBUG_FS=y
226CONFIG_MAGIC_SYSRQ=y
227CONFIG_DETECT_HUNG_TASK=y
228# CONFIG_DEBUG_BUGVERBOSE is not set
229CONFIG_SECURITY=y
230CONFIG_SECURITY_NETWORK=y
231CONFIG_CRYPTO_NULL=m
232CONFIG_CRYPTO_TEST=m
233CONFIG_CRYPTO_PCBC=m
234CONFIG_CRYPTO_HMAC=y
235CONFIG_CRYPTO_MICHAEL_MIC=m
236CONFIG_CRYPTO_SHA512=m
237CONFIG_CRYPTO_WP512=m
238CONFIG_CRYPTO_ANUBIS=m
239CONFIG_CRYPTO_BLOWFISH=m
240CONFIG_CRYPTO_CAST5=m
241CONFIG_CRYPTO_CAST6=m
242CONFIG_CRYPTO_KHAZAD=m
243CONFIG_CRYPTO_SERPENT=m
244CONFIG_CRYPTO_TEA=m
245CONFIG_CRYPTO_TWOFISH=m
246# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/powerpc/configs/mpc86xx_basic_defconfig b/arch/powerpc/configs/mpc86xx_basic_defconfig
new file mode 100644
index 000000000000..33af5c5de105
--- /dev/null
+++ b/arch/powerpc/configs/mpc86xx_basic_defconfig
@@ -0,0 +1,10 @@
1CONFIG_HIGHMEM=y
2CONFIG_KEXEC=y
3CONFIG_PPC_86xx=y
4CONFIG_PROC_KCORE=y
5CONFIG_GEF_PPC9A=y
6CONFIG_GEF_SBC310=y
7CONFIG_GEF_SBC610=y
8CONFIG_MPC8610_HPCD=y
9CONFIG_MPC8641_HPCN=y
10CONFIG_SBC8641D=y
diff --git a/arch/powerpc/configs/mpc86xx_defconfig b/arch/powerpc/configs/mpc86xx_defconfig
deleted file mode 100644
index a4572563681c..000000000000
--- a/arch/powerpc/configs/mpc86xx_defconfig
+++ /dev/null
@@ -1,162 +0,0 @@
1CONFIG_SMP=y
2CONFIG_NR_CPUS=2
3CONFIG_SYSVIPC=y
4CONFIG_POSIX_MQUEUE=y
5CONFIG_AUDIT=y
6CONFIG_NO_HZ=y
7CONFIG_HIGH_RES_TIMERS=y
8CONFIG_BSD_PROCESS_ACCT=y
9CONFIG_IKCONFIG=y
10CONFIG_IKCONFIG_PROC=y
11CONFIG_LOG_BUF_SHIFT=14
12CONFIG_BLK_DEV_INITRD=y
13CONFIG_EXPERT=y
14CONFIG_KALLSYMS_ALL=y
15CONFIG_MODULES=y
16CONFIG_MODULE_UNLOAD=y
17CONFIG_MODULE_FORCE_UNLOAD=y
18CONFIG_MODVERSIONS=y
19# CONFIG_BLK_DEV_BSG is not set
20CONFIG_PARTITION_ADVANCED=y
21CONFIG_MAC_PARTITION=y
22# CONFIG_PPC_CHRP is not set
23# CONFIG_PPC_PMAC is not set
24CONFIG_PPC_86xx=y
25CONFIG_MPC8641_HPCN=y
26CONFIG_SBC8641D=y
27CONFIG_MPC8610_HPCD=y
28CONFIG_GEF_SBC610=y
29CONFIG_HIGHMEM=y
30CONFIG_HZ_1000=y
31CONFIG_BINFMT_MISC=m
32CONFIG_PCI=y
33CONFIG_NET=y
34CONFIG_PACKET=y
35CONFIG_UNIX=y
36CONFIG_XFRM_USER=y
37CONFIG_NET_KEY=m
38CONFIG_INET=y
39CONFIG_IP_MULTICAST=y
40CONFIG_IP_ADVANCED_ROUTER=y
41CONFIG_IP_MULTIPLE_TABLES=y
42CONFIG_IP_ROUTE_MULTIPATH=y
43CONFIG_IP_ROUTE_VERBOSE=y
44CONFIG_IP_PNP=y
45CONFIG_IP_PNP_DHCP=y
46CONFIG_IP_PNP_BOOTP=y
47CONFIG_IP_PNP_RARP=y
48CONFIG_NET_IPIP=y
49CONFIG_IP_MROUTE=y
50CONFIG_IP_PIMSM_V1=y
51CONFIG_IP_PIMSM_V2=y
52# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
53# CONFIG_INET_XFRM_MODE_TUNNEL is not set
54# CONFIG_INET_XFRM_MODE_BEET is not set
55# CONFIG_INET_LRO is not set
56CONFIG_IPV6=y
57CONFIG_IP_SCTP=m
58CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
59CONFIG_BLK_DEV_LOOP=y
60CONFIG_BLK_DEV_NBD=y
61CONFIG_BLK_DEV_RAM=y
62CONFIG_BLK_DEV_RAM_SIZE=131072
63CONFIG_EEPROM_LEGACY=y
64CONFIG_BLK_DEV_SD=y
65CONFIG_CHR_DEV_ST=y
66CONFIG_BLK_DEV_SR=y
67CONFIG_CHR_DEV_SG=y
68CONFIG_SCSI_LOGGING=y
69CONFIG_ATA=y
70CONFIG_SATA_AHCI=y
71CONFIG_PATA_ALI=y
72CONFIG_NETDEVICES=y
73CONFIG_DUMMY=y
74CONFIG_GIANFAR=y
75CONFIG_VITESSE_PHY=y
76CONFIG_INPUT_FF_MEMLESS=m
77# CONFIG_INPUT_MOUSEDEV is not set
78# CONFIG_INPUT_KEYBOARD is not set
79# CONFIG_INPUT_MOUSE is not set
80CONFIG_SERIO_LIBPS2=y
81CONFIG_SERIAL_8250=y
82CONFIG_SERIAL_8250_CONSOLE=y
83CONFIG_SERIAL_8250_NR_UARTS=2
84CONFIG_SERIAL_8250_RUNTIME_UARTS=2
85CONFIG_SERIAL_8250_EXTENDED=y
86CONFIG_SERIAL_8250_MANY_PORTS=y
87CONFIG_SERIAL_8250_SHARE_IRQ=y
88CONFIG_SERIAL_8250_DETECT_IRQ=y
89CONFIG_SERIAL_8250_RSA=y
90# CONFIG_HW_RANDOM is not set
91CONFIG_NVRAM=y
92CONFIG_I2C=y
93CONFIG_I2C_MPC=y
94# CONFIG_HWMON is not set
95CONFIG_SOUND=y
96CONFIG_SND=y
97CONFIG_SND_MIXER_OSS=y
98CONFIG_SND_PCM_OSS=y
99# CONFIG_SND_SUPPORT_OLD_API is not set
100CONFIG_SND_INTEL8X0=y
101CONFIG_HID_A4TECH=y
102CONFIG_HID_APPLE=y
103CONFIG_HID_BELKIN=y
104CONFIG_HID_CHERRY=y
105CONFIG_HID_CHICONY=y
106CONFIG_HID_CYPRESS=y
107CONFIG_HID_EZKEY=y
108CONFIG_HID_GYRATION=y
109CONFIG_HID_LOGITECH=y
110CONFIG_HID_MICROSOFT=y
111CONFIG_HID_MONTEREY=y
112CONFIG_HID_PANTHERLORD=y
113CONFIG_HID_PETALYNX=y
114CONFIG_HID_SAMSUNG=y
115CONFIG_HID_SUNPLUS=y
116CONFIG_USB=y
117CONFIG_USB_MON=y
118CONFIG_USB_EHCI_HCD=y
119CONFIG_USB_OHCI_HCD=y
120CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
121CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
122CONFIG_USB_STORAGE=y
123CONFIG_RTC_CLASS=y
124CONFIG_RTC_DRV_CMOS=y
125CONFIG_EXT2_FS=y
126CONFIG_EXT3_FS=y
127# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
128CONFIG_ISO9660_FS=m
129CONFIG_JOLIET=y
130CONFIG_ZISOFS=y
131CONFIG_UDF_FS=m
132CONFIG_MSDOS_FS=m
133CONFIG_VFAT_FS=y
134CONFIG_NTFS_FS=y
135CONFIG_PROC_KCORE=y
136CONFIG_TMPFS=y
137CONFIG_ADFS_FS=m
138CONFIG_AFFS_FS=m
139CONFIG_HFS_FS=m
140CONFIG_HFSPLUS_FS=m
141CONFIG_BEFS_FS=m
142CONFIG_BFS_FS=m
143CONFIG_EFS_FS=m
144CONFIG_CRAMFS=y
145CONFIG_VXFS_FS=m
146CONFIG_HPFS_FS=m
147CONFIG_QNX4FS_FS=m
148CONFIG_SYSV_FS=m
149CONFIG_UFS_FS=m
150CONFIG_NFS_FS=y
151CONFIG_NFS_V4=y
152CONFIG_ROOT_NFS=y
153CONFIG_NFSD=y
154CONFIG_NLS_CODEPAGE_437=y
155CONFIG_NLS_CODEPAGE_850=y
156CONFIG_NLS_ISO8859_1=y
157CONFIG_CRC_T10DIF=y
158CONFIG_DEBUG_INFO=y
159CONFIG_DETECT_HUNG_TASK=y
160CONFIG_CRYPTO_PCBC=m
161CONFIG_CRYPTO_HMAC=y
162# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig
new file mode 100644
index 000000000000..045031048f8d
--- /dev/null
+++ b/arch/powerpc/configs/powernv_defconfig
@@ -0,0 +1,313 @@
1CONFIG_PPC64=y
2CONFIG_SMP=y
3CONFIG_NR_CPUS=2048
4CONFIG_CPU_LITTLE_ENDIAN=y
5CONFIG_SYSVIPC=y
6CONFIG_POSIX_MQUEUE=y
7CONFIG_FHANDLE=y
8CONFIG_AUDIT=y
9CONFIG_IRQ_DOMAIN_DEBUG=y
10CONFIG_NO_HZ=y
11CONFIG_HIGH_RES_TIMERS=y
12CONFIG_TASKSTATS=y
13CONFIG_TASK_DELAY_ACCT=y
14CONFIG_TASK_XACCT=y
15CONFIG_TASK_IO_ACCOUNTING=y
16CONFIG_IKCONFIG=y
17CONFIG_IKCONFIG_PROC=y
18CONFIG_NUMA_BALANCING=y
19CONFIG_CGROUPS=y
20CONFIG_MEMCG=y
21CONFIG_MEMCG_SWAP=y
22CONFIG_CGROUP_SCHED=y
23CONFIG_CGROUP_FREEZER=y
24CONFIG_CPUSETS=y
25CONFIG_CGROUP_DEVICE=y
26CONFIG_CGROUP_CPUACCT=y
27CONFIG_CGROUP_PERF=y
28CONFIG_USER_NS=y
29CONFIG_BLK_DEV_INITRD=y
30# CONFIG_COMPAT_BRK is not set
31CONFIG_PROFILING=y
32CONFIG_OPROFILE=y
33CONFIG_KPROBES=y
34CONFIG_JUMP_LABEL=y
35CONFIG_MODULES=y
36CONFIG_MODULE_UNLOAD=y
37CONFIG_MODVERSIONS=y
38CONFIG_MODULE_SRCVERSION_ALL=y
39CONFIG_PARTITION_ADVANCED=y
40CONFIG_OPAL_PRD=y
41# CONFIG_PPC_PSERIES is not set
42# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
43CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
44CONFIG_CPU_IDLE=y
45CONFIG_HZ_100=y
46CONFIG_BINFMT_MISC=m
47CONFIG_PPC_TRANSACTIONAL_MEM=y
48CONFIG_HOTPLUG_CPU=y
49CONFIG_KEXEC=y
50CONFIG_IRQ_ALL_CPUS=y
51CONFIG_NUMA=y
52CONFIG_MEMORY_HOTPLUG=y
53CONFIG_MEMORY_HOTREMOVE=y
54CONFIG_KSM=y
55CONFIG_TRANSPARENT_HUGEPAGE=y
56CONFIG_PPC_64K_PAGES=y
57CONFIG_PPC_SUBPAGE_PROT=y
58CONFIG_SCHED_SMT=y
59CONFIG_PM=y
60CONFIG_PCI_MSI=y
61CONFIG_HOTPLUG_PCI=y
62CONFIG_NET=y
63CONFIG_PACKET=y
64CONFIG_UNIX=y
65CONFIG_XFRM_USER=m
66CONFIG_NET_KEY=m
67CONFIG_INET=y
68CONFIG_IP_MULTICAST=y
69CONFIG_NET_IPIP=y
70CONFIG_SYN_COOKIES=y
71CONFIG_INET_AH=m
72CONFIG_INET_ESP=m
73CONFIG_INET_IPCOMP=m
74# CONFIG_IPV6 is not set
75CONFIG_NETFILTER=y
76# CONFIG_NETFILTER_ADVANCED is not set
77CONFIG_BRIDGE=m
78CONFIG_VLAN_8021Q=m
79CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
80CONFIG_DEVTMPFS=y
81CONFIG_DEVTMPFS_MOUNT=y
82CONFIG_MTD=y
83CONFIG_MTD_POWERNV_FLASH=y
84CONFIG_PARPORT=m
85CONFIG_PARPORT_PC=m
86CONFIG_BLK_DEV_FD=m
87CONFIG_BLK_DEV_LOOP=y
88CONFIG_BLK_DEV_NBD=m
89CONFIG_BLK_DEV_RAM=y
90CONFIG_BLK_DEV_RAM_SIZE=65536
91CONFIG_VIRTIO_BLK=m
92CONFIG_IDE=y
93CONFIG_BLK_DEV_IDECD=y
94CONFIG_BLK_DEV_GENERIC=y
95CONFIG_BLK_DEV_AMD74XX=y
96CONFIG_BLK_DEV_SD=y
97CONFIG_CHR_DEV_ST=y
98CONFIG_BLK_DEV_SR=y
99CONFIG_BLK_DEV_SR_VENDOR=y
100CONFIG_CHR_DEV_SG=y
101CONFIG_SCSI_CONSTANTS=y
102CONFIG_SCSI_FC_ATTRS=y
103CONFIG_SCSI_SRP_ATTRS=y
104CONFIG_SCSI_CXGB3_ISCSI=m
105CONFIG_SCSI_CXGB4_ISCSI=m
106CONFIG_SCSI_BNX2_ISCSI=m
107CONFIG_BE2ISCSI=m
108CONFIG_SCSI_MPT2SAS=m
109CONFIG_SCSI_SYM53C8XX_2=y
110CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
111CONFIG_SCSI_IPR=y
112CONFIG_SCSI_QLA_FC=m
113CONFIG_SCSI_QLA_ISCSI=m
114CONFIG_SCSI_LPFC=m
115CONFIG_SCSI_VIRTIO=m
116CONFIG_SCSI_DH=y
117CONFIG_SCSI_DH_RDAC=m
118CONFIG_SCSI_DH_ALUA=m
119CONFIG_ATA=y
120CONFIG_SATA_AHCI=y
121# CONFIG_ATA_SFF is not set
122CONFIG_MD=y
123CONFIG_BLK_DEV_MD=y
124CONFIG_MD_LINEAR=y
125CONFIG_MD_RAID0=y
126CONFIG_MD_RAID1=y
127CONFIG_MD_RAID10=m
128CONFIG_MD_RAID456=m
129CONFIG_MD_MULTIPATH=m
130CONFIG_MD_FAULTY=m
131CONFIG_BLK_DEV_DM=y
132CONFIG_DM_CRYPT=m
133CONFIG_DM_SNAPSHOT=m
134CONFIG_DM_THIN_PROVISIONING=m
135CONFIG_DM_MIRROR=m
136CONFIG_DM_ZERO=m
137CONFIG_DM_MULTIPATH=m
138CONFIG_DM_MULTIPATH_QL=m
139CONFIG_DM_MULTIPATH_ST=m
140CONFIG_DM_UEVENT=y
141CONFIG_BONDING=m
142CONFIG_DUMMY=m
143CONFIG_MACVLAN=m
144CONFIG_MACVTAP=m
145CONFIG_VXLAN=m
146CONFIG_NETCONSOLE=y
147CONFIG_TUN=m
148CONFIG_VETH=m
149CONFIG_VIRTIO_NET=m
150CONFIG_VHOST_NET=m
151CONFIG_VORTEX=y
152CONFIG_ACENIC=m
153CONFIG_ACENIC_OMIT_TIGON_I=y
154CONFIG_PCNET32=y
155CONFIG_TIGON3=y
156CONFIG_BNX2X=m
157CONFIG_CHELSIO_T1=m
158CONFIG_BE2NET=m
159CONFIG_S2IO=m
160CONFIG_E100=y
161CONFIG_E1000=y
162CONFIG_E1000E=y
163CONFIG_IXGB=m
164CONFIG_IXGBE=m
165CONFIG_MLX4_EN=m
166CONFIG_MYRI10GE=m
167CONFIG_QLGE=m
168CONFIG_NETXEN_NIC=m
169CONFIG_PPP=m
170CONFIG_PPP_BSDCOMP=m
171CONFIG_PPP_DEFLATE=m
172CONFIG_PPPOE=m
173CONFIG_PPP_ASYNC=m
174CONFIG_PPP_SYNC_TTY=m
175# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
176CONFIG_INPUT_EVDEV=m
177CONFIG_INPUT_MISC=y
178# CONFIG_SERIO_SERPORT is not set
179CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
180CONFIG_SERIAL_8250=y
181CONFIG_SERIAL_8250_CONSOLE=y
182CONFIG_SERIAL_JSM=m
183CONFIG_VIRTIO_CONSOLE=m
184CONFIG_IPMI_HANDLER=y
185CONFIG_IPMI_DEVICE_INTERFACE=y
186CONFIG_IPMI_POWERNV=y
187CONFIG_RAW_DRIVER=y
188CONFIG_MAX_RAW_DEVS=1024
189CONFIG_DRM=y
190CONFIG_DRM_AST=y
191CONFIG_FIRMWARE_EDID=y
192CONFIG_FB_OF=y
193CONFIG_FB_MATROX=y
194CONFIG_FB_MATROX_MILLENIUM=y
195CONFIG_FB_MATROX_MYSTIQUE=y
196CONFIG_FB_MATROX_G=y
197CONFIG_FB_RADEON=y
198CONFIG_FB_IBM_GXT4500=y
199CONFIG_LCD_PLATFORM=m
200# CONFIG_VGA_CONSOLE is not set
201CONFIG_LOGO=y
202CONFIG_HID_GYRATION=y
203CONFIG_HID_PANTHERLORD=y
204CONFIG_HID_PETALYNX=y
205CONFIG_HID_SAMSUNG=y
206CONFIG_HID_SUNPLUS=y
207CONFIG_USB_HIDDEV=y
208CONFIG_USB=y
209CONFIG_USB_MON=m
210CONFIG_USB_EHCI_HCD=y
211# CONFIG_USB_EHCI_HCD_PPC_OF is not set
212CONFIG_USB_OHCI_HCD=y
213CONFIG_USB_STORAGE=m
214CONFIG_NEW_LEDS=y
215CONFIG_LEDS_CLASS=m
216CONFIG_LEDS_POWERNV=m
217CONFIG_INFINIBAND=m
218CONFIG_INFINIBAND_USER_MAD=m
219CONFIG_INFINIBAND_USER_ACCESS=m
220CONFIG_INFINIBAND_MTHCA=m
221CONFIG_INFINIBAND_CXGB3=m
222CONFIG_INFINIBAND_CXGB4=m
223CONFIG_MLX4_INFINIBAND=m
224CONFIG_INFINIBAND_IPOIB=m
225CONFIG_INFINIBAND_IPOIB_CM=y
226CONFIG_INFINIBAND_SRP=m
227CONFIG_INFINIBAND_ISER=m
228CONFIG_RTC_CLASS=y
229CONFIG_RTC_DRV_GENERIC=y
230CONFIG_VIRTIO_PCI=m
231CONFIG_VIRTIO_BALLOON=m
232CONFIG_EXT2_FS=y
233CONFIG_EXT2_FS_XATTR=y
234CONFIG_EXT2_FS_POSIX_ACL=y
235CONFIG_EXT2_FS_SECURITY=y
236CONFIG_EXT3_FS=y
237CONFIG_EXT3_FS_POSIX_ACL=y
238CONFIG_EXT3_FS_SECURITY=y
239CONFIG_REISERFS_FS=y
240CONFIG_REISERFS_FS_XATTR=y
241CONFIG_REISERFS_FS_POSIX_ACL=y
242CONFIG_REISERFS_FS_SECURITY=y
243CONFIG_JFS_FS=m
244CONFIG_JFS_POSIX_ACL=y
245CONFIG_JFS_SECURITY=y
246CONFIG_XFS_FS=m
247CONFIG_XFS_POSIX_ACL=y
248CONFIG_BTRFS_FS=m
249CONFIG_BTRFS_FS_POSIX_ACL=y
250CONFIG_NILFS2_FS=m
251CONFIG_AUTOFS4_FS=m
252CONFIG_FUSE_FS=m
253CONFIG_OVERLAY_FS=m
254CONFIG_ISO9660_FS=y
255CONFIG_UDF_FS=m
256CONFIG_MSDOS_FS=y
257CONFIG_VFAT_FS=y
258CONFIG_PROC_KCORE=y
259CONFIG_TMPFS=y
260CONFIG_TMPFS_POSIX_ACL=y
261CONFIG_HUGETLBFS=y
262CONFIG_CRAMFS=m
263CONFIG_SQUASHFS=m
264CONFIG_SQUASHFS_XATTR=y
265CONFIG_SQUASHFS_LZO=y
266CONFIG_SQUASHFS_XZ=y
267CONFIG_PSTORE=y
268CONFIG_NFS_FS=y
269CONFIG_NFS_V3_ACL=y
270CONFIG_NFS_V4=y
271CONFIG_NFSD=m
272CONFIG_NFSD_V3_ACL=y
273CONFIG_NFSD_V4=y
274CONFIG_CIFS=m
275CONFIG_CIFS_XATTR=y
276CONFIG_CIFS_POSIX=y
277CONFIG_NLS_DEFAULT="utf8"
278CONFIG_NLS_CODEPAGE_437=y
279CONFIG_NLS_ASCII=y
280CONFIG_NLS_ISO8859_1=y
281CONFIG_NLS_UTF8=y
282CONFIG_MAGIC_SYSRQ=y
283CONFIG_DEBUG_KERNEL=y
284CONFIG_DEBUG_STACK_USAGE=y
285CONFIG_DEBUG_STACKOVERFLOW=y
286CONFIG_LOCKUP_DETECTOR=y
287CONFIG_LATENCYTOP=y
288CONFIG_SCHED_TRACER=y
289CONFIG_BLK_DEV_IO_TRACE=y
290CONFIG_CODE_PATCHING_SELFTEST=y
291CONFIG_FTR_FIXUP_SELFTEST=y
292CONFIG_MSI_BITMAP_SELFTEST=y
293CONFIG_XMON=y
294CONFIG_CRYPTO_TEST=m
295CONFIG_CRYPTO_CCM=m
296CONFIG_CRYPTO_PCBC=m
297CONFIG_CRYPTO_HMAC=y
298CONFIG_CRYPTO_MICHAEL_MIC=m
299CONFIG_CRYPTO_TGR192=m
300CONFIG_CRYPTO_WP512=m
301CONFIG_CRYPTO_ANUBIS=m
302CONFIG_CRYPTO_BLOWFISH=m
303CONFIG_CRYPTO_CAST6=m
304CONFIG_CRYPTO_KHAZAD=m
305CONFIG_CRYPTO_SALSA20=m
306CONFIG_CRYPTO_SERPENT=m
307CONFIG_CRYPTO_TEA=m
308CONFIG_CRYPTO_TWOFISH=m
309CONFIG_CRYPTO_LZO=m
310CONFIG_CRYPTO_DEV_NX=y
311CONFIG_VIRTUALIZATION=y
312CONFIG_KVM_BOOK3S_64=m
313CONFIG_KVM_BOOK3S_64_HV=m
diff --git a/arch/powerpc/crypto/aes-spe-core.S b/arch/powerpc/crypto/aes-spe-core.S
index 5dc6bce90a77..bc6ff43a9889 100644
--- a/arch/powerpc/crypto/aes-spe-core.S
+++ b/arch/powerpc/crypto/aes-spe-core.S
@@ -61,7 +61,7 @@
61 * via bl/blr. It expects that caller has pre-xored input data with first 61 * via bl/blr. It expects that caller has pre-xored input data with first
62 * 4 words of encryption key into rD0-rD3. Pointer/counter registers must 62 * 4 words of encryption key into rD0-rD3. Pointer/counter registers must
63 * have also been set up before (rT0, rKP, CTR). Output is stored in rD0-rD3 63 * have also been set up before (rT0, rKP, CTR). Output is stored in rD0-rD3
64 * and rW0-rW3 and caller must execute a final xor on the ouput registers. 64 * and rW0-rW3 and caller must execute a final xor on the output registers.
65 * All working registers rD0-rD3 & rW0-rW7 are overwritten during processing. 65 * All working registers rD0-rD3 & rW0-rW7 are overwritten during processing.
66 * 66 *
67 */ 67 */
@@ -209,7 +209,7 @@ ppc_encrypt_block_loop:
209 * via bl/blr. It expects that caller has pre-xored input data with first 209 * via bl/blr. It expects that caller has pre-xored input data with first
210 * 4 words of encryption key into rD0-rD3. Pointer/counter registers must 210 * 4 words of encryption key into rD0-rD3. Pointer/counter registers must
211 * have also been set up before (rT0, rKP, CTR). Output is stored in rD0-rD3 211 * have also been set up before (rT0, rKP, CTR). Output is stored in rD0-rD3
212 * and rW0-rW3 and caller must execute a final xor on the ouput registers. 212 * and rW0-rW3 and caller must execute a final xor on the output registers.
213 * All working registers rD0-rD3 & rW0-rW7 are overwritten during processing. 213 * All working registers rD0-rD3 & rW0-rW7 are overwritten during processing.
214 * 214 *
215 */ 215 */
diff --git a/arch/powerpc/crypto/aes-spe-glue.c b/arch/powerpc/crypto/aes-spe-glue.c
index ab113198ed20..748fc00c5e19 100644
--- a/arch/powerpc/crypto/aes-spe-glue.c
+++ b/arch/powerpc/crypto/aes-spe-glue.c
@@ -33,7 +33,7 @@
33 * 16 byte block block or 25 cycles per byte. Thus 768 bytes of input data 33 * 16 byte block block or 25 cycles per byte. Thus 768 bytes of input data
34 * will need an estimated maximum of 20,000 cycles. Headroom for cache misses 34 * will need an estimated maximum of 20,000 cycles. Headroom for cache misses
35 * included. Even with the low end model clocked at 667 MHz this equals to a 35 * included. Even with the low end model clocked at 667 MHz this equals to a
36 * critical time window of less than 30us. The value has been choosen to 36 * critical time window of less than 30us. The value has been chosen to
37 * process a 512 byte disk block in one or a large 1400 bytes IPsec network 37 * process a 512 byte disk block in one or a large 1400 bytes IPsec network
38 * packet in two runs. 38 * packet in two runs.
39 * 39 *
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
index 55f106ed12bf..ae0751ef8788 100644
--- a/arch/powerpc/include/asm/atomic.h
+++ b/arch/powerpc/include/asm/atomic.h
@@ -12,6 +12,24 @@
12 12
13#define ATOMIC_INIT(i) { (i) } 13#define ATOMIC_INIT(i) { (i) }
14 14
15/*
16 * Since *_return_relaxed and {cmp}xchg_relaxed are implemented with
17 * a "bne-" instruction at the end, so an isync is enough as a acquire barrier
18 * on the platform without lwsync.
19 */
20#define __atomic_op_acquire(op, args...) \
21({ \
22 typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \
23 __asm__ __volatile__(PPC_ACQUIRE_BARRIER "" : : : "memory"); \
24 __ret; \
25})
26
27#define __atomic_op_release(op, args...) \
28({ \
29 __asm__ __volatile__(PPC_RELEASE_BARRIER "" : : : "memory"); \
30 op##_relaxed(args); \
31})
32
15static __inline__ int atomic_read(const atomic_t *v) 33static __inline__ int atomic_read(const atomic_t *v)
16{ 34{
17 int t; 35 int t;
@@ -42,27 +60,27 @@ static __inline__ void atomic_##op(int a, atomic_t *v) \
42 : "cc"); \ 60 : "cc"); \
43} \ 61} \
44 62
45#define ATOMIC_OP_RETURN(op, asm_op) \ 63#define ATOMIC_OP_RETURN_RELAXED(op, asm_op) \
46static __inline__ int atomic_##op##_return(int a, atomic_t *v) \ 64static inline int atomic_##op##_return_relaxed(int a, atomic_t *v) \
47{ \ 65{ \
48 int t; \ 66 int t; \
49 \ 67 \
50 __asm__ __volatile__( \ 68 __asm__ __volatile__( \
51 PPC_ATOMIC_ENTRY_BARRIER \ 69"1: lwarx %0,0,%3 # atomic_" #op "_return_relaxed\n" \
52"1: lwarx %0,0,%2 # atomic_" #op "_return\n" \ 70 #asm_op " %0,%2,%0\n" \
53 #asm_op " %0,%1,%0\n" \ 71 PPC405_ERR77(0, %3) \
54 PPC405_ERR77(0,%2) \ 72" stwcx. %0,0,%3\n" \
55" stwcx. %0,0,%2 \n" \
56" bne- 1b\n" \ 73" bne- 1b\n" \
57 PPC_ATOMIC_EXIT_BARRIER \ 74 : "=&r" (t), "+m" (v->counter) \
58 : "=&r" (t) \
59 : "r" (a), "r" (&v->counter) \ 75 : "r" (a), "r" (&v->counter) \
60 : "cc", "memory"); \ 76 : "cc"); \
61 \ 77 \
62 return t; \ 78 return t; \
63} 79}
64 80
65#define ATOMIC_OPS(op, asm_op) ATOMIC_OP(op, asm_op) ATOMIC_OP_RETURN(op, asm_op) 81#define ATOMIC_OPS(op, asm_op) \
82 ATOMIC_OP(op, asm_op) \
83 ATOMIC_OP_RETURN_RELAXED(op, asm_op)
66 84
67ATOMIC_OPS(add, add) 85ATOMIC_OPS(add, add)
68ATOMIC_OPS(sub, subf) 86ATOMIC_OPS(sub, subf)
@@ -71,8 +89,11 @@ ATOMIC_OP(and, and)
71ATOMIC_OP(or, or) 89ATOMIC_OP(or, or)
72ATOMIC_OP(xor, xor) 90ATOMIC_OP(xor, xor)
73 91
92#define atomic_add_return_relaxed atomic_add_return_relaxed
93#define atomic_sub_return_relaxed atomic_sub_return_relaxed
94
74#undef ATOMIC_OPS 95#undef ATOMIC_OPS
75#undef ATOMIC_OP_RETURN 96#undef ATOMIC_OP_RETURN_RELAXED
76#undef ATOMIC_OP 97#undef ATOMIC_OP
77 98
78#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) 99#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
@@ -92,21 +113,19 @@ static __inline__ void atomic_inc(atomic_t *v)
92 : "cc", "xer"); 113 : "cc", "xer");
93} 114}
94 115
95static __inline__ int atomic_inc_return(atomic_t *v) 116static __inline__ int atomic_inc_return_relaxed(atomic_t *v)
96{ 117{
97 int t; 118 int t;
98 119
99 __asm__ __volatile__( 120 __asm__ __volatile__(
100 PPC_ATOMIC_ENTRY_BARRIER 121"1: lwarx %0,0,%2 # atomic_inc_return_relaxed\n"
101"1: lwarx %0,0,%1 # atomic_inc_return\n\ 122" addic %0,%0,1\n"
102 addic %0,%0,1\n" 123 PPC405_ERR77(0, %2)
103 PPC405_ERR77(0,%1) 124" stwcx. %0,0,%2\n"
104" stwcx. %0,0,%1 \n\ 125" bne- 1b"
105 bne- 1b" 126 : "=&r" (t), "+m" (v->counter)
106 PPC_ATOMIC_EXIT_BARRIER
107 : "=&r" (t)
108 : "r" (&v->counter) 127 : "r" (&v->counter)
109 : "cc", "xer", "memory"); 128 : "cc", "xer");
110 129
111 return t; 130 return t;
112} 131}
@@ -136,27 +155,34 @@ static __inline__ void atomic_dec(atomic_t *v)
136 : "cc", "xer"); 155 : "cc", "xer");
137} 156}
138 157
139static __inline__ int atomic_dec_return(atomic_t *v) 158static __inline__ int atomic_dec_return_relaxed(atomic_t *v)
140{ 159{
141 int t; 160 int t;
142 161
143 __asm__ __volatile__( 162 __asm__ __volatile__(
144 PPC_ATOMIC_ENTRY_BARRIER 163"1: lwarx %0,0,%2 # atomic_dec_return_relaxed\n"
145"1: lwarx %0,0,%1 # atomic_dec_return\n\ 164" addic %0,%0,-1\n"
146 addic %0,%0,-1\n" 165 PPC405_ERR77(0, %2)
147 PPC405_ERR77(0,%1) 166" stwcx. %0,0,%2\n"
148" stwcx. %0,0,%1\n\ 167" bne- 1b"
149 bne- 1b" 168 : "=&r" (t), "+m" (v->counter)
150 PPC_ATOMIC_EXIT_BARRIER
151 : "=&r" (t)
152 : "r" (&v->counter) 169 : "r" (&v->counter)
153 : "cc", "xer", "memory"); 170 : "cc", "xer");
154 171
155 return t; 172 return t;
156} 173}
157 174
175#define atomic_inc_return_relaxed atomic_inc_return_relaxed
176#define atomic_dec_return_relaxed atomic_dec_return_relaxed
177
158#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) 178#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
179#define atomic_cmpxchg_relaxed(v, o, n) \
180 cmpxchg_relaxed(&((v)->counter), (o), (n))
181#define atomic_cmpxchg_acquire(v, o, n) \
182 cmpxchg_acquire(&((v)->counter), (o), (n))
183
159#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) 184#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
185#define atomic_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
160 186
161/** 187/**
162 * __atomic_add_unless - add unless the number is a given value 188 * __atomic_add_unless - add unless the number is a given value
@@ -285,26 +311,27 @@ static __inline__ void atomic64_##op(long a, atomic64_t *v) \
285 : "cc"); \ 311 : "cc"); \
286} 312}
287 313
288#define ATOMIC64_OP_RETURN(op, asm_op) \ 314#define ATOMIC64_OP_RETURN_RELAXED(op, asm_op) \
289static __inline__ long atomic64_##op##_return(long a, atomic64_t *v) \ 315static inline long \
316atomic64_##op##_return_relaxed(long a, atomic64_t *v) \
290{ \ 317{ \
291 long t; \ 318 long t; \
292 \ 319 \
293 __asm__ __volatile__( \ 320 __asm__ __volatile__( \
294 PPC_ATOMIC_ENTRY_BARRIER \ 321"1: ldarx %0,0,%3 # atomic64_" #op "_return_relaxed\n" \
295"1: ldarx %0,0,%2 # atomic64_" #op "_return\n" \ 322 #asm_op " %0,%2,%0\n" \
296 #asm_op " %0,%1,%0\n" \ 323" stdcx. %0,0,%3\n" \
297" stdcx. %0,0,%2 \n" \
298" bne- 1b\n" \ 324" bne- 1b\n" \
299 PPC_ATOMIC_EXIT_BARRIER \ 325 : "=&r" (t), "+m" (v->counter) \
300 : "=&r" (t) \
301 : "r" (a), "r" (&v->counter) \ 326 : "r" (a), "r" (&v->counter) \
302 : "cc", "memory"); \ 327 : "cc"); \
303 \ 328 \
304 return t; \ 329 return t; \
305} 330}
306 331
307#define ATOMIC64_OPS(op, asm_op) ATOMIC64_OP(op, asm_op) ATOMIC64_OP_RETURN(op, asm_op) 332#define ATOMIC64_OPS(op, asm_op) \
333 ATOMIC64_OP(op, asm_op) \
334 ATOMIC64_OP_RETURN_RELAXED(op, asm_op)
308 335
309ATOMIC64_OPS(add, add) 336ATOMIC64_OPS(add, add)
310ATOMIC64_OPS(sub, subf) 337ATOMIC64_OPS(sub, subf)
@@ -312,8 +339,11 @@ ATOMIC64_OP(and, and)
312ATOMIC64_OP(or, or) 339ATOMIC64_OP(or, or)
313ATOMIC64_OP(xor, xor) 340ATOMIC64_OP(xor, xor)
314 341
315#undef ATOMIC64_OPS 342#define atomic64_add_return_relaxed atomic64_add_return_relaxed
316#undef ATOMIC64_OP_RETURN 343#define atomic64_sub_return_relaxed atomic64_sub_return_relaxed
344
345#undef ATOPIC64_OPS
346#undef ATOMIC64_OP_RETURN_RELAXED
317#undef ATOMIC64_OP 347#undef ATOMIC64_OP
318 348
319#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) 349#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
@@ -332,20 +362,18 @@ static __inline__ void atomic64_inc(atomic64_t *v)
332 : "cc", "xer"); 362 : "cc", "xer");
333} 363}
334 364
335static __inline__ long atomic64_inc_return(atomic64_t *v) 365static __inline__ long atomic64_inc_return_relaxed(atomic64_t *v)
336{ 366{
337 long t; 367 long t;
338 368
339 __asm__ __volatile__( 369 __asm__ __volatile__(
340 PPC_ATOMIC_ENTRY_BARRIER 370"1: ldarx %0,0,%2 # atomic64_inc_return_relaxed\n"
341"1: ldarx %0,0,%1 # atomic64_inc_return\n\ 371" addic %0,%0,1\n"
342 addic %0,%0,1\n\ 372" stdcx. %0,0,%2\n"
343 stdcx. %0,0,%1 \n\ 373" bne- 1b"
344 bne- 1b" 374 : "=&r" (t), "+m" (v->counter)
345 PPC_ATOMIC_EXIT_BARRIER
346 : "=&r" (t)
347 : "r" (&v->counter) 375 : "r" (&v->counter)
348 : "cc", "xer", "memory"); 376 : "cc", "xer");
349 377
350 return t; 378 return t;
351} 379}
@@ -374,24 +402,25 @@ static __inline__ void atomic64_dec(atomic64_t *v)
374 : "cc", "xer"); 402 : "cc", "xer");
375} 403}
376 404
377static __inline__ long atomic64_dec_return(atomic64_t *v) 405static __inline__ long atomic64_dec_return_relaxed(atomic64_t *v)
378{ 406{
379 long t; 407 long t;
380 408
381 __asm__ __volatile__( 409 __asm__ __volatile__(
382 PPC_ATOMIC_ENTRY_BARRIER 410"1: ldarx %0,0,%2 # atomic64_dec_return_relaxed\n"
383"1: ldarx %0,0,%1 # atomic64_dec_return\n\ 411" addic %0,%0,-1\n"
384 addic %0,%0,-1\n\ 412" stdcx. %0,0,%2\n"
385 stdcx. %0,0,%1\n\ 413" bne- 1b"
386 bne- 1b" 414 : "=&r" (t), "+m" (v->counter)
387 PPC_ATOMIC_EXIT_BARRIER
388 : "=&r" (t)
389 : "r" (&v->counter) 415 : "r" (&v->counter)
390 : "cc", "xer", "memory"); 416 : "cc", "xer");
391 417
392 return t; 418 return t;
393} 419}
394 420
421#define atomic64_inc_return_relaxed atomic64_inc_return_relaxed
422#define atomic64_dec_return_relaxed atomic64_dec_return_relaxed
423
395#define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0) 424#define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0)
396#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0) 425#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0)
397 426
@@ -420,7 +449,13 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
420} 449}
421 450
422#define atomic64_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) 451#define atomic64_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
452#define atomic64_cmpxchg_relaxed(v, o, n) \
453 cmpxchg_relaxed(&((v)->counter), (o), (n))
454#define atomic64_cmpxchg_acquire(v, o, n) \
455 cmpxchg_acquire(&((v)->counter), (o), (n))
456
423#define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) 457#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
458#define atomic64_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
424 459
425/** 460/**
426 * atomic64_add_unless - add unless the number is a given value 461 * atomic64_add_unless - add unless the number is a given value
diff --git a/arch/powerpc/include/asm/mmu-hash32.h b/arch/powerpc/include/asm/book3s/32/mmu-hash.h
index 16f513e5cbd7..16f513e5cbd7 100644
--- a/arch/powerpc/include/asm/mmu-hash32.h
+++ b/arch/powerpc/include/asm/book3s/32/mmu-hash.h
diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h
index ea0414d6659e..5f08a0832238 100644
--- a/arch/powerpc/include/asm/book3s/64/hash-4k.h
+++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h
@@ -52,44 +52,14 @@
52 _PAGE_F_SECOND | _PAGE_F_GIX) 52 _PAGE_F_SECOND | _PAGE_F_GIX)
53 53
54/* shift to put page number into pte */ 54/* shift to put page number into pte */
55#define PTE_RPN_SHIFT (18) 55#define PTE_RPN_SHIFT (12)
56#define PTE_RPN_SIZE (45) /* gives 57-bit real addresses */
56 57
57#define _PAGE_4K_PFN 0 58#define _PAGE_4K_PFN 0
58#ifndef __ASSEMBLY__ 59#ifndef __ASSEMBLY__
59/* 60/*
60 * 4-level page tables related bits 61 * On all 4K setups, remap_4k_pfn() equates to remap_pfn_range()
61 */ 62 */
62
63#define pgd_none(pgd) (!pgd_val(pgd))
64#define pgd_bad(pgd) (pgd_val(pgd) == 0)
65#define pgd_present(pgd) (pgd_val(pgd) != 0)
66#define pgd_page_vaddr(pgd) (pgd_val(pgd) & ~PGD_MASKED_BITS)
67
68static inline void pgd_clear(pgd_t *pgdp)
69{
70 *pgdp = __pgd(0);
71}
72
73static inline pte_t pgd_pte(pgd_t pgd)
74{
75 return __pte(pgd_val(pgd));
76}
77
78static inline pgd_t pte_pgd(pte_t pte)
79{
80 return __pgd(pte_val(pte));
81}
82extern struct page *pgd_page(pgd_t pgd);
83
84#define pud_offset(pgdp, addr) \
85 (((pud_t *) pgd_page_vaddr(*(pgdp))) + \
86 (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)))
87
88#define pud_ERROR(e) \
89 pr_err("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e))
90
91/*
92 * On all 4K setups, remap_4k_pfn() equates to remap_pfn_range() */
93#define remap_4k_pfn(vma, addr, pfn, prot) \ 63#define remap_4k_pfn(vma, addr, pfn, prot) \
94 remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot)) 64 remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot))
95 65
diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h
index 849bbec80f7b..0a7956a80a08 100644
--- a/arch/powerpc/include/asm/book3s/64/hash-64k.h
+++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h
@@ -1,15 +1,14 @@
1#ifndef _ASM_POWERPC_BOOK3S_64_HASH_64K_H 1#ifndef _ASM_POWERPC_BOOK3S_64_HASH_64K_H
2#define _ASM_POWERPC_BOOK3S_64_HASH_64K_H 2#define _ASM_POWERPC_BOOK3S_64_HASH_64K_H
3 3
4#include <asm-generic/pgtable-nopud.h>
5
6#define PTE_INDEX_SIZE 8 4#define PTE_INDEX_SIZE 8
7#define PMD_INDEX_SIZE 10 5#define PMD_INDEX_SIZE 5
8#define PUD_INDEX_SIZE 0 6#define PUD_INDEX_SIZE 5
9#define PGD_INDEX_SIZE 12 7#define PGD_INDEX_SIZE 12
10 8
11#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE) 9#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
12#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) 10#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
11#define PTRS_PER_PUD (1 << PUD_INDEX_SIZE)
13#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) 12#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
14 13
15/* With 4k base page size, hugepage PTEs go at the PMD level */ 14/* With 4k base page size, hugepage PTEs go at the PMD level */
@@ -20,13 +19,18 @@
20#define PMD_SIZE (1UL << PMD_SHIFT) 19#define PMD_SIZE (1UL << PMD_SHIFT)
21#define PMD_MASK (~(PMD_SIZE-1)) 20#define PMD_MASK (~(PMD_SIZE-1))
22 21
23/* PGDIR_SHIFT determines what a third-level page table entry can map */ 22/* PUD_SHIFT determines what a third-level page table entry can map */
24#define PGDIR_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE) 23#define PUD_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE)
24#define PUD_SIZE (1UL << PUD_SHIFT)
25#define PUD_MASK (~(PUD_SIZE-1))
26
27/* PGDIR_SHIFT determines what a fourth-level page table entry can map */
28#define PGDIR_SHIFT (PUD_SHIFT + PUD_INDEX_SIZE)
25#define PGDIR_SIZE (1UL << PGDIR_SHIFT) 29#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
26#define PGDIR_MASK (~(PGDIR_SIZE-1)) 30#define PGDIR_MASK (~(PGDIR_SIZE-1))
27 31
28#define _PAGE_COMBO 0x00040000 /* this is a combo 4k page */ 32#define _PAGE_COMBO 0x00001000 /* this is a combo 4k page */
29#define _PAGE_4K_PFN 0x00080000 /* PFN is for a single 4k page */ 33#define _PAGE_4K_PFN 0x00002000 /* PFN is for a single 4k page */
30/* 34/*
31 * Used to track subpage group valid if _PAGE_COMBO is set 35 * Used to track subpage group valid if _PAGE_COMBO is set
32 * This overloads _PAGE_F_GIX and _PAGE_F_SECOND 36 * This overloads _PAGE_F_GIX and _PAGE_F_SECOND
@@ -39,10 +43,12 @@
39 43
40/* Shift to put page number into pte. 44/* Shift to put page number into pte.
41 * 45 *
42 * That gives us a max RPN of 34 bits, which means a max of 50 bits 46 * That gives us a max RPN of 41 bits, which means a max of 57 bits
43 * of addressable physical space, or 46 bits for the special 4k PFNs. 47 * of addressable physical space, or 53 bits for the special 4k PFNs.
44 */ 48 */
45#define PTE_RPN_SHIFT (30) 49#define PTE_RPN_SHIFT (16)
50#define PTE_RPN_SIZE (41)
51
46/* 52/*
47 * we support 16 fragments per PTE page of 64K size. 53 * we support 16 fragments per PTE page of 64K size.
48 */ 54 */
@@ -54,13 +60,12 @@
54#define PTE_FRAG_SIZE_SHIFT 12 60#define PTE_FRAG_SIZE_SHIFT 12
55#define PTE_FRAG_SIZE (1UL << PTE_FRAG_SIZE_SHIFT) 61#define PTE_FRAG_SIZE (1UL << PTE_FRAG_SIZE_SHIFT)
56 62
57/* 63/* Bits to mask out from a PMD to get to the PTE page */
58 * Bits to mask out from a PMD to get to the PTE page 64#define PMD_MASKED_BITS 0xc0000000000000ffUL
59 * PMDs point to PTE table fragments which are PTE_FRAG_SIZE aligned. 65/* Bits to mask out from a PUD to get to the PMD page */
60 */ 66#define PUD_MASKED_BITS 0xc0000000000000ffUL
61#define PMD_MASKED_BITS (PTE_FRAG_SIZE - 1) 67/* Bits to mask out from a PGD to get to the PUD page */
62/* Bits to mask out from a PGD/PUD to get to the PMD page */ 68#define PGD_MASKED_BITS 0xc0000000000000ffUL
63#define PUD_MASKED_BITS 0x1ff
64 69
65#ifndef __ASSEMBLY__ 70#ifndef __ASSEMBLY__
66 71
@@ -120,7 +125,7 @@ extern bool __rpte_sub_valid(real_pte_t rpte, unsigned long index);
120 (((pte) & _PAGE_COMBO)? MMU_PAGE_4K: MMU_PAGE_64K) 125 (((pte) & _PAGE_COMBO)? MMU_PAGE_4K: MMU_PAGE_64K)
121 126
122#define remap_4k_pfn(vma, addr, pfn, prot) \ 127#define remap_4k_pfn(vma, addr, pfn, prot) \
123 (WARN_ON(((pfn) >= (1UL << (64 - PTE_RPN_SHIFT)))) ? -EINVAL : \ 128 (WARN_ON(((pfn) >= (1UL << PTE_RPN_SIZE))) ? -EINVAL : \
124 remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \ 129 remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \
125 __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN))) 130 __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN)))
126 131
@@ -130,11 +135,9 @@ extern bool __rpte_sub_valid(real_pte_t rpte, unsigned long index);
130#else 135#else
131#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE) 136#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
132#endif 137#endif
138#define PUD_TABLE_SIZE (sizeof(pud_t) << PUD_INDEX_SIZE)
133#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE) 139#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE)
134 140
135#define pgd_pte(pgd) (pud_pte(((pud_t){ pgd })))
136#define pte_pgd(pte) ((pgd_t)pte_pud(pte))
137
138#ifdef CONFIG_HUGETLB_PAGE 141#ifdef CONFIG_HUGETLB_PAGE
139/* 142/*
140 * We have PGD_INDEX_SIZ = 12 and PTE_INDEX_SIZE = 8, so that we can have 143 * We have PGD_INDEX_SIZ = 12 and PTE_INDEX_SIZE = 8, so that we can have
@@ -208,30 +211,30 @@ static inline char *get_hpte_slot_array(pmd_t *pmdp)
208/* 211/*
209 * The linux hugepage PMD now include the pmd entries followed by the address 212 * The linux hugepage PMD now include the pmd entries followed by the address
210 * to the stashed pgtable_t. The stashed pgtable_t contains the hpte bits. 213 * to the stashed pgtable_t. The stashed pgtable_t contains the hpte bits.
211 * [ 1 bit secondary | 3 bit hidx | 1 bit valid | 000]. We use one byte per 214 * [ 000 | 1 bit secondary | 3 bit hidx | 1 bit valid]. We use one byte per
212 * each HPTE entry. With 16MB hugepage and 64K HPTE we need 256 entries and 215 * each HPTE entry. With 16MB hugepage and 64K HPTE we need 256 entries and
213 * with 4K HPTE we need 4096 entries. Both will fit in a 4K pgtable_t. 216 * with 4K HPTE we need 4096 entries. Both will fit in a 4K pgtable_t.
214 * 217 *
215 * The last three bits are intentionally left to zero. This memory location 218 * The top three bits are intentionally left as zero. This memory location
216 * are also used as normal page PTE pointers. So if we have any pointers 219 * are also used as normal page PTE pointers. So if we have any pointers
217 * left around while we collapse a hugepage, we need to make sure 220 * left around while we collapse a hugepage, we need to make sure
218 * _PAGE_PRESENT bit of that is zero when we look at them 221 * _PAGE_PRESENT bit of that is zero when we look at them
219 */ 222 */
220static inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index) 223static inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index)
221{ 224{
222 return (hpte_slot_array[index] >> 3) & 0x1; 225 return hpte_slot_array[index] & 0x1;
223} 226}
224 227
225static inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array, 228static inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array,
226 int index) 229 int index)
227{ 230{
228 return hpte_slot_array[index] >> 4; 231 return hpte_slot_array[index] >> 1;
229} 232}
230 233
231static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array, 234static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array,
232 unsigned int index, unsigned int hidx) 235 unsigned int index, unsigned int hidx)
233{ 236{
234 hpte_slot_array[index] = hidx << 4 | 0x1 << 3; 237 hpte_slot_array[index] = (hidx << 1) | 0x1;
235} 238}
236 239
237/* 240/*
diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h
index 8d1c8162f0c1..d0ee6fcef823 100644
--- a/arch/powerpc/include/asm/book3s/64/hash.h
+++ b/arch/powerpc/include/asm/book3s/64/hash.h
@@ -4,8 +4,7 @@
4 4
5/* 5/*
6 * Common bits between 4K and 64K pages in a linux-style PTE. 6 * Common bits between 4K and 64K pages in a linux-style PTE.
7 * These match the bits in the (hardware-defined) PowerPC PTE as closely 7 * Additional bits may be defined in pgtable-hash64-*.h
8 * as possible. Additional bits may be defined in pgtable-hash64-*.h
9 * 8 *
10 * Note: We only support user read/write permissions. Supervisor always 9 * Note: We only support user read/write permissions. Supervisor always
11 * have full read/write to pages above PAGE_OFFSET (pages below that 10 * have full read/write to pages above PAGE_OFFSET (pages below that
@@ -14,32 +13,35 @@
14 * We could create separate kernel read-only if we used the 3 PP bits 13 * We could create separate kernel read-only if we used the 3 PP bits
15 * combinations that newer processors provide but we currently don't. 14 * combinations that newer processors provide but we currently don't.
16 */ 15 */
17#define _PAGE_PTE 0x00001 16#define _PAGE_BIT_SWAP_TYPE 0
18#define _PAGE_PRESENT 0x00002 /* software: pte contains a translation */ 17
19#define _PAGE_BIT_SWAP_TYPE 2 18#define _PAGE_EXEC 0x00001 /* execute permission */
20#define _PAGE_USER 0x00004 /* matches one of the PP bits */ 19#define _PAGE_RW 0x00002 /* read & write access allowed */
21#define _PAGE_EXEC 0x00008 /* No execute on POWER4 and newer (we invert) */ 20#define _PAGE_READ 0x00004 /* read access allowed */
22#define _PAGE_GUARDED 0x00010 21#define _PAGE_USER 0x00008 /* page may be accessed by userspace */
23/* We can derive Memory coherence from _PAGE_NO_CACHE */ 22#define _PAGE_GUARDED 0x00010 /* G: guarded (side-effect) page */
23/* M (memory coherence) is always set in the HPTE, so we don't need it here */
24#define _PAGE_COHERENT 0x0 24#define _PAGE_COHERENT 0x0
25#define _PAGE_NO_CACHE 0x00020 /* I: cache inhibit */ 25#define _PAGE_NO_CACHE 0x00020 /* I: cache inhibit */
26#define _PAGE_WRITETHRU 0x00040 /* W: cache write-through */ 26#define _PAGE_WRITETHRU 0x00040 /* W: cache write-through */
27#define _PAGE_DIRTY 0x00080 /* C: page changed */ 27#define _PAGE_DIRTY 0x00080 /* C: page changed */
28#define _PAGE_ACCESSED 0x00100 /* R: page referenced */ 28#define _PAGE_ACCESSED 0x00100 /* R: page referenced */
29#define _PAGE_RW 0x00200 /* software: user write access allowed */ 29#define _PAGE_SPECIAL 0x00400 /* software: special page */
30#define _PAGE_HASHPTE 0x00400 /* software: pte has an associated HPTE */
31#define _PAGE_BUSY 0x00800 /* software: PTE & hash are busy */ 30#define _PAGE_BUSY 0x00800 /* software: PTE & hash are busy */
32#define _PAGE_F_GIX 0x07000 /* full page: hidx bits */
33#define _PAGE_F_GIX_SHIFT 12
34#define _PAGE_F_SECOND 0x08000 /* Whether to use secondary hash or not */
35#define _PAGE_SPECIAL 0x10000 /* software: special page */
36 31
37#ifdef CONFIG_MEM_SOFT_DIRTY 32#ifdef CONFIG_MEM_SOFT_DIRTY
38#define _PAGE_SOFT_DIRTY 0x20000 /* software: software dirty tracking */ 33#define _PAGE_SOFT_DIRTY 0x200 /* software: software dirty tracking */
39#else 34#else
40#define _PAGE_SOFT_DIRTY 0x00000 35#define _PAGE_SOFT_DIRTY 0x000
41#endif 36#endif
42 37
38#define _PAGE_F_GIX_SHIFT 57
39#define _PAGE_F_GIX (7ul << 57) /* HPTE index within HPTEG */
40#define _PAGE_F_SECOND (1ul << 60) /* HPTE is in 2ndary HPTEG */
41#define _PAGE_HASHPTE (1ul << 61) /* PTE has associated HPTE */
42#define _PAGE_PTE (1ul << 62) /* distinguishes PTEs from pointers */
43#define _PAGE_PRESENT (1ul << 63) /* pte contains a translation */
44
43/* 45/*
44 * We need to differentiate between explicit huge page and THP huge 46 * We need to differentiate between explicit huge page and THP huge
45 * page, since THP huge page also need to track real subpage details 47 * page, since THP huge page also need to track real subpage details
@@ -132,7 +134,7 @@
132 * The mask convered by the RPN must be a ULL on 32-bit platforms with 134 * The mask convered by the RPN must be a ULL on 32-bit platforms with
133 * 64-bit PTEs 135 * 64-bit PTEs
134 */ 136 */
135#define PTE_RPN_MASK (~((1UL << PTE_RPN_SHIFT) - 1)) 137#define PTE_RPN_MASK (((1UL << PTE_RPN_SIZE) - 1) << PTE_RPN_SHIFT)
136/* 138/*
137 * _PAGE_CHG_MASK masks of bits that are to be preserved across 139 * _PAGE_CHG_MASK masks of bits that are to be preserved across
138 * pgprot changes 140 * pgprot changes
@@ -223,15 +225,17 @@
223#define PUD_BAD_BITS (PMD_TABLE_SIZE-1) 225#define PUD_BAD_BITS (PMD_TABLE_SIZE-1)
224 226
225#ifndef __ASSEMBLY__ 227#ifndef __ASSEMBLY__
226#define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \ 228#define pmd_bad(pmd) (pmd_val(pmd) & PMD_BAD_BITS)
227 || (pmd_val(pmd) & PMD_BAD_BITS)) 229#define pmd_page_vaddr(pmd) __va(pmd_val(pmd) & ~PMD_MASKED_BITS)
228#define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS) 230
231#define pud_bad(pud) (pud_val(pud) & PUD_BAD_BITS)
232#define pud_page_vaddr(pud) __va(pud_val(pud) & ~PUD_MASKED_BITS)
229 233
230#define pud_bad(pud) (!is_kernel_addr(pud_val(pud)) \ 234/* Pointers in the page table tree are physical addresses */
231 || (pud_val(pud) & PUD_BAD_BITS)) 235#define __pgtable_ptr_val(ptr) __pa(ptr)
232#define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS)
233 236
234#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1)) 237#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1))
238#define pud_index(address) (((address) >> (PUD_SHIFT)) & (PTRS_PER_PUD - 1))
235#define pmd_index(address) (((address) >> (PMD_SHIFT)) & (PTRS_PER_PMD - 1)) 239#define pmd_index(address) (((address) >> (PMD_SHIFT)) & (PTRS_PER_PMD - 1))
236#define pte_index(address) (((address) >> (PAGE_SHIFT)) & (PTRS_PER_PTE - 1)) 240#define pte_index(address) (((address) >> (PAGE_SHIFT)) & (PTRS_PER_PTE - 1))
237 241
@@ -360,8 +364,18 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
360 :"cc"); 364 :"cc");
361} 365}
362 366
367static inline int pgd_bad(pgd_t pgd)
368{
369 return (pgd_val(pgd) == 0);
370}
371
363#define __HAVE_ARCH_PTE_SAME 372#define __HAVE_ARCH_PTE_SAME
364#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0) 373#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
374static inline unsigned long pgd_page_vaddr(pgd_t pgd)
375{
376 return (unsigned long)__va(pgd_val(pgd) & ~PGD_MASKED_BITS);
377}
378
365 379
366/* Generic accessors to PTE bits */ 380/* Generic accessors to PTE bits */
367static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & _PAGE_RW);} 381static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & _PAGE_RW);}
@@ -402,7 +416,7 @@ static inline int pte_protnone(pte_t pte)
402 416
403static inline int pte_present(pte_t pte) 417static inline int pte_present(pte_t pte)
404{ 418{
405 return pte_val(pte) & _PAGE_PRESENT; 419 return !!(pte_val(pte) & _PAGE_PRESENT);
406} 420}
407 421
408/* Conversion functions: convert a page and protection to a page entry, 422/* Conversion functions: convert a page and protection to a page entry,
@@ -413,13 +427,13 @@ static inline int pte_present(pte_t pte)
413 */ 427 */
414static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) 428static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
415{ 429{
416 return __pte(((pte_basic_t)(pfn) << PTE_RPN_SHIFT) | 430 return __pte((((pte_basic_t)(pfn) << PTE_RPN_SHIFT) & PTE_RPN_MASK) |
417 pgprot_val(pgprot)); 431 pgprot_val(pgprot));
418} 432}
419 433
420static inline unsigned long pte_pfn(pte_t pte) 434static inline unsigned long pte_pfn(pte_t pte)
421{ 435{
422 return pte_val(pte) >> PTE_RPN_SHIFT; 436 return (pte_val(pte) & PTE_RPN_MASK) >> PTE_RPN_SHIFT;
423} 437}
424 438
425/* Generic modifiers for PTE bits */ 439/* Generic modifiers for PTE bits */
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h
index 7352d3f212df..0cea4807e26f 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h
@@ -114,6 +114,7 @@
114 114
115#define POWER7_TLB_SETS 128 /* # sets in POWER7 TLB */ 115#define POWER7_TLB_SETS 128 /* # sets in POWER7 TLB */
116#define POWER8_TLB_SETS 512 /* # sets in POWER8 TLB */ 116#define POWER8_TLB_SETS 512 /* # sets in POWER8 TLB */
117#define POWER9_TLB_SETS_HASH 256 /* # sets in POWER9 TLB Hash mode */
117 118
118#ifndef __ASSEMBLY__ 119#ifndef __ASSEMBLY__
119 120
@@ -607,6 +608,9 @@ static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
607 context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1; 608 context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1;
608 return get_vsid(context, ea, ssize); 609 return get_vsid(context, ea, ssize);
609} 610}
611
612unsigned htab_shift_for_mem_size(unsigned long mem_size);
613
610#endif /* __ASSEMBLY__ */ 614#endif /* __ASSEMBLY__ */
611 615
612#endif /* _ASM_POWERPC_MMU_HASH64_H_ */ 616#endif /* _ASM_POWERPC_MMU_HASH64_H_ */
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index ac07a30a7934..77d3ce05798e 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -43,13 +43,8 @@
43 */ 43 */
44#ifndef __real_pte 44#ifndef __real_pte
45 45
46#ifdef CONFIG_STRICT_MM_TYPECHECKS
47#define __real_pte(e,p) ((real_pte_t){(e)}) 46#define __real_pte(e,p) ((real_pte_t){(e)})
48#define __rpte_to_pte(r) ((r).pte) 47#define __rpte_to_pte(r) ((r).pte)
49#else
50#define __real_pte(e,p) (e)
51#define __rpte_to_pte(r) (__pte(r))
52#endif
53#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >>_PAGE_F_GIX_SHIFT) 48#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >>_PAGE_F_GIX_SHIFT)
54 49
55#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ 50#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \
@@ -111,6 +106,26 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val)
111 *pgdp = __pgd(val); 106 *pgdp = __pgd(val);
112} 107}
113 108
109static inline void pgd_clear(pgd_t *pgdp)
110{
111 *pgdp = __pgd(0);
112}
113
114#define pgd_none(pgd) (!pgd_val(pgd))
115#define pgd_present(pgd) (!pgd_none(pgd))
116
117static inline pte_t pgd_pte(pgd_t pgd)
118{
119 return __pte(pgd_val(pgd));
120}
121
122static inline pgd_t pte_pgd(pte_t pte)
123{
124 return __pgd(pte_val(pte));
125}
126
127extern struct page *pgd_page(pgd_t pgd);
128
114/* 129/*
115 * Find an entry in a page-table-directory. We combine the address region 130 * Find an entry in a page-table-directory. We combine the address region
116 * (the high order N bits) and the pgd portion of the address. 131 * (the high order N bits) and the pgd portion of the address.
@@ -118,9 +133,10 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val)
118 133
119#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) 134#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
120 135
136#define pud_offset(pgdp, addr) \
137 (((pud_t *) pgd_page_vaddr(*(pgdp))) + pud_index(addr))
121#define pmd_offset(pudp,addr) \ 138#define pmd_offset(pudp,addr) \
122 (((pmd_t *) pud_page_vaddr(*(pudp))) + pmd_index(addr)) 139 (((pmd_t *) pud_page_vaddr(*(pudp))) + pmd_index(addr))
123
124#define pte_offset_kernel(dir,addr) \ 140#define pte_offset_kernel(dir,addr) \
125 (((pte_t *) pmd_page_vaddr(*(dir))) + pte_index(addr)) 141 (((pte_t *) pmd_page_vaddr(*(dir))) + pte_index(addr))
126 142
@@ -135,6 +151,8 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val)
135 pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) 151 pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
136#define pmd_ERROR(e) \ 152#define pmd_ERROR(e) \
137 pr_err("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) 153 pr_err("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
154#define pud_ERROR(e) \
155 pr_err("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e))
138#define pgd_ERROR(e) \ 156#define pgd_ERROR(e) \
139 pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) 157 pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
140 158
@@ -154,10 +172,10 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val)
154#define SWP_TYPE_BITS 5 172#define SWP_TYPE_BITS 5
155#define __swp_type(x) (((x).val >> _PAGE_BIT_SWAP_TYPE) \ 173#define __swp_type(x) (((x).val >> _PAGE_BIT_SWAP_TYPE) \
156 & ((1UL << SWP_TYPE_BITS) - 1)) 174 & ((1UL << SWP_TYPE_BITS) - 1))
157#define __swp_offset(x) ((x).val >> PTE_RPN_SHIFT) 175#define __swp_offset(x) (((x).val & PTE_RPN_MASK) >> PTE_RPN_SHIFT)
158#define __swp_entry(type, offset) ((swp_entry_t) { \ 176#define __swp_entry(type, offset) ((swp_entry_t) { \
159 ((type) << _PAGE_BIT_SWAP_TYPE) \ 177 ((type) << _PAGE_BIT_SWAP_TYPE) \
160 | ((offset) << PTE_RPN_SHIFT) }) 178 | (((offset) << PTE_RPN_SHIFT) & PTE_RPN_MASK)})
161/* 179/*
162 * swp_entry_t must be independent of pte bits. We build a swp_entry_t from 180 * swp_entry_t must be independent of pte bits. We build a swp_entry_t from
163 * swap type and offset we get from swap and convert that to pte to find a 181 * swap type and offset we get from swap and convert that to pte to find a
diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
new file mode 100644
index 000000000000..1b753f96b374
--- /dev/null
+++ b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
@@ -0,0 +1,94 @@
1#ifndef _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H
2#define _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H
3
4#define MMU_NO_CONTEXT 0
5
6/*
7 * TLB flushing for 64-bit hash-MMU CPUs
8 */
9
10#include <linux/percpu.h>
11#include <asm/page.h>
12
13#define PPC64_TLB_BATCH_NR 192
14
15struct ppc64_tlb_batch {
16 int active;
17 unsigned long index;
18 struct mm_struct *mm;
19 real_pte_t pte[PPC64_TLB_BATCH_NR];
20 unsigned long vpn[PPC64_TLB_BATCH_NR];
21 unsigned int psize;
22 int ssize;
23};
24DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
25
26extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch);
27
28#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
29
30static inline void arch_enter_lazy_mmu_mode(void)
31{
32 struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
33
34 batch->active = 1;
35}
36
37static inline void arch_leave_lazy_mmu_mode(void)
38{
39 struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
40
41 if (batch->index)
42 __flush_tlb_pending(batch);
43 batch->active = 0;
44}
45
46#define arch_flush_lazy_mmu_mode() do {} while (0)
47
48
49extern void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize,
50 int ssize, unsigned long flags);
51extern void flush_hash_range(unsigned long number, int local);
52extern void flush_hash_hugepage(unsigned long vsid, unsigned long addr,
53 pmd_t *pmdp, unsigned int psize, int ssize,
54 unsigned long flags);
55
56static inline void local_flush_tlb_mm(struct mm_struct *mm)
57{
58}
59
60static inline void flush_tlb_mm(struct mm_struct *mm)
61{
62}
63
64static inline void local_flush_tlb_page(struct vm_area_struct *vma,
65 unsigned long vmaddr)
66{
67}
68
69static inline void flush_tlb_page(struct vm_area_struct *vma,
70 unsigned long vmaddr)
71{
72}
73
74static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
75 unsigned long vmaddr)
76{
77}
78
79static inline void flush_tlb_range(struct vm_area_struct *vma,
80 unsigned long start, unsigned long end)
81{
82}
83
84static inline void flush_tlb_kernel_range(unsigned long start,
85 unsigned long end)
86{
87}
88
89/* Private function for use by PCI IO mapping code */
90extern void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
91 unsigned long end);
92extern void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd,
93 unsigned long addr);
94#endif /* _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H */
diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
index 5f8229e24fe6..ffbafbf76b19 100644
--- a/arch/powerpc/include/asm/cache.h
+++ b/arch/powerpc/include/asm/cache.h
@@ -69,6 +69,25 @@ extern void _set_L3CR(unsigned long);
69#define _set_L3CR(val) do { } while(0) 69#define _set_L3CR(val) do { } while(0)
70#endif 70#endif
71 71
72static inline void dcbz(void *addr)
73{
74 __asm__ __volatile__ ("dcbz 0, %0" : : "r"(addr) : "memory");
75}
76
77static inline void dcbi(void *addr)
78{
79 __asm__ __volatile__ ("dcbi 0, %0" : : "r"(addr) : "memory");
80}
81
82static inline void dcbf(void *addr)
83{
84 __asm__ __volatile__ ("dcbf 0, %0" : : "r"(addr) : "memory");
85}
86
87static inline void dcbst(void *addr)
88{
89 __asm__ __volatile__ ("dcbst 0, %0" : : "r"(addr) : "memory");
90}
72#endif /* !__ASSEMBLY__ */ 91#endif /* !__ASSEMBLY__ */
73#endif /* __KERNEL__ */ 92#endif /* __KERNEL__ */
74#endif /* _ASM_POWERPC_CACHE_H */ 93#endif /* _ASM_POWERPC_CACHE_H */
diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h
index 6229e6b6037b..69fb16d7a811 100644
--- a/arch/powerpc/include/asm/cacheflush.h
+++ b/arch/powerpc/include/asm/cacheflush.h
@@ -30,8 +30,6 @@ extern void flush_dcache_page(struct page *page);
30#define flush_dcache_mmap_lock(mapping) do { } while (0) 30#define flush_dcache_mmap_lock(mapping) do { } while (0)
31#define flush_dcache_mmap_unlock(mapping) do { } while (0) 31#define flush_dcache_mmap_unlock(mapping) do { } while (0)
32 32
33extern void __flush_disable_L1(void);
34
35extern void flush_icache_range(unsigned long, unsigned long); 33extern void flush_icache_range(unsigned long, unsigned long);
36extern void flush_icache_user_range(struct vm_area_struct *vma, 34extern void flush_icache_user_range(struct vm_area_struct *vma,
37 struct page *page, unsigned long addr, 35 struct page *page, unsigned long addr,
@@ -47,12 +45,58 @@ static inline void __flush_dcache_icache_phys(unsigned long physaddr)
47} 45}
48#endif 46#endif
49 47
50extern void flush_dcache_range(unsigned long start, unsigned long stop);
51#ifdef CONFIG_PPC32 48#ifdef CONFIG_PPC32
52extern void clean_dcache_range(unsigned long start, unsigned long stop); 49/*
53extern void invalidate_dcache_range(unsigned long start, unsigned long stop); 50 * Write any modified data cache blocks out to memory and invalidate them.
51 * Does not invalidate the corresponding instruction cache blocks.
52 */
53static inline void flush_dcache_range(unsigned long start, unsigned long stop)
54{
55 void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1));
56 unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1);
57 unsigned long i;
58
59 for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
60 dcbf(addr);
61 mb(); /* sync */
62}
63
64/*
65 * Write any modified data cache blocks out to memory.
66 * Does not invalidate the corresponding cache lines (especially for
67 * any corresponding instruction cache).
68 */
69static inline void clean_dcache_range(unsigned long start, unsigned long stop)
70{
71 void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1));
72 unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1);
73 unsigned long i;
74
75 for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
76 dcbst(addr);
77 mb(); /* sync */
78}
79
80/*
81 * Like above, but invalidate the D-cache. This is used by the 8xx
82 * to invalidate the cache so the PPC core doesn't get stale data
83 * from the CPM (no cache snooping here :-).
84 */
85static inline void invalidate_dcache_range(unsigned long start,
86 unsigned long stop)
87{
88 void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1));
89 unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1);
90 unsigned long i;
91
92 for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
93 dcbi(addr);
94 mb(); /* sync */
95}
96
54#endif /* CONFIG_PPC32 */ 97#endif /* CONFIG_PPC32 */
55#ifdef CONFIG_PPC64 98#ifdef CONFIG_PPC64
99extern void flush_dcache_range(unsigned long start, unsigned long stop);
56extern void flush_inval_dcache_range(unsigned long start, unsigned long stop); 100extern void flush_inval_dcache_range(unsigned long start, unsigned long stop);
57extern void flush_dcache_phys_range(unsigned long start, unsigned long stop); 101extern void flush_dcache_phys_range(unsigned long start, unsigned long stop);
58#endif 102#endif
diff --git a/arch/powerpc/include/asm/checksum.h b/arch/powerpc/include/asm/checksum.h
index e8d9ef4755a4..ee655ed1ff1b 100644
--- a/arch/powerpc/include/asm/checksum.h
+++ b/arch/powerpc/include/asm/checksum.h
@@ -9,30 +9,9 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 11
12/*
13 * This is a version of ip_compute_csum() optimized for IP headers,
14 * which always checksum on 4 octet boundaries. ihl is the number
15 * of 32-bit words and is always >= 5.
16 */
17#ifdef CONFIG_GENERIC_CSUM 12#ifdef CONFIG_GENERIC_CSUM
18#include <asm-generic/checksum.h> 13#include <asm-generic/checksum.h>
19#else 14#else
20extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
21
22/*
23 * computes the checksum of a memory block at buff, length len,
24 * and adds in "sum" (32-bit)
25 *
26 * returns a 32-bit number suitable for feeding into itself
27 * or csum_tcpudp_magic
28 *
29 * this function must be called with even lengths, except
30 * for the last fragment, which may be odd
31 *
32 * it's best to have buff aligned on a 32-bit boundary
33 */
34extern __wsum csum_partial(const void *buff, int len, __wsum sum);
35
36/* 15/*
37 * Computes the checksum of a memory block at src, length len, 16 * Computes the checksum of a memory block at src, length len,
38 * and adds in "sum" (32-bit), while copying the block to dst. 17 * and adds in "sum" (32-bit), while copying the block to dst.
@@ -47,21 +26,12 @@ extern __wsum csum_partial_copy_generic(const void *src, void *dst,
47 int len, __wsum sum, 26 int len, __wsum sum,
48 int *src_err, int *dst_err); 27 int *src_err, int *dst_err);
49 28
50#ifdef __powerpc64__
51#define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 29#define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
52extern __wsum csum_and_copy_from_user(const void __user *src, void *dst, 30extern __wsum csum_and_copy_from_user(const void __user *src, void *dst,
53 int len, __wsum sum, int *err_ptr); 31 int len, __wsum sum, int *err_ptr);
54#define HAVE_CSUM_COPY_USER 32#define HAVE_CSUM_COPY_USER
55extern __wsum csum_and_copy_to_user(const void *src, void __user *dst, 33extern __wsum csum_and_copy_to_user(const void *src, void __user *dst,
56 int len, __wsum sum, int *err_ptr); 34 int len, __wsum sum, int *err_ptr);
57#else
58/*
59 * the same as csum_partial, but copies from src to dst while it
60 * checksums.
61 */
62#define csum_partial_copy_from_user(src, dst, len, sum, errp) \
63 csum_partial_copy_generic((__force const void *)(src), (dst), (len), (sum), (errp), NULL)
64#endif
65 35
66#define csum_partial_copy_nocheck(src, dst, len, sum) \ 36#define csum_partial_copy_nocheck(src, dst, len, sum) \
67 csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL) 37 csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL)
@@ -83,15 +53,6 @@ static inline __sum16 csum_fold(__wsum sum)
83 return (__force __sum16)(~((__force u32)sum + tmp) >> 16); 53 return (__force __sum16)(~((__force u32)sum + tmp) >> 16);
84} 54}
85 55
86/*
87 * this routine is used for miscellaneous IP-like checksums, mainly
88 * in icmp.c
89 */
90static inline __sum16 ip_compute_csum(const void *buff, int len)
91{
92 return csum_fold(csum_partial(buff, len, 0));
93}
94
95static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, 56static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
96 unsigned short len, 57 unsigned short len,
97 unsigned short proto, 58 unsigned short proto,
@@ -135,17 +96,117 @@ static inline __wsum csum_add(__wsum csum, __wsum addend)
135{ 96{
136#ifdef __powerpc64__ 97#ifdef __powerpc64__
137 u64 res = (__force u64)csum; 98 u64 res = (__force u64)csum;
99#endif
100 if (__builtin_constant_p(csum) && csum == 0)
101 return addend;
102 if (__builtin_constant_p(addend) && addend == 0)
103 return csum;
138 104
105#ifdef __powerpc64__
139 res += (__force u64)addend; 106 res += (__force u64)addend;
140 return (__force __wsum)((u32)res + (res >> 32)); 107 return (__force __wsum)((u32)res + (res >> 32));
141#else 108#else
142 asm("addc %0,%0,%1;" 109 asm("addc %0,%0,%1;"
143 "addze %0,%0;" 110 "addze %0,%0;"
144 : "+r" (csum) : "r" (addend)); 111 : "+r" (csum) : "r" (addend) : "xer");
145 return csum; 112 return csum;
146#endif 113#endif
147} 114}
148 115
116/*
117 * This is a version of ip_compute_csum() optimized for IP headers,
118 * which always checksum on 4 octet boundaries. ihl is the number
119 * of 32-bit words and is always >= 5.
120 */
121static inline __wsum ip_fast_csum_nofold(const void *iph, unsigned int ihl)
122{
123 const u32 *ptr = (const u32 *)iph + 1;
124#ifdef __powerpc64__
125 unsigned int i;
126 u64 s = *(const u32 *)iph;
127
128 for (i = 0; i < ihl - 1; i++, ptr++)
129 s += *ptr;
130 s += (s >> 32);
131 return (__force __wsum)s;
132#else
133 __wsum sum, tmp;
134
135 asm("mtctr %3;"
136 "addc %0,%4,%5;"
137 "1: lwzu %1, 4(%2);"
138 "adde %0,%0,%1;"
139 "bdnz 1b;"
140 "addze %0,%0;"
141 : "=r" (sum), "=r" (tmp), "+b" (ptr)
142 : "r" (ihl - 2), "r" (*(const u32 *)iph), "r" (*ptr)
143 : "ctr", "xer", "memory");
144
145 return sum;
146#endif
147}
148
149static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
150{
151 return csum_fold(ip_fast_csum_nofold(iph, ihl));
152}
153
154/*
155 * computes the checksum of a memory block at buff, length len,
156 * and adds in "sum" (32-bit)
157 *
158 * returns a 32-bit number suitable for feeding into itself
159 * or csum_tcpudp_magic
160 *
161 * this function must be called with even lengths, except
162 * for the last fragment, which may be odd
163 *
164 * it's best to have buff aligned on a 32-bit boundary
165 */
166__wsum __csum_partial(const void *buff, int len, __wsum sum);
167
168static inline __wsum csum_partial(const void *buff, int len, __wsum sum)
169{
170 if (__builtin_constant_p(len) && len <= 16 && (len & 1) == 0) {
171 if (len == 2)
172 sum = csum_add(sum, (__force __wsum)*(const u16 *)buff);
173 if (len >= 4)
174 sum = csum_add(sum, (__force __wsum)*(const u32 *)buff);
175 if (len == 6)
176 sum = csum_add(sum, (__force __wsum)
177 *(const u16 *)(buff + 4));
178 if (len >= 8)
179 sum = csum_add(sum, (__force __wsum)
180 *(const u32 *)(buff + 4));
181 if (len == 10)
182 sum = csum_add(sum, (__force __wsum)
183 *(const u16 *)(buff + 8));
184 if (len >= 12)
185 sum = csum_add(sum, (__force __wsum)
186 *(const u32 *)(buff + 8));
187 if (len == 14)
188 sum = csum_add(sum, (__force __wsum)
189 *(const u16 *)(buff + 12));
190 if (len >= 16)
191 sum = csum_add(sum, (__force __wsum)
192 *(const u32 *)(buff + 12));
193 } else if (__builtin_constant_p(len) && (len & 3) == 0) {
194 sum = csum_add(sum, ip_fast_csum_nofold(buff, len >> 2));
195 } else {
196 sum = __csum_partial(buff, len, sum);
197 }
198 return sum;
199}
200
201/*
202 * this routine is used for miscellaneous IP-like checksums, mainly
203 * in icmp.c
204 */
205static inline __sum16 ip_compute_csum(const void *buff, int len)
206{
207 return csum_fold(csum_partial(buff, len, 0));
208}
209
149#endif 210#endif
150#endif /* __KERNEL__ */ 211#endif /* __KERNEL__ */
151#endif 212#endif
diff --git a/arch/powerpc/include/asm/cmpxchg.h b/arch/powerpc/include/asm/cmpxchg.h
index d1a8d93cccfd..44efe739b6b9 100644
--- a/arch/powerpc/include/asm/cmpxchg.h
+++ b/arch/powerpc/include/asm/cmpxchg.h
@@ -5,25 +5,25 @@
5#include <linux/compiler.h> 5#include <linux/compiler.h>
6#include <asm/synch.h> 6#include <asm/synch.h>
7#include <asm/asm-compat.h> 7#include <asm/asm-compat.h>
8#include <linux/bug.h>
8 9
9/* 10/*
10 * Atomic exchange 11 * Atomic exchange
11 * 12 *
12 * Changes the memory location '*ptr' to be val and returns 13 * Changes the memory location '*p' to be val and returns
13 * the previous value stored there. 14 * the previous value stored there.
14 */ 15 */
16
15static __always_inline unsigned long 17static __always_inline unsigned long
16__xchg_u32(volatile void *p, unsigned long val) 18__xchg_u32_local(volatile void *p, unsigned long val)
17{ 19{
18 unsigned long prev; 20 unsigned long prev;
19 21
20 __asm__ __volatile__( 22 __asm__ __volatile__(
21 PPC_ATOMIC_ENTRY_BARRIER
22"1: lwarx %0,0,%2 \n" 23"1: lwarx %0,0,%2 \n"
23 PPC405_ERR77(0,%2) 24 PPC405_ERR77(0,%2)
24" stwcx. %3,0,%2 \n\ 25" stwcx. %3,0,%2 \n\
25 bne- 1b" 26 bne- 1b"
26 PPC_ATOMIC_EXIT_BARRIER
27 : "=&r" (prev), "+m" (*(volatile unsigned int *)p) 27 : "=&r" (prev), "+m" (*(volatile unsigned int *)p)
28 : "r" (p), "r" (val) 28 : "r" (p), "r" (val)
29 : "cc", "memory"); 29 : "cc", "memory");
@@ -31,42 +31,34 @@ __xchg_u32(volatile void *p, unsigned long val)
31 return prev; 31 return prev;
32} 32}
33 33
34/*
35 * Atomic exchange
36 *
37 * Changes the memory location '*ptr' to be val and returns
38 * the previous value stored there.
39 */
40static __always_inline unsigned long 34static __always_inline unsigned long
41__xchg_u32_local(volatile void *p, unsigned long val) 35__xchg_u32_relaxed(u32 *p, unsigned long val)
42{ 36{
43 unsigned long prev; 37 unsigned long prev;
44 38
45 __asm__ __volatile__( 39 __asm__ __volatile__(
46"1: lwarx %0,0,%2 \n" 40"1: lwarx %0,0,%2\n"
47 PPC405_ERR77(0,%2) 41 PPC405_ERR77(0, %2)
48" stwcx. %3,0,%2 \n\ 42" stwcx. %3,0,%2\n"
49 bne- 1b" 43" bne- 1b"
50 : "=&r" (prev), "+m" (*(volatile unsigned int *)p) 44 : "=&r" (prev), "+m" (*p)
51 : "r" (p), "r" (val) 45 : "r" (p), "r" (val)
52 : "cc", "memory"); 46 : "cc");
53 47
54 return prev; 48 return prev;
55} 49}
56 50
57#ifdef CONFIG_PPC64 51#ifdef CONFIG_PPC64
58static __always_inline unsigned long 52static __always_inline unsigned long
59__xchg_u64(volatile void *p, unsigned long val) 53__xchg_u64_local(volatile void *p, unsigned long val)
60{ 54{
61 unsigned long prev; 55 unsigned long prev;
62 56
63 __asm__ __volatile__( 57 __asm__ __volatile__(
64 PPC_ATOMIC_ENTRY_BARRIER
65"1: ldarx %0,0,%2 \n" 58"1: ldarx %0,0,%2 \n"
66 PPC405_ERR77(0,%2) 59 PPC405_ERR77(0,%2)
67" stdcx. %3,0,%2 \n\ 60" stdcx. %3,0,%2 \n\
68 bne- 1b" 61 bne- 1b"
69 PPC_ATOMIC_EXIT_BARRIER
70 : "=&r" (prev), "+m" (*(volatile unsigned long *)p) 62 : "=&r" (prev), "+m" (*(volatile unsigned long *)p)
71 : "r" (p), "r" (val) 63 : "r" (p), "r" (val)
72 : "cc", "memory"); 64 : "cc", "memory");
@@ -75,64 +67,52 @@ __xchg_u64(volatile void *p, unsigned long val)
75} 67}
76 68
77static __always_inline unsigned long 69static __always_inline unsigned long
78__xchg_u64_local(volatile void *p, unsigned long val) 70__xchg_u64_relaxed(u64 *p, unsigned long val)
79{ 71{
80 unsigned long prev; 72 unsigned long prev;
81 73
82 __asm__ __volatile__( 74 __asm__ __volatile__(
83"1: ldarx %0,0,%2 \n" 75"1: ldarx %0,0,%2\n"
84 PPC405_ERR77(0,%2) 76 PPC405_ERR77(0, %2)
85" stdcx. %3,0,%2 \n\ 77" stdcx. %3,0,%2\n"
86 bne- 1b" 78" bne- 1b"
87 : "=&r" (prev), "+m" (*(volatile unsigned long *)p) 79 : "=&r" (prev), "+m" (*p)
88 : "r" (p), "r" (val) 80 : "r" (p), "r" (val)
89 : "cc", "memory"); 81 : "cc");
90 82
91 return prev; 83 return prev;
92} 84}
93#endif 85#endif
94 86
95/*
96 * This function doesn't exist, so you'll get a linker error
97 * if something tries to do an invalid xchg().
98 */
99extern void __xchg_called_with_bad_pointer(void);
100
101static __always_inline unsigned long 87static __always_inline unsigned long
102__xchg(volatile void *ptr, unsigned long x, unsigned int size) 88__xchg_local(volatile void *ptr, unsigned long x, unsigned int size)
103{ 89{
104 switch (size) { 90 switch (size) {
105 case 4: 91 case 4:
106 return __xchg_u32(ptr, x); 92 return __xchg_u32_local(ptr, x);
107#ifdef CONFIG_PPC64 93#ifdef CONFIG_PPC64
108 case 8: 94 case 8:
109 return __xchg_u64(ptr, x); 95 return __xchg_u64_local(ptr, x);
110#endif 96#endif
111 } 97 }
112 __xchg_called_with_bad_pointer(); 98 BUILD_BUG_ON_MSG(1, "Unsupported size for __xchg");
113 return x; 99 return x;
114} 100}
115 101
116static __always_inline unsigned long 102static __always_inline unsigned long
117__xchg_local(volatile void *ptr, unsigned long x, unsigned int size) 103__xchg_relaxed(void *ptr, unsigned long x, unsigned int size)
118{ 104{
119 switch (size) { 105 switch (size) {
120 case 4: 106 case 4:
121 return __xchg_u32_local(ptr, x); 107 return __xchg_u32_relaxed(ptr, x);
122#ifdef CONFIG_PPC64 108#ifdef CONFIG_PPC64
123 case 8: 109 case 8:
124 return __xchg_u64_local(ptr, x); 110 return __xchg_u64_relaxed(ptr, x);
125#endif 111#endif
126 } 112 }
127 __xchg_called_with_bad_pointer(); 113 BUILD_BUG_ON_MSG(1, "Unsupported size for __xchg_local");
128 return x; 114 return x;
129} 115}
130#define xchg(ptr,x) \
131 ({ \
132 __typeof__(*(ptr)) _x_ = (x); \
133 (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
134 })
135
136#define xchg_local(ptr,x) \ 116#define xchg_local(ptr,x) \
137 ({ \ 117 ({ \
138 __typeof__(*(ptr)) _x_ = (x); \ 118 __typeof__(*(ptr)) _x_ = (x); \
@@ -140,6 +120,12 @@ __xchg_local(volatile void *ptr, unsigned long x, unsigned int size)
140 (unsigned long)_x_, sizeof(*(ptr))); \ 120 (unsigned long)_x_, sizeof(*(ptr))); \
141 }) 121 })
142 122
123#define xchg_relaxed(ptr, x) \
124({ \
125 __typeof__(*(ptr)) _x_ = (x); \
126 (__typeof__(*(ptr))) __xchg_relaxed((ptr), \
127 (unsigned long)_x_, sizeof(*(ptr))); \
128})
143/* 129/*
144 * Compare and exchange - if *p == old, set it to new, 130 * Compare and exchange - if *p == old, set it to new,
145 * and return the old value of *p. 131 * and return the old value of *p.
@@ -190,6 +176,56 @@ __cmpxchg_u32_local(volatile unsigned int *p, unsigned long old,
190 return prev; 176 return prev;
191} 177}
192 178
179static __always_inline unsigned long
180__cmpxchg_u32_relaxed(u32 *p, unsigned long old, unsigned long new)
181{
182 unsigned long prev;
183
184 __asm__ __volatile__ (
185"1: lwarx %0,0,%2 # __cmpxchg_u32_relaxed\n"
186" cmpw 0,%0,%3\n"
187" bne- 2f\n"
188 PPC405_ERR77(0, %2)
189" stwcx. %4,0,%2\n"
190" bne- 1b\n"
191"2:"
192 : "=&r" (prev), "+m" (*p)
193 : "r" (p), "r" (old), "r" (new)
194 : "cc");
195
196 return prev;
197}
198
199/*
200 * cmpxchg family don't have order guarantee if cmp part fails, therefore we
201 * can avoid superfluous barriers if we use assembly code to implement
202 * cmpxchg() and cmpxchg_acquire(), however we don't do the similar for
203 * cmpxchg_release() because that will result in putting a barrier in the
204 * middle of a ll/sc loop, which is probably a bad idea. For example, this
205 * might cause the conditional store more likely to fail.
206 */
207static __always_inline unsigned long
208__cmpxchg_u32_acquire(u32 *p, unsigned long old, unsigned long new)
209{
210 unsigned long prev;
211
212 __asm__ __volatile__ (
213"1: lwarx %0,0,%2 # __cmpxchg_u32_acquire\n"
214" cmpw 0,%0,%3\n"
215" bne- 2f\n"
216 PPC405_ERR77(0, %2)
217" stwcx. %4,0,%2\n"
218" bne- 1b\n"
219 PPC_ACQUIRE_BARRIER
220 "\n"
221"2:"
222 : "=&r" (prev), "+m" (*p)
223 : "r" (p), "r" (old), "r" (new)
224 : "cc", "memory");
225
226 return prev;
227}
228
193#ifdef CONFIG_PPC64 229#ifdef CONFIG_PPC64
194static __always_inline unsigned long 230static __always_inline unsigned long
195__cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new) 231__cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
@@ -233,11 +269,47 @@ __cmpxchg_u64_local(volatile unsigned long *p, unsigned long old,
233 269
234 return prev; 270 return prev;
235} 271}
236#endif
237 272
238/* This function doesn't exist, so you'll get a linker error 273static __always_inline unsigned long
239 if something tries to do an invalid cmpxchg(). */ 274__cmpxchg_u64_relaxed(u64 *p, unsigned long old, unsigned long new)
240extern void __cmpxchg_called_with_bad_pointer(void); 275{
276 unsigned long prev;
277
278 __asm__ __volatile__ (
279"1: ldarx %0,0,%2 # __cmpxchg_u64_relaxed\n"
280" cmpd 0,%0,%3\n"
281" bne- 2f\n"
282" stdcx. %4,0,%2\n"
283" bne- 1b\n"
284"2:"
285 : "=&r" (prev), "+m" (*p)
286 : "r" (p), "r" (old), "r" (new)
287 : "cc");
288
289 return prev;
290}
291
292static __always_inline unsigned long
293__cmpxchg_u64_acquire(u64 *p, unsigned long old, unsigned long new)
294{
295 unsigned long prev;
296
297 __asm__ __volatile__ (
298"1: ldarx %0,0,%2 # __cmpxchg_u64_acquire\n"
299" cmpd 0,%0,%3\n"
300" bne- 2f\n"
301" stdcx. %4,0,%2\n"
302" bne- 1b\n"
303 PPC_ACQUIRE_BARRIER
304 "\n"
305"2:"
306 : "=&r" (prev), "+m" (*p)
307 : "r" (p), "r" (old), "r" (new)
308 : "cc", "memory");
309
310 return prev;
311}
312#endif
241 313
242static __always_inline unsigned long 314static __always_inline unsigned long
243__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, 315__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
@@ -251,7 +323,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
251 return __cmpxchg_u64(ptr, old, new); 323 return __cmpxchg_u64(ptr, old, new);
252#endif 324#endif
253 } 325 }
254 __cmpxchg_called_with_bad_pointer(); 326 BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg");
255 return old; 327 return old;
256} 328}
257 329
@@ -267,10 +339,41 @@ __cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
267 return __cmpxchg_u64_local(ptr, old, new); 339 return __cmpxchg_u64_local(ptr, old, new);
268#endif 340#endif
269 } 341 }
270 __cmpxchg_called_with_bad_pointer(); 342 BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_local");
343 return old;
344}
345
346static __always_inline unsigned long
347__cmpxchg_relaxed(void *ptr, unsigned long old, unsigned long new,
348 unsigned int size)
349{
350 switch (size) {
351 case 4:
352 return __cmpxchg_u32_relaxed(ptr, old, new);
353#ifdef CONFIG_PPC64
354 case 8:
355 return __cmpxchg_u64_relaxed(ptr, old, new);
356#endif
357 }
358 BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_relaxed");
271 return old; 359 return old;
272} 360}
273 361
362static __always_inline unsigned long
363__cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
364 unsigned int size)
365{
366 switch (size) {
367 case 4:
368 return __cmpxchg_u32_acquire(ptr, old, new);
369#ifdef CONFIG_PPC64
370 case 8:
371 return __cmpxchg_u64_acquire(ptr, old, new);
372#endif
373 }
374 BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_acquire");
375 return old;
376}
274#define cmpxchg(ptr, o, n) \ 377#define cmpxchg(ptr, o, n) \
275 ({ \ 378 ({ \
276 __typeof__(*(ptr)) _o_ = (o); \ 379 __typeof__(*(ptr)) _o_ = (o); \
@@ -288,6 +391,23 @@ __cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
288 (unsigned long)_n_, sizeof(*(ptr))); \ 391 (unsigned long)_n_, sizeof(*(ptr))); \
289 }) 392 })
290 393
394#define cmpxchg_relaxed(ptr, o, n) \
395({ \
396 __typeof__(*(ptr)) _o_ = (o); \
397 __typeof__(*(ptr)) _n_ = (n); \
398 (__typeof__(*(ptr))) __cmpxchg_relaxed((ptr), \
399 (unsigned long)_o_, (unsigned long)_n_, \
400 sizeof(*(ptr))); \
401})
402
403#define cmpxchg_acquire(ptr, o, n) \
404({ \
405 __typeof__(*(ptr)) _o_ = (o); \
406 __typeof__(*(ptr)) _n_ = (n); \
407 (__typeof__(*(ptr))) __cmpxchg_acquire((ptr), \
408 (unsigned long)_o_, (unsigned long)_n_, \
409 sizeof(*(ptr))); \
410})
291#ifdef CONFIG_PPC64 411#ifdef CONFIG_PPC64
292#define cmpxchg64(ptr, o, n) \ 412#define cmpxchg64(ptr, o, n) \
293 ({ \ 413 ({ \
@@ -299,7 +419,16 @@ __cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
299 BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ 419 BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
300 cmpxchg_local((ptr), (o), (n)); \ 420 cmpxchg_local((ptr), (o), (n)); \
301 }) 421 })
302#define cmpxchg64_relaxed cmpxchg64_local 422#define cmpxchg64_relaxed(ptr, o, n) \
423({ \
424 BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
425 cmpxchg_relaxed((ptr), (o), (n)); \
426})
427#define cmpxchg64_acquire(ptr, o, n) \
428({ \
429 BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
430 cmpxchg_acquire((ptr), (o), (n)); \
431})
303#else 432#else
304#include <asm-generic/cmpxchg-local.h> 433#include <asm-generic/cmpxchg-local.h>
305#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) 434#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index 840a5509b3f1..994c60a857ce 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -99,4 +99,25 @@ static inline unsigned long ppc_global_function_entry(void *func)
99#endif 99#endif
100} 100}
101 101
102#ifdef CONFIG_PPC64
103/*
104 * Some instruction encodings commonly used in dynamic ftracing
105 * and function live patching.
106 */
107
108/* This must match the definition of STK_GOT in <asm/ppc_asm.h> */
109#if defined(_CALL_ELF) && _CALL_ELF == 2
110#define R2_STACK_OFFSET 24
111#else
112#define R2_STACK_OFFSET 40
113#endif
114
115#define PPC_INST_LD_TOC (PPC_INST_LD | ___PPC_RT(__REG_R2) | \
116 ___PPC_RA(__REG_R1) | R2_STACK_OFFSET)
117
118/* usually preceded by a mflr r0 */
119#define PPC_INST_STD_LR (PPC_INST_STD | ___PPC_RS(__REG_R0) | \
120 ___PPC_RA(__REG_R1) | PPC_LR_STKOFF)
121#endif /* CONFIG_PPC64 */
122
102#endif /* _ASM_POWERPC_CODE_PATCHING_H */ 123#endif /* _ASM_POWERPC_CODE_PATCHING_H */
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index b118072670fb..df4fb5faba43 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -43,6 +43,11 @@ extern int machine_check_e500(struct pt_regs *regs);
43extern int machine_check_e200(struct pt_regs *regs); 43extern int machine_check_e200(struct pt_regs *regs);
44extern int machine_check_47x(struct pt_regs *regs); 44extern int machine_check_47x(struct pt_regs *regs);
45 45
46extern void cpu_down_flush_e500v2(void);
47extern void cpu_down_flush_e500mc(void);
48extern void cpu_down_flush_e5500(void);
49extern void cpu_down_flush_e6500(void);
50
46/* NOTE WELL: Update identify_cpu() if fields are added or removed! */ 51/* NOTE WELL: Update identify_cpu() if fields are added or removed! */
47struct cpu_spec { 52struct cpu_spec {
48 /* CPU is matched via (PVR & pvr_mask) == pvr_value */ 53 /* CPU is matched via (PVR & pvr_mask) == pvr_value */
@@ -59,6 +64,9 @@ struct cpu_spec {
59 unsigned int icache_bsize; 64 unsigned int icache_bsize;
60 unsigned int dcache_bsize; 65 unsigned int dcache_bsize;
61 66
67 /* flush caches inside the current cpu */
68 void (*cpu_down_flush)(void);
69
62 /* number of performance monitor counters */ 70 /* number of performance monitor counters */
63 unsigned int num_pmcs; 71 unsigned int num_pmcs;
64 enum powerpc_pmc_type pmc_type; 72 enum powerpc_pmc_type pmc_type;
@@ -171,7 +179,7 @@ enum {
171#define CPU_FTR_ARCH_201 LONG_ASM_CONST(0x0000000200000000) 179#define CPU_FTR_ARCH_201 LONG_ASM_CONST(0x0000000200000000)
172#define CPU_FTR_ARCH_206 LONG_ASM_CONST(0x0000000400000000) 180#define CPU_FTR_ARCH_206 LONG_ASM_CONST(0x0000000400000000)
173#define CPU_FTR_ARCH_207S LONG_ASM_CONST(0x0000000800000000) 181#define CPU_FTR_ARCH_207S LONG_ASM_CONST(0x0000000800000000)
174/* Free LONG_ASM_CONST(0x0000001000000000) */ 182#define CPU_FTR_ARCH_300 LONG_ASM_CONST(0x0000001000000000)
175#define CPU_FTR_MMCRA LONG_ASM_CONST(0x0000002000000000) 183#define CPU_FTR_MMCRA LONG_ASM_CONST(0x0000002000000000)
176#define CPU_FTR_CTRL LONG_ASM_CONST(0x0000004000000000) 184#define CPU_FTR_CTRL LONG_ASM_CONST(0x0000004000000000)
177#define CPU_FTR_SMT LONG_ASM_CONST(0x0000008000000000) 185#define CPU_FTR_SMT LONG_ASM_CONST(0x0000008000000000)
@@ -196,6 +204,7 @@ enum {
196#define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000) 204#define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000)
197#define CPU_FTR_DABRX LONG_ASM_CONST(0x0800000000000000) 205#define CPU_FTR_DABRX LONG_ASM_CONST(0x0800000000000000)
198#define CPU_FTR_PMAO_BUG LONG_ASM_CONST(0x1000000000000000) 206#define CPU_FTR_PMAO_BUG LONG_ASM_CONST(0x1000000000000000)
207#define CPU_FTR_SUBCORE LONG_ASM_CONST(0x2000000000000000)
199 208
200#ifndef __ASSEMBLY__ 209#ifndef __ASSEMBLY__
201 210
@@ -443,9 +452,19 @@ enum {
443 CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ 452 CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
444 CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ 453 CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
445 CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \ 454 CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
446 CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP) 455 CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_SUBCORE)
447#define CPU_FTRS_POWER8E (CPU_FTRS_POWER8 | CPU_FTR_PMAO_BUG) 456#define CPU_FTRS_POWER8E (CPU_FTRS_POWER8 | CPU_FTR_PMAO_BUG)
448#define CPU_FTRS_POWER8_DD1 (CPU_FTRS_POWER8 & ~CPU_FTR_DBELL) 457#define CPU_FTRS_POWER8_DD1 (CPU_FTRS_POWER8 & ~CPU_FTR_DBELL)
458#define CPU_FTRS_POWER9 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
459 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
460 CPU_FTR_MMCRA | CPU_FTR_SMT | \
461 CPU_FTR_COHERENT_ICACHE | \
462 CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
463 CPU_FTR_DSCR | CPU_FTR_SAO | \
464 CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
465 CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
466 CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
467 CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_ARCH_300)
449#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ 468#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
450 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 469 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
451 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ 470 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -464,7 +483,7 @@ enum {
464 (CPU_FTRS_POWER4 | CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \ 483 (CPU_FTRS_POWER4 | CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \
465 CPU_FTRS_POWER6 | CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | \ 484 CPU_FTRS_POWER6 | CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | \
466 CPU_FTRS_POWER8 | CPU_FTRS_POWER8_DD1 | CPU_FTRS_CELL | \ 485 CPU_FTRS_POWER8 | CPU_FTRS_POWER8_DD1 | CPU_FTRS_CELL | \
467 CPU_FTRS_PA6T | CPU_FTR_VSX) 486 CPU_FTRS_PA6T | CPU_FTR_VSX | CPU_FTRS_POWER9)
468#endif 487#endif
469#else 488#else
470enum { 489enum {
@@ -515,7 +534,8 @@ enum {
515 (CPU_FTRS_POWER4 & CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & \ 534 (CPU_FTRS_POWER4 & CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & \
516 CPU_FTRS_POWER6 & CPU_FTRS_POWER7 & CPU_FTRS_CELL & \ 535 CPU_FTRS_POWER6 & CPU_FTRS_POWER7 & CPU_FTRS_CELL & \
517 CPU_FTRS_PA6T & CPU_FTRS_POWER8 & CPU_FTRS_POWER8E & \ 536 CPU_FTRS_PA6T & CPU_FTRS_POWER8 & CPU_FTRS_POWER8E & \
518 CPU_FTRS_POWER8_DD1 & ~CPU_FTR_HVMODE & CPU_FTRS_POSSIBLE) 537 CPU_FTRS_POWER8_DD1 & ~CPU_FTR_HVMODE & CPU_FTRS_POSSIBLE & \
538 CPU_FTRS_POWER9)
519#endif 539#endif
520#else 540#else
521enum { 541enum {
diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h
index ba42e46ea58e..666bef4ebfae 100644
--- a/arch/powerpc/include/asm/cputhreads.h
+++ b/arch/powerpc/include/asm/cputhreads.h
@@ -1,6 +1,7 @@
1#ifndef _ASM_POWERPC_CPUTHREADS_H 1#ifndef _ASM_POWERPC_CPUTHREADS_H
2#define _ASM_POWERPC_CPUTHREADS_H 2#define _ASM_POWERPC_CPUTHREADS_H
3 3
4#ifndef __ASSEMBLY__
4#include <linux/cpumask.h> 5#include <linux/cpumask.h>
5 6
6/* 7/*
@@ -94,7 +95,21 @@ static inline int cpu_last_thread_sibling(int cpu)
94 return cpu | (threads_per_core - 1); 95 return cpu | (threads_per_core - 1);
95} 96}
96 97
98static inline u32 get_tensr(void)
99{
100#ifdef CONFIG_BOOKE
101 if (cpu_has_feature(CPU_FTR_SMT))
102 return mfspr(SPRN_TENSR);
103#endif
104 return 1;
105}
106
107void book3e_start_thread(int thread, unsigned long addr);
108void book3e_stop_thread(int thread);
109
110#endif /* __ASSEMBLY__ */
97 111
112#define INVALID_THREAD_HWID 0x0fff
98 113
99#endif /* _ASM_POWERPC_CPUTHREADS_H */ 114#endif /* _ASM_POWERPC_CPUTHREADS_H */
100 115
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 867c39b45df6..fb9f376ae27b 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -72,6 +72,7 @@ struct pci_dn;
72#define EEH_PE_PHB (1 << 1) /* PHB PE */ 72#define EEH_PE_PHB (1 << 1) /* PHB PE */
73#define EEH_PE_DEVICE (1 << 2) /* Device PE */ 73#define EEH_PE_DEVICE (1 << 2) /* Device PE */
74#define EEH_PE_BUS (1 << 3) /* Bus PE */ 74#define EEH_PE_BUS (1 << 3) /* Bus PE */
75#define EEH_PE_VF (1 << 4) /* VF PE */
75 76
76#define EEH_PE_ISOLATED (1 << 0) /* Isolated PE */ 77#define EEH_PE_ISOLATED (1 << 0) /* Isolated PE */
77#define EEH_PE_RECOVERING (1 << 1) /* Recovering PE */ 78#define EEH_PE_RECOVERING (1 << 1) /* Recovering PE */
@@ -136,11 +137,15 @@ struct eeh_dev {
136 int pcix_cap; /* Saved PCIx capability */ 137 int pcix_cap; /* Saved PCIx capability */
137 int pcie_cap; /* Saved PCIe capability */ 138 int pcie_cap; /* Saved PCIe capability */
138 int aer_cap; /* Saved AER capability */ 139 int aer_cap; /* Saved AER capability */
140 int af_cap; /* Saved AF capability */
139 struct eeh_pe *pe; /* Associated PE */ 141 struct eeh_pe *pe; /* Associated PE */
140 struct list_head list; /* Form link list in the PE */ 142 struct list_head list; /* Form link list in the PE */
143 struct list_head rmv_list; /* Record the removed edevs */
141 struct pci_controller *phb; /* Associated PHB */ 144 struct pci_controller *phb; /* Associated PHB */
142 struct pci_dn *pdn; /* Associated PCI device node */ 145 struct pci_dn *pdn; /* Associated PCI device node */
143 struct pci_dev *pdev; /* Associated PCI device */ 146 struct pci_dev *pdev; /* Associated PCI device */
147 bool in_error; /* Error flag for edev */
148 struct pci_dev *physfn; /* Associated SRIOV PF */
144 struct pci_bus *bus; /* PCI bus for partial hotplug */ 149 struct pci_bus *bus; /* PCI bus for partial hotplug */
145}; 150};
146 151
diff --git a/arch/powerpc/include/asm/fsl_pm.h b/arch/powerpc/include/asm/fsl_pm.h
new file mode 100644
index 000000000000..47df55e36d4f
--- /dev/null
+++ b/arch/powerpc/include/asm/fsl_pm.h
@@ -0,0 +1,51 @@
1/*
2 * Support Power Management
3 *
4 * Copyright 2014-2015 Freescale Semiconductor Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11#ifndef __PPC_FSL_PM_H
12#define __PPC_FSL_PM_H
13
14#define E500_PM_PH10 1
15#define E500_PM_PH15 2
16#define E500_PM_PH20 3
17#define E500_PM_PH30 4
18#define E500_PM_DOZE E500_PM_PH10
19#define E500_PM_NAP E500_PM_PH15
20
21#define PLAT_PM_SLEEP 20
22#define PLAT_PM_LPM20 30
23
24#define FSL_PM_SLEEP (1 << 0)
25#define FSL_PM_DEEP_SLEEP (1 << 1)
26
27struct fsl_pm_ops {
28 /* mask pending interrupts to the RCPM from MPIC */
29 void (*irq_mask)(int cpu);
30
31 /* unmask pending interrupts to the RCPM from MPIC */
32 void (*irq_unmask)(int cpu);
33 void (*cpu_enter_state)(int cpu, int state);
34 void (*cpu_exit_state)(int cpu, int state);
35 void (*cpu_up_prepare)(int cpu);
36 void (*cpu_die)(int cpu);
37 int (*plat_enter_sleep)(void);
38 void (*freeze_time_base)(bool freeze);
39
40 /* keep the power of IP blocks during sleep/deep sleep */
41 void (*set_ip_power)(bool enable, u32 mask);
42
43 /* get platform supported power management modes */
44 unsigned int (*get_pm_modes)(void);
45};
46
47extern const struct fsl_pm_ops *qoriq_pm_ops;
48
49int __init fsl_rcpm_init(void);
50
51#endif /* __PPC_FSL_PM_H */
diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h
index ef89b1465573..50ca7585abe2 100644
--- a/arch/powerpc/include/asm/ftrace.h
+++ b/arch/powerpc/include/asm/ftrace.h
@@ -46,6 +46,8 @@
46extern void _mcount(void); 46extern void _mcount(void);
47 47
48#ifdef CONFIG_DYNAMIC_FTRACE 48#ifdef CONFIG_DYNAMIC_FTRACE
49# define FTRACE_ADDR ((unsigned long)ftrace_caller)
50# define FTRACE_REGS_ADDR FTRACE_ADDR
49static inline unsigned long ftrace_call_adjust(unsigned long addr) 51static inline unsigned long ftrace_call_adjust(unsigned long addr)
50{ 52{
51 /* reloction of mcount call site is the same as the address */ 53 /* reloction of mcount call site is the same as the address */
@@ -58,6 +60,9 @@ struct dyn_arch_ftrace {
58#endif /* CONFIG_DYNAMIC_FTRACE */ 60#endif /* CONFIG_DYNAMIC_FTRACE */
59#endif /* __ASSEMBLY__ */ 61#endif /* __ASSEMBLY__ */
60 62
63#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
64#define ARCH_SUPPORTS_FTRACE_OPS 1
65#endif
61#endif 66#endif
62 67
63#if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__) 68#if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__)
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index 7eac89b9f02e..42814f0567cc 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -19,7 +19,7 @@ static inline pte_t *hugepd_page(hugepd_t hpd)
19 * We have only four bits to encode, MMU page size 19 * We have only four bits to encode, MMU page size
20 */ 20 */
21 BUILD_BUG_ON((MMU_PAGE_COUNT - 1) > 0xf); 21 BUILD_BUG_ON((MMU_PAGE_COUNT - 1) > 0xf);
22 return (pte_t *)(hpd.pd & ~HUGEPD_SHIFT_MASK); 22 return __va(hpd.pd & HUGEPD_ADDR_MASK);
23} 23}
24 24
25static inline unsigned int hugepd_mmu_psize(hugepd_t hpd) 25static inline unsigned int hugepd_mmu_psize(hugepd_t hpd)
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index e3b54dd4f730..0bc9c284aa10 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -94,6 +94,7 @@
94#define H_SG_LIST -72 94#define H_SG_LIST -72
95#define H_OP_MODE -73 95#define H_OP_MODE -73
96#define H_COP_HW -74 96#define H_COP_HW -74
97#define H_STATE -75
97#define H_UNSUPPORTED_FLAG_START -256 98#define H_UNSUPPORTED_FLAG_START -256
98#define H_UNSUPPORTED_FLAG_END -511 99#define H_UNSUPPORTED_FLAG_END -511
99#define H_MULTI_THREADS_ACTIVE -9005 100#define H_MULTI_THREADS_ACTIVE -9005
diff --git a/arch/powerpc/include/asm/hydra.h b/arch/powerpc/include/asm/hydra.h
index 1cb39c96d155..b3b0f2d020f0 100644
--- a/arch/powerpc/include/asm/hydra.h
+++ b/arch/powerpc/include/asm/hydra.h
@@ -89,7 +89,7 @@ extern volatile struct Hydra __iomem *Hydra;
89#define HYDRA_INT_EXT2 13 /* PCI IRQX */ 89#define HYDRA_INT_EXT2 13 /* PCI IRQX */
90#define HYDRA_INT_EXT3 14 /* PCI IRQY */ 90#define HYDRA_INT_EXT3 14 /* PCI IRQY */
91#define HYDRA_INT_EXT4 15 /* PCI IRQZ */ 91#define HYDRA_INT_EXT4 15 /* PCI IRQZ */
92#define HYDRA_INT_EXT5 16 /* IDE Primay/Secondary */ 92#define HYDRA_INT_EXT5 16 /* IDE Primary/Secondary */
93#define HYDRA_INT_EXT6 17 /* IDE Secondary */ 93#define HYDRA_INT_EXT6 17 /* IDE Secondary */
94#define HYDRA_INT_EXT7 18 /* Power Off Request */ 94#define HYDRA_INT_EXT7 18 /* Power Off Request */
95#define HYDRA_INT_SPARE 19 95#define HYDRA_INT_SPARE 19
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index 6c1297ec374c..2fd1690b79d2 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -300,7 +300,7 @@ extern void _memcpy_toio(volatile void __iomem *dest, const void *src,
300 * When CONFIG_PPC_INDIRECT_MMIO is set, the platform can provide hooks 300 * When CONFIG_PPC_INDIRECT_MMIO is set, the platform can provide hooks
301 * on all MMIOs. (Note that this is all 64 bits only for now) 301 * on all MMIOs. (Note that this is all 64 bits only for now)
302 * 302 *
303 * To help platforms who may need to differenciate MMIO addresses in 303 * To help platforms who may need to differentiate MMIO addresses in
304 * their hooks, a bitfield is reserved for use by the platform near the 304 * their hooks, a bitfield is reserved for use by the platform near the
305 * top of MMIO addresses (not PIO, those have to cope the hard way). 305 * top of MMIO addresses (not PIO, those have to cope the hard way).
306 * 306 *
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 3f191f573d4f..fd22442d30a9 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -54,7 +54,7 @@ struct machdep_calls {
54 int psize, int apsize, 54 int psize, int apsize,
55 int ssize); 55 int ssize);
56 long (*hpte_remove)(unsigned long hpte_group); 56 long (*hpte_remove)(unsigned long hpte_group);
57 void (*hpte_removebolted)(unsigned long ea, 57 int (*hpte_removebolted)(unsigned long ea,
58 int psize, int ssize); 58 int psize, int ssize);
59 void (*flush_hash_range)(unsigned long number, int local); 59 void (*flush_hash_range)(unsigned long number, int local);
60 void (*hugepage_invalidate)(unsigned long vsid, 60 void (*hugepage_invalidate)(unsigned long vsid,
@@ -174,11 +174,11 @@ struct machdep_calls {
174 platform, called once per cpu. */ 174 platform, called once per cpu. */
175 void (*enable_pmcs)(void); 175 void (*enable_pmcs)(void);
176 176
177 /* Set DABR for this platform, leave empty for default implemenation */ 177 /* Set DABR for this platform, leave empty for default implementation */
178 int (*set_dabr)(unsigned long dabr, 178 int (*set_dabr)(unsigned long dabr,
179 unsigned long dabrx); 179 unsigned long dabrx);
180 180
181 /* Set DAWR for this platform, leave empty for default implemenation */ 181 /* Set DAWR for this platform, leave empty for default implementation */
182 int (*set_dawr)(unsigned long dawr, 182 int (*set_dawr)(unsigned long dawr,
183 unsigned long dawrx); 183 unsigned long dawrx);
184 184
diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/mmu-8xx.h
index f05500a29a60..0a566f15f985 100644
--- a/arch/powerpc/include/asm/mmu-8xx.h
+++ b/arch/powerpc/include/asm/mmu-8xx.h
@@ -171,9 +171,9 @@ typedef struct {
171} mm_context_t; 171} mm_context_t;
172#endif /* !__ASSEMBLY__ */ 172#endif /* !__ASSEMBLY__ */
173 173
174#if (PAGE_SHIFT == 12) 174#if defined(CONFIG_PPC_4K_PAGES)
175#define mmu_virtual_psize MMU_PAGE_4K 175#define mmu_virtual_psize MMU_PAGE_4K
176#elif (PAGE_SHIFT == 14) 176#elif defined(CONFIG_PPC_16K_PAGES)
177#define mmu_virtual_psize MMU_PAGE_16K 177#define mmu_virtual_psize MMU_PAGE_16K
178#else 178#else
179#error "Unsupported PAGE_SIZE" 179#error "Unsupported PAGE_SIZE"
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index 3d5abfe6ba67..8ca1c983bf6c 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -97,6 +97,7 @@
97#define MMU_FTRS_POWER6 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE 97#define MMU_FTRS_POWER6 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
98#define MMU_FTRS_POWER7 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE 98#define MMU_FTRS_POWER7 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
99#define MMU_FTRS_POWER8 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE 99#define MMU_FTRS_POWER8 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
100#define MMU_FTRS_POWER9 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
100#define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ 101#define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
101 MMU_FTR_CI_LARGE_PAGE 102 MMU_FTR_CI_LARGE_PAGE
102#define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ 103#define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
@@ -182,10 +183,10 @@ static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
182 183
183#if defined(CONFIG_PPC_STD_MMU_64) 184#if defined(CONFIG_PPC_STD_MMU_64)
184/* 64-bit classic hash table MMU */ 185/* 64-bit classic hash table MMU */
185# include <asm/mmu-hash64.h> 186#include <asm/book3s/64/mmu-hash.h>
186#elif defined(CONFIG_PPC_STD_MMU_32) 187#elif defined(CONFIG_PPC_STD_MMU_32)
187/* 32-bit classic hash table MMU */ 188/* 32-bit classic hash table MMU */
188# include <asm/mmu-hash32.h> 189#include <asm/book3s/32/mmu-hash.h>
189#elif defined(CONFIG_40x) 190#elif defined(CONFIG_40x)
190/* 40x-style software loaded TLB */ 191/* 40x-style software loaded TLB */
191# include <asm/mmu-40x.h> 192# include <asm/mmu-40x.h>
diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h
index dcfcad139bcc..cd4ffd86765f 100644
--- a/arch/powerpc/include/asm/module.h
+++ b/arch/powerpc/include/asm/module.h
@@ -19,7 +19,7 @@
19 * Thanks to Paul M for explaining this. 19 * Thanks to Paul M for explaining this.
20 * 20 *
21 * PPC can only do rel jumps += 32MB, and often the kernel and other 21 * PPC can only do rel jumps += 32MB, and often the kernel and other
22 * modules are furthur away than this. So, we jump to a table of 22 * modules are further away than this. So, we jump to a table of
23 * trampolines attached to the module (the Procedure Linkage Table) 23 * trampolines attached to the module (the Procedure Linkage Table)
24 * whenever that happens. 24 * whenever that happens.
25 */ 25 */
@@ -78,10 +78,18 @@ struct mod_arch_specific {
78# endif /* MODULE */ 78# endif /* MODULE */
79#endif 79#endif
80 80
81bool is_module_trampoline(u32 *insns); 81int module_trampoline_target(struct module *mod, unsigned long trampoline,
82int module_trampoline_target(struct module *mod, u32 *trampoline,
83 unsigned long *target); 82 unsigned long *target);
84 83
84#ifdef CONFIG_DYNAMIC_FTRACE
85int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs);
86#else
87static inline int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs)
88{
89 return 0;
90}
91#endif
92
85struct exception_table_entry; 93struct exception_table_entry;
86void sort_ex_table(struct exception_table_entry *start, 94void sort_ex_table(struct exception_table_entry *start,
87 struct exception_table_entry *finish); 95 struct exception_table_entry *finish);
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index c82cbf52d19e..780847597514 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -86,7 +86,7 @@ extern int icache_44x_need_flush;
86 * We no longer map larger than phys RAM with the BATs so we don't have 86 * We no longer map larger than phys RAM with the BATs so we don't have
87 * to worry about the VMALLOC_OFFSET causing problems. We do have to worry 87 * to worry about the VMALLOC_OFFSET causing problems. We do have to worry
88 * about clashes between our early calls to ioremap() that start growing down 88 * about clashes between our early calls to ioremap() that start growing down
89 * from ioremap_base being run into the VM area allocations (growing upwards 89 * from IOREMAP_TOP being run into the VM area allocations (growing upwards
90 * from VMALLOC_START). For this reason we have ioremap_bot to check when 90 * from VMALLOC_START). For this reason we have ioremap_bot to check when
91 * we actually run into our mappings setup in the early boot with the VM 91 * we actually run into our mappings setup in the early boot with the VM
92 * system. This really does become a problem for machines with good amounts 92 * system. This really does become a problem for machines with good amounts
@@ -309,7 +309,8 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
309#define pte_index(address) \ 309#define pte_index(address) \
310 (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) 310 (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
311#define pte_offset_kernel(dir, addr) \ 311#define pte_offset_kernel(dir, addr) \
312 ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(addr)) 312 (pmd_bad(*(dir)) ? NULL : (pte_t *)pmd_page_vaddr(*(dir)) + \
313 pte_index(addr))
313#define pte_offset_map(dir, addr) \ 314#define pte_offset_map(dir, addr) \
314 ((pte_t *) kmap_atomic(pmd_page(*(dir))) + pte_index(addr)) 315 ((pte_t *) kmap_atomic(pmd_page(*(dir))) + pte_index(addr))
315#define pte_unmap(pte) kunmap_atomic(pte) 316#define pte_unmap(pte) kunmap_atomic(pte)
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h
index b9f734dd5b81..10debb93c4a4 100644
--- a/arch/powerpc/include/asm/nohash/64/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
@@ -108,6 +108,9 @@
108#ifndef __ASSEMBLY__ 108#ifndef __ASSEMBLY__
109/* pte_clear moved to later in this file */ 109/* pte_clear moved to later in this file */
110 110
111/* Pointers in the page table tree are virtual addresses */
112#define __pgtable_ptr_val(ptr) ((unsigned long)(ptr))
113
111#define PMD_BAD_BITS (PTE_TABLE_SIZE-1) 114#define PMD_BAD_BITS (PTE_TABLE_SIZE-1)
112#define PUD_BAD_BITS (PMD_TABLE_SIZE-1) 115#define PUD_BAD_BITS (PMD_TABLE_SIZE-1)
113 116
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 07a99e638449..9d86c6651716 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -248,6 +248,7 @@ extern int opal_elog_init(void);
248extern void opal_platform_dump_init(void); 248extern void opal_platform_dump_init(void);
249extern void opal_sys_param_init(void); 249extern void opal_sys_param_init(void);
250extern void opal_msglog_init(void); 250extern void opal_msglog_init(void);
251extern void opal_msglog_sysfs_init(void);
251extern int opal_async_comp_init(void); 252extern int opal_async_comp_init(void);
252extern int opal_sensor_init(void); 253extern int opal_sensor_init(void);
253extern int opal_hmi_handler_init(void); 254extern int opal_hmi_handler_init(void);
@@ -273,6 +274,8 @@ void opal_free_sg_list(struct opal_sg_list *sg);
273 274
274extern int opal_error_code(int rc); 275extern int opal_error_code(int rc);
275 276
277ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count);
278
276#endif /* __ASSEMBLY__ */ 279#endif /* __ASSEMBLY__ */
277 280
278#endif /* _ASM_POWERPC_OPAL_H */ 281#endif /* _ASM_POWERPC_OPAL_H */
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index e34124f6fbf2..ab3d8977bacd 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -271,6 +271,13 @@ extern long long virt_phys_offset;
271#else 271#else
272#define PD_HUGE 0x80000000 272#define PD_HUGE 0x80000000
273#endif 273#endif
274
275#else /* CONFIG_PPC_BOOK3S_64 */
276/*
277 * Book3S 64 stores real addresses in the hugepd entries to
278 * avoid overlaps with _PAGE_PRESENT and _PAGE_PTE.
279 */
280#define HUGEPD_ADDR_MASK (0x0ffffffffffffffful & ~HUGEPD_SHIFT_MASK)
274#endif /* CONFIG_PPC_BOOK3S_64 */ 281#endif /* CONFIG_PPC_BOOK3S_64 */
275 282
276/* 283/*
@@ -281,109 +288,7 @@ extern long long virt_phys_offset;
281 288
282#ifndef __ASSEMBLY__ 289#ifndef __ASSEMBLY__
283 290
284#ifdef CONFIG_STRICT_MM_TYPECHECKS 291#include <asm/pgtable-types.h>
285/* These are used to make use of C type-checking. */
286
287/* PTE level */
288typedef struct { pte_basic_t pte; } pte_t;
289#define __pte(x) ((pte_t) { (x) })
290static inline pte_basic_t pte_val(pte_t x)
291{
292 return x.pte;
293}
294
295/* 64k pages additionally define a bigger "real PTE" type that gathers
296 * the "second half" part of the PTE for pseudo 64k pages
297 */
298#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64)
299typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
300#else
301typedef struct { pte_t pte; } real_pte_t;
302#endif
303
304/* PMD level */
305#ifdef CONFIG_PPC64
306typedef struct { unsigned long pmd; } pmd_t;
307#define __pmd(x) ((pmd_t) { (x) })
308static inline unsigned long pmd_val(pmd_t x)
309{
310 return x.pmd;
311}
312
313/* PUD level exusts only on 4k pages */
314#ifndef CONFIG_PPC_64K_PAGES
315typedef struct { unsigned long pud; } pud_t;
316#define __pud(x) ((pud_t) { (x) })
317static inline unsigned long pud_val(pud_t x)
318{
319 return x.pud;
320}
321#endif /* !CONFIG_PPC_64K_PAGES */
322#endif /* CONFIG_PPC64 */
323
324/* PGD level */
325typedef struct { unsigned long pgd; } pgd_t;
326#define __pgd(x) ((pgd_t) { (x) })
327static inline unsigned long pgd_val(pgd_t x)
328{
329 return x.pgd;
330}
331
332/* Page protection bits */
333typedef struct { unsigned long pgprot; } pgprot_t;
334#define pgprot_val(x) ((x).pgprot)
335#define __pgprot(x) ((pgprot_t) { (x) })
336
337#else
338
339/*
340 * .. while these make it easier on the compiler
341 */
342
343typedef pte_basic_t pte_t;
344#define __pte(x) (x)
345static inline pte_basic_t pte_val(pte_t pte)
346{
347 return pte;
348}
349
350#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64)
351typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
352#else
353typedef pte_t real_pte_t;
354#endif
355
356
357#ifdef CONFIG_PPC64
358typedef unsigned long pmd_t;
359#define __pmd(x) (x)
360static inline unsigned long pmd_val(pmd_t pmd)
361{
362 return pmd;
363}
364
365#ifndef CONFIG_PPC_64K_PAGES
366typedef unsigned long pud_t;
367#define __pud(x) (x)
368static inline unsigned long pud_val(pud_t pud)
369{
370 return pud;
371}
372#endif /* !CONFIG_PPC_64K_PAGES */
373#endif /* CONFIG_PPC64 */
374
375typedef unsigned long pgd_t;
376#define __pgd(x) (x)
377static inline unsigned long pgd_val(pgd_t pgd)
378{
379 return pgd;
380}
381
382typedef unsigned long pgprot_t;
383#define pgprot_val(x) (x)
384#define __pgprot(x) (x)
385
386#endif
387 292
388typedef struct { signed long pd; } hugepd_t; 293typedef struct { signed long pd; } hugepd_t;
389 294
diff --git a/arch/powerpc/include/asm/page_32.h b/arch/powerpc/include/asm/page_32.h
index 68d73b2a7bfc..6a8e1797f223 100644
--- a/arch/powerpc/include/asm/page_32.h
+++ b/arch/powerpc/include/asm/page_32.h
@@ -1,6 +1,8 @@
1#ifndef _ASM_POWERPC_PAGE_32_H 1#ifndef _ASM_POWERPC_PAGE_32_H
2#define _ASM_POWERPC_PAGE_32_H 2#define _ASM_POWERPC_PAGE_32_H
3 3
4#include <asm/cache.h>
5
4#if defined(CONFIG_PHYSICAL_ALIGN) && (CONFIG_PHYSICAL_START != 0) 6#if defined(CONFIG_PHYSICAL_ALIGN) && (CONFIG_PHYSICAL_START != 0)
5#if (CONFIG_PHYSICAL_START % CONFIG_PHYSICAL_ALIGN) != 0 7#if (CONFIG_PHYSICAL_START % CONFIG_PHYSICAL_ALIGN) != 0
6#error "CONFIG_PHYSICAL_START must be a multiple of CONFIG_PHYSICAL_ALIGN" 8#error "CONFIG_PHYSICAL_START must be a multiple of CONFIG_PHYSICAL_ALIGN"
@@ -36,9 +38,18 @@ typedef unsigned long long pte_basic_t;
36typedef unsigned long pte_basic_t; 38typedef unsigned long pte_basic_t;
37#endif 39#endif
38 40
39struct page; 41/*
40extern void clear_pages(void *page, int order); 42 * Clear page using the dcbz instruction, which doesn't cause any
41static inline void clear_page(void *page) { clear_pages(page, 0); } 43 * memory traffic (except to write out any cache lines which get
44 * displaced). This only works on cacheable memory.
45 */
46static inline void clear_page(void *addr)
47{
48 unsigned int i;
49
50 for (i = 0; i < PAGE_SIZE / L1_CACHE_BYTES; i++, addr += L1_CACHE_BYTES)
51 dcbz(addr);
52}
42extern void copy_page(void *to, void *from); 53extern void copy_page(void *to, void *from);
43 54
44#include <asm-generic/getorder.h> 55#include <asm-generic/getorder.h>
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 78968c1ff931..f5056e3394b4 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -211,15 +211,16 @@ struct pci_dn {
211#define IODA_INVALID_PE (-1) 211#define IODA_INVALID_PE (-1)
212#ifdef CONFIG_PPC_POWERNV 212#ifdef CONFIG_PPC_POWERNV
213 int pe_number; 213 int pe_number;
214 int vf_index; /* VF index in the PF */
214#ifdef CONFIG_PCI_IOV 215#ifdef CONFIG_PCI_IOV
215 u16 vfs_expanded; /* number of VFs IOV BAR expanded */ 216 u16 vfs_expanded; /* number of VFs IOV BAR expanded */
216 u16 num_vfs; /* number of VFs enabled*/ 217 u16 num_vfs; /* number of VFs enabled*/
217 int offset; /* PE# for the first VF PE */ 218 int *pe_num_map; /* PE# for the first VF PE or array */
218#define M64_PER_IOV 4 219 bool m64_single_mode; /* Use M64 BAR in Single Mode */
219 int m64_per_iov;
220#define IODA_INVALID_M64 (-1) 220#define IODA_INVALID_M64 (-1)
221 int m64_wins[PCI_SRIOV_NUM_BARS][M64_PER_IOV]; 221 int (*m64_map)[PCI_SRIOV_NUM_BARS];
222#endif /* CONFIG_PCI_IOV */ 222#endif /* CONFIG_PCI_IOV */
223 int mps; /* Maximum Payload Size */
223#endif 224#endif
224 struct list_head child_list; 225 struct list_head child_list;
225 struct list_head list; 226 struct list_head list;
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h
index 814622146d5a..e157489ee7a1 100644
--- a/arch/powerpc/include/asm/perf_event_server.h
+++ b/arch/powerpc/include/asm/perf_event_server.h
@@ -136,16 +136,24 @@ extern ssize_t power_events_sysfs_show(struct device *dev,
136 * event 'cpu-cycles' can have two entries in sysfs: 'cpu-cycles' and 136 * event 'cpu-cycles' can have two entries in sysfs: 'cpu-cycles' and
137 * 'PM_CYC' where the latter is the name by which the event is known in 137 * 'PM_CYC' where the latter is the name by which the event is known in
138 * POWER CPU specification. 138 * POWER CPU specification.
139 *
140 * Similarly, some hardware and cache events use the same event code. Eg.
141 * on POWER8, both "cache-references" and "L1-dcache-loads" events refer
142 * to the same event, PM_LD_REF_L1. The suffix, allows us to have two
143 * sysfs objects for the same event and thus two entries/aliases in sysfs.
139 */ 144 */
140#define EVENT_VAR(_id, _suffix) event_attr_##_id##_suffix 145#define EVENT_VAR(_id, _suffix) event_attr_##_id##_suffix
141#define EVENT_PTR(_id, _suffix) &EVENT_VAR(_id, _suffix).attr.attr 146#define EVENT_PTR(_id, _suffix) &EVENT_VAR(_id, _suffix).attr.attr
142 147
143#define EVENT_ATTR(_name, _id, _suffix) \ 148#define EVENT_ATTR(_name, _id, _suffix) \
144 PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), PME_##_id, \ 149 PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), _id, \
145 power_events_sysfs_show) 150 power_events_sysfs_show)
146 151
147#define GENERIC_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _g) 152#define GENERIC_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _g)
148#define GENERIC_EVENT_PTR(_id) EVENT_PTR(_id, _g) 153#define GENERIC_EVENT_PTR(_id) EVENT_PTR(_id, _g)
149 154
155#define CACHE_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _c)
156#define CACHE_EVENT_PTR(_id) EVENT_PTR(_id, _c)
157
150#define POWER_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _p) 158#define POWER_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _p)
151#define POWER_EVENT_PTR(_id) EVENT_PTR(_id, _p) 159#define POWER_EVENT_PTR(_id) EVENT_PTR(_id, _p)
diff --git a/arch/powerpc/include/asm/pgalloc-64.h b/arch/powerpc/include/asm/pgalloc-64.h
index 69ef28a81733..8d5fc3ac43da 100644
--- a/arch/powerpc/include/asm/pgalloc-64.h
+++ b/arch/powerpc/include/asm/pgalloc-64.h
@@ -53,7 +53,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
53 53
54#ifndef CONFIG_PPC_64K_PAGES 54#ifndef CONFIG_PPC_64K_PAGES
55 55
56#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, (unsigned long)PUD) 56#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, __pgtable_ptr_val(PUD))
57 57
58static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) 58static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
59{ 59{
@@ -68,19 +68,19 @@ static inline void pud_free(struct mm_struct *mm, pud_t *pud)
68 68
69static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) 69static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
70{ 70{
71 pud_set(pud, (unsigned long)pmd); 71 pud_set(pud, __pgtable_ptr_val(pmd));
72} 72}
73 73
74static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, 74static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
75 pte_t *pte) 75 pte_t *pte)
76{ 76{
77 pmd_set(pmd, (unsigned long)pte); 77 pmd_set(pmd, __pgtable_ptr_val(pte));
78} 78}
79 79
80static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, 80static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
81 pgtable_t pte_page) 81 pgtable_t pte_page)
82{ 82{
83 pmd_set(pmd, (unsigned long)page_address(pte_page)); 83 pmd_set(pmd, __pgtable_ptr_val(page_address(pte_page)));
84} 84}
85 85
86#define pmd_pgtable(pmd) pmd_page(pmd) 86#define pmd_pgtable(pmd) pmd_page(pmd)
@@ -171,23 +171,45 @@ extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift);
171extern void __tlb_remove_table(void *_table); 171extern void __tlb_remove_table(void *_table);
172#endif 172#endif
173 173
174#define pud_populate(mm, pud, pmd) pud_set(pud, (unsigned long)pmd) 174#ifndef __PAGETABLE_PUD_FOLDED
175/* book3s 64 is 4 level page table */
176static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
177{
178 pgd_set(pgd, __pgtable_ptr_val(pud));
179}
180
181static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
182{
183 return kmem_cache_alloc(PGT_CACHE(PUD_INDEX_SIZE),
184 GFP_KERNEL|__GFP_REPEAT);
185}
186
187static inline void pud_free(struct mm_struct *mm, pud_t *pud)
188{
189 kmem_cache_free(PGT_CACHE(PUD_INDEX_SIZE), pud);
190}
191#endif
192
193static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
194{
195 pud_set(pud, __pgtable_ptr_val(pmd));
196}
175 197
176static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, 198static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
177 pte_t *pte) 199 pte_t *pte)
178{ 200{
179 pmd_set(pmd, (unsigned long)pte); 201 pmd_set(pmd, __pgtable_ptr_val(pte));
180} 202}
181 203
182static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, 204static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
183 pgtable_t pte_page) 205 pgtable_t pte_page)
184{ 206{
185 pmd_set(pmd, (unsigned long)pte_page); 207 pmd_set(pmd, __pgtable_ptr_val(pte_page));
186} 208}
187 209
188static inline pgtable_t pmd_pgtable(pmd_t pmd) 210static inline pgtable_t pmd_pgtable(pmd_t pmd)
189{ 211{
190 return (pgtable_t)(pmd_val(pmd) & ~PMD_MASKED_BITS); 212 return (pgtable_t)pmd_page_vaddr(pmd);
191} 213}
192 214
193static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, 215static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
@@ -233,11 +255,11 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
233 255
234#define __pmd_free_tlb(tlb, pmd, addr) \ 256#define __pmd_free_tlb(tlb, pmd, addr) \
235 pgtable_free_tlb(tlb, pmd, PMD_CACHE_INDEX) 257 pgtable_free_tlb(tlb, pmd, PMD_CACHE_INDEX)
236#ifndef CONFIG_PPC_64K_PAGES 258#ifndef __PAGETABLE_PUD_FOLDED
237#define __pud_free_tlb(tlb, pud, addr) \ 259#define __pud_free_tlb(tlb, pud, addr) \
238 pgtable_free_tlb(tlb, pud, PUD_INDEX_SIZE) 260 pgtable_free_tlb(tlb, pud, PUD_INDEX_SIZE)
239 261
240#endif /* CONFIG_PPC_64K_PAGES */ 262#endif /* __PAGETABLE_PUD_FOLDED */
241 263
242#define check_pgt_cache() do { } while (0) 264#define check_pgt_cache() do { } while (0)
243 265
diff --git a/arch/powerpc/include/asm/pgtable-types.h b/arch/powerpc/include/asm/pgtable-types.h
new file mode 100644
index 000000000000..43140f8b0592
--- /dev/null
+++ b/arch/powerpc/include/asm/pgtable-types.h
@@ -0,0 +1,103 @@
1#ifndef _ASM_POWERPC_PGTABLE_TYPES_H
2#define _ASM_POWERPC_PGTABLE_TYPES_H
3
4#ifdef CONFIG_STRICT_MM_TYPECHECKS
5/* These are used to make use of C type-checking. */
6
7/* PTE level */
8typedef struct { pte_basic_t pte; } pte_t;
9#define __pte(x) ((pte_t) { (x) })
10static inline pte_basic_t pte_val(pte_t x)
11{
12 return x.pte;
13}
14
15/* PMD level */
16#ifdef CONFIG_PPC64
17typedef struct { unsigned long pmd; } pmd_t;
18#define __pmd(x) ((pmd_t) { (x) })
19static inline unsigned long pmd_val(pmd_t x)
20{
21 return x.pmd;
22}
23
24/*
25 * 64 bit hash always use 4 level table. Everybody else use 4 level
26 * only for 4K page size.
27 */
28#if defined(CONFIG_PPC_BOOK3S_64) || !defined(CONFIG_PPC_64K_PAGES)
29typedef struct { unsigned long pud; } pud_t;
30#define __pud(x) ((pud_t) { (x) })
31static inline unsigned long pud_val(pud_t x)
32{
33 return x.pud;
34}
35#endif /* CONFIG_PPC_BOOK3S_64 || !CONFIG_PPC_64K_PAGES */
36#endif /* CONFIG_PPC64 */
37
38/* PGD level */
39typedef struct { unsigned long pgd; } pgd_t;
40#define __pgd(x) ((pgd_t) { (x) })
41static inline unsigned long pgd_val(pgd_t x)
42{
43 return x.pgd;
44}
45
46/* Page protection bits */
47typedef struct { unsigned long pgprot; } pgprot_t;
48#define pgprot_val(x) ((x).pgprot)
49#define __pgprot(x) ((pgprot_t) { (x) })
50
51#else
52
53/*
54 * .. while these make it easier on the compiler
55 */
56
57typedef pte_basic_t pte_t;
58#define __pte(x) (x)
59static inline pte_basic_t pte_val(pte_t pte)
60{
61 return pte;
62}
63
64#ifdef CONFIG_PPC64
65typedef unsigned long pmd_t;
66#define __pmd(x) (x)
67static inline unsigned long pmd_val(pmd_t pmd)
68{
69 return pmd;
70}
71
72#if defined(CONFIG_PPC_BOOK3S_64) || !defined(CONFIG_PPC_64K_PAGES)
73typedef unsigned long pud_t;
74#define __pud(x) (x)
75static inline unsigned long pud_val(pud_t pud)
76{
77 return pud;
78}
79#endif /* CONFIG_PPC_BOOK3S_64 || !CONFIG_PPC_64K_PAGES */
80#endif /* CONFIG_PPC64 */
81
82typedef unsigned long pgd_t;
83#define __pgd(x) (x)
84static inline unsigned long pgd_val(pgd_t pgd)
85{
86 return pgd;
87}
88
89typedef unsigned long pgprot_t;
90#define pgprot_val(x) (x)
91#define __pgprot(x) (x)
92
93#endif /* CONFIG_STRICT_MM_TYPECHECKS */
94/*
95 * With hash config 64k pages additionally define a bigger "real PTE" type that
96 * gathers the "second half" part of the PTE for pseudo 64k pages
97 */
98#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64)
99typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
100#else
101typedef struct { pte_t pte; } real_pte_t;
102#endif
103#endif /* _ASM_POWERPC_PGTABLE_TYPES_H */
diff --git a/arch/powerpc/include/asm/pmac_feature.h b/arch/powerpc/include/asm/pmac_feature.h
index 10902c9375d0..925697968946 100644
--- a/arch/powerpc/include/asm/pmac_feature.h
+++ b/arch/powerpc/include/asm/pmac_feature.h
@@ -46,7 +46,7 @@
46 46
47/* PowerSurge are the first generation of PCI Pmacs. This include 47/* PowerSurge are the first generation of PCI Pmacs. This include
48 * all of the Grand-Central based machines. We currently don't 48 * all of the Grand-Central based machines. We currently don't
49 * differenciate most of them. 49 * differentiate most of them.
50 */ 50 */
51#define PMAC_TYPE_PSURGE 0x10 /* PowerSurge */ 51#define PMAC_TYPE_PSURGE 0x10 /* PowerSurge */
52#define PMAC_TYPE_ANS 0x11 /* Apple Network Server */ 52#define PMAC_TYPE_ANS 0x11 /* Apple Network Server */
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index ac2330820b9a..8ab8a1a9610a 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -236,7 +236,9 @@ struct thread_struct {
236#endif 236#endif
237 struct arch_hw_breakpoint hw_brk; /* info on the hardware breakpoint */ 237 struct arch_hw_breakpoint hw_brk; /* info on the hardware breakpoint */
238 unsigned long trap_nr; /* last trap # on this thread */ 238 unsigned long trap_nr; /* last trap # on this thread */
239 u8 load_fp;
239#ifdef CONFIG_ALTIVEC 240#ifdef CONFIG_ALTIVEC
241 u8 load_vec;
240 struct thread_vr_state vr_state; 242 struct thread_vr_state vr_state;
241 struct thread_vr_state *vr_save_area; 243 struct thread_vr_state *vr_save_area;
242 unsigned long vrsave; 244 unsigned long vrsave;
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index c4cb2ffc624e..f5f4c66bbbc9 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -75,6 +75,14 @@
75#define MSR_HV 0 75#define MSR_HV 0
76#endif 76#endif
77 77
78/*
79 * To be used in shared book E/book S, this avoids needing to worry about
80 * book S/book E in shared code
81 */
82#ifndef MSR_SPE
83#define MSR_SPE 0
84#endif
85
78#define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */ 86#define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */
79#define MSR_VSX __MASK(MSR_VSX_LG) /* Enable VSX */ 87#define MSR_VSX __MASK(MSR_VSX_LG) /* Enable VSX */
80#define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */ 88#define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */
@@ -376,7 +384,7 @@
376#define SPRN_TSCR 0x399 /* Thread Switch Control Register */ 384#define SPRN_TSCR 0x399 /* Thread Switch Control Register */
377 385
378#define SPRN_DEC 0x016 /* Decrement Register */ 386#define SPRN_DEC 0x016 /* Decrement Register */
379#define SPRN_DER 0x095 /* Debug Enable Regsiter */ 387#define SPRN_DER 0x095 /* Debug Enable Register */
380#define DER_RSTE 0x40000000 /* Reset Interrupt */ 388#define DER_RSTE 0x40000000 /* Reset Interrupt */
381#define DER_CHSTPE 0x20000000 /* Check Stop */ 389#define DER_CHSTPE 0x20000000 /* Check Stop */
382#define DER_MCIE 0x10000000 /* Machine Check Interrupt */ 390#define DER_MCIE 0x10000000 /* Machine Check Interrupt */
@@ -401,7 +409,7 @@
401#define SPRN_DPDES 0x0B0 /* Directed Priv. Doorbell Exc. State */ 409#define SPRN_DPDES 0x0B0 /* Directed Priv. Doorbell Exc. State */
402#define SPRN_EAR 0x11A /* External Address Register */ 410#define SPRN_EAR 0x11A /* External Address Register */
403#define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */ 411#define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */
404#define SPRN_HASH2 0x3D3 /* Secondary Hash Address Resgister */ 412#define SPRN_HASH2 0x3D3 /* Secondary Hash Address Register */
405#define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */ 413#define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */
406#define HID0_HDICE_SH (63 - 23) /* 970 HDEC interrupt enable */ 414#define HID0_HDICE_SH (63 - 23) /* 970 HDEC interrupt enable */
407#define HID0_EMCP (1<<31) /* Enable Machine Check pin */ 415#define HID0_EMCP (1<<31) /* Enable Machine Check pin */
@@ -514,7 +522,7 @@
514#define ICTRL_EICP 0x00000100 /* enable icache par. check */ 522#define ICTRL_EICP 0x00000100 /* enable icache par. check */
515#define SPRN_IMISS 0x3D4 /* Instruction TLB Miss Register */ 523#define SPRN_IMISS 0x3D4 /* Instruction TLB Miss Register */
516#define SPRN_IMMR 0x27E /* Internal Memory Map Register */ 524#define SPRN_IMMR 0x27E /* Internal Memory Map Register */
517#define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ 525#define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Register */
518#define SPRN_L2CR2 0x3f8 526#define SPRN_L2CR2 0x3f8
519#define L2CR_L2E 0x80000000 /* L2 enable */ 527#define L2CR_L2E 0x80000000 /* L2 enable */
520#define L2CR_L2PE 0x40000000 /* L2 parity enable */ 528#define L2CR_L2PE 0x40000000 /* L2 parity enable */
@@ -549,7 +557,7 @@
549#define L2CR_L2DO_745x 0x00010000 /* L2 data only (745x) */ 557#define L2CR_L2DO_745x 0x00010000 /* L2 data only (745x) */
550#define L2CR_L2REP_745x 0x00001000 /* L2 repl. algorithm (745x) */ 558#define L2CR_L2REP_745x 0x00001000 /* L2 repl. algorithm (745x) */
551#define L2CR_L2HWF_745x 0x00000800 /* L2 hardware flush (745x) */ 559#define L2CR_L2HWF_745x 0x00000800 /* L2 hardware flush (745x) */
552#define SPRN_L3CR 0x3FA /* Level 3 Cache Control Regsiter */ 560#define SPRN_L3CR 0x3FA /* Level 3 Cache Control Register */
553#define L3CR_L3E 0x80000000 /* L3 enable */ 561#define L3CR_L3E 0x80000000 /* L3 enable */
554#define L3CR_L3PE 0x40000000 /* L3 data parity enable */ 562#define L3CR_L3PE 0x40000000 /* L3 data parity enable */
555#define L3CR_L3APE 0x20000000 /* L3 addr parity enable */ 563#define L3CR_L3APE 0x20000000 /* L3 addr parity enable */
@@ -1211,9 +1219,11 @@ static inline void mtmsr_isync(unsigned long val)
1211#define mfspr(rn) ({unsigned long rval; \ 1219#define mfspr(rn) ({unsigned long rval; \
1212 asm volatile("mfspr %0," __stringify(rn) \ 1220 asm volatile("mfspr %0," __stringify(rn) \
1213 : "=r" (rval)); rval;}) 1221 : "=r" (rval)); rval;})
1222#ifndef mtspr
1214#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \ 1223#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \
1215 : "r" ((unsigned long)(v)) \ 1224 : "r" ((unsigned long)(v)) \
1216 : "memory") 1225 : "memory")
1226#endif
1217 1227
1218extern void msr_check_and_set(unsigned long bits); 1228extern void msr_check_and_set(unsigned long bits);
1219extern bool strict_msr_control; 1229extern bool strict_msr_control;
diff --git a/arch/powerpc/include/asm/reg_8xx.h b/arch/powerpc/include/asm/reg_8xx.h
index e8ea346b21d3..94d01f81e668 100644
--- a/arch/powerpc/include/asm/reg_8xx.h
+++ b/arch/powerpc/include/asm/reg_8xx.h
@@ -4,6 +4,8 @@
4#ifndef _ASM_POWERPC_REG_8xx_H 4#ifndef _ASM_POWERPC_REG_8xx_H
5#define _ASM_POWERPC_REG_8xx_H 5#define _ASM_POWERPC_REG_8xx_H
6 6
7#include <asm/mmu-8xx.h>
8
7/* Cache control on the MPC8xx is provided through some additional 9/* Cache control on the MPC8xx is provided through some additional
8 * special purpose registers. 10 * special purpose registers.
9 */ 11 */
@@ -14,6 +16,15 @@
14#define SPRN_DC_ADR 569 /* Address needed for some commands */ 16#define SPRN_DC_ADR 569 /* Address needed for some commands */
15#define SPRN_DC_DAT 570 /* Read-only data register */ 17#define SPRN_DC_DAT 570 /* Read-only data register */
16 18
19/* Misc Debug */
20#define SPRN_DPDR 630
21#define SPRN_MI_CAM 816
22#define SPRN_MI_RAM0 817
23#define SPRN_MI_RAM1 818
24#define SPRN_MD_CAM 824
25#define SPRN_MD_RAM0 825
26#define SPRN_MD_RAM1 826
27
17/* Commands. Only the first few are available to the instruction cache. 28/* Commands. Only the first few are available to the instruction cache.
18*/ 29*/
19#define IDC_ENABLE 0x02000000 /* Cache enable */ 30#define IDC_ENABLE 0x02000000 /* Cache enable */
@@ -39,4 +50,86 @@
39#define DC_DFWT 0x40000000 /* Data cache is forced write through */ 50#define DC_DFWT 0x40000000 /* Data cache is forced write through */
40#define DC_LES 0x20000000 /* Caches are little endian mode */ 51#define DC_LES 0x20000000 /* Caches are little endian mode */
41 52
53#ifdef CONFIG_8xx_CPU6
54#define do_mtspr_cpu6(rn, rn_addr, v) \
55 do { \
56 int _reg_cpu6 = rn_addr, _tmp_cpu6; \
57 asm volatile("stw %0, %1;" \
58 "lwz %0, %1;" \
59 "mtspr " __stringify(rn) ",%2" : \
60 : "r" (_reg_cpu6), "m"(_tmp_cpu6), \
61 "r" ((unsigned long)(v)) \
62 : "memory"); \
63 } while (0)
64
65#define do_mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \
66 : "r" ((unsigned long)(v)) \
67 : "memory")
68#define mtspr(rn, v) \
69 do { \
70 if (rn == SPRN_IMMR) \
71 do_mtspr_cpu6(rn, 0x3d30, v); \
72 else if (rn == SPRN_IC_CST) \
73 do_mtspr_cpu6(rn, 0x2110, v); \
74 else if (rn == SPRN_IC_ADR) \
75 do_mtspr_cpu6(rn, 0x2310, v); \
76 else if (rn == SPRN_IC_DAT) \
77 do_mtspr_cpu6(rn, 0x2510, v); \
78 else if (rn == SPRN_DC_CST) \
79 do_mtspr_cpu6(rn, 0x3110, v); \
80 else if (rn == SPRN_DC_ADR) \
81 do_mtspr_cpu6(rn, 0x3310, v); \
82 else if (rn == SPRN_DC_DAT) \
83 do_mtspr_cpu6(rn, 0x3510, v); \
84 else if (rn == SPRN_MI_CTR) \
85 do_mtspr_cpu6(rn, 0x2180, v); \
86 else if (rn == SPRN_MI_AP) \
87 do_mtspr_cpu6(rn, 0x2580, v); \
88 else if (rn == SPRN_MI_EPN) \
89 do_mtspr_cpu6(rn, 0x2780, v); \
90 else if (rn == SPRN_MI_TWC) \
91 do_mtspr_cpu6(rn, 0x2b80, v); \
92 else if (rn == SPRN_MI_RPN) \
93 do_mtspr_cpu6(rn, 0x2d80, v); \
94 else if (rn == SPRN_MI_CAM) \
95 do_mtspr_cpu6(rn, 0x2190, v); \
96 else if (rn == SPRN_MI_RAM0) \
97 do_mtspr_cpu6(rn, 0x2390, v); \
98 else if (rn == SPRN_MI_RAM1) \
99 do_mtspr_cpu6(rn, 0x2590, v); \
100 else if (rn == SPRN_MD_CTR) \
101 do_mtspr_cpu6(rn, 0x3180, v); \
102 else if (rn == SPRN_M_CASID) \
103 do_mtspr_cpu6(rn, 0x3380, v); \
104 else if (rn == SPRN_MD_AP) \
105 do_mtspr_cpu6(rn, 0x3580, v); \
106 else if (rn == SPRN_MD_EPN) \
107 do_mtspr_cpu6(rn, 0x3780, v); \
108 else if (rn == SPRN_M_TWB) \
109 do_mtspr_cpu6(rn, 0x3980, v); \
110 else if (rn == SPRN_MD_TWC) \
111 do_mtspr_cpu6(rn, 0x3b80, v); \
112 else if (rn == SPRN_MD_RPN) \
113 do_mtspr_cpu6(rn, 0x3d80, v); \
114 else if (rn == SPRN_M_TW) \
115 do_mtspr_cpu6(rn, 0x3f80, v); \
116 else if (rn == SPRN_MD_CAM) \
117 do_mtspr_cpu6(rn, 0x3190, v); \
118 else if (rn == SPRN_MD_RAM0) \
119 do_mtspr_cpu6(rn, 0x3390, v); \
120 else if (rn == SPRN_MD_RAM1) \
121 do_mtspr_cpu6(rn, 0x3590, v); \
122 else if (rn == SPRN_DEC) \
123 do_mtspr_cpu6(rn, 0x2c00, v); \
124 else if (rn == SPRN_TBWL) \
125 do_mtspr_cpu6(rn, 0x3880, v); \
126 else if (rn == SPRN_TBWU) \
127 do_mtspr_cpu6(rn, 0x3a80, v); \
128 else if (rn == SPRN_DPDR) \
129 do_mtspr_cpu6(rn, 0x2d30, v); \
130 else \
131 do_mtspr(rn, v); \
132 } while (0)
133#endif
134
42#endif /* _ASM_POWERPC_REG_8xx_H */ 135#endif /* _ASM_POWERPC_REG_8xx_H */
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 2fef74b474f0..737e012ef56e 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -681,7 +681,7 @@
681#define SPRN_CDBCR 0x3D7 /* Cache Debug Control Register */ 681#define SPRN_CDBCR 0x3D7 /* Cache Debug Control Register */
682#define SPRN_TBHI 0x3DC /* Time Base High */ 682#define SPRN_TBHI 0x3DC /* Time Base High */
683#define SPRN_TBLO 0x3DD /* Time Base Low */ 683#define SPRN_TBLO 0x3DD /* Time Base Low */
684#define SPRN_DBCR 0x3F2 /* Debug Control Regsiter */ 684#define SPRN_DBCR 0x3F2 /* Debug Control Register */
685#define SPRN_PBL1 0x3FC /* Protection Bound Lower 1 */ 685#define SPRN_PBL1 0x3FC /* Protection Bound Lower 1 */
686#define SPRN_PBL2 0x3FE /* Protection Bound Lower 2 */ 686#define SPRN_PBL2 0x3FE /* Protection Bound Lower 2 */
687#define SPRN_PBU1 0x3FD /* Protection Bound Upper 1 */ 687#define SPRN_PBU1 0x3FD /* Protection Bound Upper 1 */
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index a5e930aca804..abf5866e08c6 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -22,6 +22,18 @@ static inline int in_kernel_text(unsigned long addr)
22 return 0; 22 return 0;
23} 23}
24 24
25static inline unsigned long kernel_toc_addr(void)
26{
27 /* Defined by the linker, see vmlinux.lds.S */
28 extern unsigned long __toc_start;
29
30 /*
31 * The TOC register (r2) points 32kB into the TOC, so that 64kB of
32 * the TOC can be addressed using a single machine instruction.
33 */
34 return (unsigned long)(&__toc_start) + 0x8000UL;
35}
36
25static inline int overlaps_interrupt_vector_text(unsigned long start, 37static inline int overlaps_interrupt_vector_text(unsigned long start,
26 unsigned long end) 38 unsigned long end)
27{ 39{
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 78083ed20792..e1afd4c4f695 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -67,6 +67,9 @@ void generic_cpu_die(unsigned int cpu);
67void generic_set_cpu_dead(unsigned int cpu); 67void generic_set_cpu_dead(unsigned int cpu);
68void generic_set_cpu_up(unsigned int cpu); 68void generic_set_cpu_up(unsigned int cpu);
69int generic_check_cpu_restart(unsigned int cpu); 69int generic_check_cpu_restart(unsigned int cpu);
70int is_cpu_dead(unsigned int cpu);
71#else
72#define generic_set_cpu_up(i) do { } while (0)
70#endif 73#endif
71 74
72#ifdef CONFIG_PPC64 75#ifdef CONFIG_PPC64
@@ -201,6 +204,7 @@ extern void generic_secondary_thread_init(void);
201extern unsigned long __secondary_hold_spinloop; 204extern unsigned long __secondary_hold_spinloop;
202extern unsigned long __secondary_hold_acknowledge; 205extern unsigned long __secondary_hold_acknowledge;
203extern char __secondary_hold; 206extern char __secondary_hold;
207extern unsigned int booting_thread_hwid;
204 208
205extern void __early_start(void); 209extern void __early_start(void);
206#endif /* __ASSEMBLY__ */ 210#endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/include/asm/smu.h b/arch/powerpc/include/asm/smu.h
index 37d2da6feabf..f280dd11243f 100644
--- a/arch/powerpc/include/asm/smu.h
+++ b/arch/powerpc/include/asm/smu.h
@@ -154,7 +154,7 @@
154 * 154 *
155 * The Darwin I2C driver is less subtle though. On any non-success status 155 * The Darwin I2C driver is less subtle though. On any non-success status
156 * from the response command, it waits 5ms and tries again up to 20 times, 156 * from the response command, it waits 5ms and tries again up to 20 times,
157 * it doesn't differenciate between fatal errors or "busy" status. 157 * it doesn't differentiate between fatal errors or "busy" status.
158 * 158 *
159 * This driver provides an asynchronous paramblock based i2c command 159 * This driver provides an asynchronous paramblock based i2c command
160 * interface to be used either directly by low level code or by a higher 160 * interface to be used either directly by low level code or by a higher
diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h
index 5b268b6be74c..17c8380673a6 100644
--- a/arch/powerpc/include/asm/switch_to.h
+++ b/arch/powerpc/include/asm/switch_to.h
@@ -28,12 +28,14 @@ extern void giveup_all(struct task_struct *);
28extern void enable_kernel_fp(void); 28extern void enable_kernel_fp(void);
29extern void flush_fp_to_thread(struct task_struct *); 29extern void flush_fp_to_thread(struct task_struct *);
30extern void giveup_fpu(struct task_struct *); 30extern void giveup_fpu(struct task_struct *);
31extern void __giveup_fpu(struct task_struct *); 31extern void save_fpu(struct task_struct *);
32static inline void disable_kernel_fp(void) 32static inline void disable_kernel_fp(void)
33{ 33{
34 msr_check_and_clear(MSR_FP); 34 msr_check_and_clear(MSR_FP);
35} 35}
36#else 36#else
37static inline void __giveup_fpu(struct task_struct *t) { }
38static inline void save_fpu(struct task_struct *t) { }
37static inline void flush_fp_to_thread(struct task_struct *t) { } 39static inline void flush_fp_to_thread(struct task_struct *t) { }
38#endif 40#endif
39 41
@@ -41,18 +43,19 @@ static inline void flush_fp_to_thread(struct task_struct *t) { }
41extern void enable_kernel_altivec(void); 43extern void enable_kernel_altivec(void);
42extern void flush_altivec_to_thread(struct task_struct *); 44extern void flush_altivec_to_thread(struct task_struct *);
43extern void giveup_altivec(struct task_struct *); 45extern void giveup_altivec(struct task_struct *);
44extern void __giveup_altivec(struct task_struct *); 46extern void save_altivec(struct task_struct *);
45static inline void disable_kernel_altivec(void) 47static inline void disable_kernel_altivec(void)
46{ 48{
47 msr_check_and_clear(MSR_VEC); 49 msr_check_and_clear(MSR_VEC);
48} 50}
51#else
52static inline void save_altivec(struct task_struct *t) { }
53static inline void __giveup_altivec(struct task_struct *t) { }
49#endif 54#endif
50 55
51#ifdef CONFIG_VSX 56#ifdef CONFIG_VSX
52extern void enable_kernel_vsx(void); 57extern void enable_kernel_vsx(void);
53extern void flush_vsx_to_thread(struct task_struct *); 58extern void flush_vsx_to_thread(struct task_struct *);
54extern void giveup_vsx(struct task_struct *);
55extern void __giveup_vsx(struct task_struct *);
56static inline void disable_kernel_vsx(void) 59static inline void disable_kernel_vsx(void)
57{ 60{
58 msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); 61 msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX);
@@ -68,6 +71,8 @@ static inline void disable_kernel_spe(void)
68{ 71{
69 msr_check_and_clear(MSR_SPE); 72 msr_check_and_clear(MSR_SPE);
70} 73}
74#else
75static inline void __giveup_spe(struct task_struct *t) { }
71#endif 76#endif
72 77
73static inline void clear_task_ebb(struct task_struct *t) 78static inline void clear_task_ebb(struct task_struct *t)
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
index 2d7109a8d296..1092fdd7e737 100644
--- a/arch/powerpc/include/asm/time.h
+++ b/arch/powerpc/include/asm/time.h
@@ -31,8 +31,6 @@ extern void tick_broadcast_ipi_handler(void);
31 31
32extern void generic_calibrate_decr(void); 32extern void generic_calibrate_decr(void);
33 33
34extern void set_dec_cpu6(unsigned int val);
35
36/* Some sane defaults: 125 MHz timebase, 1GHz processor */ 34/* Some sane defaults: 125 MHz timebase, 1GHz processor */
37extern unsigned long ppc_proc_freq; 35extern unsigned long ppc_proc_freq;
38#define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8) 36#define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8)
@@ -166,14 +164,12 @@ static inline void set_dec(int val)
166{ 164{
167#if defined(CONFIG_40x) 165#if defined(CONFIG_40x)
168 mtspr(SPRN_PIT, val); 166 mtspr(SPRN_PIT, val);
169#elif defined(CONFIG_8xx_CPU6)
170 set_dec_cpu6(val - 1);
171#else 167#else
172#ifndef CONFIG_BOOKE 168#ifndef CONFIG_BOOKE
173 --val; 169 --val;
174#endif 170#endif
175 mtspr(SPRN_DEC, val); 171 mtspr(SPRN_DEC, val);
176#endif /* not 40x or 8xx_CPU6 */ 172#endif /* not 40x */
177} 173}
178 174
179static inline unsigned long tb_ticks_since(unsigned long tstamp) 175static inline unsigned long tb_ticks_since(unsigned long tstamp)
diff --git a/arch/powerpc/include/asm/tlbflush.h b/arch/powerpc/include/asm/tlbflush.h
index 23d351ca0303..9f77f85e3e99 100644
--- a/arch/powerpc/include/asm/tlbflush.h
+++ b/arch/powerpc/include/asm/tlbflush.h
@@ -78,97 +78,7 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
78} 78}
79 79
80#elif defined(CONFIG_PPC_STD_MMU_64) 80#elif defined(CONFIG_PPC_STD_MMU_64)
81 81#include <asm/book3s/64/tlbflush-hash.h>
82#define MMU_NO_CONTEXT 0
83
84/*
85 * TLB flushing for 64-bit hash-MMU CPUs
86 */
87
88#include <linux/percpu.h>
89#include <asm/page.h>
90
91#define PPC64_TLB_BATCH_NR 192
92
93struct ppc64_tlb_batch {
94 int active;
95 unsigned long index;
96 struct mm_struct *mm;
97 real_pte_t pte[PPC64_TLB_BATCH_NR];
98 unsigned long vpn[PPC64_TLB_BATCH_NR];
99 unsigned int psize;
100 int ssize;
101};
102DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
103
104extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch);
105
106#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
107
108static inline void arch_enter_lazy_mmu_mode(void)
109{
110 struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
111
112 batch->active = 1;
113}
114
115static inline void arch_leave_lazy_mmu_mode(void)
116{
117 struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
118
119 if (batch->index)
120 __flush_tlb_pending(batch);
121 batch->active = 0;
122}
123
124#define arch_flush_lazy_mmu_mode() do {} while (0)
125
126
127extern void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize,
128 int ssize, unsigned long flags);
129extern void flush_hash_range(unsigned long number, int local);
130extern void flush_hash_hugepage(unsigned long vsid, unsigned long addr,
131 pmd_t *pmdp, unsigned int psize, int ssize,
132 unsigned long flags);
133
134static inline void local_flush_tlb_mm(struct mm_struct *mm)
135{
136}
137
138static inline void flush_tlb_mm(struct mm_struct *mm)
139{
140}
141
142static inline void local_flush_tlb_page(struct vm_area_struct *vma,
143 unsigned long vmaddr)
144{
145}
146
147static inline void flush_tlb_page(struct vm_area_struct *vma,
148 unsigned long vmaddr)
149{
150}
151
152static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
153 unsigned long vmaddr)
154{
155}
156
157static inline void flush_tlb_range(struct vm_area_struct *vma,
158 unsigned long start, unsigned long end)
159{
160}
161
162static inline void flush_tlb_kernel_range(unsigned long start,
163 unsigned long end)
164{
165}
166
167/* Private function for use by PCI IO mapping code */
168extern void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
169 unsigned long end);
170extern void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd,
171 unsigned long addr);
172#else 82#else
173#error Unsupported MMU type 83#error Unsupported MMU type
174#endif 84#endif
diff --git a/arch/powerpc/include/asm/uninorth.h b/arch/powerpc/include/asm/uninorth.h
index d12b11d7641e..a1d112979fd2 100644
--- a/arch/powerpc/include/asm/uninorth.h
+++ b/arch/powerpc/include/asm/uninorth.h
@@ -132,7 +132,7 @@
132 132
133/* This one _might_ return the CPU number of the CPU reading it; 133/* This one _might_ return the CPU number of the CPU reading it;
134 * the bootROM decides whether to boot or to sleep/spinloop depending 134 * the bootROM decides whether to boot or to sleep/spinloop depending
135 * on this register beeing 0 or not 135 * on this register being 0 or not
136 */ 136 */
137#define UNI_N_CPU_NUMBER 0x0050 137#define UNI_N_CPU_NUMBER 0x0050
138 138
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h
index 254604856e69..04ef3ae511da 100644
--- a/arch/powerpc/include/asm/xics.h
+++ b/arch/powerpc/include/asm/xics.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Common definitions accross all variants of ICP and ICS interrupt 2 * Common definitions across all variants of ICP and ICS interrupt
3 * controllers. 3 * controllers.
4 */ 4 */
5 5
diff --git a/arch/powerpc/include/uapi/asm/epapr_hcalls.h b/arch/powerpc/include/uapi/asm/epapr_hcalls.h
index 7f9c74b46704..b4504f394427 100644
--- a/arch/powerpc/include/uapi/asm/epapr_hcalls.h
+++ b/arch/powerpc/include/uapi/asm/epapr_hcalls.h
@@ -78,7 +78,7 @@
78#define EV_SUCCESS 0 78#define EV_SUCCESS 0
79#define EV_EPERM 1 /* Operation not permitted */ 79#define EV_EPERM 1 /* Operation not permitted */
80#define EV_ENOENT 2 /* Entry Not Found */ 80#define EV_ENOENT 2 /* Entry Not Found */
81#define EV_EIO 3 /* I/O error occured */ 81#define EV_EIO 3 /* I/O error occurred */
82#define EV_EAGAIN 4 /* The operation had insufficient 82#define EV_EAGAIN 4 /* The operation had insufficient
83 * resources to complete and should be 83 * resources to complete and should be
84 * retried 84 * retried
@@ -89,7 +89,7 @@
89#define EV_ENODEV 7 /* No such device */ 89#define EV_ENODEV 7 /* No such device */
90#define EV_EINVAL 8 /* An argument supplied to the hcall 90#define EV_EINVAL 8 /* An argument supplied to the hcall
91 was out of range or invalid */ 91 was out of range or invalid */
92#define EV_INTERNAL 9 /* An internal error occured */ 92#define EV_INTERNAL 9 /* An internal error occurred */
93#define EV_CONFIG 10 /* A configuration error was detected */ 93#define EV_CONFIG 10 /* A configuration error was detected */
94#define EV_INVALID_STATE 11 /* The object is in an invalid state */ 94#define EV_INVALID_STATE 11 /* The object is in an invalid state */
95#define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */ 95#define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 794f22adf99d..2da380fcc34c 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -16,14 +16,14 @@ endif
16 16
17ifdef CONFIG_FUNCTION_TRACER 17ifdef CONFIG_FUNCTION_TRACER
18# Do not trace early boot code 18# Do not trace early boot code
19CFLAGS_REMOVE_cputable.o = -pg -mno-sched-epilog 19CFLAGS_REMOVE_cputable.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
20CFLAGS_REMOVE_prom_init.o = -pg -mno-sched-epilog 20CFLAGS_REMOVE_prom_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
21CFLAGS_REMOVE_btext.o = -pg -mno-sched-epilog 21CFLAGS_REMOVE_btext.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
22CFLAGS_REMOVE_prom.o = -pg -mno-sched-epilog 22CFLAGS_REMOVE_prom.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
23# do not trace tracer code 23# do not trace tracer code
24CFLAGS_REMOVE_ftrace.o = -pg -mno-sched-epilog 24CFLAGS_REMOVE_ftrace.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
25# timers used by tracing 25# timers used by tracing
26CFLAGS_REMOVE_time.o = -pg -mno-sched-epilog 26CFLAGS_REMOVE_time.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
27endif 27endif
28 28
29obj-y := cputable.o ptrace.o syscalls.o \ 29obj-y := cputable.o ptrace.o syscalls.o \
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 07cebc3514f3..0d0183d3180a 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -95,12 +95,14 @@ int main(void)
95 DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fp_state)); 95 DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fp_state));
96 DEFINE(THREAD_FPSAVEAREA, offsetof(struct thread_struct, fp_save_area)); 96 DEFINE(THREAD_FPSAVEAREA, offsetof(struct thread_struct, fp_save_area));
97 DEFINE(FPSTATE_FPSCR, offsetof(struct thread_fp_state, fpscr)); 97 DEFINE(FPSTATE_FPSCR, offsetof(struct thread_fp_state, fpscr));
98 DEFINE(THREAD_LOAD_FP, offsetof(struct thread_struct, load_fp));
98#ifdef CONFIG_ALTIVEC 99#ifdef CONFIG_ALTIVEC
99 DEFINE(THREAD_VRSTATE, offsetof(struct thread_struct, vr_state)); 100 DEFINE(THREAD_VRSTATE, offsetof(struct thread_struct, vr_state));
100 DEFINE(THREAD_VRSAVEAREA, offsetof(struct thread_struct, vr_save_area)); 101 DEFINE(THREAD_VRSAVEAREA, offsetof(struct thread_struct, vr_save_area));
101 DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave)); 102 DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
102 DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr)); 103 DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
103 DEFINE(VRSTATE_VSCR, offsetof(struct thread_vr_state, vscr)); 104 DEFINE(VRSTATE_VSCR, offsetof(struct thread_vr_state, vscr));
105 DEFINE(THREAD_LOAD_VEC, offsetof(struct thread_struct, load_vec));
104#endif /* CONFIG_ALTIVEC */ 106#endif /* CONFIG_ALTIVEC */
105#ifdef CONFIG_VSX 107#ifdef CONFIG_VSX
106 DEFINE(THREAD_USED_VSR, offsetof(struct thread_struct, used_vsr)); 108 DEFINE(THREAD_USED_VSR, offsetof(struct thread_struct, used_vsr));
@@ -374,6 +376,7 @@ int main(void)
374 DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); 376 DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
375 DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); 377 DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
376 DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore)); 378 DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore));
379 DEFINE(CPU_DOWN_FLUSH, offsetof(struct cpu_spec, cpu_down_flush));
377 380
378 DEFINE(pbe_address, offsetof(struct pbe, address)); 381 DEFINE(pbe_address, offsetof(struct pbe, address));
379 DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); 382 DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index dddba3e94260..462aed9bcf51 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -13,11 +13,13 @@
13 * 13 *
14 */ 14 */
15 15
16#include <asm/page.h>
16#include <asm/processor.h> 17#include <asm/processor.h>
17#include <asm/cputable.h> 18#include <asm/cputable.h>
18#include <asm/ppc_asm.h> 19#include <asm/ppc_asm.h>
19#include <asm/mmu-book3e.h> 20#include <asm/mmu-book3e.h>
20#include <asm/asm-offsets.h> 21#include <asm/asm-offsets.h>
22#include <asm/mpc85xx.h>
21 23
22_GLOBAL(__e500_icache_setup) 24_GLOBAL(__e500_icache_setup)
23 mfspr r0, SPRN_L1CSR1 25 mfspr r0, SPRN_L1CSR1
@@ -233,3 +235,113 @@ _GLOBAL(__setup_cpu_e5500)
233 mtlr r5 235 mtlr r5
234 blr 236 blr
235#endif 237#endif
238
239/* flush L1 date cache, it can apply to e500v2, e500mc and e5500 */
240_GLOBAL(flush_dcache_L1)
241 mfmsr r10
242 wrteei 0
243
244 mfspr r3,SPRN_L1CFG0
245 rlwinm r5,r3,9,3 /* Extract cache block size */
246 twlgti r5,1 /* Only 32 and 64 byte cache blocks
247 * are currently defined.
248 */
249 li r4,32
250 subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) -
251 * log2(number of ways)
252 */
253 slw r5,r4,r5 /* r5 = cache block size */
254
255 rlwinm r7,r3,0,0xff /* Extract number of KiB in the cache */
256 mulli r7,r7,13 /* An 8-way cache will require 13
257 * loads per set.
258 */
259 slw r7,r7,r6
260
261 /* save off HID0 and set DCFA */
262 mfspr r8,SPRN_HID0
263 ori r9,r8,HID0_DCFA@l
264 mtspr SPRN_HID0,r9
265 isync
266
267 LOAD_REG_IMMEDIATE(r6, KERNELBASE)
268 mr r4, r6
269 mtctr r7
270
2711: lwz r3,0(r4) /* Load... */
272 add r4,r4,r5
273 bdnz 1b
274
275 msync
276 mr r4, r6
277 mtctr r7
278
2791: dcbf 0,r4 /* ...and flush. */
280 add r4,r4,r5
281 bdnz 1b
282
283 /* restore HID0 */
284 mtspr SPRN_HID0,r8
285 isync
286
287 wrtee r10
288
289 blr
290
291has_L2_cache:
292 /* skip L2 cache on P2040/P2040E as they have no L2 cache */
293 mfspr r3, SPRN_SVR
294 /* shift right by 8 bits and clear E bit of SVR */
295 rlwinm r4, r3, 24, ~0x800
296
297 lis r3, SVR_P2040@h
298 ori r3, r3, SVR_P2040@l
299 cmpw r4, r3
300 beq 1f
301
302 li r3, 1
303 blr
3041:
305 li r3, 0
306 blr
307
308/* flush backside L2 cache */
309flush_backside_L2_cache:
310 mflr r10
311 bl has_L2_cache
312 mtlr r10
313 cmpwi r3, 0
314 beq 2f
315
316 /* Flush the L2 cache */
317 mfspr r3, SPRN_L2CSR0
318 ori r3, r3, L2CSR0_L2FL@l
319 msync
320 isync
321 mtspr SPRN_L2CSR0,r3
322 isync
323
324 /* check if it is complete */
3251: mfspr r3,SPRN_L2CSR0
326 andi. r3, r3, L2CSR0_L2FL@l
327 bne 1b
3282:
329 blr
330
331_GLOBAL(cpu_down_flush_e500v2)
332 mflr r0
333 bl flush_dcache_L1
334 mtlr r0
335 blr
336
337_GLOBAL(cpu_down_flush_e500mc)
338_GLOBAL(cpu_down_flush_e5500)
339 mflr r0
340 bl flush_dcache_L1
341 bl flush_backside_L2_cache
342 mtlr r0
343 blr
344
345/* L1 Data Cache of e6500 contains no modified data, no flush is required */
346_GLOBAL(cpu_down_flush_e6500)
347 blr
diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S
index 9c9b7411b28b..584e119fa8b0 100644
--- a/arch/powerpc/kernel/cpu_setup_power.S
+++ b/arch/powerpc/kernel/cpu_setup_power.S
@@ -15,6 +15,7 @@
15#include <asm/ppc_asm.h> 15#include <asm/ppc_asm.h>
16#include <asm/asm-offsets.h> 16#include <asm/asm-offsets.h>
17#include <asm/cache.h> 17#include <asm/cache.h>
18#include <asm/book3s/64/mmu-hash.h>
18 19
19/* Entry: r3 = crap, r4 = ptr to cputable entry 20/* Entry: r3 = crap, r4 = ptr to cputable entry
20 * 21 *
@@ -83,6 +84,39 @@ _GLOBAL(__restore_cpu_power8)
83 mtlr r11 84 mtlr r11
84 blr 85 blr
85 86
87_GLOBAL(__setup_cpu_power9)
88 mflr r11
89 bl __init_FSCR
90 bl __init_hvmode_206
91 mtlr r11
92 beqlr
93 li r0,0
94 mtspr SPRN_LPID,r0
95 mfspr r3,SPRN_LPCR
96 ori r3, r3, LPCR_PECEDH
97 bl __init_LPCR
98 bl __init_HFSCR
99 bl __init_tlb_power9
100 mtlr r11
101 blr
102
103_GLOBAL(__restore_cpu_power9)
104 mflr r11
105 bl __init_FSCR
106 mfmsr r3
107 rldicl. r0,r3,4,63
108 mtlr r11
109 beqlr
110 li r0,0
111 mtspr SPRN_LPID,r0
112 mfspr r3,SPRN_LPCR
113 ori r3, r3, LPCR_PECEDH
114 bl __init_LPCR
115 bl __init_HFSCR
116 bl __init_tlb_power9
117 mtlr r11
118 blr
119
86__init_hvmode_206: 120__init_hvmode_206:
87 /* Disable CPU_FTR_HVMODE and exit if MSR:HV is not set */ 121 /* Disable CPU_FTR_HVMODE and exit if MSR:HV is not set */
88 mfmsr r3 122 mfmsr r3
@@ -139,7 +173,7 @@ __init_HFSCR:
139 * (invalidate by congruence class). P7 has 128 CCs., P8 has 512. 173 * (invalidate by congruence class). P7 has 128 CCs., P8 has 512.
140 */ 174 */
141__init_tlb_power7: 175__init_tlb_power7:
142 li r6,128 176 li r6,POWER7_TLB_SETS
143 mtctr r6 177 mtctr r6
144 li r7,0xc00 /* IS field = 0b11 */ 178 li r7,0xc00 /* IS field = 0b11 */
145 ptesync 179 ptesync
@@ -150,7 +184,18 @@ __init_tlb_power7:
1501: blr 1841: blr
151 185
152__init_tlb_power8: 186__init_tlb_power8:
153 li r6,512 187 li r6,POWER8_TLB_SETS
188 mtctr r6
189 li r7,0xc00 /* IS field = 0b11 */
190 ptesync
1912: tlbiel r7
192 addi r7,r7,0x1000
193 bdnz 2b
194 ptesync
1951: blr
196
197__init_tlb_power9:
198 li r6,POWER9_TLB_SETS_HASH
154 mtctr r6 199 mtctr r6
155 li r7,0xc00 /* IS field = 0b11 */ 200 li r7,0xc00 /* IS field = 0b11 */
156 ptesync 201 ptesync
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 7d80bfdfb15e..6c662b8de90d 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -70,9 +70,12 @@ extern void __setup_cpu_power7(unsigned long offset, struct cpu_spec* spec);
70extern void __restore_cpu_power7(void); 70extern void __restore_cpu_power7(void);
71extern void __setup_cpu_power8(unsigned long offset, struct cpu_spec* spec); 71extern void __setup_cpu_power8(unsigned long offset, struct cpu_spec* spec);
72extern void __restore_cpu_power8(void); 72extern void __restore_cpu_power8(void);
73extern void __setup_cpu_power9(unsigned long offset, struct cpu_spec* spec);
74extern void __restore_cpu_power9(void);
73extern void __restore_cpu_a2(void); 75extern void __restore_cpu_a2(void);
74extern void __flush_tlb_power7(unsigned int action); 76extern void __flush_tlb_power7(unsigned int action);
75extern void __flush_tlb_power8(unsigned int action); 77extern void __flush_tlb_power8(unsigned int action);
78extern void __flush_tlb_power9(unsigned int action);
76extern long __machine_check_early_realmode_p7(struct pt_regs *regs); 79extern long __machine_check_early_realmode_p7(struct pt_regs *regs);
77extern long __machine_check_early_realmode_p8(struct pt_regs *regs); 80extern long __machine_check_early_realmode_p8(struct pt_regs *regs);
78#endif /* CONFIG_PPC64 */ 81#endif /* CONFIG_PPC64 */
@@ -116,6 +119,11 @@ extern void __restore_cpu_e6500(void);
116#define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\ 119#define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\
117 PPC_FEATURE_TRUE_LE | \ 120 PPC_FEATURE_TRUE_LE | \
118 PPC_FEATURE_HAS_ALTIVEC_COMP) 121 PPC_FEATURE_HAS_ALTIVEC_COMP)
122#define COMMON_USER_POWER9 COMMON_USER_POWER8
123#define COMMON_USER2_POWER9 (COMMON_USER2_POWER8 | \
124 PPC_FEATURE2_ARCH_3_00 | \
125 PPC_FEATURE2_HAS_IEEE128)
126
119#ifdef CONFIG_PPC_BOOK3E_64 127#ifdef CONFIG_PPC_BOOK3E_64
120#define COMMON_USER_BOOKE (COMMON_USER_PPC64 | PPC_FEATURE_BOOKE) 128#define COMMON_USER_BOOKE (COMMON_USER_PPC64 | PPC_FEATURE_BOOKE)
121#else 129#else
@@ -499,6 +507,25 @@ static struct cpu_spec __initdata cpu_specs[] = {
499 .machine_check_early = __machine_check_early_realmode_p8, 507 .machine_check_early = __machine_check_early_realmode_p8,
500 .platform = "power8", 508 .platform = "power8",
501 }, 509 },
510 { /* Power9 */
511 .pvr_mask = 0xffff0000,
512 .pvr_value = 0x004e0000,
513 .cpu_name = "POWER9 (raw)",
514 .cpu_features = CPU_FTRS_POWER9,
515 .cpu_user_features = COMMON_USER_POWER9,
516 .cpu_user_features2 = COMMON_USER2_POWER9,
517 .mmu_features = MMU_FTRS_POWER9,
518 .icache_bsize = 128,
519 .dcache_bsize = 128,
520 .num_pmcs = 6,
521 .pmc_type = PPC_PMC_IBM,
522 .oprofile_cpu_type = "ppc64/power9",
523 .oprofile_type = PPC_OPROFILE_INVALID,
524 .cpu_setup = __setup_cpu_power9,
525 .cpu_restore = __restore_cpu_power9,
526 .flush_tlb = __flush_tlb_power9,
527 .platform = "power9",
528 },
502 { /* Cell Broadband Engine */ 529 { /* Cell Broadband Engine */
503 .pvr_mask = 0xffff0000, 530 .pvr_mask = 0xffff0000,
504 .pvr_value = 0x00700000, 531 .pvr_value = 0x00700000,
@@ -2023,6 +2050,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
2023 .cpu_setup = __setup_cpu_e500v2, 2050 .cpu_setup = __setup_cpu_e500v2,
2024 .machine_check = machine_check_e500, 2051 .machine_check = machine_check_e500,
2025 .platform = "ppc8548", 2052 .platform = "ppc8548",
2053 .cpu_down_flush = cpu_down_flush_e500v2,
2026 }, 2054 },
2027#else 2055#else
2028 { /* e500mc */ 2056 { /* e500mc */
@@ -2042,6 +2070,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
2042 .cpu_setup = __setup_cpu_e500mc, 2070 .cpu_setup = __setup_cpu_e500mc,
2043 .machine_check = machine_check_e500mc, 2071 .machine_check = machine_check_e500mc,
2044 .platform = "ppce500mc", 2072 .platform = "ppce500mc",
2073 .cpu_down_flush = cpu_down_flush_e500mc,
2045 }, 2074 },
2046#endif /* CONFIG_PPC_E500MC */ 2075#endif /* CONFIG_PPC_E500MC */
2047#endif /* CONFIG_PPC32 */ 2076#endif /* CONFIG_PPC32 */
@@ -2066,6 +2095,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
2066#endif 2095#endif
2067 .machine_check = machine_check_e500mc, 2096 .machine_check = machine_check_e500mc,
2068 .platform = "ppce5500", 2097 .platform = "ppce5500",
2098 .cpu_down_flush = cpu_down_flush_e5500,
2069 }, 2099 },
2070 { /* e6500 */ 2100 { /* e6500 */
2071 .pvr_mask = 0xffff0000, 2101 .pvr_mask = 0xffff0000,
@@ -2088,6 +2118,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
2088#endif 2118#endif
2089 .machine_check = machine_check_e500mc, 2119 .machine_check = machine_check_e500mc,
2090 .platform = "ppce6500", 2120 .platform = "ppce6500",
2121 .cpu_down_flush = cpu_down_flush_e6500,
2091 }, 2122 },
2092#endif /* CONFIG_PPC_E500MC */ 2123#endif /* CONFIG_PPC_E500MC */
2093#ifdef CONFIG_PPC32 2124#ifdef CONFIG_PPC32
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 40e4d4a27663..6544017eb90b 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -268,13 +268,6 @@ static void *eeh_dump_pe_log(void *data, void *flag)
268 struct eeh_dev *edev, *tmp; 268 struct eeh_dev *edev, *tmp;
269 size_t *plen = flag; 269 size_t *plen = flag;
270 270
271 /* If the PE's config space is blocked, 0xFF's will be
272 * returned. It's pointless to collect the log in this
273 * case.
274 */
275 if (pe->state & EEH_PE_CFG_BLOCKED)
276 return NULL;
277
278 eeh_pe_for_each_dev(pe, edev, tmp) 271 eeh_pe_for_each_dev(pe, edev, tmp)
279 *plen += eeh_dump_dev_log(edev, pci_regs_buf + *plen, 272 *plen += eeh_dump_dev_log(edev, pci_regs_buf + *plen,
280 EEH_PCI_REGS_LOG_LEN - *plen); 273 EEH_PCI_REGS_LOG_LEN - *plen);
@@ -677,7 +670,7 @@ int eeh_pci_enable(struct eeh_pe *pe, int function)
677 /* Check if the request is finished successfully */ 670 /* Check if the request is finished successfully */
678 if (active_flag) { 671 if (active_flag) {
679 rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC); 672 rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC);
680 if (rc <= 0) 673 if (rc < 0)
681 return rc; 674 return rc;
682 675
683 if (rc & active_flag) 676 if (rc & active_flag)
@@ -739,7 +732,7 @@ static void *eeh_restore_dev_state(void *data, void *userdata)
739} 732}
740 733
741/** 734/**
742 * pcibios_set_pcie_slot_reset - Set PCI-E reset state 735 * pcibios_set_pcie_reset_state - Set PCI-E reset state
743 * @dev: pci device struct 736 * @dev: pci device struct
744 * @state: reset state to enter 737 * @state: reset state to enter
745 * 738 *
@@ -761,7 +754,8 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat
761 case pcie_deassert_reset: 754 case pcie_deassert_reset:
762 eeh_ops->reset(pe, EEH_RESET_DEACTIVATE); 755 eeh_ops->reset(pe, EEH_RESET_DEACTIVATE);
763 eeh_unfreeze_pe(pe, false); 756 eeh_unfreeze_pe(pe, false);
764 eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED); 757 if (!(pe->type & EEH_PE_VF))
758 eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED);
765 eeh_pe_dev_traverse(pe, eeh_restore_dev_state, dev); 759 eeh_pe_dev_traverse(pe, eeh_restore_dev_state, dev);
766 eeh_pe_state_clear(pe, EEH_PE_ISOLATED); 760 eeh_pe_state_clear(pe, EEH_PE_ISOLATED);
767 break; 761 break;
@@ -769,14 +763,16 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat
769 eeh_pe_state_mark_with_cfg(pe, EEH_PE_ISOLATED); 763 eeh_pe_state_mark_with_cfg(pe, EEH_PE_ISOLATED);
770 eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE); 764 eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE);
771 eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev); 765 eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev);
772 eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED); 766 if (!(pe->type & EEH_PE_VF))
767 eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED);
773 eeh_ops->reset(pe, EEH_RESET_HOT); 768 eeh_ops->reset(pe, EEH_RESET_HOT);
774 break; 769 break;
775 case pcie_warm_reset: 770 case pcie_warm_reset:
776 eeh_pe_state_mark_with_cfg(pe, EEH_PE_ISOLATED); 771 eeh_pe_state_mark_with_cfg(pe, EEH_PE_ISOLATED);
777 eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE); 772 eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE);
778 eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev); 773 eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev);
779 eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED); 774 if (!(pe->type & EEH_PE_VF))
775 eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED);
780 eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL); 776 eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL);
781 break; 777 break;
782 default: 778 default:
@@ -1243,6 +1239,14 @@ void eeh_remove_device(struct pci_dev *dev)
1243 * from the parent PE during the BAR resotre. 1239 * from the parent PE during the BAR resotre.
1244 */ 1240 */
1245 edev->pdev = NULL; 1241 edev->pdev = NULL;
1242
1243 /*
1244 * The flag "in_error" is used to trace EEH devices for VFs
1245 * in error state or not. It's set in eeh_report_error(). If
1246 * it's not set, eeh_report_{reset,resume}() won't be called
1247 * for the VF EEH device.
1248 */
1249 edev->in_error = false;
1246 dev->dev.archdata.edev = NULL; 1250 dev->dev.archdata.edev = NULL;
1247 if (!(edev->pe->state & EEH_PE_KEEP)) 1251 if (!(edev->pe->state & EEH_PE_KEEP))
1248 eeh_rmv_from_parent_pe(edev); 1252 eeh_rmv_from_parent_pe(edev);
@@ -1537,6 +1541,17 @@ int eeh_pe_get_state(struct eeh_pe *pe)
1537 if (!eeh_ops || !eeh_ops->get_state) 1541 if (!eeh_ops || !eeh_ops->get_state)
1538 return -ENOENT; 1542 return -ENOENT;
1539 1543
1544 /*
1545 * If the parent PE is owned by the host kernel and is undergoing
1546 * error recovery, we should return the PE state as temporarily
1547 * unavailable so that the error recovery on the guest is suspended
1548 * until the recovery completes on the host.
1549 */
1550 if (pe->parent &&
1551 !(pe->state & EEH_PE_REMOVED) &&
1552 (pe->parent->state & (EEH_PE_ISOLATED | EEH_PE_RECOVERING)))
1553 return EEH_PE_STATE_UNAVAIL;
1554
1540 result = eeh_ops->get_state(pe, NULL); 1555 result = eeh_ops->get_state(pe, NULL);
1541 rst_active = !!(result & EEH_STATE_RESET_ACTIVE); 1556 rst_active = !!(result & EEH_STATE_RESET_ACTIVE);
1542 dma_en = !!(result & EEH_STATE_DMA_ENABLED); 1557 dma_en = !!(result & EEH_STATE_DMA_ENABLED);
diff --git a/arch/powerpc/kernel/eeh_cache.c b/arch/powerpc/kernel/eeh_cache.c
index a1e86e172e3c..ddbcfab7efdf 100644
--- a/arch/powerpc/kernel/eeh_cache.c
+++ b/arch/powerpc/kernel/eeh_cache.c
@@ -195,8 +195,11 @@ static void __eeh_addr_cache_insert_dev(struct pci_dev *dev)
195 return; 195 return;
196 } 196 }
197 197
198 /* Walk resources on this device, poke them into the tree */ 198 /*
199 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { 199 * Walk resources on this device, poke the first 7 (6 normal BAR and 1
200 * ROM BAR) into the tree.
201 */
202 for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
200 resource_size_t start = pci_resource_start(dev,i); 203 resource_size_t start = pci_resource_start(dev,i);
201 resource_size_t end = pci_resource_end(dev,i); 204 resource_size_t end = pci_resource_end(dev,i);
202 unsigned long flags = pci_resource_flags(dev,i); 205 unsigned long flags = pci_resource_flags(dev,i);
@@ -222,10 +225,6 @@ void eeh_addr_cache_insert_dev(struct pci_dev *dev)
222{ 225{
223 unsigned long flags; 226 unsigned long flags;
224 227
225 /* Ignore PCI bridges */
226 if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
227 return;
228
229 spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags); 228 spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
230 __eeh_addr_cache_insert_dev(dev); 229 __eeh_addr_cache_insert_dev(dev);
231 spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags); 230 spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
diff --git a/arch/powerpc/kernel/eeh_dev.c b/arch/powerpc/kernel/eeh_dev.c
index aabba94ff9cb..7815095fe3d8 100644
--- a/arch/powerpc/kernel/eeh_dev.c
+++ b/arch/powerpc/kernel/eeh_dev.c
@@ -67,6 +67,7 @@ void *eeh_dev_init(struct pci_dn *pdn, void *data)
67 edev->pdn = pdn; 67 edev->pdn = pdn;
68 edev->phb = phb; 68 edev->phb = phb;
69 INIT_LIST_HEAD(&edev->list); 69 INIT_LIST_HEAD(&edev->list);
70 INIT_LIST_HEAD(&edev->rmv_list);
70 71
71 return NULL; 72 return NULL;
72} 73}
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 650cfb31ea3d..fb6207d2c604 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -34,6 +34,11 @@
34#include <asm/prom.h> 34#include <asm/prom.h>
35#include <asm/rtas.h> 35#include <asm/rtas.h>
36 36
37struct eeh_rmv_data {
38 struct list_head edev_list;
39 int removed;
40};
41
37/** 42/**
38 * eeh_pcid_name - Retrieve name of PCI device driver 43 * eeh_pcid_name - Retrieve name of PCI device driver
39 * @pdev: PCI device 44 * @pdev: PCI device
@@ -190,7 +195,7 @@ static void *eeh_report_error(void *data, void *userdata)
190 enum pci_ers_result rc, *res = userdata; 195 enum pci_ers_result rc, *res = userdata;
191 struct pci_driver *driver; 196 struct pci_driver *driver;
192 197
193 if (!dev || eeh_dev_removed(edev)) 198 if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe))
194 return NULL; 199 return NULL;
195 dev->error_state = pci_channel_io_frozen; 200 dev->error_state = pci_channel_io_frozen;
196 201
@@ -211,6 +216,7 @@ static void *eeh_report_error(void *data, void *userdata)
211 if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; 216 if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
212 if (*res == PCI_ERS_RESULT_NONE) *res = rc; 217 if (*res == PCI_ERS_RESULT_NONE) *res = rc;
213 218
219 edev->in_error = true;
214 eeh_pcid_put(dev); 220 eeh_pcid_put(dev);
215 return NULL; 221 return NULL;
216} 222}
@@ -231,7 +237,7 @@ static void *eeh_report_mmio_enabled(void *data, void *userdata)
231 enum pci_ers_result rc, *res = userdata; 237 enum pci_ers_result rc, *res = userdata;
232 struct pci_driver *driver; 238 struct pci_driver *driver;
233 239
234 if (!dev || eeh_dev_removed(edev)) 240 if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe))
235 return NULL; 241 return NULL;
236 242
237 driver = eeh_pcid_get(dev); 243 driver = eeh_pcid_get(dev);
@@ -271,7 +277,7 @@ static void *eeh_report_reset(void *data, void *userdata)
271 enum pci_ers_result rc, *res = userdata; 277 enum pci_ers_result rc, *res = userdata;
272 struct pci_driver *driver; 278 struct pci_driver *driver;
273 279
274 if (!dev || eeh_dev_removed(edev)) 280 if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe))
275 return NULL; 281 return NULL;
276 dev->error_state = pci_channel_io_normal; 282 dev->error_state = pci_channel_io_normal;
277 283
@@ -282,7 +288,8 @@ static void *eeh_report_reset(void *data, void *userdata)
282 288
283 if (!driver->err_handler || 289 if (!driver->err_handler ||
284 !driver->err_handler->slot_reset || 290 !driver->err_handler->slot_reset ||
285 (edev->mode & EEH_DEV_NO_HANDLER)) { 291 (edev->mode & EEH_DEV_NO_HANDLER) ||
292 (!edev->in_error)) {
286 eeh_pcid_put(dev); 293 eeh_pcid_put(dev);
287 return NULL; 294 return NULL;
288 } 295 }
@@ -326,20 +333,23 @@ static void *eeh_report_resume(void *data, void *userdata)
326{ 333{
327 struct eeh_dev *edev = (struct eeh_dev *)data; 334 struct eeh_dev *edev = (struct eeh_dev *)data;
328 struct pci_dev *dev = eeh_dev_to_pci_dev(edev); 335 struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
336 bool was_in_error;
329 struct pci_driver *driver; 337 struct pci_driver *driver;
330 338
331 if (!dev || eeh_dev_removed(edev)) 339 if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe))
332 return NULL; 340 return NULL;
333 dev->error_state = pci_channel_io_normal; 341 dev->error_state = pci_channel_io_normal;
334 342
335 driver = eeh_pcid_get(dev); 343 driver = eeh_pcid_get(dev);
336 if (!driver) return NULL; 344 if (!driver) return NULL;
337 345
346 was_in_error = edev->in_error;
347 edev->in_error = false;
338 eeh_enable_irq(dev); 348 eeh_enable_irq(dev);
339 349
340 if (!driver->err_handler || 350 if (!driver->err_handler ||
341 !driver->err_handler->resume || 351 !driver->err_handler->resume ||
342 (edev->mode & EEH_DEV_NO_HANDLER)) { 352 (edev->mode & EEH_DEV_NO_HANDLER) || !was_in_error) {
343 edev->mode &= ~EEH_DEV_NO_HANDLER; 353 edev->mode &= ~EEH_DEV_NO_HANDLER;
344 eeh_pcid_put(dev); 354 eeh_pcid_put(dev);
345 return NULL; 355 return NULL;
@@ -365,7 +375,7 @@ static void *eeh_report_failure(void *data, void *userdata)
365 struct pci_dev *dev = eeh_dev_to_pci_dev(edev); 375 struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
366 struct pci_driver *driver; 376 struct pci_driver *driver;
367 377
368 if (!dev || eeh_dev_removed(edev)) 378 if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe))
369 return NULL; 379 return NULL;
370 dev->error_state = pci_channel_io_perm_failure; 380 dev->error_state = pci_channel_io_perm_failure;
371 381
@@ -386,12 +396,40 @@ static void *eeh_report_failure(void *data, void *userdata)
386 return NULL; 396 return NULL;
387} 397}
388 398
399static void *eeh_add_virt_device(void *data, void *userdata)
400{
401 struct pci_driver *driver;
402 struct eeh_dev *edev = (struct eeh_dev *)data;
403 struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
404 struct pci_dn *pdn = eeh_dev_to_pdn(edev);
405
406 if (!(edev->physfn)) {
407 pr_warn("%s: EEH dev %04x:%02x:%02x.%01x not for VF\n",
408 __func__, edev->phb->global_number, pdn->busno,
409 PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn));
410 return NULL;
411 }
412
413 driver = eeh_pcid_get(dev);
414 if (driver) {
415 eeh_pcid_put(dev);
416 if (driver->err_handler)
417 return NULL;
418 }
419
420#ifdef CONFIG_PPC_POWERNV
421 pci_iov_add_virtfn(edev->physfn, pdn->vf_index, 0);
422#endif
423 return NULL;
424}
425
389static void *eeh_rmv_device(void *data, void *userdata) 426static void *eeh_rmv_device(void *data, void *userdata)
390{ 427{
391 struct pci_driver *driver; 428 struct pci_driver *driver;
392 struct eeh_dev *edev = (struct eeh_dev *)data; 429 struct eeh_dev *edev = (struct eeh_dev *)data;
393 struct pci_dev *dev = eeh_dev_to_pci_dev(edev); 430 struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
394 int *removed = (int *)userdata; 431 struct eeh_rmv_data *rmv_data = (struct eeh_rmv_data *)userdata;
432 int *removed = rmv_data ? &rmv_data->removed : NULL;
395 433
396 /* 434 /*
397 * Actually, we should remove the PCI bridges as well. 435 * Actually, we should remove the PCI bridges as well.
@@ -416,7 +454,11 @@ static void *eeh_rmv_device(void *data, void *userdata)
416 driver = eeh_pcid_get(dev); 454 driver = eeh_pcid_get(dev);
417 if (driver) { 455 if (driver) {
418 eeh_pcid_put(dev); 456 eeh_pcid_put(dev);
419 if (driver->err_handler && 457 if (removed &&
458 eeh_pe_passed(edev->pe))
459 return NULL;
460 if (removed &&
461 driver->err_handler &&
420 driver->err_handler->error_detected && 462 driver->err_handler->error_detected &&
421 driver->err_handler->slot_reset) 463 driver->err_handler->slot_reset)
422 return NULL; 464 return NULL;
@@ -427,11 +469,29 @@ static void *eeh_rmv_device(void *data, void *userdata)
427 pci_name(dev)); 469 pci_name(dev));
428 edev->bus = dev->bus; 470 edev->bus = dev->bus;
429 edev->mode |= EEH_DEV_DISCONNECTED; 471 edev->mode |= EEH_DEV_DISCONNECTED;
430 (*removed)++; 472 if (removed)
473 (*removed)++;
431 474
432 pci_lock_rescan_remove(); 475 if (edev->physfn) {
433 pci_stop_and_remove_bus_device(dev); 476#ifdef CONFIG_PPC_POWERNV
434 pci_unlock_rescan_remove(); 477 struct pci_dn *pdn = eeh_dev_to_pdn(edev);
478
479 pci_iov_remove_virtfn(edev->physfn, pdn->vf_index, 0);
480 edev->pdev = NULL;
481
482 /*
483 * We have to set the VF PE number to invalid one, which is
484 * required to plug the VF successfully.
485 */
486 pdn->pe_number = IODA_INVALID_PE;
487#endif
488 if (rmv_data)
489 list_add(&edev->rmv_list, &rmv_data->edev_list);
490 } else {
491 pci_lock_rescan_remove();
492 pci_stop_and_remove_bus_device(dev);
493 pci_unlock_rescan_remove();
494 }
435 495
436 return NULL; 496 return NULL;
437} 497}
@@ -545,11 +605,13 @@ int eeh_pe_reset_and_recover(struct eeh_pe *pe)
545 * During the reset, udev might be invoked because those affected 605 * During the reset, udev might be invoked because those affected
546 * PCI devices will be removed and then added. 606 * PCI devices will be removed and then added.
547 */ 607 */
548static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) 608static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus,
609 struct eeh_rmv_data *rmv_data)
549{ 610{
550 struct pci_bus *frozen_bus = eeh_pe_bus_get(pe); 611 struct pci_bus *frozen_bus = eeh_pe_bus_get(pe);
551 struct timeval tstamp; 612 struct timeval tstamp;
552 int cnt, rc, removed = 0; 613 int cnt, rc;
614 struct eeh_dev *edev;
553 615
554 /* pcibios will clear the counter; save the value */ 616 /* pcibios will clear the counter; save the value */
555 cnt = pe->freeze_count; 617 cnt = pe->freeze_count;
@@ -563,12 +625,16 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
563 */ 625 */
564 eeh_pe_state_mark(pe, EEH_PE_KEEP); 626 eeh_pe_state_mark(pe, EEH_PE_KEEP);
565 if (bus) { 627 if (bus) {
566 eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); 628 if (pe->type & EEH_PE_VF) {
567 pci_lock_rescan_remove(); 629 eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL);
568 pcibios_remove_pci_devices(bus); 630 } else {
569 pci_unlock_rescan_remove(); 631 eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
632 pci_lock_rescan_remove();
633 pcibios_remove_pci_devices(bus);
634 pci_unlock_rescan_remove();
635 }
570 } else if (frozen_bus) { 636 } else if (frozen_bus) {
571 eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed); 637 eeh_pe_dev_traverse(pe, eeh_rmv_device, &rmv_data);
572 } 638 }
573 639
574 /* 640 /*
@@ -610,14 +676,22 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
610 * PE. We should disconnect it so the binding can be 676 * PE. We should disconnect it so the binding can be
611 * rebuilt when adding PCI devices. 677 * rebuilt when adding PCI devices.
612 */ 678 */
679 edev = list_first_entry(&pe->edevs, struct eeh_dev, list);
613 eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL); 680 eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL);
614 pcibios_add_pci_devices(bus); 681 if (pe->type & EEH_PE_VF)
615 } else if (frozen_bus && removed) { 682 eeh_add_virt_device(edev, NULL);
683 else
684 pcibios_add_pci_devices(bus);
685 } else if (frozen_bus && rmv_data->removed) {
616 pr_info("EEH: Sleep 5s ahead of partial hotplug\n"); 686 pr_info("EEH: Sleep 5s ahead of partial hotplug\n");
617 ssleep(5); 687 ssleep(5);
618 688
689 edev = list_first_entry(&pe->edevs, struct eeh_dev, list);
619 eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL); 690 eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL);
620 pcibios_add_pci_devices(frozen_bus); 691 if (pe->type & EEH_PE_VF)
692 eeh_add_virt_device(edev, NULL);
693 else
694 pcibios_add_pci_devices(frozen_bus);
621 } 695 }
622 eeh_pe_state_clear(pe, EEH_PE_KEEP); 696 eeh_pe_state_clear(pe, EEH_PE_KEEP);
623 697
@@ -636,8 +710,10 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
636static void eeh_handle_normal_event(struct eeh_pe *pe) 710static void eeh_handle_normal_event(struct eeh_pe *pe)
637{ 711{
638 struct pci_bus *frozen_bus; 712 struct pci_bus *frozen_bus;
713 struct eeh_dev *edev, *tmp;
639 int rc = 0; 714 int rc = 0;
640 enum pci_ers_result result = PCI_ERS_RESULT_NONE; 715 enum pci_ers_result result = PCI_ERS_RESULT_NONE;
716 struct eeh_rmv_data rmv_data = {LIST_HEAD_INIT(rmv_data.edev_list), 0};
641 717
642 frozen_bus = eeh_pe_bus_get(pe); 718 frozen_bus = eeh_pe_bus_get(pe);
643 if (!frozen_bus) { 719 if (!frozen_bus) {
@@ -692,7 +768,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
692 */ 768 */
693 if (result == PCI_ERS_RESULT_NONE) { 769 if (result == PCI_ERS_RESULT_NONE) {
694 pr_info("EEH: Reset with hotplug activity\n"); 770 pr_info("EEH: Reset with hotplug activity\n");
695 rc = eeh_reset_device(pe, frozen_bus); 771 rc = eeh_reset_device(pe, frozen_bus, NULL);
696 if (rc) { 772 if (rc) {
697 pr_warn("%s: Unable to reset, err=%d\n", 773 pr_warn("%s: Unable to reset, err=%d\n",
698 __func__, rc); 774 __func__, rc);
@@ -744,7 +820,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
744 /* If any device called out for a reset, then reset the slot */ 820 /* If any device called out for a reset, then reset the slot */
745 if (result == PCI_ERS_RESULT_NEED_RESET) { 821 if (result == PCI_ERS_RESULT_NEED_RESET) {
746 pr_info("EEH: Reset without hotplug activity\n"); 822 pr_info("EEH: Reset without hotplug activity\n");
747 rc = eeh_reset_device(pe, NULL); 823 rc = eeh_reset_device(pe, NULL, &rmv_data);
748 if (rc) { 824 if (rc) {
749 pr_warn("%s: Cannot reset, err=%d\n", 825 pr_warn("%s: Cannot reset, err=%d\n",
750 __func__, rc); 826 __func__, rc);
@@ -764,6 +840,15 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
764 goto hard_fail; 840 goto hard_fail;
765 } 841 }
766 842
843 /*
844 * For those hot removed VFs, we should add back them after PF get
845 * recovered properly.
846 */
847 list_for_each_entry_safe(edev, tmp, &rmv_data.edev_list, rmv_list) {
848 eeh_add_virt_device(edev, NULL);
849 list_del(&edev->rmv_list);
850 }
851
767 /* Tell all device drivers that they can resume operations */ 852 /* Tell all device drivers that they can resume operations */
768 pr_info("EEH: Notify device driver to resume\n"); 853 pr_info("EEH: Notify device driver to resume\n");
769 eeh_pe_dev_traverse(pe, eeh_report_resume, NULL); 854 eeh_pe_dev_traverse(pe, eeh_report_resume, NULL);
@@ -803,12 +888,17 @@ perm_error:
803 * the their PCI config any more. 888 * the their PCI config any more.
804 */ 889 */
805 if (frozen_bus) { 890 if (frozen_bus) {
806 eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); 891 if (pe->type & EEH_PE_VF) {
807 eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); 892 eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL);
893 eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
894 } else {
895 eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
896 eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
808 897
809 pci_lock_rescan_remove(); 898 pci_lock_rescan_remove();
810 pcibios_remove_pci_devices(frozen_bus); 899 pcibios_remove_pci_devices(frozen_bus);
811 pci_unlock_rescan_remove(); 900 pci_unlock_rescan_remove();
901 }
812 } 902 }
813} 903}
814 904
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index 98f81800e00c..eea48d8baf49 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -299,7 +299,10 @@ static struct eeh_pe *eeh_pe_get_parent(struct eeh_dev *edev)
299 * EEH device already having associated PE, but 299 * EEH device already having associated PE, but
300 * the direct parent EEH device doesn't have yet. 300 * the direct parent EEH device doesn't have yet.
301 */ 301 */
302 pdn = pdn ? pdn->parent : NULL; 302 if (edev->physfn)
303 pdn = pci_get_pdn(edev->physfn);
304 else
305 pdn = pdn ? pdn->parent : NULL;
303 while (pdn) { 306 while (pdn) {
304 /* We're poking out of PCI territory */ 307 /* We're poking out of PCI territory */
305 parent = pdn_to_eeh_dev(pdn); 308 parent = pdn_to_eeh_dev(pdn);
@@ -382,7 +385,10 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
382 } 385 }
383 386
384 /* Create a new EEH PE */ 387 /* Create a new EEH PE */
385 pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE); 388 if (edev->physfn)
389 pe = eeh_pe_alloc(edev->phb, EEH_PE_VF);
390 else
391 pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE);
386 if (!pe) { 392 if (!pe) {
387 pr_err("%s: out of memory!\n", __func__); 393 pr_err("%s: out of memory!\n", __func__);
388 return -ENOMEM; 394 return -ENOMEM;
@@ -920,25 +926,21 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
920 */ 926 */
921struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe) 927struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
922{ 928{
923 struct pci_bus *bus = NULL;
924 struct eeh_dev *edev; 929 struct eeh_dev *edev;
925 struct pci_dev *pdev; 930 struct pci_dev *pdev;
926 931
927 if (pe->type & EEH_PE_PHB) { 932 if (pe->type & EEH_PE_PHB)
928 bus = pe->phb->bus; 933 return pe->phb->bus;
929 } else if (pe->type & EEH_PE_BUS ||
930 pe->type & EEH_PE_DEVICE) {
931 if (pe->state & EEH_PE_PRI_BUS) {
932 bus = pe->bus;
933 goto out;
934 }
935 934
936 edev = list_first_entry(&pe->edevs, struct eeh_dev, list); 935 /* The primary bus might be cached during probe time */
937 pdev = eeh_dev_to_pci_dev(edev); 936 if (pe->state & EEH_PE_PRI_BUS)
938 if (pdev) 937 return pe->bus;
939 bus = pdev->bus;
940 }
941 938
942out: 939 /* Retrieve the parent PCI bus of first (top) PCI device */
943 return bus; 940 edev = list_first_entry_or_null(&pe->edevs, struct eeh_dev, list);
941 pdev = eeh_dev_to_pci_dev(edev);
942 if (pdev)
943 return pdev->bus;
944
945 return NULL;
944} 946}
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 0d525ce3717f..9916d150b28c 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -210,7 +210,29 @@ system_call: /* label this so stack traces look sane */
210 li r11,-MAX_ERRNO 210 li r11,-MAX_ERRNO
211 andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK) 211 andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
212 bne- syscall_exit_work 212 bne- syscall_exit_work
213 cmpld r3,r11 213
214 andi. r0,r8,MSR_FP
215 beq 2f
216#ifdef CONFIG_ALTIVEC
217 andis. r0,r8,MSR_VEC@h
218 bne 3f
219#endif
2202: addi r3,r1,STACK_FRAME_OVERHEAD
221#ifdef CONFIG_PPC_BOOK3S
222 mtmsrd r10,1 /* Restore RI */
223#endif
224 bl restore_math
225#ifdef CONFIG_PPC_BOOK3S
226 ld r10,PACAKMSR(r13)
227 li r9,MSR_RI
228 andc r11,r10,r9 /* Re-clear RI */
229 mtmsrd r11,1
230#endif
231 ld r8,_MSR(r1)
232 ld r3,RESULT(r1)
233 li r11,-MAX_ERRNO
234
2353: cmpld r3,r11
214 ld r5,_CCR(r1) 236 ld r5,_CCR(r1)
215 bge- syscall_error 237 bge- syscall_error
216.Lsyscall_error_cont: 238.Lsyscall_error_cont:
@@ -602,8 +624,8 @@ _GLOBAL(ret_from_except_lite)
602 624
603 /* Check current_thread_info()->flags */ 625 /* Check current_thread_info()->flags */
604 andi. r0,r4,_TIF_USER_WORK_MASK 626 andi. r0,r4,_TIF_USER_WORK_MASK
605#ifdef CONFIG_PPC_BOOK3E
606 bne 1f 627 bne 1f
628#ifdef CONFIG_PPC_BOOK3E
607 /* 629 /*
608 * Check to see if the dbcr0 register is set up to debug. 630 * Check to see if the dbcr0 register is set up to debug.
609 * Use the internal debug mode bit to do this. 631 * Use the internal debug mode bit to do this.
@@ -618,7 +640,9 @@ _GLOBAL(ret_from_except_lite)
618 mtspr SPRN_DBSR,r10 640 mtspr SPRN_DBSR,r10
619 b restore 641 b restore
620#else 642#else
621 beq restore 643 addi r3,r1,STACK_FRAME_OVERHEAD
644 bl restore_math
645 b restore
622#endif 646#endif
6231: andi. r0,r4,_TIF_NEED_RESCHED 6471: andi. r0,r4,_TIF_NEED_RESCHED
624 beq 2f 648 beq 2f
@@ -1143,8 +1167,12 @@ _GLOBAL(enter_prom)
1143#ifdef CONFIG_DYNAMIC_FTRACE 1167#ifdef CONFIG_DYNAMIC_FTRACE
1144_GLOBAL(mcount) 1168_GLOBAL(mcount)
1145_GLOBAL(_mcount) 1169_GLOBAL(_mcount)
1146 blr 1170 mflr r12
1171 mtctr r12
1172 mtlr r0
1173 bctr
1147 1174
1175#ifndef CC_USING_MPROFILE_KERNEL
1148_GLOBAL_TOC(ftrace_caller) 1176_GLOBAL_TOC(ftrace_caller)
1149 /* Taken from output of objdump from lib64/glibc */ 1177 /* Taken from output of objdump from lib64/glibc */
1150 mflr r3 1178 mflr r3
@@ -1166,6 +1194,115 @@ _GLOBAL(ftrace_graph_stub)
1166 ld r0, 128(r1) 1194 ld r0, 128(r1)
1167 mtlr r0 1195 mtlr r0
1168 addi r1, r1, 112 1196 addi r1, r1, 112
1197
1198#else /* CC_USING_MPROFILE_KERNEL */
1199/*
1200 *
1201 * ftrace_caller() is the function that replaces _mcount() when ftrace is
1202 * active.
1203 *
1204 * We arrive here after a function A calls function B, and we are the trace
1205 * function for B. When we enter r1 points to A's stack frame, B has not yet
1206 * had a chance to allocate one yet.
1207 *
1208 * Additionally r2 may point either to the TOC for A, or B, depending on
1209 * whether B did a TOC setup sequence before calling us.
1210 *
1211 * On entry the LR points back to the _mcount() call site, and r0 holds the
1212 * saved LR as it was on entry to B, ie. the original return address at the
1213 * call site in A.
1214 *
1215 * Our job is to save the register state into a struct pt_regs (on the stack)
1216 * and then arrange for the ftrace function to be called.
1217 */
1218_GLOBAL(ftrace_caller)
1219 /* Save the original return address in A's stack frame */
1220 std r0,LRSAVE(r1)
1221
1222 /* Create our stack frame + pt_regs */
1223 stdu r1,-SWITCH_FRAME_SIZE(r1)
1224
1225 /* Save all gprs to pt_regs */
1226 SAVE_8GPRS(0,r1)
1227 SAVE_8GPRS(8,r1)
1228 SAVE_8GPRS(16,r1)
1229 SAVE_8GPRS(24,r1)
1230
1231 /* Load special regs for save below */
1232 mfmsr r8
1233 mfctr r9
1234 mfxer r10
1235 mfcr r11
1236
1237 /* Get the _mcount() call site out of LR */
1238 mflr r7
1239 /* Save it as pt_regs->nip & pt_regs->link */
1240 std r7, _NIP(r1)
1241 std r7, _LINK(r1)
1242
1243 /* Save callee's TOC in the ABI compliant location */
1244 std r2, 24(r1)
1245 ld r2,PACATOC(r13) /* get kernel TOC in r2 */
1246
1247 addis r3,r2,function_trace_op@toc@ha
1248 addi r3,r3,function_trace_op@toc@l
1249 ld r5,0(r3)
1250
1251 /* Calculate ip from nip-4 into r3 for call below */
1252 subi r3, r7, MCOUNT_INSN_SIZE
1253
1254 /* Put the original return address in r4 as parent_ip */
1255 mr r4, r0
1256
1257 /* Save special regs */
1258 std r8, _MSR(r1)
1259 std r9, _CTR(r1)
1260 std r10, _XER(r1)
1261 std r11, _CCR(r1)
1262
1263 /* Load &pt_regs in r6 for call below */
1264 addi r6, r1 ,STACK_FRAME_OVERHEAD
1265
1266 /* ftrace_call(r3, r4, r5, r6) */
1267.globl ftrace_call
1268ftrace_call:
1269 bl ftrace_stub
1270 nop
1271
1272 /* Load ctr with the possibly modified NIP */
1273 ld r3, _NIP(r1)
1274 mtctr r3
1275
1276 /* Restore gprs */
1277 REST_8GPRS(0,r1)
1278 REST_8GPRS(8,r1)
1279 REST_8GPRS(16,r1)
1280 REST_8GPRS(24,r1)
1281
1282 /* Restore callee's TOC */
1283 ld r2, 24(r1)
1284
1285 /* Pop our stack frame */
1286 addi r1, r1, SWITCH_FRAME_SIZE
1287
1288 /* Restore original LR for return to B */
1289 ld r0, LRSAVE(r1)
1290 mtlr r0
1291
1292#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1293 stdu r1, -112(r1)
1294.globl ftrace_graph_call
1295ftrace_graph_call:
1296 b ftrace_graph_stub
1297_GLOBAL(ftrace_graph_stub)
1298 addi r1, r1, 112
1299#endif
1300
1301 ld r0,LRSAVE(r1) /* restore callee's lr at _mcount site */
1302 mtlr r0
1303 bctr /* jump after _mcount site */
1304#endif /* CC_USING_MPROFILE_KERNEL */
1305
1169_GLOBAL(ftrace_stub) 1306_GLOBAL(ftrace_stub)
1170 blr 1307 blr
1171#else 1308#else
@@ -1198,6 +1335,7 @@ _GLOBAL(ftrace_stub)
1198#endif /* CONFIG_DYNAMIC_FTRACE */ 1335#endif /* CONFIG_DYNAMIC_FTRACE */
1199 1336
1200#ifdef CONFIG_FUNCTION_GRAPH_TRACER 1337#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1338#ifndef CC_USING_MPROFILE_KERNEL
1201_GLOBAL(ftrace_graph_caller) 1339_GLOBAL(ftrace_graph_caller)
1202 /* load r4 with local address */ 1340 /* load r4 with local address */
1203 ld r4, 128(r1) 1341 ld r4, 128(r1)
@@ -1222,6 +1360,56 @@ _GLOBAL(ftrace_graph_caller)
1222 addi r1, r1, 112 1360 addi r1, r1, 112
1223 blr 1361 blr
1224 1362
1363#else /* CC_USING_MPROFILE_KERNEL */
1364_GLOBAL(ftrace_graph_caller)
1365 /* with -mprofile-kernel, parameter regs are still alive at _mcount */
1366 std r10, 104(r1)
1367 std r9, 96(r1)
1368 std r8, 88(r1)
1369 std r7, 80(r1)
1370 std r6, 72(r1)
1371 std r5, 64(r1)
1372 std r4, 56(r1)
1373 std r3, 48(r1)
1374
1375 /* Save callee's TOC in the ABI compliant location */
1376 std r2, 24(r1)
1377 ld r2, PACATOC(r13) /* get kernel TOC in r2 */
1378
1379 mfctr r4 /* ftrace_caller has moved local addr here */
1380 std r4, 40(r1)
1381 mflr r3 /* ftrace_caller has restored LR from stack */
1382 subi r4, r4, MCOUNT_INSN_SIZE
1383
1384 bl prepare_ftrace_return
1385 nop
1386
1387 /*
1388 * prepare_ftrace_return gives us the address we divert to.
1389 * Change the LR to this.
1390 */
1391 mtlr r3
1392
1393 ld r0, 40(r1)
1394 mtctr r0
1395 ld r10, 104(r1)
1396 ld r9, 96(r1)
1397 ld r8, 88(r1)
1398 ld r7, 80(r1)
1399 ld r6, 72(r1)
1400 ld r5, 64(r1)
1401 ld r4, 56(r1)
1402 ld r3, 48(r1)
1403
1404 /* Restore callee's TOC */
1405 ld r2, 24(r1)
1406
1407 addi r1, r1, 112
1408 mflr r0
1409 std r0, LRSAVE(r1)
1410 bctr
1411#endif /* CC_USING_MPROFILE_KERNEL */
1412
1225_GLOBAL(return_to_handler) 1413_GLOBAL(return_to_handler)
1226 /* need to save return values */ 1414 /* need to save return values */
1227 std r4, -32(r1) 1415 std r4, -32(r1)
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
index 2117eaca3d28..15da2b5df85e 100644
--- a/arch/powerpc/kernel/fpu.S
+++ b/arch/powerpc/kernel/fpu.S
@@ -130,6 +130,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
130 or r12,r12,r4 130 or r12,r12,r4
131 std r12,_MSR(r1) 131 std r12,_MSR(r1)
132#endif 132#endif
133 /* Don't care if r4 overflows, this is desired behaviour */
134 lbz r4,THREAD_LOAD_FP(r5)
135 addi r4,r4,1
136 stb r4,THREAD_LOAD_FP(r5)
133 addi r10,r5,THREAD_FPSTATE 137 addi r10,r5,THREAD_FPSTATE
134 lfd fr0,FPSTATE_FPSCR(r10) 138 lfd fr0,FPSTATE_FPSCR(r10)
135 MTFSF_L(fr0) 139 MTFSF_L(fr0)
@@ -139,33 +143,20 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
139 blr 143 blr
140 144
141/* 145/*
142 * __giveup_fpu(tsk) 146 * save_fpu(tsk)
143 * Disable FP for the task given as the argument, 147 * Save the floating-point registers in its thread_struct.
144 * and save the floating-point registers in its thread_struct.
145 * Enables the FPU for use in the kernel on return. 148 * Enables the FPU for use in the kernel on return.
146 */ 149 */
147_GLOBAL(__giveup_fpu) 150_GLOBAL(save_fpu)
148 addi r3,r3,THREAD /* want THREAD of task */ 151 addi r3,r3,THREAD /* want THREAD of task */
149 PPC_LL r6,THREAD_FPSAVEAREA(r3) 152 PPC_LL r6,THREAD_FPSAVEAREA(r3)
150 PPC_LL r5,PT_REGS(r3) 153 PPC_LL r5,PT_REGS(r3)
151 PPC_LCMPI 0,r6,0 154 PPC_LCMPI 0,r6,0
152 bne 2f 155 bne 2f
153 addi r6,r3,THREAD_FPSTATE 156 addi r6,r3,THREAD_FPSTATE
1542: PPC_LCMPI 0,r5,0 1572: SAVE_32FPVSRS(0, R4, R6)
155 SAVE_32FPVSRS(0, R4, R6)
156 mffs fr0 158 mffs fr0
157 stfd fr0,FPSTATE_FPSCR(r6) 159 stfd fr0,FPSTATE_FPSCR(r6)
158 beq 1f
159 PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
160 li r3,MSR_FP|MSR_FE0|MSR_FE1
161#ifdef CONFIG_VSX
162BEGIN_FTR_SECTION
163 oris r3,r3,MSR_VSX@h
164END_FTR_SECTION_IFSET(CPU_FTR_VSX)
165#endif
166 andc r4,r4,r3 /* disable FP for previous task */
167 PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1681:
169 blr 160 blr
170 161
171/* 162/*
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index 44d4d8eb3c85..9dac18dabd03 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -61,8 +61,11 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
61 return -EFAULT; 61 return -EFAULT;
62 62
63 /* Make sure it is what we expect it to be */ 63 /* Make sure it is what we expect it to be */
64 if (replaced != old) 64 if (replaced != old) {
65 pr_err("%p: replaced (%#x) != old (%#x)",
66 (void *)ip, replaced, old);
65 return -EINVAL; 67 return -EINVAL;
68 }
66 69
67 /* replace the text with the new text */ 70 /* replace the text with the new text */
68 if (patch_instruction((unsigned int *)ip, new)) 71 if (patch_instruction((unsigned int *)ip, new))
@@ -106,14 +109,15 @@ static int
106__ftrace_make_nop(struct module *mod, 109__ftrace_make_nop(struct module *mod,
107 struct dyn_ftrace *rec, unsigned long addr) 110 struct dyn_ftrace *rec, unsigned long addr)
108{ 111{
109 unsigned int op; 112 unsigned long entry, ptr, tramp;
110 unsigned long entry, ptr;
111 unsigned long ip = rec->ip; 113 unsigned long ip = rec->ip;
112 void *tramp; 114 unsigned int op, pop;
113 115
114 /* read where this goes */ 116 /* read where this goes */
115 if (probe_kernel_read(&op, (void *)ip, sizeof(int))) 117 if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
118 pr_err("Fetching opcode failed.\n");
116 return -EFAULT; 119 return -EFAULT;
120 }
117 121
118 /* Make sure that that this is still a 24bit jump */ 122 /* Make sure that that this is still a 24bit jump */
119 if (!is_bl_op(op)) { 123 if (!is_bl_op(op)) {
@@ -122,14 +126,9 @@ __ftrace_make_nop(struct module *mod,
122 } 126 }
123 127
124 /* lets find where the pointer goes */ 128 /* lets find where the pointer goes */
125 tramp = (void *)find_bl_target(ip, op); 129 tramp = find_bl_target(ip, op);
126
127 pr_devel("ip:%lx jumps to %p", ip, tramp);
128 130
129 if (!is_module_trampoline(tramp)) { 131 pr_devel("ip:%lx jumps to %lx", ip, tramp);
130 pr_err("Not a trampoline\n");
131 return -EINVAL;
132 }
133 132
134 if (module_trampoline_target(mod, tramp, &ptr)) { 133 if (module_trampoline_target(mod, tramp, &ptr)) {
135 pr_err("Failed to get trampoline target\n"); 134 pr_err("Failed to get trampoline target\n");
@@ -158,10 +157,42 @@ __ftrace_make_nop(struct module *mod,
158 * 157 *
159 * Use a b +8 to jump over the load. 158 * Use a b +8 to jump over the load.
160 */ 159 */
161 op = 0x48000008; /* b +8 */
162 160
163 if (patch_instruction((unsigned int *)ip, op)) 161 pop = PPC_INST_BRANCH | 8; /* b +8 */
162
163 /*
164 * Check what is in the next instruction. We can see ld r2,40(r1), but
165 * on first pass after boot we will see mflr r0.
166 */
167 if (probe_kernel_read(&op, (void *)(ip+4), MCOUNT_INSN_SIZE)) {
168 pr_err("Fetching op failed.\n");
169 return -EFAULT;
170 }
171
172 if (op != PPC_INST_LD_TOC) {
173 unsigned int inst;
174
175 if (probe_kernel_read(&inst, (void *)(ip - 4), 4)) {
176 pr_err("Fetching instruction at %lx failed.\n", ip - 4);
177 return -EFAULT;
178 }
179
180 /* We expect either a mlfr r0, or a std r0, LRSAVE(r1) */
181 if (inst != PPC_INST_MFLR && inst != PPC_INST_STD_LR) {
182 pr_err("Unexpected instructions around bl _mcount\n"
183 "when enabling dynamic ftrace!\t"
184 "(%08x,bl,%08x)\n", inst, op);
185 return -EINVAL;
186 }
187
188 /* When using -mkernel_profile there is no load to jump over */
189 pop = PPC_INST_NOP;
190 }
191
192 if (patch_instruction((unsigned int *)ip, pop)) {
193 pr_err("Patching NOP failed.\n");
164 return -EPERM; 194 return -EPERM;
195 }
165 196
166 return 0; 197 return 0;
167} 198}
@@ -287,16 +318,15 @@ int ftrace_make_nop(struct module *mod,
287 318
288#ifdef CONFIG_MODULES 319#ifdef CONFIG_MODULES
289#ifdef CONFIG_PPC64 320#ifdef CONFIG_PPC64
321/*
322 * Examine the existing instructions for __ftrace_make_call.
323 * They should effectively be a NOP, and follow formal constraints,
324 * depending on the ABI. Return false if they don't.
325 */
326#ifndef CC_USING_MPROFILE_KERNEL
290static int 327static int
291__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) 328expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
292{ 329{
293 unsigned int op[2];
294 void *ip = (void *)rec->ip;
295
296 /* read where this goes */
297 if (probe_kernel_read(op, ip, sizeof(op)))
298 return -EFAULT;
299
300 /* 330 /*
301 * We expect to see: 331 * We expect to see:
302 * 332 *
@@ -306,8 +336,34 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
306 * The load offset is different depending on the ABI. For simplicity 336 * The load offset is different depending on the ABI. For simplicity
307 * just mask it out when doing the compare. 337 * just mask it out when doing the compare.
308 */ 338 */
309 if ((op[0] != 0x48000008) || ((op[1] & 0xffff0000) != 0xe8410000)) { 339 if ((op0 != 0x48000008) || ((op1 & 0xffff0000) != 0xe8410000))
310 pr_err("Unexpected call sequence: %x %x\n", op[0], op[1]); 340 return 0;
341 return 1;
342}
343#else
344static int
345expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
346{
347 /* look for patched "NOP" on ppc64 with -mprofile-kernel */
348 if (op0 != PPC_INST_NOP)
349 return 0;
350 return 1;
351}
352#endif
353
354static int
355__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
356{
357 unsigned int op[2];
358 void *ip = (void *)rec->ip;
359
360 /* read where this goes */
361 if (probe_kernel_read(op, ip, sizeof(op)))
362 return -EFAULT;
363
364 if (!expected_nop_sequence(ip, op[0], op[1])) {
365 pr_err("Unexpected call sequence at %p: %x %x\n",
366 ip, op[0], op[1]);
311 return -EINVAL; 367 return -EINVAL;
312 } 368 }
313 369
@@ -330,7 +386,16 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
330 386
331 return 0; 387 return 0;
332} 388}
333#else 389
390#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
391int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
392 unsigned long addr)
393{
394 return ftrace_make_call(rec, addr);
395}
396#endif
397
398#else /* !CONFIG_PPC64: */
334static int 399static int
335__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) 400__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
336{ 401{
@@ -455,20 +520,13 @@ void ftrace_replace_code(int enable)
455 } 520 }
456} 521}
457 522
523/*
524 * Use the default ftrace_modify_all_code, but without
525 * stop_machine().
526 */
458void arch_ftrace_update_code(int command) 527void arch_ftrace_update_code(int command)
459{ 528{
460 if (command & FTRACE_UPDATE_CALLS) 529 ftrace_modify_all_code(command);
461 ftrace_replace_code(1);
462 else if (command & FTRACE_DISABLE_CALLS)
463 ftrace_replace_code(0);
464
465 if (command & FTRACE_UPDATE_TRACE_FUNC)
466 ftrace_update_ftrace_func(ftrace_trace_function);
467
468 if (command & FTRACE_START_FUNC_RET)
469 ftrace_enable_ftrace_graph_caller();
470 else if (command & FTRACE_STOP_FUNC_RET)
471 ftrace_disable_ftrace_graph_caller();
472} 530}
473 531
474int __init ftrace_dyn_arch_init(void) 532int __init ftrace_dyn_arch_init(void)
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index b5061abbd2e0..9cdf5c71e426 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -806,7 +806,7 @@ _GLOBAL(set_context)
806_GLOBAL(init_cpu_state) 806_GLOBAL(init_cpu_state)
807 mflr r22 807 mflr r22
808#ifdef CONFIG_PPC_47x 808#ifdef CONFIG_PPC_47x
809 /* We use the PVR to differenciate 44x cores from 476 */ 809 /* We use the PVR to differentiate 44x cores from 476 */
810 mfspr r3,SPRN_PVR 810 mfspr r3,SPRN_PVR
811 srwi r3,r3,16 811 srwi r3,r3,16
812 cmplwi cr0,r3,PVR_476FPE@h 812 cmplwi cr0,r3,PVR_476FPE@h
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 1b779560728f..4286775cbde9 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -40,6 +40,8 @@
40#include <asm/kvm_book3s_asm.h> 40#include <asm/kvm_book3s_asm.h>
41#include <asm/ptrace.h> 41#include <asm/ptrace.h>
42#include <asm/hw_irq.h> 42#include <asm/hw_irq.h>
43#include <asm/cputhreads.h>
44#include <asm/ppc-opcode.h>
43 45
44/* The physical memory is laid out such that the secondary processor 46/* The physical memory is laid out such that the secondary processor
45 * spin code sits at 0x0000...0x00ff. On server, the vectors follow 47 * spin code sits at 0x0000...0x00ff. On server, the vectors follow
@@ -181,6 +183,64 @@ exception_marker:
181#endif 183#endif
182 184
183#ifdef CONFIG_PPC_BOOK3E 185#ifdef CONFIG_PPC_BOOK3E
186/*
187 * The booting_thread_hwid holds the thread id we want to boot in cpu
188 * hotplug case. It is set by cpu hotplug code, and is invalid by default.
189 * The thread id is the same as the initial value of SPRN_PIR[THREAD_ID]
190 * bit field.
191 */
192 .globl booting_thread_hwid
193booting_thread_hwid:
194 .long INVALID_THREAD_HWID
195 .align 3
196/*
197 * start a thread in the same core
198 * input parameters:
199 * r3 = the thread physical id
200 * r4 = the entry point where thread starts
201 */
202_GLOBAL(book3e_start_thread)
203 LOAD_REG_IMMEDIATE(r5, MSR_KERNEL)
204 cmpi 0, r3, 0
205 beq 10f
206 cmpi 0, r3, 1
207 beq 11f
208 /* If the thread id is invalid, just exit. */
209 b 13f
21010:
211 MTTMR(TMRN_IMSR0, 5)
212 MTTMR(TMRN_INIA0, 4)
213 b 12f
21411:
215 MTTMR(TMRN_IMSR1, 5)
216 MTTMR(TMRN_INIA1, 4)
21712:
218 isync
219 li r6, 1
220 sld r6, r6, r3
221 mtspr SPRN_TENS, r6
22213:
223 blr
224
225/*
226 * stop a thread in the same core
227 * input parameter:
228 * r3 = the thread physical id
229 */
230_GLOBAL(book3e_stop_thread)
231 cmpi 0, r3, 0
232 beq 10f
233 cmpi 0, r3, 1
234 beq 10f
235 /* If the thread id is invalid, just exit. */
236 b 13f
23710:
238 li r4, 1
239 sld r4, r4, r3
240 mtspr SPRN_TENC, r4
24113:
242 blr
243
184_GLOBAL(fsl_secondary_thread_init) 244_GLOBAL(fsl_secondary_thread_init)
185 mfspr r4,SPRN_BUCSR 245 mfspr r4,SPRN_BUCSR
186 246
@@ -261,6 +321,44 @@ _GLOBAL(generic_secondary_smp_init)
261 mr r3,r24 321 mr r3,r24
262 mr r4,r25 322 mr r4,r25
263 bl book3e_secondary_core_init 323 bl book3e_secondary_core_init
324
325/*
326 * After common core init has finished, check if the current thread is the
327 * one we wanted to boot. If not, start the specified thread and stop the
328 * current thread.
329 */
330 LOAD_REG_ADDR(r4, booting_thread_hwid)
331 lwz r3, 0(r4)
332 li r5, INVALID_THREAD_HWID
333 cmpw r3, r5
334 beq 20f
335
336 /*
337 * The value of booting_thread_hwid has been stored in r3,
338 * so make it invalid.
339 */
340 stw r5, 0(r4)
341
342 /*
343 * Get the current thread id and check if it is the one we wanted.
344 * If not, start the one specified in booting_thread_hwid and stop
345 * the current thread.
346 */
347 mfspr r8, SPRN_TIR
348 cmpw r3, r8
349 beq 20f
350
351 /* start the specified thread */
352 LOAD_REG_ADDR(r5, fsl_secondary_thread_init)
353 ld r4, 0(r5)
354 bl book3e_start_thread
355
356 /* stop the current thread */
357 mr r3, r8
358 bl book3e_stop_thread
35910:
360 b 10b
36120:
264#endif 362#endif
265 363
266generic_secondary_common_init: 364generic_secondary_common_init:
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 78c1eba4c04a..80c69472314e 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -329,7 +329,7 @@ InstructionTLBMiss:
329 /* If we are faulting a kernel address, we have to use the 329 /* If we are faulting a kernel address, we have to use the
330 * kernel page tables. 330 * kernel page tables.
331 */ 331 */
332#ifdef CONFIG_MODULES 332#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC)
333 /* Only modules will cause ITLB Misses as we always 333 /* Only modules will cause ITLB Misses as we always
334 * pin the first 8MB of kernel memory */ 334 * pin the first 8MB of kernel memory */
335 mfspr r11, SPRN_SRR0 /* Get effective address of fault */ 335 mfspr r11, SPRN_SRR0 /* Get effective address of fault */
@@ -385,27 +385,26 @@ InstructionTLBMiss:
385 385
386 . = 0x1200 386 . = 0x1200
387DataStoreTLBMiss: 387DataStoreTLBMiss:
388#ifdef CONFIG_8xx_CPU6
389 mtspr SPRN_SPRG_SCRATCH2, r3 388 mtspr SPRN_SPRG_SCRATCH2, r3
390#endif
391 EXCEPTION_PROLOG_0 389 EXCEPTION_PROLOG_0
392 mfcr r10 390 mfcr r3
393 391
394 /* If we are faulting a kernel address, we have to use the 392 /* If we are faulting a kernel address, we have to use the
395 * kernel page tables. 393 * kernel page tables.
396 */ 394 */
397 mfspr r11, SPRN_MD_EPN 395 mfspr r10, SPRN_MD_EPN
398 IS_KERNEL(r11, r11) 396 IS_KERNEL(r11, r10)
399 mfspr r11, SPRN_M_TW /* Get level 1 table */ 397 mfspr r11, SPRN_M_TW /* Get level 1 table */
400 BRANCH_UNLESS_KERNEL(3f) 398 BRANCH_UNLESS_KERNEL(3f)
401 lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha 399 lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
4023: 4003:
403 mtcr r10
404 mfspr r10, SPRN_MD_EPN
405 401
406 /* Insert level 1 index */ 402 /* Insert level 1 index */
407 rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 403 rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
408 lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */ 404 lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */
405 mtcr r11
406 bt- 28,DTLBMiss8M /* bit 28 = Large page (8M) */
407 mtcr r3
409 408
410 /* We have a pte table, so load fetch the pte from the table. 409 /* We have a pte table, so load fetch the pte from the table.
411 */ 410 */
@@ -453,13 +452,34 @@ DataStoreTLBMiss:
453 MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */ 452 MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */
454 453
455 /* Restore registers */ 454 /* Restore registers */
456#ifdef CONFIG_8xx_CPU6
457 mfspr r3, SPRN_SPRG_SCRATCH2 455 mfspr r3, SPRN_SPRG_SCRATCH2
456 mtspr SPRN_DAR, r11 /* Tag DAR */
457 EXCEPTION_EPILOG_0
458 rfi
459
460DTLBMiss8M:
461 mtcr r3
462 ori r11, r11, MD_SVALID
463 MTSPR_CPU6(SPRN_MD_TWC, r11, r3)
464#ifdef CONFIG_PPC_16K_PAGES
465 /*
466 * In 16k pages mode, each PGD entry defines a 64M block.
467 * Here we select the 8M page within the block.
468 */
469 rlwimi r11, r10, 0, 0x03800000
458#endif 470#endif
471 rlwinm r10, r11, 0, 0xff800000
472 ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \
473 _PAGE_PRESENT
474 MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */
475
476 li r11, RPN_PATTERN
477 mfspr r3, SPRN_SPRG_SCRATCH2
459 mtspr SPRN_DAR, r11 /* Tag DAR */ 478 mtspr SPRN_DAR, r11 /* Tag DAR */
460 EXCEPTION_EPILOG_0 479 EXCEPTION_EPILOG_0
461 rfi 480 rfi
462 481
482
463/* This is an instruction TLB error on the MPC8xx. This could be due 483/* This is an instruction TLB error on the MPC8xx. This could be due
464 * to many reasons, such as executing guarded memory or illegal instruction 484 * to many reasons, such as executing guarded memory or illegal instruction
465 * addresses. There is nothing to do but handle a big time error fault. 485 * addresses. There is nothing to do but handle a big time error fault.
@@ -537,13 +557,15 @@ FixupDAR:/* Entry point for dcbx workaround. */
537 /* Insert level 1 index */ 557 /* Insert level 1 index */
5383: rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 5583: rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
539 lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */ 559 lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */
560 mtcr r11
561 bt 28,200f /* bit 28 = Large page (8M) */
540 rlwinm r11, r11,0,0,19 /* Extract page descriptor page address */ 562 rlwinm r11, r11,0,0,19 /* Extract page descriptor page address */
541 /* Insert level 2 index */ 563 /* Insert level 2 index */
542 rlwimi r11, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29 564 rlwimi r11, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
543 lwz r11, 0(r11) /* Get the pte */ 565 lwz r11, 0(r11) /* Get the pte */
544 /* concat physical page address(r11) and page offset(r10) */ 566 /* concat physical page address(r11) and page offset(r10) */
545 rlwimi r11, r10, 0, 32 - PAGE_SHIFT, 31 567 rlwimi r11, r10, 0, 32 - PAGE_SHIFT, 31
546 lwz r11,0(r11) 568201: lwz r11,0(r11)
547/* Check if it really is a dcbx instruction. */ 569/* Check if it really is a dcbx instruction. */
548/* dcbt and dcbtst does not generate DTLB Misses/Errors, 570/* dcbt and dcbtst does not generate DTLB Misses/Errors,
549 * no need to include them here */ 571 * no need to include them here */
@@ -562,6 +584,10 @@ FixupDAR:/* Entry point for dcbx workaround. */
562141: mfspr r10,SPRN_SPRG_SCRATCH2 584141: mfspr r10,SPRN_SPRG_SCRATCH2
563 b DARFixed /* Nope, go back to normal TLB processing */ 585 b DARFixed /* Nope, go back to normal TLB processing */
564 586
587 /* concat physical page address(r11) and page offset(r10) */
588200: rlwimi r11, r10, 0, 32 - (PAGE_SHIFT << 1), 31
589 b 201b
590
565144: mfspr r10, SPRN_DSISR 591144: mfspr r10, SPRN_DSISR
566 rlwinm r10, r10,0,7,5 /* Clear store bit for buggy dcbst insn */ 592 rlwinm r10, r10,0,7,5 /* Clear store bit for buggy dcbst insn */
567 mtspr SPRN_DSISR, r10 593 mtspr SPRN_DSISR, r10
@@ -857,68 +883,6 @@ initial_mmu:
857 883
858 884
859/* 885/*
860 * Set up to use a given MMU context.
861 * r3 is context number, r4 is PGD pointer.
862 *
863 * We place the physical address of the new task page directory loaded
864 * into the MMU base register, and set the ASID compare register with
865 * the new "context."
866 */
867_GLOBAL(set_context)
868
869#ifdef CONFIG_BDI_SWITCH
870 /* Context switch the PTE pointer for the Abatron BDI2000.
871 * The PGDIR is passed as second argument.
872 */
873 lis r5, KERNELBASE@h
874 lwz r5, 0xf0(r5)
875 stw r4, 0x4(r5)
876#endif
877
878 /* Register M_TW will contain base address of level 1 table minus the
879 * lower part of the kernel PGDIR base address, so that all accesses to
880 * level 1 table are done relative to lower part of kernel PGDIR base
881 * address.
882 */
883 li r5, (swapper_pg_dir-PAGE_OFFSET)@l
884 sub r4, r4, r5
885 tophys (r4, r4)
886#ifdef CONFIG_8xx_CPU6
887 lis r6, cpu6_errata_word@h
888 ori r6, r6, cpu6_errata_word@l
889 li r7, 0x3f80
890 stw r7, 12(r6)
891 lwz r7, 12(r6)
892#endif
893 mtspr SPRN_M_TW, r4 /* Update pointeur to level 1 table */
894#ifdef CONFIG_8xx_CPU6
895 li r7, 0x3380
896 stw r7, 12(r6)
897 lwz r7, 12(r6)
898#endif
899 mtspr SPRN_M_CASID, r3 /* Update context */
900 SYNC
901 blr
902
903#ifdef CONFIG_8xx_CPU6
904/* It's here because it is unique to the 8xx.
905 * It is important we get called with interrupts disabled. I used to
906 * do that, but it appears that all code that calls this already had
907 * interrupt disabled.
908 */
909 .globl set_dec_cpu6
910set_dec_cpu6:
911 lis r7, cpu6_errata_word@h
912 ori r7, r7, cpu6_errata_word@l
913 li r4, 0x2c00
914 stw r4, 8(r7)
915 lwz r4, 8(r7)
916 mtspr 22, r3 /* Update Decrementer */
917 SYNC
918 blr
919#endif
920
921/*
922 * We put a few things here that have to be page-aligned. 886 * We put a few things here that have to be page-aligned.
923 * This stuff goes at the beginning of the data segment, 887 * This stuff goes at the beginning of the data segment,
924 * which is page-aligned. 888 * which is page-aligned.
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index f705171b924b..3bfa3150911f 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -1037,80 +1037,6 @@ _GLOBAL(set_context)
1037 isync /* Force context change */ 1037 isync /* Force context change */
1038 blr 1038 blr
1039 1039
1040_GLOBAL(flush_dcache_L1)
1041 mfspr r3,SPRN_L1CFG0
1042
1043 rlwinm r5,r3,9,3 /* Extract cache block size */
1044 twlgti r5,1 /* Only 32 and 64 byte cache blocks
1045 * are currently defined.
1046 */
1047 li r4,32
1048 subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) -
1049 * log2(number of ways)
1050 */
1051 slw r5,r4,r5 /* r5 = cache block size */
1052
1053 rlwinm r7,r3,0,0xff /* Extract number of KiB in the cache */
1054 mulli r7,r7,13 /* An 8-way cache will require 13
1055 * loads per set.
1056 */
1057 slw r7,r7,r6
1058
1059 /* save off HID0 and set DCFA */
1060 mfspr r8,SPRN_HID0
1061 ori r9,r8,HID0_DCFA@l
1062 mtspr SPRN_HID0,r9
1063 isync
1064
1065 lis r4,KERNELBASE@h
1066 mtctr r7
1067
10681: lwz r3,0(r4) /* Load... */
1069 add r4,r4,r5
1070 bdnz 1b
1071
1072 msync
1073 lis r4,KERNELBASE@h
1074 mtctr r7
1075
10761: dcbf 0,r4 /* ...and flush. */
1077 add r4,r4,r5
1078 bdnz 1b
1079
1080 /* restore HID0 */
1081 mtspr SPRN_HID0,r8
1082 isync
1083
1084 blr
1085
1086/* Flush L1 d-cache, invalidate and disable d-cache and i-cache */
1087_GLOBAL(__flush_disable_L1)
1088 mflr r10
1089 bl flush_dcache_L1 /* Flush L1 d-cache */
1090 mtlr r10
1091
1092 mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */
1093 li r5, 2
1094 rlwimi r4, r5, 0, 3
1095
1096 msync
1097 isync
1098 mtspr SPRN_L1CSR0, r4
1099 isync
1100
11011: mfspr r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */
1102 andi. r4, r4, 2
1103 bne 1b
1104
1105 mfspr r4, SPRN_L1CSR1 /* Invalidate and disable i-cache */
1106 li r5, 2
1107 rlwimi r4, r5, 0, 3
1108
1109 mtspr SPRN_L1CSR1, r4
1110 isync
1111
1112 blr
1113
1114#ifdef CONFIG_SMP 1040#ifdef CONFIG_SMP
1115/* When we get here, r24 needs to hold the CPU # */ 1041/* When we get here, r24 needs to hold the CPU # */
1116 .globl __secondary_start 1042 .globl __secondary_start
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S
index cf4fb5429cf1..470ceebd2d23 100644
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -19,7 +19,7 @@
19#include <asm/kvm_book3s_asm.h> 19#include <asm/kvm_book3s_asm.h>
20#include <asm/opal.h> 20#include <asm/opal.h>
21#include <asm/cpuidle.h> 21#include <asm/cpuidle.h>
22#include <asm/mmu-hash64.h> 22#include <asm/book3s/64/mmu-hash.h>
23 23
24#undef DEBUG 24#undef DEBUG
25 25
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index e77c3ccf8dcf..dbf098121ce6 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -445,7 +445,11 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
445 * Global data 445 * Global data
446 */ 446 */
447struct kgdb_arch arch_kgdb_ops = { 447struct kgdb_arch arch_kgdb_ops = {
448#ifdef __LITTLE_ENDIAN__
449 .gdb_bpt_instr = {0x08, 0x10, 0x82, 0x7d},
450#else
448 .gdb_bpt_instr = {0x7d, 0x82, 0x10, 0x08}, 451 .gdb_bpt_instr = {0x7d, 0x82, 0x10, 0x08},
452#endif
449}; 453};
450 454
451static int kgdb_not_implemented(struct pt_regs *regs) 455static int kgdb_not_implemented(struct pt_regs *regs)
diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c
index 2c647b1e62e4..ee62b197502d 100644
--- a/arch/powerpc/kernel/mce_power.c
+++ b/arch/powerpc/kernel/mce_power.c
@@ -54,8 +54,8 @@ static void flush_tlb_206(unsigned int num_sets, unsigned int action)
54} 54}
55 55
56/* 56/*
57 * Generic routine to flush TLB on power7. This routine is used as 57 * Generic routines to flush TLB on POWER processors. These routines
58 * flush_tlb hook in cpu_spec for Power7 processor. 58 * are used as flush_tlb hook in the cpu_spec.
59 * 59 *
60 * action => TLB_INVAL_SCOPE_GLOBAL: Invalidate all TLBs. 60 * action => TLB_INVAL_SCOPE_GLOBAL: Invalidate all TLBs.
61 * TLB_INVAL_SCOPE_LPID: Invalidate TLB for current LPID. 61 * TLB_INVAL_SCOPE_LPID: Invalidate TLB for current LPID.
@@ -65,18 +65,17 @@ void __flush_tlb_power7(unsigned int action)
65 flush_tlb_206(POWER7_TLB_SETS, action); 65 flush_tlb_206(POWER7_TLB_SETS, action);
66} 66}
67 67
68/*
69 * Generic routine to flush TLB on power8. This routine is used as
70 * flush_tlb hook in cpu_spec for power8 processor.
71 *
72 * action => TLB_INVAL_SCOPE_GLOBAL: Invalidate all TLBs.
73 * TLB_INVAL_SCOPE_LPID: Invalidate TLB for current LPID.
74 */
75void __flush_tlb_power8(unsigned int action) 68void __flush_tlb_power8(unsigned int action)
76{ 69{
77 flush_tlb_206(POWER8_TLB_SETS, action); 70 flush_tlb_206(POWER8_TLB_SETS, action);
78} 71}
79 72
73void __flush_tlb_power9(unsigned int action)
74{
75 flush_tlb_206(POWER9_TLB_SETS_HASH, action);
76}
77
78
80/* flush SLBs and reload */ 79/* flush SLBs and reload */
81static void flush_and_reload_slb(void) 80static void flush_and_reload_slb(void)
82{ 81{
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index be8edd67f05b..bf5160fbf9d8 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -91,17 +91,16 @@ _GLOBAL(mulhdu)
91 addc r7,r0,r7 91 addc r7,r0,r7
92 addze r4,r4 92 addze r4,r4
931: beqlr cr1 /* all done if high part of A is 0 */ 931: beqlr cr1 /* all done if high part of A is 0 */
94 mr r10,r3
95 mullw r9,r3,r5 94 mullw r9,r3,r5
96 mulhwu r3,r3,r5 95 mulhwu r10,r3,r5
97 beq 2f 96 beq 2f
98 mullw r0,r10,r6 97 mullw r0,r3,r6
99 mulhwu r8,r10,r6 98 mulhwu r8,r3,r6
100 addc r7,r0,r7 99 addc r7,r0,r7
101 adde r4,r4,r8 100 adde r4,r4,r8
102 addze r3,r3 101 addze r10,r10
1032: addc r4,r4,r9 1022: addc r4,r4,r9
104 addze r3,r3 103 addze r3,r10
105 blr 104 blr
106 105
107/* 106/*
@@ -296,12 +295,9 @@ _GLOBAL(real_writeb)
296 * Flush instruction cache. 295 * Flush instruction cache.
297 * This is a no-op on the 601. 296 * This is a no-op on the 601.
298 */ 297 */
298#ifndef CONFIG_PPC_8xx
299_GLOBAL(flush_instruction_cache) 299_GLOBAL(flush_instruction_cache)
300#if defined(CONFIG_8xx) 300#if defined(CONFIG_4xx)
301 isync
302 lis r5, IDC_INVALL@h
303 mtspr SPRN_IC_CST, r5
304#elif defined(CONFIG_4xx)
305#ifdef CONFIG_403GCX 301#ifdef CONFIG_403GCX
306 li r3, 512 302 li r3, 512
307 mtctr r3 303 mtctr r3
@@ -334,9 +330,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE)
334 mfspr r3,SPRN_HID0 330 mfspr r3,SPRN_HID0
335 ori r3,r3,HID0_ICFI 331 ori r3,r3,HID0_ICFI
336 mtspr SPRN_HID0,r3 332 mtspr SPRN_HID0,r3
337#endif /* CONFIG_8xx/4xx */ 333#endif /* CONFIG_4xx */
338 isync 334 isync
339 blr 335 blr
336#endif /* CONFIG_PPC_8xx */
340 337
341/* 338/*
342 * Write any modified data cache blocks out to memory 339 * Write any modified data cache blocks out to memory
@@ -350,10 +347,9 @@ BEGIN_FTR_SECTION
350 PURGE_PREFETCHED_INS 347 PURGE_PREFETCHED_INS
351 blr /* for 601, do nothing */ 348 blr /* for 601, do nothing */
352END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) 349END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
353 li r5,L1_CACHE_BYTES-1 350 rlwinm r3,r3,0,0,31 - L1_CACHE_SHIFT
354 andc r3,r3,r5
355 subf r4,r3,r4 351 subf r4,r3,r4
356 add r4,r4,r5 352 addi r4,r4,L1_CACHE_BYTES - 1
357 srwi. r4,r4,L1_CACHE_SHIFT 353 srwi. r4,r4,L1_CACHE_SHIFT
358 beqlr 354 beqlr
359 mtctr r4 355 mtctr r4
@@ -377,71 +373,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
377 isync 373 isync
378 blr 374 blr
379/* 375/*
380 * Write any modified data cache blocks out to memory.
381 * Does not invalidate the corresponding cache lines (especially for
382 * any corresponding instruction cache).
383 *
384 * clean_dcache_range(unsigned long start, unsigned long stop)
385 */
386_GLOBAL(clean_dcache_range)
387 li r5,L1_CACHE_BYTES-1
388 andc r3,r3,r5
389 subf r4,r3,r4
390 add r4,r4,r5
391 srwi. r4,r4,L1_CACHE_SHIFT
392 beqlr
393 mtctr r4
394
3951: dcbst 0,r3
396 addi r3,r3,L1_CACHE_BYTES
397 bdnz 1b
398 sync /* wait for dcbst's to get to ram */
399 blr
400
401/*
402 * Write any modified data cache blocks out to memory and invalidate them.
403 * Does not invalidate the corresponding instruction cache blocks.
404 *
405 * flush_dcache_range(unsigned long start, unsigned long stop)
406 */
407_GLOBAL(flush_dcache_range)
408 li r5,L1_CACHE_BYTES-1
409 andc r3,r3,r5
410 subf r4,r3,r4
411 add r4,r4,r5
412 srwi. r4,r4,L1_CACHE_SHIFT
413 beqlr
414 mtctr r4
415
4161: dcbf 0,r3
417 addi r3,r3,L1_CACHE_BYTES
418 bdnz 1b
419 sync /* wait for dcbst's to get to ram */
420 blr
421
422/*
423 * Like above, but invalidate the D-cache. This is used by the 8xx
424 * to invalidate the cache so the PPC core doesn't get stale data
425 * from the CPM (no cache snooping here :-).
426 *
427 * invalidate_dcache_range(unsigned long start, unsigned long stop)
428 */
429_GLOBAL(invalidate_dcache_range)
430 li r5,L1_CACHE_BYTES-1
431 andc r3,r3,r5
432 subf r4,r3,r4
433 add r4,r4,r5
434 srwi. r4,r4,L1_CACHE_SHIFT
435 beqlr
436 mtctr r4
437
4381: dcbi 0,r3
439 addi r3,r3,L1_CACHE_BYTES
440 bdnz 1b
441 sync /* wait for dcbi's to get to ram */
442 blr
443
444/*
445 * Flush a particular page from the data cache to RAM. 376 * Flush a particular page from the data cache to RAM.
446 * Note: this is necessary because the instruction cache does *not* 377 * Note: this is necessary because the instruction cache does *not*
447 * snoop from the data cache. 378 * snoop from the data cache.
@@ -519,22 +450,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
519#endif /* CONFIG_BOOKE */ 450#endif /* CONFIG_BOOKE */
520 451
521/* 452/*
522 * Clear pages using the dcbz instruction, which doesn't cause any
523 * memory traffic (except to write out any cache lines which get
524 * displaced). This only works on cacheable memory.
525 *
526 * void clear_pages(void *page, int order) ;
527 */
528_GLOBAL(clear_pages)
529 li r0,PAGE_SIZE/L1_CACHE_BYTES
530 slw r0,r0,r4
531 mtctr r0
5321: dcbz 0,r3
533 addi r3,r3,L1_CACHE_BYTES
534 bdnz 1b
535 blr
536
537/*
538 * Copy a whole page. We use the dcbz instruction on the destination 453 * Copy a whole page. We use the dcbz instruction on the destination
539 * to reduce memory traffic (it eliminates the unnecessary reads of 454 * to reduce memory traffic (it eliminates the unnecessary reads of
540 * the destination into cache). This requires that the destination 455 * the destination into cache). This requires that the destination
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
index 9547381b631a..d1f1b35bf0c7 100644
--- a/arch/powerpc/kernel/module.c
+++ b/arch/powerpc/kernel/module.c
@@ -47,6 +47,11 @@ int module_finalize(const Elf_Ehdr *hdr,
47 const Elf_Shdr *sechdrs, struct module *me) 47 const Elf_Shdr *sechdrs, struct module *me)
48{ 48{
49 const Elf_Shdr *sect; 49 const Elf_Shdr *sect;
50 int rc;
51
52 rc = module_finalize_ftrace(me, sechdrs);
53 if (rc)
54 return rc;
50 55
51 /* Apply feature fixups */ 56 /* Apply feature fixups */
52 sect = find_section(hdr, sechdrs, "__ftr_fixup"); 57 sect = find_section(hdr, sechdrs, "__ftr_fixup");
diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c
index 2c01665eb410..5a7a78f12562 100644
--- a/arch/powerpc/kernel/module_32.c
+++ b/arch/powerpc/kernel/module_32.c
@@ -181,7 +181,7 @@ static inline int entry_matches(struct ppc_plt_entry *entry, Elf32_Addr val)
181/* Set up a trampoline in the PLT to bounce us to the distant function */ 181/* Set up a trampoline in the PLT to bounce us to the distant function */
182static uint32_t do_plt_call(void *location, 182static uint32_t do_plt_call(void *location,
183 Elf32_Addr val, 183 Elf32_Addr val,
184 Elf32_Shdr *sechdrs, 184 const Elf32_Shdr *sechdrs,
185 struct module *mod) 185 struct module *mod)
186{ 186{
187 struct ppc_plt_entry *entry; 187 struct ppc_plt_entry *entry;
@@ -294,11 +294,19 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
294 return -ENOEXEC; 294 return -ENOEXEC;
295 } 295 }
296 } 296 }
297
298 return 0;
299}
300
297#ifdef CONFIG_DYNAMIC_FTRACE 301#ifdef CONFIG_DYNAMIC_FTRACE
298 module->arch.tramp = 302int module_finalize_ftrace(struct module *module, const Elf_Shdr *sechdrs)
299 do_plt_call(module->core_layout.base, 303{
300 (unsigned long)ftrace_caller, 304 module->arch.tramp = do_plt_call(module->core_layout.base,
301 sechdrs, module); 305 (unsigned long)ftrace_caller,
302#endif 306 sechdrs, module);
307 if (!module->arch.tramp)
308 return -ENOENT;
309
303 return 0; 310 return 0;
304} 311}
312#endif
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 08b7a40de5f8..9ce9a25f58b5 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -31,6 +31,7 @@
31#include <asm/code-patching.h> 31#include <asm/code-patching.h>
32#include <linux/sort.h> 32#include <linux/sort.h>
33#include <asm/setup.h> 33#include <asm/setup.h>
34#include <asm/sections.h>
34 35
35/* FIXME: We don't do .init separately. To do this, we'd need to have 36/* FIXME: We don't do .init separately. To do this, we'd need to have
36 a separate r2 value in the init and core section, and stub between 37 a separate r2 value in the init and core section, and stub between
@@ -41,7 +42,6 @@
41 --RR. */ 42 --RR. */
42 43
43#if defined(_CALL_ELF) && _CALL_ELF == 2 44#if defined(_CALL_ELF) && _CALL_ELF == 2
44#define R2_STACK_OFFSET 24
45 45
46/* An address is simply the address of the function. */ 46/* An address is simply the address of the function. */
47typedef unsigned long func_desc_t; 47typedef unsigned long func_desc_t;
@@ -73,7 +73,6 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym)
73 return PPC64_LOCAL_ENTRY_OFFSET(sym->st_other); 73 return PPC64_LOCAL_ENTRY_OFFSET(sym->st_other);
74} 74}
75#else 75#else
76#define R2_STACK_OFFSET 40
77 76
78/* An address is address of the OPD entry, which contains address of fn. */ 77/* An address is address of the OPD entry, which contains address of fn. */
79typedef struct ppc64_opd_entry func_desc_t; 78typedef struct ppc64_opd_entry func_desc_t;
@@ -96,6 +95,8 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym)
96} 95}
97#endif 96#endif
98 97
98#define STUB_MAGIC 0x73747562 /* stub */
99
99/* Like PPC32, we need little trampolines to do > 24-bit jumps (into 100/* Like PPC32, we need little trampolines to do > 24-bit jumps (into
100 the kernel itself). But on PPC64, these need to be used for every 101 the kernel itself). But on PPC64, these need to be used for every
101 jump, actually, to reset r2 (TOC+0x8000). */ 102 jump, actually, to reset r2 (TOC+0x8000). */
@@ -105,7 +106,8 @@ struct ppc64_stub_entry
105 * need 6 instructions on ABIv2 but we always allocate 7 so 106 * need 6 instructions on ABIv2 but we always allocate 7 so
106 * so we don't have to modify the trampoline load instruction. */ 107 * so we don't have to modify the trampoline load instruction. */
107 u32 jump[7]; 108 u32 jump[7];
108 u32 unused; 109 /* Used by ftrace to identify stubs */
110 u32 magic;
109 /* Data for the above code */ 111 /* Data for the above code */
110 func_desc_t funcdata; 112 func_desc_t funcdata;
111}; 113};
@@ -139,70 +141,39 @@ static u32 ppc64_stub_insns[] = {
139}; 141};
140 142
141#ifdef CONFIG_DYNAMIC_FTRACE 143#ifdef CONFIG_DYNAMIC_FTRACE
142 144int module_trampoline_target(struct module *mod, unsigned long addr,
143static u32 ppc64_stub_mask[] = { 145 unsigned long *target)
144 0xffff0000,
145 0xffff0000,
146 0xffffffff,
147 0xffffffff,
148#if !defined(_CALL_ELF) || _CALL_ELF != 2
149 0xffffffff,
150#endif
151 0xffffffff,
152 0xffffffff
153};
154
155bool is_module_trampoline(u32 *p)
156{ 146{
157 unsigned int i; 147 struct ppc64_stub_entry *stub;
158 u32 insns[ARRAY_SIZE(ppc64_stub_insns)]; 148 func_desc_t funcdata;
159 149 u32 magic;
160 BUILD_BUG_ON(sizeof(ppc64_stub_insns) != sizeof(ppc64_stub_mask));
161 150
162 if (probe_kernel_read(insns, p, sizeof(insns))) 151 if (!within_module_core(addr, mod)) {
152 pr_err("%s: stub %lx not in module %s\n", __func__, addr, mod->name);
163 return -EFAULT; 153 return -EFAULT;
164
165 for (i = 0; i < ARRAY_SIZE(ppc64_stub_insns); i++) {
166 u32 insna = insns[i];
167 u32 insnb = ppc64_stub_insns[i];
168 u32 mask = ppc64_stub_mask[i];
169
170 if ((insna & mask) != (insnb & mask))
171 return false;
172 } 154 }
173 155
174 return true; 156 stub = (struct ppc64_stub_entry *)addr;
175}
176
177int module_trampoline_target(struct module *mod, u32 *trampoline,
178 unsigned long *target)
179{
180 u32 buf[2];
181 u16 upper, lower;
182 long offset;
183 void *toc_entry;
184 157
185 if (probe_kernel_read(buf, trampoline, sizeof(buf))) 158 if (probe_kernel_read(&magic, &stub->magic, sizeof(magic))) {
159 pr_err("%s: fault reading magic for stub %lx for %s\n", __func__, addr, mod->name);
186 return -EFAULT; 160 return -EFAULT;
161 }
187 162
188 upper = buf[0] & 0xffff; 163 if (magic != STUB_MAGIC) {
189 lower = buf[1] & 0xffff; 164 pr_err("%s: bad magic for stub %lx for %s\n", __func__, addr, mod->name);
190 165 return -EFAULT;
191 /* perform the addis/addi, both signed */ 166 }
192 offset = ((short)upper << 16) + (short)lower;
193 167
194 /* 168 if (probe_kernel_read(&funcdata, &stub->funcdata, sizeof(funcdata))) {
195 * Now get the address this trampoline jumps to. This 169 pr_err("%s: fault reading funcdata for stub %lx for %s\n", __func__, addr, mod->name);
196 * is always 32 bytes into our trampoline stub. 170 return -EFAULT;
197 */ 171 }
198 toc_entry = (void *)mod->arch.toc + offset + 32;
199 172
200 if (probe_kernel_read(target, toc_entry, sizeof(*target))) 173 *target = stub_func_addr(funcdata);
201 return -EFAULT;
202 174
203 return 0; 175 return 0;
204} 176}
205
206#endif 177#endif
207 178
208/* Count how many different 24-bit relocations (different symbol, 179/* Count how many different 24-bit relocations (different symbol,
@@ -413,7 +384,7 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
413/* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this 384/* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this
414 gives the value maximum span in an instruction which uses a signed 385 gives the value maximum span in an instruction which uses a signed
415 offset) */ 386 offset) */
416static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me) 387static inline unsigned long my_r2(const Elf64_Shdr *sechdrs, struct module *me)
417{ 388{
418 return sechdrs[me->arch.toc_section].sh_addr + 0x8000; 389 return sechdrs[me->arch.toc_section].sh_addr + 0x8000;
419} 390}
@@ -426,7 +397,7 @@ static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me)
426#define PPC_HA(v) PPC_HI ((v) + 0x8000) 397#define PPC_HA(v) PPC_HI ((v) + 0x8000)
427 398
428/* Patch stub to reference function and correct r2 value. */ 399/* Patch stub to reference function and correct r2 value. */
429static inline int create_stub(Elf64_Shdr *sechdrs, 400static inline int create_stub(const Elf64_Shdr *sechdrs,
430 struct ppc64_stub_entry *entry, 401 struct ppc64_stub_entry *entry,
431 unsigned long addr, 402 unsigned long addr,
432 struct module *me) 403 struct module *me)
@@ -447,12 +418,14 @@ static inline int create_stub(Elf64_Shdr *sechdrs,
447 entry->jump[0] |= PPC_HA(reladdr); 418 entry->jump[0] |= PPC_HA(reladdr);
448 entry->jump[1] |= PPC_LO(reladdr); 419 entry->jump[1] |= PPC_LO(reladdr);
449 entry->funcdata = func_desc(addr); 420 entry->funcdata = func_desc(addr);
421 entry->magic = STUB_MAGIC;
422
450 return 1; 423 return 1;
451} 424}
452 425
453/* Create stub to jump to function described in this OPD/ptr: we need the 426/* Create stub to jump to function described in this OPD/ptr: we need the
454 stub to set up the TOC ptr (r2) for the function. */ 427 stub to set up the TOC ptr (r2) for the function. */
455static unsigned long stub_for_addr(Elf64_Shdr *sechdrs, 428static unsigned long stub_for_addr(const Elf64_Shdr *sechdrs,
456 unsigned long addr, 429 unsigned long addr,
457 struct module *me) 430 struct module *me)
458{ 431{
@@ -476,17 +449,60 @@ static unsigned long stub_for_addr(Elf64_Shdr *sechdrs,
476 return (unsigned long)&stubs[i]; 449 return (unsigned long)&stubs[i];
477} 450}
478 451
452#ifdef CC_USING_MPROFILE_KERNEL
453static bool is_early_mcount_callsite(u32 *instruction)
454{
455 /*
456 * Check if this is one of the -mprofile-kernel sequences.
457 */
458 if (instruction[-1] == PPC_INST_STD_LR &&
459 instruction[-2] == PPC_INST_MFLR)
460 return true;
461
462 if (instruction[-1] == PPC_INST_MFLR)
463 return true;
464
465 return false;
466}
467
468/*
469 * In case of _mcount calls, do not save the current callee's TOC (in r2) into
470 * the original caller's stack frame. If we did we would clobber the saved TOC
471 * value of the original caller.
472 */
473static void squash_toc_save_inst(const char *name, unsigned long addr)
474{
475 struct ppc64_stub_entry *stub = (struct ppc64_stub_entry *)addr;
476
477 /* Only for calls to _mcount */
478 if (strcmp("_mcount", name) != 0)
479 return;
480
481 stub->jump[2] = PPC_INST_NOP;
482}
483#else
484static void squash_toc_save_inst(const char *name, unsigned long addr) { }
485
486/* without -mprofile-kernel, mcount calls are never early */
487static bool is_early_mcount_callsite(u32 *instruction)
488{
489 return false;
490}
491#endif
492
479/* We expect a noop next: if it is, replace it with instruction to 493/* We expect a noop next: if it is, replace it with instruction to
480 restore r2. */ 494 restore r2. */
481static int restore_r2(u32 *instruction, struct module *me) 495static int restore_r2(u32 *instruction, struct module *me)
482{ 496{
483 if (*instruction != PPC_INST_NOP) { 497 if (*instruction != PPC_INST_NOP) {
498 if (is_early_mcount_callsite(instruction - 1))
499 return 1;
484 pr_err("%s: Expect noop after relocate, got %08x\n", 500 pr_err("%s: Expect noop after relocate, got %08x\n",
485 me->name, *instruction); 501 me->name, *instruction);
486 return 0; 502 return 0;
487 } 503 }
488 /* ld r2,R2_STACK_OFFSET(r1) */ 504 /* ld r2,R2_STACK_OFFSET(r1) */
489 *instruction = 0xe8410000 | R2_STACK_OFFSET; 505 *instruction = PPC_INST_LD_TOC;
490 return 1; 506 return 1;
491} 507}
492 508
@@ -611,6 +627,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
611 return -ENOENT; 627 return -ENOENT;
612 if (!restore_r2((u32 *)location + 1, me)) 628 if (!restore_r2((u32 *)location + 1, me))
613 return -ENOEXEC; 629 return -ENOEXEC;
630
631 squash_toc_save_inst(strtab + sym->st_name, value);
614 } else 632 } else
615 value += local_entry_offset(sym); 633 value += local_entry_offset(sym);
616 634
@@ -693,12 +711,84 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
693 } 711 }
694 } 712 }
695 713
714 return 0;
715}
716
696#ifdef CONFIG_DYNAMIC_FTRACE 717#ifdef CONFIG_DYNAMIC_FTRACE
697 me->arch.toc = my_r2(sechdrs, me); 718
698 me->arch.tramp = stub_for_addr(sechdrs, 719#ifdef CC_USING_MPROFILE_KERNEL
699 (unsigned long)ftrace_caller, 720
700 me); 721#define PACATOC offsetof(struct paca_struct, kernel_toc)
722
723/*
724 * For mprofile-kernel we use a special stub for ftrace_caller() because we
725 * can't rely on r2 containing this module's TOC when we enter the stub.
726 *
727 * That can happen if the function calling us didn't need to use the toc. In
728 * that case it won't have setup r2, and the r2 value will be either the
729 * kernel's toc, or possibly another modules toc.
730 *
731 * To deal with that this stub uses the kernel toc, which is always accessible
732 * via the paca (in r13). The target (ftrace_caller()) is responsible for
733 * saving and restoring the toc before returning.
734 */
735static unsigned long create_ftrace_stub(const Elf64_Shdr *sechdrs, struct module *me)
736{
737 struct ppc64_stub_entry *entry;
738 unsigned int i, num_stubs;
739 static u32 stub_insns[] = {
740 0xe98d0000 | PACATOC, /* ld r12,PACATOC(r13) */
741 0x3d8c0000, /* addis r12,r12,<high> */
742 0x398c0000, /* addi r12,r12,<low> */
743 0x7d8903a6, /* mtctr r12 */
744 0x4e800420, /* bctr */
745 };
746 long reladdr;
747
748 num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*entry);
749
750 /* Find the next available stub entry */
751 entry = (void *)sechdrs[me->arch.stubs_section].sh_addr;
752 for (i = 0; i < num_stubs && stub_func_addr(entry->funcdata); i++, entry++);
753
754 if (i >= num_stubs) {
755 pr_err("%s: Unable to find a free slot for ftrace stub.\n", me->name);
756 return 0;
757 }
758
759 memcpy(entry->jump, stub_insns, sizeof(stub_insns));
760
761 /* Stub uses address relative to kernel toc (from the paca) */
762 reladdr = (unsigned long)ftrace_caller - kernel_toc_addr();
763 if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) {
764 pr_err("%s: Address of ftrace_caller out of range of kernel_toc.\n", me->name);
765 return 0;
766 }
767
768 entry->jump[1] |= PPC_HA(reladdr);
769 entry->jump[2] |= PPC_LO(reladdr);
770
771 /* Eventhough we don't use funcdata in the stub, it's needed elsewhere. */
772 entry->funcdata = func_desc((unsigned long)ftrace_caller);
773 entry->magic = STUB_MAGIC;
774
775 return (unsigned long)entry;
776}
777#else
778static unsigned long create_ftrace_stub(const Elf64_Shdr *sechdrs, struct module *me)
779{
780 return stub_for_addr(sechdrs, (unsigned long)ftrace_caller, me);
781}
701#endif 782#endif
702 783
784int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs)
785{
786 mod->arch.toc = my_r2(sechdrs, mod);
787 mod->arch.tramp = create_ftrace_stub(sechdrs, mod);
788
789 if (!mod->arch.tramp)
790 return -ENOENT;
791
703 return 0; 792 return 0;
704} 793}
794#endif
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 01ea0edf0579..93dae296b6be 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -17,10 +17,6 @@
17#include <asm/pgtable.h> 17#include <asm/pgtable.h>
18#include <asm/kexec.h> 18#include <asm/kexec.h>
19 19
20/* This symbol is provided by the linker - let it fill in the paca
21 * field correctly */
22extern unsigned long __toc_start;
23
24#ifdef CONFIG_PPC_BOOK3S 20#ifdef CONFIG_PPC_BOOK3S
25 21
26/* 22/*
@@ -149,11 +145,6 @@ EXPORT_SYMBOL(paca);
149 145
150void __init initialise_paca(struct paca_struct *new_paca, int cpu) 146void __init initialise_paca(struct paca_struct *new_paca, int cpu)
151{ 147{
152 /* The TOC register (GPR2) points 32kB into the TOC, so that 64kB
153 * of the TOC can be addressed using a single machine instruction.
154 */
155 unsigned long kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL;
156
157#ifdef CONFIG_PPC_BOOK3S 148#ifdef CONFIG_PPC_BOOK3S
158 new_paca->lppaca_ptr = new_lppaca(cpu); 149 new_paca->lppaca_ptr = new_lppaca(cpu);
159#else 150#else
@@ -161,7 +152,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
161#endif 152#endif
162 new_paca->lock_token = 0x8000; 153 new_paca->lock_token = 0x8000;
163 new_paca->paca_index = cpu; 154 new_paca->paca_index = cpu;
164 new_paca->kernel_toc = kernel_toc; 155 new_paca->kernel_toc = kernel_toc_addr();
165 new_paca->kernelbase = (unsigned long) _stext; 156 new_paca->kernelbase = (unsigned long) _stext;
166 /* Only set MSR:IR/DR when MMU is initialized */ 157 /* Only set MSR:IR/DR when MMU is initialized */
167 new_paca->kernel_msr = MSR_KERNEL & ~(MSR_IR | MSR_DR); 158 new_paca->kernel_msr = MSR_KERNEL & ~(MSR_IR | MSR_DR);
diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c
index 7f9ed0c1f6b9..59c436189f46 100644
--- a/arch/powerpc/kernel/pci-hotplug.c
+++ b/arch/powerpc/kernel/pci-hotplug.c
@@ -55,7 +55,7 @@ void pcibios_remove_pci_devices(struct pci_bus *bus)
55 55
56 pr_debug("PCI: Removing devices on bus %04x:%02x\n", 56 pr_debug("PCI: Removing devices on bus %04x:%02x\n",
57 pci_domain_nr(bus), bus->number); 57 pci_domain_nr(bus), bus->number);
58 list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { 58 list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) {
59 pr_debug(" Removing %s...\n", pci_name(dev)); 59 pr_debug(" Removing %s...\n", pci_name(dev));
60 pci_stop_and_remove_bus_device(dev); 60 pci_stop_and_remove_bus_device(dev);
61 } 61 }
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index b3b4df91b792..38102cb9baa9 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -139,6 +139,7 @@ struct pci_dn *pci_get_pdn(struct pci_dev *pdev)
139#ifdef CONFIG_PCI_IOV 139#ifdef CONFIG_PCI_IOV
140static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent, 140static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent,
141 struct pci_dev *pdev, 141 struct pci_dev *pdev,
142 int vf_index,
142 int busno, int devfn) 143 int busno, int devfn)
143{ 144{
144 struct pci_dn *pdn; 145 struct pci_dn *pdn;
@@ -158,6 +159,7 @@ static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent,
158 pdn->busno = busno; 159 pdn->busno = busno;
159 pdn->devfn = devfn; 160 pdn->devfn = devfn;
160#ifdef CONFIG_PPC_POWERNV 161#ifdef CONFIG_PPC_POWERNV
162 pdn->vf_index = vf_index;
161 pdn->pe_number = IODA_INVALID_PE; 163 pdn->pe_number = IODA_INVALID_PE;
162#endif 164#endif
163 INIT_LIST_HEAD(&pdn->child_list); 165 INIT_LIST_HEAD(&pdn->child_list);
@@ -179,6 +181,7 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
179{ 181{
180#ifdef CONFIG_PCI_IOV 182#ifdef CONFIG_PCI_IOV
181 struct pci_dn *parent, *pdn; 183 struct pci_dn *parent, *pdn;
184 struct eeh_dev *edev;
182 int i; 185 int i;
183 186
184 /* Only support IOV for now */ 187 /* Only support IOV for now */
@@ -196,7 +199,7 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
196 return NULL; 199 return NULL;
197 200
198 for (i = 0; i < pci_sriov_get_totalvfs(pdev); i++) { 201 for (i = 0; i < pci_sriov_get_totalvfs(pdev); i++) {
199 pdn = add_one_dev_pci_data(parent, NULL, 202 pdn = add_one_dev_pci_data(parent, NULL, i,
200 pci_iov_virtfn_bus(pdev, i), 203 pci_iov_virtfn_bus(pdev, i),
201 pci_iov_virtfn_devfn(pdev, i)); 204 pci_iov_virtfn_devfn(pdev, i));
202 if (!pdn) { 205 if (!pdn) {
@@ -204,6 +207,12 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
204 __func__, i); 207 __func__, i);
205 return NULL; 208 return NULL;
206 } 209 }
210
211 /* Create the EEH device for the VF */
212 eeh_dev_init(pdn, pci_bus_to_host(pdev->bus));
213 edev = pdn_to_eeh_dev(pdn);
214 BUG_ON(!edev);
215 edev->physfn = pdev;
207 } 216 }
208#endif /* CONFIG_PCI_IOV */ 217#endif /* CONFIG_PCI_IOV */
209 218
@@ -215,6 +224,7 @@ void remove_dev_pci_data(struct pci_dev *pdev)
215#ifdef CONFIG_PCI_IOV 224#ifdef CONFIG_PCI_IOV
216 struct pci_dn *parent; 225 struct pci_dn *parent;
217 struct pci_dn *pdn, *tmp; 226 struct pci_dn *pdn, *tmp;
227 struct eeh_dev *edev;
218 int i; 228 int i;
219 229
220 /* 230 /*
@@ -256,6 +266,13 @@ void remove_dev_pci_data(struct pci_dev *pdev)
256 pdn->devfn != pci_iov_virtfn_devfn(pdev, i)) 266 pdn->devfn != pci_iov_virtfn_devfn(pdev, i))
257 continue; 267 continue;
258 268
269 /* Release EEH device for the VF */
270 edev = pdn_to_eeh_dev(pdn);
271 if (edev) {
272 pdn->edev = NULL;
273 kfree(edev);
274 }
275
259 if (!list_empty(&pdn->list)) 276 if (!list_empty(&pdn->list))
260 list_del(&pdn->list); 277 list_del(&pdn->list);
261 278
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 41e1607e800c..9f01e28ecef3 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -6,7 +6,9 @@
6#include <asm/cacheflush.h> 6#include <asm/cacheflush.h>
7#include <asm/epapr_hcalls.h> 7#include <asm/epapr_hcalls.h>
8 8
9#ifdef CONFIG_PPC64
9EXPORT_SYMBOL(flush_dcache_range); 10EXPORT_SYMBOL(flush_dcache_range);
11#endif
10EXPORT_SYMBOL(flush_icache_range); 12EXPORT_SYMBOL(flush_icache_range);
11 13
12EXPORT_SYMBOL(empty_zero_page); 14EXPORT_SYMBOL(empty_zero_page);
@@ -28,10 +30,6 @@ EXPORT_SYMBOL(load_vr_state);
28EXPORT_SYMBOL(store_vr_state); 30EXPORT_SYMBOL(store_vr_state);
29#endif 31#endif
30 32
31#ifdef CONFIG_VSX
32EXPORT_SYMBOL_GPL(__giveup_vsx);
33#endif
34
35#ifdef CONFIG_EPAPR_PARAVIRT 33#ifdef CONFIG_EPAPR_PARAVIRT
36EXPORT_SYMBOL(epapr_hypercall_start); 34EXPORT_SYMBOL(epapr_hypercall_start);
37#endif 35#endif
diff --git a/arch/powerpc/kernel/ppc_ksyms_32.c b/arch/powerpc/kernel/ppc_ksyms_32.c
index 30ddd8a24eee..2bfaafe5be99 100644
--- a/arch/powerpc/kernel/ppc_ksyms_32.c
+++ b/arch/powerpc/kernel/ppc_ksyms_32.c
@@ -10,7 +10,6 @@
10#include <asm/pgtable.h> 10#include <asm/pgtable.h>
11#include <asm/dcr.h> 11#include <asm/dcr.h>
12 12
13EXPORT_SYMBOL(clear_pages);
14EXPORT_SYMBOL(ISA_DMA_THRESHOLD); 13EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
15EXPORT_SYMBOL(DMA_MODE_READ); 14EXPORT_SYMBOL(DMA_MODE_READ);
16EXPORT_SYMBOL(DMA_MODE_WRITE); 15EXPORT_SYMBOL(DMA_MODE_WRITE);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 3c5736e52a14..612df305886b 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -133,6 +133,16 @@ void __msr_check_and_clear(unsigned long bits)
133EXPORT_SYMBOL(__msr_check_and_clear); 133EXPORT_SYMBOL(__msr_check_and_clear);
134 134
135#ifdef CONFIG_PPC_FPU 135#ifdef CONFIG_PPC_FPU
136void __giveup_fpu(struct task_struct *tsk)
137{
138 save_fpu(tsk);
139 tsk->thread.regs->msr &= ~MSR_FP;
140#ifdef CONFIG_VSX
141 if (cpu_has_feature(CPU_FTR_VSX))
142 tsk->thread.regs->msr &= ~MSR_VSX;
143#endif
144}
145
136void giveup_fpu(struct task_struct *tsk) 146void giveup_fpu(struct task_struct *tsk)
137{ 147{
138 check_if_tm_restore_required(tsk); 148 check_if_tm_restore_required(tsk);
@@ -187,9 +197,32 @@ void enable_kernel_fp(void)
187 } 197 }
188} 198}
189EXPORT_SYMBOL(enable_kernel_fp); 199EXPORT_SYMBOL(enable_kernel_fp);
200
201static int restore_fp(struct task_struct *tsk) {
202 if (tsk->thread.load_fp) {
203 load_fp_state(&current->thread.fp_state);
204 current->thread.load_fp++;
205 return 1;
206 }
207 return 0;
208}
209#else
210static int restore_fp(struct task_struct *tsk) { return 0; }
190#endif /* CONFIG_PPC_FPU */ 211#endif /* CONFIG_PPC_FPU */
191 212
192#ifdef CONFIG_ALTIVEC 213#ifdef CONFIG_ALTIVEC
214#define loadvec(thr) ((thr).load_vec)
215
216static void __giveup_altivec(struct task_struct *tsk)
217{
218 save_altivec(tsk);
219 tsk->thread.regs->msr &= ~MSR_VEC;
220#ifdef CONFIG_VSX
221 if (cpu_has_feature(CPU_FTR_VSX))
222 tsk->thread.regs->msr &= ~MSR_VSX;
223#endif
224}
225
193void giveup_altivec(struct task_struct *tsk) 226void giveup_altivec(struct task_struct *tsk)
194{ 227{
195 check_if_tm_restore_required(tsk); 228 check_if_tm_restore_required(tsk);
@@ -229,22 +262,49 @@ void flush_altivec_to_thread(struct task_struct *tsk)
229 } 262 }
230} 263}
231EXPORT_SYMBOL_GPL(flush_altivec_to_thread); 264EXPORT_SYMBOL_GPL(flush_altivec_to_thread);
265
266static int restore_altivec(struct task_struct *tsk)
267{
268 if (cpu_has_feature(CPU_FTR_ALTIVEC) && tsk->thread.load_vec) {
269 load_vr_state(&tsk->thread.vr_state);
270 tsk->thread.used_vr = 1;
271 tsk->thread.load_vec++;
272
273 return 1;
274 }
275 return 0;
276}
277#else
278#define loadvec(thr) 0
279static inline int restore_altivec(struct task_struct *tsk) { return 0; }
232#endif /* CONFIG_ALTIVEC */ 280#endif /* CONFIG_ALTIVEC */
233 281
234#ifdef CONFIG_VSX 282#ifdef CONFIG_VSX
235void giveup_vsx(struct task_struct *tsk) 283static void __giveup_vsx(struct task_struct *tsk)
236{ 284{
237 check_if_tm_restore_required(tsk);
238
239 msr_check_and_set(MSR_FP|MSR_VEC|MSR_VSX);
240 if (tsk->thread.regs->msr & MSR_FP) 285 if (tsk->thread.regs->msr & MSR_FP)
241 __giveup_fpu(tsk); 286 __giveup_fpu(tsk);
242 if (tsk->thread.regs->msr & MSR_VEC) 287 if (tsk->thread.regs->msr & MSR_VEC)
243 __giveup_altivec(tsk); 288 __giveup_altivec(tsk);
289 tsk->thread.regs->msr &= ~MSR_VSX;
290}
291
292static void giveup_vsx(struct task_struct *tsk)
293{
294 check_if_tm_restore_required(tsk);
295
296 msr_check_and_set(MSR_FP|MSR_VEC|MSR_VSX);
244 __giveup_vsx(tsk); 297 __giveup_vsx(tsk);
245 msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); 298 msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX);
246} 299}
247EXPORT_SYMBOL(giveup_vsx); 300
301static void save_vsx(struct task_struct *tsk)
302{
303 if (tsk->thread.regs->msr & MSR_FP)
304 save_fpu(tsk);
305 if (tsk->thread.regs->msr & MSR_VEC)
306 save_altivec(tsk);
307}
248 308
249void enable_kernel_vsx(void) 309void enable_kernel_vsx(void)
250{ 310{
@@ -275,6 +335,19 @@ void flush_vsx_to_thread(struct task_struct *tsk)
275 } 335 }
276} 336}
277EXPORT_SYMBOL_GPL(flush_vsx_to_thread); 337EXPORT_SYMBOL_GPL(flush_vsx_to_thread);
338
339static int restore_vsx(struct task_struct *tsk)
340{
341 if (cpu_has_feature(CPU_FTR_VSX)) {
342 tsk->thread.used_vsr = 1;
343 return 1;
344 }
345
346 return 0;
347}
348#else
349static inline int restore_vsx(struct task_struct *tsk) { return 0; }
350static inline void save_vsx(struct task_struct *tsk) { }
278#endif /* CONFIG_VSX */ 351#endif /* CONFIG_VSX */
279 352
280#ifdef CONFIG_SPE 353#ifdef CONFIG_SPE
@@ -374,12 +447,76 @@ void giveup_all(struct task_struct *tsk)
374} 447}
375EXPORT_SYMBOL(giveup_all); 448EXPORT_SYMBOL(giveup_all);
376 449
450void restore_math(struct pt_regs *regs)
451{
452 unsigned long msr;
453
454 if (!current->thread.load_fp && !loadvec(current->thread))
455 return;
456
457 msr = regs->msr;
458 msr_check_and_set(msr_all_available);
459
460 /*
461 * Only reload if the bit is not set in the user MSR, the bit BEING set
462 * indicates that the registers are hot
463 */
464 if ((!(msr & MSR_FP)) && restore_fp(current))
465 msr |= MSR_FP | current->thread.fpexc_mode;
466
467 if ((!(msr & MSR_VEC)) && restore_altivec(current))
468 msr |= MSR_VEC;
469
470 if ((msr & (MSR_FP | MSR_VEC)) == (MSR_FP | MSR_VEC) &&
471 restore_vsx(current)) {
472 msr |= MSR_VSX;
473 }
474
475 msr_check_and_clear(msr_all_available);
476
477 regs->msr = msr;
478}
479
480void save_all(struct task_struct *tsk)
481{
482 unsigned long usermsr;
483
484 if (!tsk->thread.regs)
485 return;
486
487 usermsr = tsk->thread.regs->msr;
488
489 if ((usermsr & msr_all_available) == 0)
490 return;
491
492 msr_check_and_set(msr_all_available);
493
494 /*
495 * Saving the way the register space is in hardware, save_vsx boils
496 * down to a save_fpu() and save_altivec()
497 */
498 if (usermsr & MSR_VSX) {
499 save_vsx(tsk);
500 } else {
501 if (usermsr & MSR_FP)
502 save_fpu(tsk);
503
504 if (usermsr & MSR_VEC)
505 save_altivec(tsk);
506 }
507
508 if (usermsr & MSR_SPE)
509 __giveup_spe(tsk);
510
511 msr_check_and_clear(msr_all_available);
512}
513
377void flush_all_to_thread(struct task_struct *tsk) 514void flush_all_to_thread(struct task_struct *tsk)
378{ 515{
379 if (tsk->thread.regs) { 516 if (tsk->thread.regs) {
380 preempt_disable(); 517 preempt_disable();
381 BUG_ON(tsk != current); 518 BUG_ON(tsk != current);
382 giveup_all(tsk); 519 save_all(tsk);
383 520
384#ifdef CONFIG_SPE 521#ifdef CONFIG_SPE
385 if (tsk->thread.regs->msr & MSR_SPE) 522 if (tsk->thread.regs->msr & MSR_SPE)
@@ -832,17 +969,9 @@ void restore_tm_state(struct pt_regs *regs)
832 969
833 msr_diff = current->thread.ckpt_regs.msr & ~regs->msr; 970 msr_diff = current->thread.ckpt_regs.msr & ~regs->msr;
834 msr_diff &= MSR_FP | MSR_VEC | MSR_VSX; 971 msr_diff &= MSR_FP | MSR_VEC | MSR_VSX;
835 if (msr_diff & MSR_FP) { 972
836 msr_check_and_set(MSR_FP); 973 restore_math(regs);
837 load_fp_state(&current->thread.fp_state); 974
838 msr_check_and_clear(MSR_FP);
839 regs->msr |= current->thread.fpexc_mode;
840 }
841 if (msr_diff & MSR_VEC) {
842 msr_check_and_set(MSR_VEC);
843 load_vr_state(&current->thread.vr_state);
844 msr_check_and_clear(MSR_VEC);
845 }
846 regs->msr |= msr_diff; 975 regs->msr |= msr_diff;
847} 976}
848 977
@@ -1006,6 +1135,10 @@ struct task_struct *__switch_to(struct task_struct *prev,
1006 batch = this_cpu_ptr(&ppc64_tlb_batch); 1135 batch = this_cpu_ptr(&ppc64_tlb_batch);
1007 batch->active = 1; 1136 batch->active = 1;
1008 } 1137 }
1138
1139 if (current_thread_info()->task->thread.regs)
1140 restore_math(current_thread_info()->task->thread.regs);
1141
1009#endif /* CONFIG_PPC_BOOK3S_64 */ 1142#endif /* CONFIG_PPC_BOOK3S_64 */
1010 1143
1011 return last; 1144 return last;
@@ -1307,6 +1440,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
1307 1440
1308 f = ret_from_fork; 1441 f = ret_from_fork;
1309 } 1442 }
1443 childregs->msr &= ~(MSR_FP|MSR_VEC|MSR_VSX);
1310 sp -= STACK_FRAME_OVERHEAD; 1444 sp -= STACK_FRAME_OVERHEAD;
1311 1445
1312 /* 1446 /*
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index cf8c7e4e0b21..cb64d6feb45a 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Common signal handling code for both 32 and 64 bits 2 * Common signal handling code for both 32 and 64 bits
3 * 3 *
4 * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Coproration 4 * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Corporation
5 * Extracted from signal_32.c and signal_64.c 5 * Extracted from signal_32.c and signal_64.c
6 * 6 *
7 * This file is subject to the terms and conditions of the GNU General 7 * This file is subject to the terms and conditions of the GNU General
@@ -178,7 +178,7 @@ unsigned long get_tm_stackpointer(struct pt_regs *regs)
178 * need to use the stack pointer from the checkpointed state, rather 178 * need to use the stack pointer from the checkpointed state, rather
179 * than the speculated state. This ensures that the signal context 179 * than the speculated state. This ensures that the signal context
180 * (written tm suspended) will be written below the stack required for 180 * (written tm suspended) will be written below the stack required for
181 * the rollback. The transaction is aborted becuase of the treclaim, 181 * the rollback. The transaction is aborted because of the treclaim,
182 * so any memory written between the tbegin and the signal will be 182 * so any memory written between the tbegin and the signal will be
183 * rolled back anyway. 183 * rolled back anyway.
184 * 184 *
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index 51b274199dd9..be305c858e51 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Coproration 2 * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Corporation
3 * Extracted from signal_32.c and signal_64.c 3 * Extracted from signal_32.c and signal_64.c
4 * 4 *
5 * This file is subject to the terms and conditions of the GNU General 5 * This file is subject to the terms and conditions of the GNU General
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index b7dea05f0725..8cac1eb41466 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -445,7 +445,7 @@ void generic_cpu_die(unsigned int cpu)
445 445
446 for (i = 0; i < 100; i++) { 446 for (i = 0; i < 100; i++) {
447 smp_rmb(); 447 smp_rmb();
448 if (per_cpu(cpu_state, cpu) == CPU_DEAD) 448 if (is_cpu_dead(cpu))
449 return; 449 return;
450 msleep(100); 450 msleep(100);
451 } 451 }
@@ -472,6 +472,11 @@ int generic_check_cpu_restart(unsigned int cpu)
472 return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; 472 return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE;
473} 473}
474 474
475int is_cpu_dead(unsigned int cpu)
476{
477 return per_cpu(cpu_state, cpu) == CPU_DEAD;
478}
479
475static bool secondaries_inhibited(void) 480static bool secondaries_inhibited(void)
476{ 481{
477 return kvm_hv_mode_active(); 482 return kvm_hv_mode_active();
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 33c47fcc455a..9229ba63c370 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -1147,6 +1147,7 @@ void __kprobes program_check_exception(struct pt_regs *regs)
1147 goto bail; 1147 goto bail;
1148 } 1148 }
1149 if (reason & REASON_TRAP) { 1149 if (reason & REASON_TRAP) {
1150 unsigned long bugaddr;
1150 /* Debugger is first in line to stop recursive faults in 1151 /* Debugger is first in line to stop recursive faults in
1151 * rcu_lock, notify_die, or atomic_notifier_call_chain */ 1152 * rcu_lock, notify_die, or atomic_notifier_call_chain */
1152 if (debugger_bpt(regs)) 1153 if (debugger_bpt(regs))
@@ -1157,8 +1158,15 @@ void __kprobes program_check_exception(struct pt_regs *regs)
1157 == NOTIFY_STOP) 1158 == NOTIFY_STOP)
1158 goto bail; 1159 goto bail;
1159 1160
1161 bugaddr = regs->nip;
1162 /*
1163 * Fixup bugaddr for BUG_ON() in real mode
1164 */
1165 if (!is_kernel_addr(bugaddr) && !(regs->msr & MSR_IR))
1166 bugaddr += PAGE_OFFSET;
1167
1160 if (!(regs->msr & MSR_PR) && /* not user-mode */ 1168 if (!(regs->msr & MSR_PR) && /* not user-mode */
1161 report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { 1169 report_bug(bugaddr, regs) == BUG_TRAP_TYPE_WARN) {
1162 regs->nip += 4; 1170 regs->nip += 4;
1163 goto bail; 1171 goto bail;
1164 } 1172 }
@@ -1393,7 +1401,7 @@ void facility_unavailable_exception(struct pt_regs *regs)
1393 * is a read DSCR attempt through a mfspr instruction, we 1401 * is a read DSCR attempt through a mfspr instruction, we
1394 * just emulate the instruction instead. This code path will 1402 * just emulate the instruction instead. This code path will
1395 * always emulate all the mfspr instructions till the user 1403 * always emulate all the mfspr instructions till the user
1396 * has attempted atleast one mtspr instruction. This way it 1404 * has attempted at least one mtspr instruction. This way it
1397 * preserves the same behaviour when the user is accessing 1405 * preserves the same behaviour when the user is accessing
1398 * the DSCR through privilege level only SPR number (0x11) 1406 * the DSCR through privilege level only SPR number (0x11)
1399 * which is emulated through illegal instruction exception. 1407 * which is emulated through illegal instruction exception.
diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S
index 162d0f714941..1c2e7a343bf5 100644
--- a/arch/powerpc/kernel/vector.S
+++ b/arch/powerpc/kernel/vector.S
@@ -91,6 +91,10 @@ _GLOBAL(load_up_altivec)
91 oris r12,r12,MSR_VEC@h 91 oris r12,r12,MSR_VEC@h
92 std r12,_MSR(r1) 92 std r12,_MSR(r1)
93#endif 93#endif
94 /* Don't care if r4 overflows, this is desired behaviour */
95 lbz r4,THREAD_LOAD_VEC(r5)
96 addi r4,r4,1
97 stb r4,THREAD_LOAD_VEC(r5)
94 addi r6,r5,THREAD_VRSTATE 98 addi r6,r5,THREAD_VRSTATE
95 li r4,1 99 li r4,1
96 li r10,VRSTATE_VSCR 100 li r10,VRSTATE_VSCR
@@ -102,36 +106,20 @@ _GLOBAL(load_up_altivec)
102 blr 106 blr
103 107
104/* 108/*
105 * __giveup_altivec(tsk) 109 * save_altivec(tsk)
106 * Disable VMX for the task given as the argument, 110 * Save the vector registers to its thread_struct
107 * and save the vector registers in its thread_struct.
108 */ 111 */
109_GLOBAL(__giveup_altivec) 112_GLOBAL(save_altivec)
110 addi r3,r3,THREAD /* want THREAD of task */ 113 addi r3,r3,THREAD /* want THREAD of task */
111 PPC_LL r7,THREAD_VRSAVEAREA(r3) 114 PPC_LL r7,THREAD_VRSAVEAREA(r3)
112 PPC_LL r5,PT_REGS(r3) 115 PPC_LL r5,PT_REGS(r3)
113 PPC_LCMPI 0,r7,0 116 PPC_LCMPI 0,r7,0
114 bne 2f 117 bne 2f
115 addi r7,r3,THREAD_VRSTATE 118 addi r7,r3,THREAD_VRSTATE
1162: PPC_LCMPI 0,r5,0 1192: SAVE_32VRS(0,r4,r7)
117 SAVE_32VRS(0,r4,r7)
118 mfvscr v0 120 mfvscr v0
119 li r4,VRSTATE_VSCR 121 li r4,VRSTATE_VSCR
120 stvx v0,r4,r7 122 stvx v0,r4,r7
121 beq 1f
122 PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
123#ifdef CONFIG_VSX
124BEGIN_FTR_SECTION
125 lis r3,(MSR_VEC|MSR_VSX)@h
126FTR_SECTION_ELSE
127 lis r3,MSR_VEC@h
128ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX)
129#else
130 lis r3,MSR_VEC@h
131#endif
132 andc r4,r4,r3 /* disable FP for previous task */
133 PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1341:
135 blr 123 blr
136 124
137#ifdef CONFIG_VSX 125#ifdef CONFIG_VSX
@@ -163,23 +151,6 @@ _GLOBAL(load_up_vsx)
163 std r12,_MSR(r1) 151 std r12,_MSR(r1)
164 b fast_exception_return 152 b fast_exception_return
165 153
166/*
167 * __giveup_vsx(tsk)
168 * Disable VSX for the task given as the argument.
169 * Does NOT save vsx registers.
170 */
171_GLOBAL(__giveup_vsx)
172 addi r3,r3,THREAD /* want THREAD of task */
173 ld r5,PT_REGS(r3)
174 cmpdi 0,r5,0
175 beq 1f
176 ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
177 lis r3,MSR_VSX@h
178 andc r4,r4,r3 /* disable VSX for previous task */
179 std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1801:
181 blr
182
183#endif /* CONFIG_VSX */ 154#endif /* CONFIG_VSX */
184 155
185 156
diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c
index 55c4d51ea3e2..999106991a76 100644
--- a/arch/powerpc/kvm/book3s_32_mmu_host.c
+++ b/arch/powerpc/kvm/book3s_32_mmu_host.c
@@ -22,7 +22,7 @@
22 22
23#include <asm/kvm_ppc.h> 23#include <asm/kvm_ppc.h>
24#include <asm/kvm_book3s.h> 24#include <asm/kvm_book3s.h>
25#include <asm/mmu-hash32.h> 25#include <asm/book3s/32/mmu-hash.h>
26#include <asm/machdep.h> 26#include <asm/machdep.h>
27#include <asm/mmu_context.h> 27#include <asm/mmu_context.h>
28#include <asm/hw_irq.h> 28#include <asm/hw_irq.h>
diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c
index 9bf7031a67ff..b9131aa1aedf 100644
--- a/arch/powerpc/kvm/book3s_64_mmu.c
+++ b/arch/powerpc/kvm/book3s_64_mmu.c
@@ -26,7 +26,7 @@
26#include <asm/tlbflush.h> 26#include <asm/tlbflush.h>
27#include <asm/kvm_ppc.h> 27#include <asm/kvm_ppc.h>
28#include <asm/kvm_book3s.h> 28#include <asm/kvm_book3s.h>
29#include <asm/mmu-hash64.h> 29#include <asm/book3s/64/mmu-hash.h>
30 30
31/* #define DEBUG_MMU */ 31/* #define DEBUG_MMU */
32 32
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c
index 913cd2198fa6..114edace6cdd 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_host.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_host.c
@@ -23,7 +23,7 @@
23 23
24#include <asm/kvm_ppc.h> 24#include <asm/kvm_ppc.h>
25#include <asm/kvm_book3s.h> 25#include <asm/kvm_book3s.h>
26#include <asm/mmu-hash64.h> 26#include <asm/book3s/64/mmu-hash.h>
27#include <asm/machdep.h> 27#include <asm/machdep.h>
28#include <asm/mmu_context.h> 28#include <asm/mmu_context.h>
29#include <asm/hw_irq.h> 29#include <asm/hw_irq.h>
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index fb37290a57b4..c7b78d8336b2 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -32,7 +32,7 @@
32#include <asm/tlbflush.h> 32#include <asm/tlbflush.h>
33#include <asm/kvm_ppc.h> 33#include <asm/kvm_ppc.h>
34#include <asm/kvm_book3s.h> 34#include <asm/kvm_book3s.h>
35#include <asm/mmu-hash64.h> 35#include <asm/book3s/64/mmu-hash.h>
36#include <asm/hvcall.h> 36#include <asm/hvcall.h>
37#include <asm/synch.h> 37#include <asm/synch.h>
38#include <asm/ppc-opcode.h> 38#include <asm/ppc-opcode.h>
diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
index 2c2d1030843a..82970042295e 100644
--- a/arch/powerpc/kvm/book3s_64_vio.c
+++ b/arch/powerpc/kvm/book3s_64_vio.c
@@ -31,7 +31,7 @@
31#include <asm/tlbflush.h> 31#include <asm/tlbflush.h>
32#include <asm/kvm_ppc.h> 32#include <asm/kvm_ppc.h>
33#include <asm/kvm_book3s.h> 33#include <asm/kvm_book3s.h>
34#include <asm/mmu-hash64.h> 34#include <asm/book3s/64/mmu-hash.h>
35#include <asm/hvcall.h> 35#include <asm/hvcall.h>
36#include <asm/synch.h> 36#include <asm/synch.h>
37#include <asm/ppc-opcode.h> 37#include <asm/ppc-opcode.h>
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index 44be73e6aa26..f88b859af53b 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -30,7 +30,7 @@
30#include <asm/tlbflush.h> 30#include <asm/tlbflush.h>
31#include <asm/kvm_ppc.h> 31#include <asm/kvm_ppc.h>
32#include <asm/kvm_book3s.h> 32#include <asm/kvm_book3s.h>
33#include <asm/mmu-hash64.h> 33#include <asm/book3s/64/mmu-hash.h>
34#include <asm/mmu_context.h> 34#include <asm/mmu_context.h>
35#include <asm/hvcall.h> 35#include <asm/hvcall.h>
36#include <asm/synch.h> 36#include <asm/synch.h>
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
index 91700518bbf3..4cb8db05f3e5 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -17,7 +17,7 @@
17#include <asm/tlbflush.h> 17#include <asm/tlbflush.h>
18#include <asm/kvm_ppc.h> 18#include <asm/kvm_ppc.h>
19#include <asm/kvm_book3s.h> 19#include <asm/kvm_book3s.h>
20#include <asm/mmu-hash64.h> 20#include <asm/book3s/64/mmu-hash.h>
21#include <asm/hvcall.h> 21#include <asm/hvcall.h>
22#include <asm/synch.h> 22#include <asm/synch.h>
23#include <asm/ppc-opcode.h> 23#include <asm/ppc-opcode.h>
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 85b32f16fa74..62ea3c6acdee 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -27,7 +27,7 @@
27#include <asm/asm-offsets.h> 27#include <asm/asm-offsets.h>
28#include <asm/exception-64s.h> 28#include <asm/exception-64s.h>
29#include <asm/kvm_book3s_asm.h> 29#include <asm/kvm_book3s_asm.h>
30#include <asm/mmu-hash64.h> 30#include <asm/book3s/64/mmu-hash.h>
31#include <asm/tm.h> 31#include <asm/tm.h>
32 32
33#define VCPU_GPRS_TM(reg) (((reg) * ULONG_SIZE) + VCPU_GPR_TM) 33#define VCPU_GPRS_TM(reg) (((reg) * ULONG_SIZE) + VCPU_GPR_TM)
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c
index 905e94a1370f..46871d554057 100644
--- a/arch/powerpc/kvm/book3s_xics.c
+++ b/arch/powerpc/kvm/book3s_xics.c
@@ -432,7 +432,7 @@ static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp,
432 * the whole masked_pending business which is about not 432 * the whole masked_pending business which is about not
433 * losing interrupts that occur while masked. 433 * losing interrupts that occur while masked.
434 * 434 *
435 * I don't differenciate normal deliveries and resends, this 435 * I don't differentiate normal deliveries and resends, this
436 * implementation will differ from PAPR and not lose such 436 * implementation will differ from PAPR and not lose such
437 * interrupts. 437 * interrupts.
438 */ 438 */
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 778ef86e187e..4d66f44a1657 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -992,7 +992,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
992 kvmppc_restart_interrupt(vcpu, exit_nr); 992 kvmppc_restart_interrupt(vcpu, exit_nr);
993 993
994 /* 994 /*
995 * get last instruction before beeing preempted 995 * get last instruction before being preempted
996 * TODO: for e6500 check also BOOKE_INTERRUPT_LRAT_ERROR & ESR_DATA 996 * TODO: for e6500 check also BOOKE_INTERRUPT_LRAT_ERROR & ESR_DATA
997 */ 997 */
998 switch (exit_nr) { 998 switch (exit_nr) {
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index cda695de8aa7..f48a0c22e8f9 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -182,7 +182,7 @@ int kvmppc_core_check_processor_compat(void)
182 r = 0; 182 r = 0;
183#ifdef CONFIG_ALTIVEC 183#ifdef CONFIG_ALTIVEC
184 /* 184 /*
185 * Since guests have the priviledge to enable AltiVec, we need AltiVec 185 * Since guests have the privilege to enable AltiVec, we need AltiVec
186 * support in the host to save/restore their context. 186 * support in the host to save/restore their context.
187 * Don't use CPU_FTR_ALTIVEC to identify cores with AltiVec unit 187 * Don't use CPU_FTR_ALTIVEC to identify cores with AltiVec unit
188 * because it's cleared in the absence of CONFIG_ALTIVEC! 188 * because it's cleared in the absence of CONFIG_ALTIVEC!
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index a47e14277fd8..ba21be15310f 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -6,8 +6,8 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
6 6
7ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) 7ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
8 8
9CFLAGS_REMOVE_code-patching.o = -pg 9CFLAGS_REMOVE_code-patching.o = $(CC_FLAGS_FTRACE)
10CFLAGS_REMOVE_feature-fixups.o = -pg 10CFLAGS_REMOVE_feature-fixups.o = $(CC_FLAGS_FTRACE)
11 11
12obj-y += string.o alloc.o crtsavres.o ppc_ksyms.o code-patching.o \ 12obj-y += string.o alloc.o crtsavres.o ppc_ksyms.o code-patching.o \
13 feature-fixups.o 13 feature-fixups.o
@@ -22,8 +22,7 @@ obj64-$(CONFIG_SMP) += locks.o
22obj64-$(CONFIG_ALTIVEC) += vmx-helper.o 22obj64-$(CONFIG_ALTIVEC) += vmx-helper.o
23 23
24ifeq ($(CONFIG_GENERIC_CSUM),) 24ifeq ($(CONFIG_GENERIC_CSUM),)
25obj-y += checksum_$(CONFIG_WORD_SIZE).o 25obj-y += checksum_$(CONFIG_WORD_SIZE).o checksum_wrappers.o
26obj-$(CONFIG_PPC64) += checksum_wrappers_64.o
27endif 26endif
28 27
29obj-$(CONFIG_PPC_EMULATE_SSTEP) += sstep.o ldstfp.o 28obj-$(CONFIG_PPC_EMULATE_SSTEP) += sstep.o ldstfp.o
diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S
index 6d67e057f15e..d90870a66b60 100644
--- a/arch/powerpc/lib/checksum_32.S
+++ b/arch/powerpc/lib/checksum_32.S
@@ -14,68 +14,59 @@
14 14
15#include <linux/sys.h> 15#include <linux/sys.h>
16#include <asm/processor.h> 16#include <asm/processor.h>
17#include <asm/cache.h>
17#include <asm/errno.h> 18#include <asm/errno.h>
18#include <asm/ppc_asm.h> 19#include <asm/ppc_asm.h>
19 20
20 .text 21 .text
21 22
22/* 23/*
23 * ip_fast_csum(buf, len) -- Optimized for IP header
24 * len is in words and is always >= 5.
25 */
26_GLOBAL(ip_fast_csum)
27 lwz r0,0(r3)
28 lwzu r5,4(r3)
29 addic. r4,r4,-2
30 addc r0,r0,r5
31 mtctr r4
32 blelr-
331: lwzu r4,4(r3)
34 adde r0,r0,r4
35 bdnz 1b
36 addze r0,r0 /* add in final carry */
37 rlwinm r3,r0,16,0,31 /* fold two halves together */
38 add r3,r0,r3
39 not r3,r3
40 srwi r3,r3,16
41 blr
42
43/*
44 * computes the checksum of a memory block at buff, length len, 24 * computes the checksum of a memory block at buff, length len,
45 * and adds in "sum" (32-bit) 25 * and adds in "sum" (32-bit)
46 * 26 *
47 * csum_partial(buff, len, sum) 27 * __csum_partial(buff, len, sum)
48 */ 28 */
49_GLOBAL(csum_partial) 29_GLOBAL(__csum_partial)
50 addic r0,r5,0
51 subi r3,r3,4 30 subi r3,r3,4
52 srwi. r6,r4,2 31 srawi. r6,r4,2 /* Divide len by 4 and also clear carry */
53 beq 3f /* if we're doing < 4 bytes */ 32 beq 3f /* if we're doing < 4 bytes */
54 andi. r5,r3,2 /* Align buffer to longword boundary */ 33 andi. r0,r3,2 /* Align buffer to longword boundary */
55 beq+ 1f 34 beq+ 1f
56 lhz r5,4(r3) /* do 2 bytes to get aligned */ 35 lhz r0,4(r3) /* do 2 bytes to get aligned */
57 addi r3,r3,2
58 subi r4,r4,2 36 subi r4,r4,2
59 addc r0,r0,r5 37 addi r3,r3,2
60 srwi. r6,r4,2 /* # words to do */ 38 srwi. r6,r4,2 /* # words to do */
39 adde r5,r5,r0
61 beq 3f 40 beq 3f
621: mtctr r6 411: andi. r6,r6,3 /* Prepare to handle words 4 by 4 */
632: lwzu r5,4(r3) /* the bdnz has zero overhead, so it should */ 42 beq 21f
64 adde r0,r0,r5 /* be unnecessary to unroll this loop */ 43 mtctr r6
442: lwzu r0,4(r3)
45 adde r5,r5,r0
65 bdnz 2b 46 bdnz 2b
66 andi. r4,r4,3 4721: srwi. r6,r4,4 /* # blocks of 4 words to do */
673: cmpwi 0,r4,2 48 beq 3f
68 blt+ 4f 49 mtctr r6
69 lhz r5,4(r3) 5022: lwz r0,4(r3)
51 lwz r6,8(r3)
52 lwz r7,12(r3)
53 lwzu r8,16(r3)
54 adde r5,r5,r0
55 adde r5,r5,r6
56 adde r5,r5,r7
57 adde r5,r5,r8
58 bdnz 22b
593: andi. r0,r4,2
60 beq+ 4f
61 lhz r0,4(r3)
70 addi r3,r3,2 62 addi r3,r3,2
71 subi r4,r4,2 63 adde r5,r5,r0
72 adde r0,r0,r5 644: andi. r0,r4,1
734: cmpwi 0,r4,1 65 beq+ 5f
74 bne+ 5f 66 lbz r0,4(r3)
75 lbz r5,4(r3) 67 slwi r0,r0,8 /* Upper byte of word */
76 slwi r5,r5,8 /* Upper byte of word */ 68 adde r5,r5,r0
77 adde r0,r0,r5 695: addze r3,r5 /* add in final carry */
785: addze r3,r0 /* add in final carry */
79 blr 70 blr
80 71
81/* 72/*
@@ -87,123 +78,220 @@ _GLOBAL(csum_partial)
87 * 78 *
88 * csum_partial_copy_generic(src, dst, len, sum, src_err, dst_err) 79 * csum_partial_copy_generic(src, dst, len, sum, src_err, dst_err)
89 */ 80 */
81#define CSUM_COPY_16_BYTES_WITHEX(n) \
828 ## n ## 0: \
83 lwz r7,4(r4); \
848 ## n ## 1: \
85 lwz r8,8(r4); \
868 ## n ## 2: \
87 lwz r9,12(r4); \
888 ## n ## 3: \
89 lwzu r10,16(r4); \
908 ## n ## 4: \
91 stw r7,4(r6); \
92 adde r12,r12,r7; \
938 ## n ## 5: \
94 stw r8,8(r6); \
95 adde r12,r12,r8; \
968 ## n ## 6: \
97 stw r9,12(r6); \
98 adde r12,r12,r9; \
998 ## n ## 7: \
100 stwu r10,16(r6); \
101 adde r12,r12,r10
102
103#define CSUM_COPY_16_BYTES_EXCODE(n) \
104.section __ex_table,"a"; \
105 .align 2; \
106 .long 8 ## n ## 0b,src_error; \
107 .long 8 ## n ## 1b,src_error; \
108 .long 8 ## n ## 2b,src_error; \
109 .long 8 ## n ## 3b,src_error; \
110 .long 8 ## n ## 4b,dst_error; \
111 .long 8 ## n ## 5b,dst_error; \
112 .long 8 ## n ## 6b,dst_error; \
113 .long 8 ## n ## 7b,dst_error; \
114 .text
115
116 .text
117 .stabs "arch/powerpc/lib/",N_SO,0,0,0f
118 .stabs "checksum_32.S",N_SO,0,0,0f
1190:
120
121CACHELINE_BYTES = L1_CACHE_BYTES
122LG_CACHELINE_BYTES = L1_CACHE_SHIFT
123CACHELINE_MASK = (L1_CACHE_BYTES-1)
124
90_GLOBAL(csum_partial_copy_generic) 125_GLOBAL(csum_partial_copy_generic)
91 addic r0,r6,0 126 stwu r1,-16(r1)
92 subi r3,r3,4 127 stw r7,12(r1)
93 subi r4,r4,4 128 stw r8,8(r1)
94 srwi. r6,r5,2 129
95 beq 3f /* if we're doing < 4 bytes */ 130 andi. r0,r4,1 /* is destination address even ? */
96 andi. r9,r4,2 /* Align dst to longword boundary */ 131 cmplwi cr7,r0,0
97 beq+ 1f 132 addic r12,r6,0
9881: lhz r6,4(r3) /* do 2 bytes to get aligned */ 133 addi r6,r4,-4
99 addi r3,r3,2 134 neg r0,r4
100 subi r5,r5,2 135 addi r4,r3,-4
10191: sth r6,4(r4) 136 andi. r0,r0,CACHELINE_MASK /* # bytes to start of cache line */
102 addi r4,r4,2 137 beq 58f
103 addc r0,r0,r6 138
104 srwi. r6,r5,2 /* # words to do */ 139 cmplw 0,r5,r0 /* is this more than total to do? */
105 beq 3f 140 blt 63f /* if not much to do */
1061: srwi. r6,r5,4 /* # groups of 4 words to do */ 141 andi. r8,r0,3 /* get it word-aligned first */
107 beq 10f 142 mtctr r8
108 mtctr r6 143 beq+ 61f
10971: lwz r6,4(r3) 144 li r3,0
11072: lwz r9,8(r3) 14570: lbz r9,4(r4) /* do some bytes */
11173: lwz r10,12(r3) 146 addi r4,r4,1
11274: lwzu r11,16(r3) 147 slwi r3,r3,8
113 adde r0,r0,r6 148 rlwimi r3,r9,0,24,31
11475: stw r6,4(r4) 14971: stb r9,4(r6)
115 adde r0,r0,r9 150 addi r6,r6,1
11676: stw r9,8(r4) 151 bdnz 70b
117 adde r0,r0,r10 152 adde r12,r12,r3
11877: stw r10,12(r4) 15361: subf r5,r0,r5
119 adde r0,r0,r11 154 srwi. r0,r0,2
12078: stwu r11,16(r4) 155 mtctr r0
121 bdnz 71b 156 beq 58f
12210: rlwinm. r6,r5,30,30,31 /* # words left to do */ 15772: lwzu r9,4(r4) /* do some words */
123 beq 13f 158 adde r12,r12,r9
124 mtctr r6 15973: stwu r9,4(r6)
12582: lwzu r9,4(r3) 160 bdnz 72b
12692: stwu r9,4(r4) 161
127 adde r0,r0,r9 16258: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
128 bdnz 82b 163 clrlwi r5,r5,32-LG_CACHELINE_BYTES
12913: andi. r5,r5,3 164 li r11,4
1303: cmpwi 0,r5,2 165 beq 63f
131 blt+ 4f 166
13283: lhz r6,4(r3) 167 /* Here we decide how far ahead to prefetch the source */
133 addi r3,r3,2 168 li r3,4
134 subi r5,r5,2 169 cmpwi r0,1
13593: sth r6,4(r4) 170 li r7,0
171 ble 114f
172 li r7,1
173#if MAX_COPY_PREFETCH > 1
174 /* Heuristically, for large transfers we prefetch
175 MAX_COPY_PREFETCH cachelines ahead. For small transfers
176 we prefetch 1 cacheline ahead. */
177 cmpwi r0,MAX_COPY_PREFETCH
178 ble 112f
179 li r7,MAX_COPY_PREFETCH
180112: mtctr r7
181111: dcbt r3,r4
182 addi r3,r3,CACHELINE_BYTES
183 bdnz 111b
184#else
185 dcbt r3,r4
186 addi r3,r3,CACHELINE_BYTES
187#endif /* MAX_COPY_PREFETCH > 1 */
188
189114: subf r8,r7,r0
190 mr r0,r7
191 mtctr r8
192
19353: dcbt r3,r4
19454: dcbz r11,r6
195/* the main body of the cacheline loop */
196 CSUM_COPY_16_BYTES_WITHEX(0)
197#if L1_CACHE_BYTES >= 32
198 CSUM_COPY_16_BYTES_WITHEX(1)
199#if L1_CACHE_BYTES >= 64
200 CSUM_COPY_16_BYTES_WITHEX(2)
201 CSUM_COPY_16_BYTES_WITHEX(3)
202#if L1_CACHE_BYTES >= 128
203 CSUM_COPY_16_BYTES_WITHEX(4)
204 CSUM_COPY_16_BYTES_WITHEX(5)
205 CSUM_COPY_16_BYTES_WITHEX(6)
206 CSUM_COPY_16_BYTES_WITHEX(7)
207#endif
208#endif
209#endif
210 bdnz 53b
211 cmpwi r0,0
212 li r3,4
213 li r7,0
214 bne 114b
215
21663: srwi. r0,r5,2
217 mtctr r0
218 beq 64f
21930: lwzu r0,4(r4)
220 adde r12,r12,r0
22131: stwu r0,4(r6)
222 bdnz 30b
223
22464: andi. r0,r5,2
225 beq+ 65f
22640: lhz r0,4(r4)
136 addi r4,r4,2 227 addi r4,r4,2
137 adde r0,r0,r6 22841: sth r0,4(r6)
1384: cmpwi 0,r5,1 229 adde r12,r12,r0
139 bne+ 5f 230 addi r6,r6,2
14084: lbz r6,4(r3) 23165: andi. r0,r5,1
14194: stb r6,4(r4) 232 beq+ 66f
142 slwi r6,r6,8 /* Upper byte of word */ 23350: lbz r0,4(r4)
143 adde r0,r0,r6 23451: stb r0,4(r6)
1445: addze r3,r0 /* add in final carry */ 235 slwi r0,r0,8
236 adde r12,r12,r0
23766: addze r3,r12
238 addi r1,r1,16
239 beqlr+ cr7
240 rlwinm r3,r3,8,0,31 /* swap bytes for odd destination */
145 blr 241 blr
146 242
147/* These shouldn't go in the fixup section, since that would 243/* read fault */
148 cause the ex_table addresses to get out of order. */
149
150src_error_4:
151 mfctr r6 /* update # bytes remaining from ctr */
152 rlwimi r5,r6,4,0,27
153 b 79f
154src_error_1:
155 li r6,0
156 subi r5,r5,2
15795: sth r6,4(r4)
158 addi r4,r4,2
15979: srwi. r6,r5,2
160 beq 3f
161 mtctr r6
162src_error_2:
163 li r6,0
16496: stwu r6,4(r4)
165 bdnz 96b
1663: andi. r5,r5,3
167 beq src_error
168src_error_3:
169 li r6,0
170 mtctr r5
171 addi r4,r4,3
17297: stbu r6,1(r4)
173 bdnz 97b
174src_error: 244src_error:
175 cmpwi 0,r7,0 245 lwz r7,12(r1)
176 beq 1f 246 addi r1,r1,16
177 li r6,-EFAULT 247 cmpwi cr0,r7,0
178 stw r6,0(r7) 248 beqlr
1791: addze r3,r0 249 li r0,-EFAULT
250 stw r0,0(r7)
180 blr 251 blr
181 252/* write fault */
182dst_error: 253dst_error:
183 cmpwi 0,r8,0 254 lwz r8,8(r1)
184 beq 1f 255 addi r1,r1,16
185 li r6,-EFAULT 256 cmpwi cr0,r8,0
186 stw r6,0(r8) 257 beqlr
1871: addze r3,r0 258 li r0,-EFAULT
259 stw r0,0(r8)
188 blr 260 blr
189 261
190.section __ex_table,"a" 262 .section __ex_table,"a"
191 .long 81b,src_error_1 263 .align 2
192 .long 91b,dst_error 264 .long 70b,src_error
193 .long 71b,src_error_4 265 .long 71b,dst_error
194 .long 72b,src_error_4 266 .long 72b,src_error
195 .long 73b,src_error_4 267 .long 73b,dst_error
196 .long 74b,src_error_4 268 .long 54b,dst_error
197 .long 75b,dst_error 269 .text
198 .long 76b,dst_error 270
199 .long 77b,dst_error 271/*
200 .long 78b,dst_error 272 * this stuff handles faults in the cacheline loop and branches to either
201 .long 82b,src_error_2 273 * src_error (if in read part) or dst_error (if in write part)
202 .long 92b,dst_error 274 */
203 .long 83b,src_error_3 275 CSUM_COPY_16_BYTES_EXCODE(0)
204 .long 93b,dst_error 276#if L1_CACHE_BYTES >= 32
205 .long 84b,src_error_3 277 CSUM_COPY_16_BYTES_EXCODE(1)
206 .long 94b,dst_error 278#if L1_CACHE_BYTES >= 64
207 .long 95b,dst_error 279 CSUM_COPY_16_BYTES_EXCODE(2)
208 .long 96b,dst_error 280 CSUM_COPY_16_BYTES_EXCODE(3)
209 .long 97b,dst_error 281#if L1_CACHE_BYTES >= 128
282 CSUM_COPY_16_BYTES_EXCODE(4)
283 CSUM_COPY_16_BYTES_EXCODE(5)
284 CSUM_COPY_16_BYTES_EXCODE(6)
285 CSUM_COPY_16_BYTES_EXCODE(7)
286#endif
287#endif
288#endif
289
290 .section __ex_table,"a"
291 .align 2
292 .long 30b,src_error
293 .long 31b,dst_error
294 .long 40b,src_error
295 .long 41b,dst_error
296 .long 50b,src_error
297 .long 51b,dst_error
diff --git a/arch/powerpc/lib/checksum_64.S b/arch/powerpc/lib/checksum_64.S
index f3ef35436612..8e6e51016cc5 100644
--- a/arch/powerpc/lib/checksum_64.S
+++ b/arch/powerpc/lib/checksum_64.S
@@ -18,39 +18,12 @@
18#include <asm/ppc_asm.h> 18#include <asm/ppc_asm.h>
19 19
20/* 20/*
21 * ip_fast_csum(r3=buf, r4=len) -- Optimized for IP header
22 * len is in words and is always >= 5.
23 *
24 * In practice len == 5, but this is not guaranteed. So this code does not
25 * attempt to use doubleword instructions.
26 */
27_GLOBAL(ip_fast_csum)
28 lwz r0,0(r3)
29 lwzu r5,4(r3)
30 addic. r4,r4,-2
31 addc r0,r0,r5
32 mtctr r4
33 blelr-
341: lwzu r4,4(r3)
35 adde r0,r0,r4
36 bdnz 1b
37 addze r0,r0 /* add in final carry */
38 rldicl r4,r0,32,0 /* fold two 32-bit halves together */
39 add r0,r0,r4
40 srdi r0,r0,32
41 rlwinm r3,r0,16,0,31 /* fold two halves together */
42 add r3,r0,r3
43 not r3,r3
44 srwi r3,r3,16
45 blr
46
47/*
48 * Computes the checksum of a memory block at buff, length len, 21 * Computes the checksum of a memory block at buff, length len,
49 * and adds in "sum" (32-bit). 22 * and adds in "sum" (32-bit).
50 * 23 *
51 * csum_partial(r3=buff, r4=len, r5=sum) 24 * __csum_partial(r3=buff, r4=len, r5=sum)
52 */ 25 */
53_GLOBAL(csum_partial) 26_GLOBAL(__csum_partial)
54 addic r0,r5,0 /* clear carry */ 27 addic r0,r5,0 /* clear carry */
55 28
56 srdi. r6,r4,3 /* less than 8 bytes? */ 29 srdi. r6,r4,3 /* less than 8 bytes? */
diff --git a/arch/powerpc/lib/checksum_wrappers_64.c b/arch/powerpc/lib/checksum_wrappers.c
index 08e3a3356c40..08e3a3356c40 100644
--- a/arch/powerpc/lib/checksum_wrappers_64.c
+++ b/arch/powerpc/lib/checksum_wrappers.c
diff --git a/arch/powerpc/lib/ppc_ksyms.c b/arch/powerpc/lib/ppc_ksyms.c
index c7f8e9586316..c422812f7405 100644
--- a/arch/powerpc/lib/ppc_ksyms.c
+++ b/arch/powerpc/lib/ppc_ksyms.c
@@ -17,10 +17,8 @@ EXPORT_SYMBOL(strcmp);
17EXPORT_SYMBOL(strncmp); 17EXPORT_SYMBOL(strncmp);
18 18
19#ifndef CONFIG_GENERIC_CSUM 19#ifndef CONFIG_GENERIC_CSUM
20EXPORT_SYMBOL(csum_partial); 20EXPORT_SYMBOL(__csum_partial);
21EXPORT_SYMBOL(csum_partial_copy_generic); 21EXPORT_SYMBOL(csum_partial_copy_generic);
22EXPORT_SYMBOL(ip_fast_csum);
23EXPORT_SYMBOL(csum_tcpudp_magic);
24#endif 22#endif
25 23
26EXPORT_SYMBOL(__copy_tofrom_user); 24EXPORT_SYMBOL(__copy_tofrom_user);
diff --git a/arch/powerpc/mm/8xx_mmu.c b/arch/powerpc/mm/8xx_mmu.c
new file mode 100644
index 000000000000..949100577db5
--- /dev/null
+++ b/arch/powerpc/mm/8xx_mmu.c
@@ -0,0 +1,141 @@
1/*
2 * This file contains the routines for initializing the MMU
3 * on the 8xx series of chips.
4 * -- christophe
5 *
6 * Derived from arch/powerpc/mm/40x_mmu.c:
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 *
13 */
14
15#include <linux/memblock.h>
16
17#include "mmu_decl.h"
18
19extern int __map_without_ltlbs;
20/*
21 * MMU_init_hw does the chip-specific initialization of the MMU hardware.
22 */
23void __init MMU_init_hw(void)
24{
25 /* Nothing to do for the time being but keep it similar to other PPC */
26}
27
28#define LARGE_PAGE_SIZE_4M (1<<22)
29#define LARGE_PAGE_SIZE_8M (1<<23)
30#define LARGE_PAGE_SIZE_64M (1<<26)
31
32unsigned long __init mmu_mapin_ram(unsigned long top)
33{
34 unsigned long v, s, mapped;
35 phys_addr_t p;
36
37 v = KERNELBASE;
38 p = 0;
39 s = top;
40
41 if (__map_without_ltlbs)
42 return 0;
43
44#ifdef CONFIG_PPC_4K_PAGES
45 while (s >= LARGE_PAGE_SIZE_8M) {
46 pmd_t *pmdp;
47 unsigned long val = p | MD_PS8MEG;
48
49 pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v);
50 *pmdp++ = __pmd(val);
51 *pmdp++ = __pmd(val + LARGE_PAGE_SIZE_4M);
52
53 v += LARGE_PAGE_SIZE_8M;
54 p += LARGE_PAGE_SIZE_8M;
55 s -= LARGE_PAGE_SIZE_8M;
56 }
57#else /* CONFIG_PPC_16K_PAGES */
58 while (s >= LARGE_PAGE_SIZE_64M) {
59 pmd_t *pmdp;
60 unsigned long val = p | MD_PS8MEG;
61
62 pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v);
63 *pmdp++ = __pmd(val);
64
65 v += LARGE_PAGE_SIZE_64M;
66 p += LARGE_PAGE_SIZE_64M;
67 s -= LARGE_PAGE_SIZE_64M;
68 }
69#endif
70
71 mapped = top - s;
72
73 /* If the size of RAM is not an exact power of two, we may not
74 * have covered RAM in its entirety with 8 MiB
75 * pages. Consequently, restrict the top end of RAM currently
76 * allocable so that calls to the MEMBLOCK to allocate PTEs for "tail"
77 * coverage with normal-sized pages (or other reasons) do not
78 * attempt to allocate outside the allowed range.
79 */
80 memblock_set_current_limit(mapped);
81
82 return mapped;
83}
84
85void setup_initial_memory_limit(phys_addr_t first_memblock_base,
86 phys_addr_t first_memblock_size)
87{
88 /* We don't currently support the first MEMBLOCK not mapping 0
89 * physical on those processors
90 */
91 BUG_ON(first_memblock_base != 0);
92
93#ifdef CONFIG_PIN_TLB
94 /* 8xx can only access 24MB at the moment */
95 memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01800000));
96#else
97 /* 8xx can only access 8MB at the moment */
98 memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000));
99#endif
100}
101
102/*
103 * Set up to use a given MMU context.
104 * id is context number, pgd is PGD pointer.
105 *
106 * We place the physical address of the new task page directory loaded
107 * into the MMU base register, and set the ASID compare register with
108 * the new "context."
109 */
110void set_context(unsigned long id, pgd_t *pgd)
111{
112 s16 offset = (s16)(__pa(swapper_pg_dir));
113
114#ifdef CONFIG_BDI_SWITCH
115 pgd_t **ptr = *(pgd_t ***)(KERNELBASE + 0xf0);
116
117 /* Context switch the PTE pointer for the Abatron BDI2000.
118 * The PGDIR is passed as second argument.
119 */
120 *(ptr + 1) = pgd;
121#endif
122
123 /* Register M_TW will contain base address of level 1 table minus the
124 * lower part of the kernel PGDIR base address, so that all accesses to
125 * level 1 table are done relative to lower part of kernel PGDIR base
126 * address.
127 */
128 mtspr(SPRN_M_TW, __pa(pgd) - offset);
129
130 /* Update context */
131 mtspr(SPRN_M_CASID, id);
132 /* sync */
133 mb();
134}
135
136void flush_instruction_cache(void)
137{
138 isync();
139 mtspr(SPRN_IC_CST, IDC_INVALL);
140 isync();
141}
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 1ffeda85c086..adfee3f1aeb9 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_PPC_ICSWX) += icswx.o
25obj-$(CONFIG_PPC_ICSWX_PID) += icswx_pid.o 25obj-$(CONFIG_PPC_ICSWX_PID) += icswx_pid.o
26obj-$(CONFIG_40x) += 40x_mmu.o 26obj-$(CONFIG_40x) += 40x_mmu.o
27obj-$(CONFIG_44x) += 44x_mmu.o 27obj-$(CONFIG_44x) += 44x_mmu.o
28obj-$(CONFIG_PPC_8xx) += 8xx_mmu.o
28obj-$(CONFIG_PPC_FSL_BOOK3E) += fsl_booke_mmu.o 29obj-$(CONFIG_PPC_FSL_BOOK3E) += fsl_booke_mmu.o
29obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o 30obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
30obj-$(CONFIG_PPC_SPLPAR) += vphn.o 31obj-$(CONFIG_PPC_SPLPAR) += vphn.o
diff --git a/arch/powerpc/mm/dma-noncoherent.c b/arch/powerpc/mm/dma-noncoherent.c
index 169aba446a74..2dc74e5c6458 100644
--- a/arch/powerpc/mm/dma-noncoherent.c
+++ b/arch/powerpc/mm/dma-noncoherent.c
@@ -327,7 +327,7 @@ void __dma_sync(void *vaddr, size_t size, int direction)
327 * invalidate only when cache-line aligned otherwise there is 327 * invalidate only when cache-line aligned otherwise there is
328 * the potential for discarding uncommitted data from the cache 328 * the potential for discarding uncommitted data from the cache
329 */ 329 */
330 if ((start & (L1_CACHE_BYTES - 1)) || (size & (L1_CACHE_BYTES - 1))) 330 if ((start | end) & (L1_CACHE_BYTES - 1))
331 flush_dcache_range(start, end); 331 flush_dcache_range(start, end);
332 else 332 else
333 invalidate_dcache_range(start, end); 333 invalidate_dcache_range(start, end);
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index f3afe3d97f6b..a1b2713f6e96 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -72,10 +72,11 @@ unsigned long tlbcam_sz(int idx)
72 return tlbcam_addrs[idx].limit - tlbcam_addrs[idx].start + 1; 72 return tlbcam_addrs[idx].limit - tlbcam_addrs[idx].start + 1;
73} 73}
74 74
75#ifdef CONFIG_FSL_BOOKE
75/* 76/*
76 * Return PA for this VA if it is mapped by a CAM, or 0 77 * Return PA for this VA if it is mapped by a CAM, or 0
77 */ 78 */
78phys_addr_t v_mapped_by_tlbcam(unsigned long va) 79phys_addr_t v_block_mapped(unsigned long va)
79{ 80{
80 int b; 81 int b;
81 for (b = 0; b < tlbcam_index; ++b) 82 for (b = 0; b < tlbcam_index; ++b)
@@ -87,7 +88,7 @@ phys_addr_t v_mapped_by_tlbcam(unsigned long va)
87/* 88/*
88 * Return VA for a given PA or 0 if not mapped 89 * Return VA for a given PA or 0 if not mapped
89 */ 90 */
90unsigned long p_mapped_by_tlbcam(phys_addr_t pa) 91unsigned long p_block_mapped(phys_addr_t pa)
91{ 92{
92 int b; 93 int b;
93 for (b = 0; b < tlbcam_index; ++b) 94 for (b = 0; b < tlbcam_index; ++b)
@@ -97,6 +98,7 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa)
97 return tlbcam_addrs[b].start+(pa-tlbcam_addrs[b].phys); 98 return tlbcam_addrs[b].start+(pa-tlbcam_addrs[b].phys);
98 return 0; 99 return 0;
99} 100}
101#endif
100 102
101/* 103/*
102 * Set up a variable-size TLB entry (tlbcam). The parameters are not checked; 104 * Set up a variable-size TLB entry (tlbcam). The parameters are not checked;
diff --git a/arch/powerpc/mm/hash64_4k.c b/arch/powerpc/mm/hash64_4k.c
index e7c04542ba62..47d1b26effc6 100644
--- a/arch/powerpc/mm/hash64_4k.c
+++ b/arch/powerpc/mm/hash64_4k.c
@@ -44,7 +44,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
44 * a write access. Since this is 4K insert of 64K page size 44 * a write access. Since this is 4K insert of 64K page size
45 * also add _PAGE_COMBO 45 * also add _PAGE_COMBO
46 */ 46 */
47 new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE; 47 new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED;
48 if (access & _PAGE_RW) 48 if (access & _PAGE_RW)
49 new_pte |= _PAGE_DIRTY; 49 new_pte |= _PAGE_DIRTY;
50 } while (old_pte != __cmpxchg_u64((unsigned long *)ptep, 50 } while (old_pte != __cmpxchg_u64((unsigned long *)ptep,
@@ -106,7 +106,7 @@ repeat:
106 } 106 }
107 } 107 }
108 /* 108 /*
109 * Hypervisor failure. Restore old pmd and return -1 109 * Hypervisor failure. Restore old pte and return -1
110 * similar to __hash_page_* 110 * similar to __hash_page_*
111 */ 111 */
112 if (unlikely(slot == -2)) { 112 if (unlikely(slot == -2)) {
diff --git a/arch/powerpc/mm/hash64_64k.c b/arch/powerpc/mm/hash64_64k.c
index edb09912f0c9..b2d659cf51c6 100644
--- a/arch/powerpc/mm/hash64_64k.c
+++ b/arch/powerpc/mm/hash64_64k.c
@@ -188,7 +188,7 @@ repeat:
188 } 188 }
189 } 189 }
190 /* 190 /*
191 * Hypervisor failure. Restore old pmd and return -1 191 * Hypervisor failure. Restore old pte and return -1
192 * similar to __hash_page_* 192 * similar to __hash_page_*
193 */ 193 */
194 if (unlikely(slot == -2)) { 194 if (unlikely(slot == -2)) {
@@ -249,8 +249,7 @@ int __hash_page_64K(unsigned long ea, unsigned long access,
249 return 0; 249 return 0;
250 /* 250 /*
251 * Try to lock the PTE, add ACCESSED and DIRTY if it was 251 * Try to lock the PTE, add ACCESSED and DIRTY if it was
252 * a write access. Since this is 4K insert of 64K page size 252 * a write access.
253 * also add _PAGE_COMBO
254 */ 253 */
255 new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED; 254 new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED;
256 if (access & _PAGE_RW) 255 if (access & _PAGE_RW)
@@ -311,7 +310,7 @@ repeat:
311 } 310 }
312 } 311 }
313 /* 312 /*
314 * Hypervisor failure. Restore old pmd and return -1 313 * Hypervisor failure. Restore old pte and return -1
315 * similar to __hash_page_* 314 * similar to __hash_page_*
316 */ 315 */
317 if (unlikely(slot == -2)) { 316 if (unlikely(slot == -2)) {
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 1005281be9a6..7635b1c6b5da 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -168,11 +168,11 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags)
168 rflags |= HPTE_R_N; 168 rflags |= HPTE_R_N;
169 /* 169 /*
170 * PP bits: 170 * PP bits:
171 * Linux use slb key 0 for kernel and 1 for user. 171 * Linux uses slb key 0 for kernel and 1 for user.
172 * kernel areas are mapped by PP bits 00 172 * kernel areas are mapped with PP=00
173 * and and there is no kernel RO (_PAGE_KERNEL_RO). 173 * and there is no kernel RO (_PAGE_KERNEL_RO).
174 * User area mapped by 0x2 and read only use by 174 * User area is mapped with PP=0x2 for read/write
175 * 0x3. 175 * or PP=0x3 for read-only (including writeable but clean pages).
176 */ 176 */
177 if (pteflags & _PAGE_USER) { 177 if (pteflags & _PAGE_USER) {
178 rflags |= 0x2; 178 rflags |= 0x2;
@@ -265,28 +265,32 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
265 return ret < 0 ? ret : 0; 265 return ret < 0 ? ret : 0;
266} 266}
267 267
268#ifdef CONFIG_MEMORY_HOTPLUG
269int htab_remove_mapping(unsigned long vstart, unsigned long vend, 268int htab_remove_mapping(unsigned long vstart, unsigned long vend,
270 int psize, int ssize) 269 int psize, int ssize)
271{ 270{
272 unsigned long vaddr; 271 unsigned long vaddr;
273 unsigned int step, shift; 272 unsigned int step, shift;
273 int rc;
274 int ret = 0;
274 275
275 shift = mmu_psize_defs[psize].shift; 276 shift = mmu_psize_defs[psize].shift;
276 step = 1 << shift; 277 step = 1 << shift;
277 278
278 if (!ppc_md.hpte_removebolted) { 279 if (!ppc_md.hpte_removebolted)
279 printk(KERN_WARNING "Platform doesn't implement " 280 return -ENODEV;
280 "hpte_removebolted\n");
281 return -EINVAL;
282 }
283 281
284 for (vaddr = vstart; vaddr < vend; vaddr += step) 282 for (vaddr = vstart; vaddr < vend; vaddr += step) {
285 ppc_md.hpte_removebolted(vaddr, psize, ssize); 283 rc = ppc_md.hpte_removebolted(vaddr, psize, ssize);
284 if (rc == -ENOENT) {
285 ret = -ENOENT;
286 continue;
287 }
288 if (rc < 0)
289 return rc;
290 }
286 291
287 return 0; 292 return ret;
288} 293}
289#endif /* CONFIG_MEMORY_HOTPLUG */
290 294
291static int __init htab_dt_scan_seg_sizes(unsigned long node, 295static int __init htab_dt_scan_seg_sizes(unsigned long node,
292 const char *uname, int depth, 296 const char *uname, int depth,
@@ -607,10 +611,28 @@ static int __init htab_dt_scan_pftsize(unsigned long node,
607 return 0; 611 return 0;
608} 612}
609 613
610static unsigned long __init htab_get_table_size(void) 614unsigned htab_shift_for_mem_size(unsigned long mem_size)
611{ 615{
612 unsigned long mem_size, rnd_mem_size, pteg_count, psize; 616 unsigned memshift = __ilog2(mem_size);
617 unsigned pshift = mmu_psize_defs[mmu_virtual_psize].shift;
618 unsigned pteg_shift;
619
620 /* round mem_size up to next power of 2 */
621 if ((1UL << memshift) < mem_size)
622 memshift += 1;
623
624 /* aim for 2 pages / pteg */
625 pteg_shift = memshift - (pshift + 1);
613 626
627 /*
628 * 2^11 PTEGS of 128 bytes each, ie. 2^18 bytes is the minimum htab
629 * size permitted by the architecture.
630 */
631 return max(pteg_shift + 7, 18U);
632}
633
634static unsigned long __init htab_get_table_size(void)
635{
614 /* If hash size isn't already provided by the platform, we try to 636 /* If hash size isn't already provided by the platform, we try to
615 * retrieve it from the device-tree. If it's not there neither, we 637 * retrieve it from the device-tree. If it's not there neither, we
616 * calculate it now based on the total RAM size 638 * calculate it now based on the total RAM size
@@ -620,31 +642,30 @@ static unsigned long __init htab_get_table_size(void)
620 if (ppc64_pft_size) 642 if (ppc64_pft_size)
621 return 1UL << ppc64_pft_size; 643 return 1UL << ppc64_pft_size;
622 644
623 /* round mem_size up to next power of 2 */ 645 return 1UL << htab_shift_for_mem_size(memblock_phys_mem_size());
624 mem_size = memblock_phys_mem_size();
625 rnd_mem_size = 1UL << __ilog2(mem_size);
626 if (rnd_mem_size < mem_size)
627 rnd_mem_size <<= 1;
628
629 /* # pages / 2 */
630 psize = mmu_psize_defs[mmu_virtual_psize].shift;
631 pteg_count = max(rnd_mem_size >> (psize + 1), 1UL << 11);
632
633 return pteg_count << 7;
634} 646}
635 647
636#ifdef CONFIG_MEMORY_HOTPLUG 648#ifdef CONFIG_MEMORY_HOTPLUG
637int create_section_mapping(unsigned long start, unsigned long end) 649int create_section_mapping(unsigned long start, unsigned long end)
638{ 650{
639 return htab_bolt_mapping(start, end, __pa(start), 651 int rc = htab_bolt_mapping(start, end, __pa(start),
640 pgprot_val(PAGE_KERNEL), mmu_linear_psize, 652 pgprot_val(PAGE_KERNEL), mmu_linear_psize,
641 mmu_kernel_ssize); 653 mmu_kernel_ssize);
654
655 if (rc < 0) {
656 int rc2 = htab_remove_mapping(start, end, mmu_linear_psize,
657 mmu_kernel_ssize);
658 BUG_ON(rc2 && (rc2 != -ENOENT));
659 }
660 return rc;
642} 661}
643 662
644int remove_section_mapping(unsigned long start, unsigned long end) 663int remove_section_mapping(unsigned long start, unsigned long end)
645{ 664{
646 return htab_remove_mapping(start, end, mmu_linear_psize, 665 int rc = htab_remove_mapping(start, end, mmu_linear_psize,
647 mmu_kernel_ssize); 666 mmu_kernel_ssize);
667 WARN_ON(rc < 0);
668 return rc;
648} 669}
649#endif /* CONFIG_MEMORY_HOTPLUG */ 670#endif /* CONFIG_MEMORY_HOTPLUG */
650 671
diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c
index e2138c7ae70f..8555fce902fe 100644
--- a/arch/powerpc/mm/hugetlbpage-hash64.c
+++ b/arch/powerpc/mm/hugetlbpage-hash64.c
@@ -76,7 +76,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
76 if (old_pte & _PAGE_F_SECOND) 76 if (old_pte & _PAGE_F_SECOND)
77 hash = ~hash; 77 hash = ~hash;
78 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; 78 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
79 slot += (old_pte & _PAGE_F_GIX) >> 12; 79 slot += (old_pte & _PAGE_F_GIX) >> _PAGE_F_GIX_SHIFT;
80 80
81 if (ppc_md.hpte_updatepp(slot, rflags, vpn, mmu_psize, 81 if (ppc_md.hpte_updatepp(slot, rflags, vpn, mmu_psize,
82 mmu_psize, ssize, flags) == -1) 82 mmu_psize, ssize, flags) == -1)
@@ -105,7 +105,8 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
105 return -1; 105 return -1;
106 } 106 }
107 107
108 new_pte |= (slot << 12) & (_PAGE_F_SECOND | _PAGE_F_GIX); 108 new_pte |= (slot << _PAGE_F_GIX_SHIFT) &
109 (_PAGE_F_SECOND | _PAGE_F_GIX);
109 } 110 }
110 111
111 /* 112 /*
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 744e24bcb85c..6dd272b6196f 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -107,8 +107,7 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
107 kmem_cache_free(cachep, new); 107 kmem_cache_free(cachep, new);
108 else { 108 else {
109#ifdef CONFIG_PPC_BOOK3S_64 109#ifdef CONFIG_PPC_BOOK3S_64
110 hpdp->pd = (unsigned long)new | 110 hpdp->pd = __pa(new) | (shift_to_mmu_psize(pshift) << 2);
111 (shift_to_mmu_psize(pshift) << 2);
112#else 111#else
113 hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift; 112 hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift;
114#endif 113#endif
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index c2b771614d4f..c899fe340bbd 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -178,10 +178,6 @@ void __init MMU_init(void)
178 /* Initialize early top-down ioremap allocator */ 178 /* Initialize early top-down ioremap allocator */
179 ioremap_bot = IOREMAP_TOP; 179 ioremap_bot = IOREMAP_TOP;
180 180
181 /* Map in I/O resources */
182 if (ppc_md.progress)
183 ppc_md.progress("MMU:setio", 0x302);
184
185 if (ppc_md.progress) 181 if (ppc_md.progress)
186 ppc_md.progress("MMU:exit", 0x211); 182 ppc_md.progress("MMU:exit", 0x211);
187 183
@@ -193,22 +189,3 @@ void __init MMU_init(void)
193 /* Shortly after that, the entire linear mapping will be available */ 189 /* Shortly after that, the entire linear mapping will be available */
194 memblock_set_current_limit(lowmem_end_addr); 190 memblock_set_current_limit(lowmem_end_addr);
195} 191}
196
197#ifdef CONFIG_8xx /* No 8xx specific .c file to put that in ... */
198void setup_initial_memory_limit(phys_addr_t first_memblock_base,
199 phys_addr_t first_memblock_size)
200{
201 /* We don't currently support the first MEMBLOCK not mapping 0
202 * physical on those processors
203 */
204 BUG_ON(first_memblock_base != 0);
205
206#ifdef CONFIG_PIN_TLB
207 /* 8xx can only access 24MB at the moment */
208 memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01800000));
209#else
210 /* 8xx can only access 8MB at the moment */
211 memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000));
212#endif
213}
214#endif /* CONFIG_8xx */
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 379a6a90644b..ba655666186d 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -85,6 +85,11 @@ static void pgd_ctor(void *addr)
85 memset(addr, 0, PGD_TABLE_SIZE); 85 memset(addr, 0, PGD_TABLE_SIZE);
86} 86}
87 87
88static void pud_ctor(void *addr)
89{
90 memset(addr, 0, PUD_TABLE_SIZE);
91}
92
88static void pmd_ctor(void *addr) 93static void pmd_ctor(void *addr)
89{ 94{
90 memset(addr, 0, PMD_TABLE_SIZE); 95 memset(addr, 0, PMD_TABLE_SIZE);
@@ -138,14 +143,18 @@ void pgtable_cache_init(void)
138{ 143{
139 pgtable_cache_add(PGD_INDEX_SIZE, pgd_ctor); 144 pgtable_cache_add(PGD_INDEX_SIZE, pgd_ctor);
140 pgtable_cache_add(PMD_CACHE_INDEX, pmd_ctor); 145 pgtable_cache_add(PMD_CACHE_INDEX, pmd_ctor);
146 /*
147 * In all current configs, when the PUD index exists it's the
148 * same size as either the pgd or pmd index except with THP enabled
149 * on book3s 64
150 */
151 if (PUD_INDEX_SIZE && !PGT_CACHE(PUD_INDEX_SIZE))
152 pgtable_cache_add(PUD_INDEX_SIZE, pud_ctor);
153
141 if (!PGT_CACHE(PGD_INDEX_SIZE) || !PGT_CACHE(PMD_CACHE_INDEX)) 154 if (!PGT_CACHE(PGD_INDEX_SIZE) || !PGT_CACHE(PMD_CACHE_INDEX))
142 panic("Couldn't allocate pgtable caches"); 155 panic("Couldn't allocate pgtable caches");
143 /* In all current configs, when the PUD index exists it's the 156 if (PUD_INDEX_SIZE && !PGT_CACHE(PUD_INDEX_SIZE))
144 * same size as either the pgd or pmd index. Verify that the 157 panic("Couldn't allocate pud pgtable caches");
145 * initialization above has also created a PUD cache. This
146 * will need re-examiniation if we add new possibilities for
147 * the pagetable layout. */
148 BUG_ON(PUD_INDEX_SIZE && !PGT_CACHE(PUD_INDEX_SIZE));
149} 158}
150 159
151#ifdef CONFIG_SPARSEMEM_VMEMMAP 160#ifdef CONFIG_SPARSEMEM_VMEMMAP
@@ -188,9 +197,9 @@ static int __meminit vmemmap_populated(unsigned long start, int page_size)
188 */ 197 */
189 198
190#ifdef CONFIG_PPC_BOOK3E 199#ifdef CONFIG_PPC_BOOK3E
191static void __meminit vmemmap_create_mapping(unsigned long start, 200static int __meminit vmemmap_create_mapping(unsigned long start,
192 unsigned long page_size, 201 unsigned long page_size,
193 unsigned long phys) 202 unsigned long phys)
194{ 203{
195 /* Create a PTE encoding without page size */ 204 /* Create a PTE encoding without page size */
196 unsigned long i, flags = _PAGE_PRESENT | _PAGE_ACCESSED | 205 unsigned long i, flags = _PAGE_PRESENT | _PAGE_ACCESSED |
@@ -208,6 +217,8 @@ static void __meminit vmemmap_create_mapping(unsigned long start,
208 */ 217 */
209 for (i = 0; i < page_size; i += PAGE_SIZE) 218 for (i = 0; i < page_size; i += PAGE_SIZE)
210 BUG_ON(map_kernel_page(start + i, phys, flags)); 219 BUG_ON(map_kernel_page(start + i, phys, flags));
220
221 return 0;
211} 222}
212 223
213#ifdef CONFIG_MEMORY_HOTPLUG 224#ifdef CONFIG_MEMORY_HOTPLUG
@@ -217,25 +228,31 @@ static void vmemmap_remove_mapping(unsigned long start,
217} 228}
218#endif 229#endif
219#else /* CONFIG_PPC_BOOK3E */ 230#else /* CONFIG_PPC_BOOK3E */
220static void __meminit vmemmap_create_mapping(unsigned long start, 231static int __meminit vmemmap_create_mapping(unsigned long start,
221 unsigned long page_size, 232 unsigned long page_size,
222 unsigned long phys) 233 unsigned long phys)
223{ 234{
224 int mapped = htab_bolt_mapping(start, start + page_size, phys, 235 int rc = htab_bolt_mapping(start, start + page_size, phys,
225 pgprot_val(PAGE_KERNEL), 236 pgprot_val(PAGE_KERNEL),
226 mmu_vmemmap_psize, 237 mmu_vmemmap_psize, mmu_kernel_ssize);
227 mmu_kernel_ssize); 238 if (rc < 0) {
228 BUG_ON(mapped < 0); 239 int rc2 = htab_remove_mapping(start, start + page_size,
240 mmu_vmemmap_psize,
241 mmu_kernel_ssize);
242 BUG_ON(rc2 && (rc2 != -ENOENT));
243 }
244 return rc;
229} 245}
230 246
231#ifdef CONFIG_MEMORY_HOTPLUG 247#ifdef CONFIG_MEMORY_HOTPLUG
232static void vmemmap_remove_mapping(unsigned long start, 248static void vmemmap_remove_mapping(unsigned long start,
233 unsigned long page_size) 249 unsigned long page_size)
234{ 250{
235 int mapped = htab_remove_mapping(start, start + page_size, 251 int rc = htab_remove_mapping(start, start + page_size,
236 mmu_vmemmap_psize, 252 mmu_vmemmap_psize,
237 mmu_kernel_ssize); 253 mmu_kernel_ssize);
238 BUG_ON(mapped < 0); 254 BUG_ON((rc < 0) && (rc != -ENOENT));
255 WARN_ON(rc == -ENOENT);
239} 256}
240#endif 257#endif
241 258
@@ -303,6 +320,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
303 320
304 for (; start < end; start += page_size) { 321 for (; start < end; start += page_size) {
305 void *p; 322 void *p;
323 int rc;
306 324
307 if (vmemmap_populated(start, page_size)) 325 if (vmemmap_populated(start, page_size))
308 continue; 326 continue;
@@ -316,7 +334,13 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
316 pr_debug(" * %016lx..%016lx allocated at %p\n", 334 pr_debug(" * %016lx..%016lx allocated at %p\n",
317 start, start + page_size, p); 335 start, start + page_size, p);
318 336
319 vmemmap_create_mapping(start, page_size, __pa(p)); 337 rc = vmemmap_create_mapping(start, page_size, __pa(p));
338 if (rc < 0) {
339 pr_warning(
340 "vmemmap_populate: Unable to create vmemmap mapping: %d\n",
341 rc);
342 return -EFAULT;
343 }
320 } 344 }
321 345
322 return 0; 346 return 0;
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index f078a1f94fc2..ac79dbde1015 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -119,12 +119,18 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
119 struct zone *zone; 119 struct zone *zone;
120 unsigned long start_pfn = start >> PAGE_SHIFT; 120 unsigned long start_pfn = start >> PAGE_SHIFT;
121 unsigned long nr_pages = size >> PAGE_SHIFT; 121 unsigned long nr_pages = size >> PAGE_SHIFT;
122 int rc;
122 123
123 pgdata = NODE_DATA(nid); 124 pgdata = NODE_DATA(nid);
124 125
125 start = (unsigned long)__va(start); 126 start = (unsigned long)__va(start);
126 if (create_section_mapping(start, start + size)) 127 rc = create_section_mapping(start, start + size);
127 return -EINVAL; 128 if (rc) {
129 pr_warning(
130 "Unable to create mapping for hot added memory 0x%llx..0x%llx: %d\n",
131 start, start + size, rc);
132 return -EFAULT;
133 }
128 134
129 /* this should work for most non-highmem platforms */ 135 /* this should work for most non-highmem platforms */
130 zone = pgdata->node_zones + 136 zone = pgdata->node_zones +
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 9f58ff44a075..bfb7c0bcabd5 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -100,7 +100,6 @@ extern void setbat(int index, unsigned long virt, phys_addr_t phys,
100 100
101extern int __map_without_bats; 101extern int __map_without_bats;
102extern int __allow_ioremap_reserved; 102extern int __allow_ioremap_reserved;
103extern unsigned long ioremap_base;
104extern unsigned int rtas_data, rtas_size; 103extern unsigned int rtas_data, rtas_size;
105 104
106struct hash_pte; 105struct hash_pte;
@@ -110,7 +109,8 @@ extern unsigned long Hash_size, Hash_mask;
110#endif /* CONFIG_PPC32 */ 109#endif /* CONFIG_PPC32 */
111 110
112#ifdef CONFIG_PPC64 111#ifdef CONFIG_PPC64
113extern int map_kernel_page(unsigned long ea, unsigned long pa, int flags); 112extern int map_kernel_page(unsigned long ea, unsigned long pa,
113 unsigned long flags);
114#endif /* CONFIG_PPC64 */ 114#endif /* CONFIG_PPC64 */
115 115
116extern unsigned long ioremap_bot; 116extern unsigned long ioremap_bot;
@@ -132,22 +132,17 @@ extern void wii_memory_fixups(void);
132/* ...and now those things that may be slightly different between processor 132/* ...and now those things that may be slightly different between processor
133 * architectures. -- Dan 133 * architectures. -- Dan
134 */ 134 */
135#if defined(CONFIG_8xx) 135#ifdef CONFIG_PPC32
136#define MMU_init_hw() do { } while(0)
137#define mmu_mapin_ram(top) (0UL)
138
139#elif defined(CONFIG_4xx)
140extern void MMU_init_hw(void); 136extern void MMU_init_hw(void);
141extern unsigned long mmu_mapin_ram(unsigned long top); 137extern unsigned long mmu_mapin_ram(unsigned long top);
138#endif
142 139
143#elif defined(CONFIG_PPC_FSL_BOOK3E) 140#ifdef CONFIG_PPC_FSL_BOOK3E
144extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx, 141extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx,
145 bool dryrun); 142 bool dryrun);
146extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt, 143extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt,
147 phys_addr_t phys); 144 phys_addr_t phys);
148#ifdef CONFIG_PPC32 145#ifdef CONFIG_PPC32
149extern void MMU_init_hw(void);
150extern unsigned long mmu_mapin_ram(unsigned long top);
151extern void adjust_total_lowmem(void); 146extern void adjust_total_lowmem(void);
152extern int switch_to_as1(void); 147extern int switch_to_as1(void);
153extern void restore_to_as0(int esel, int offset, void *dt_ptr, int bootcpu); 148extern void restore_to_as0(int esel, int offset, void *dt_ptr, int bootcpu);
@@ -162,8 +157,14 @@ struct tlbcam {
162 u32 MAS3; 157 u32 MAS3;
163 u32 MAS7; 158 u32 MAS7;
164}; 159};
165#elif defined(CONFIG_PPC32) 160#endif
166/* anything 32-bit except 4xx or 8xx */ 161
167extern void MMU_init_hw(void); 162#if defined(CONFIG_6xx) || defined(CONFIG_FSL_BOOKE)
168extern unsigned long mmu_mapin_ram(unsigned long top); 163/* 6xx have BATS */
164/* FSL_BOOKE have TLBCAM */
165phys_addr_t v_block_mapped(unsigned long va);
166unsigned long p_block_mapped(phys_addr_t pa);
167#else
168static inline phys_addr_t v_block_mapped(unsigned long va) { return 0; }
169static inline unsigned long p_block_mapped(phys_addr_t pa) { return 0; }
169#endif 170#endif
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 7692d1bb1bc6..bf7bf32b54f8 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -37,35 +37,10 @@
37 37
38#include "mmu_decl.h" 38#include "mmu_decl.h"
39 39
40unsigned long ioremap_base;
41unsigned long ioremap_bot; 40unsigned long ioremap_bot;
42EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */ 41EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */
43 42
44#ifdef CONFIG_6xx 43extern char etext[], _stext[], _sinittext[], _einittext[];
45#define HAVE_BATS 1
46#endif
47
48#if defined(CONFIG_FSL_BOOKE)
49#define HAVE_TLBCAM 1
50#endif
51
52extern char etext[], _stext[];
53
54#ifdef HAVE_BATS
55extern phys_addr_t v_mapped_by_bats(unsigned long va);
56extern unsigned long p_mapped_by_bats(phys_addr_t pa);
57#else /* !HAVE_BATS */
58#define v_mapped_by_bats(x) (0UL)
59#define p_mapped_by_bats(x) (0UL)
60#endif /* HAVE_BATS */
61
62#ifdef HAVE_TLBCAM
63extern phys_addr_t v_mapped_by_tlbcam(unsigned long va);
64extern unsigned long p_mapped_by_tlbcam(phys_addr_t pa);
65#else /* !HAVE_TLBCAM */
66#define v_mapped_by_tlbcam(x) (0UL)
67#define p_mapped_by_tlbcam(x) (0UL)
68#endif /* HAVE_TLBCAM */
69 44
70#define PGDIR_ORDER (32 + PGD_T_LOG2 - PGDIR_SHIFT) 45#define PGDIR_ORDER (32 + PGD_T_LOG2 - PGDIR_SHIFT)
71 46
@@ -197,7 +172,7 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags,
197 /* 172 /*
198 * Choose an address to map it to. 173 * Choose an address to map it to.
199 * Once the vmalloc system is running, we use it. 174 * Once the vmalloc system is running, we use it.
200 * Before then, we use space going down from ioremap_base 175 * Before then, we use space going down from IOREMAP_TOP
201 * (ioremap_bot records where we're up to). 176 * (ioremap_bot records where we're up to).
202 */ 177 */
203 p = addr & PAGE_MASK; 178 p = addr & PAGE_MASK;
@@ -228,19 +203,10 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags,
228 203
229 /* 204 /*
230 * Is it already mapped? Perhaps overlapped by a previous 205 * Is it already mapped? Perhaps overlapped by a previous
231 * BAT mapping. If the whole area is mapped then we're done, 206 * mapping.
232 * otherwise remap it since we want to keep the virt addrs for
233 * each request contiguous.
234 *
235 * We make the assumption here that if the bottom and top
236 * of the range we want are mapped then it's mapped to the
237 * same virt address (and this is contiguous).
238 * -- Cort
239 */ 207 */
240 if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ ) 208 v = p_block_mapped(p);
241 goto out; 209 if (v)
242
243 if ((v = p_mapped_by_tlbcam(p)))
244 goto out; 210 goto out;
245 211
246 if (slab_is_available()) { 212 if (slab_is_available()) {
@@ -278,7 +244,8 @@ void iounmap(volatile void __iomem *addr)
278 * If mapped by BATs then there is nothing to do. 244 * If mapped by BATs then there is nothing to do.
279 * Calling vfree() generates a benign warning. 245 * Calling vfree() generates a benign warning.
280 */ 246 */
281 if (v_mapped_by_bats((unsigned long)addr)) return; 247 if (v_block_mapped((unsigned long)addr))
248 return;
282 249
283 if (addr > high_memory && (unsigned long) addr < ioremap_bot) 250 if (addr > high_memory && (unsigned long) addr < ioremap_bot)
284 vunmap((void *) (PAGE_MASK & (unsigned long)addr)); 251 vunmap((void *) (PAGE_MASK & (unsigned long)addr));
@@ -322,7 +289,8 @@ void __init __mapin_ram_chunk(unsigned long offset, unsigned long top)
322 v = PAGE_OFFSET + s; 289 v = PAGE_OFFSET + s;
323 p = memstart_addr + s; 290 p = memstart_addr + s;
324 for (; s < top; s += PAGE_SIZE) { 291 for (; s < top; s += PAGE_SIZE) {
325 ktext = ((char *) v >= _stext && (char *) v < etext); 292 ktext = ((char *)v >= _stext && (char *)v < etext) ||
293 ((char *)v >= _sinittext && (char *)v < _einittext);
326 f = ktext ? pgprot_val(PAGE_KERNEL_TEXT) : pgprot_val(PAGE_KERNEL); 294 f = ktext ? pgprot_val(PAGE_KERNEL_TEXT) : pgprot_val(PAGE_KERNEL);
327 map_page(v, p, f); 295 map_page(v, p, f);
328#ifdef CONFIG_PPC_STD_MMU_32 296#ifdef CONFIG_PPC_STD_MMU_32
@@ -403,7 +371,7 @@ static int __change_page_attr(struct page *page, pgprot_t prot)
403 BUG_ON(PageHighMem(page)); 371 BUG_ON(PageHighMem(page));
404 address = (unsigned long)page_address(page); 372 address = (unsigned long)page_address(page);
405 373
406 if (v_mapped_by_bats(address) || v_mapped_by_tlbcam(address)) 374 if (v_block_mapped(address))
407 return 0; 375 return 0;
408 if (!get_pteptr(&init_mm, address, &kpte, &kpmd)) 376 if (!get_pteptr(&init_mm, address, &kpte, &kpmd))
409 return -EINVAL; 377 return -EINVAL;
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index d9cc66cbdbb7..347106080bb1 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -88,7 +88,7 @@ static __ref void *early_alloc_pgtable(unsigned long size)
88 * map_kernel_page adds an entry to the ioremap page table 88 * map_kernel_page adds an entry to the ioremap page table
89 * and adds an entry to the HPT, possibly bolting it 89 * and adds an entry to the HPT, possibly bolting it
90 */ 90 */
91int map_kernel_page(unsigned long ea, unsigned long pa, int flags) 91int map_kernel_page(unsigned long ea, unsigned long pa, unsigned long flags)
92{ 92{
93 pgd_t *pgdp; 93 pgd_t *pgdp;
94 pud_t *pudp; 94 pud_t *pudp;
@@ -749,7 +749,7 @@ pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot)
749{ 749{
750 unsigned long pmdv; 750 unsigned long pmdv;
751 751
752 pmdv = pfn << PTE_RPN_SHIFT; 752 pmdv = (pfn << PTE_RPN_SHIFT) & PTE_RPN_MASK;
753 return pmd_set_protbits(__pmd(pmdv), pgprot); 753 return pmd_set_protbits(__pmd(pmdv), pgprot);
754} 754}
755 755
@@ -817,6 +817,13 @@ pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
817 817
818int has_transparent_hugepage(void) 818int has_transparent_hugepage(void)
819{ 819{
820
821 BUILD_BUG_ON_MSG((PMD_SHIFT - PAGE_SHIFT) >= MAX_ORDER,
822 "hugepages can't be allocated by the buddy allocator");
823
824 BUILD_BUG_ON_MSG((PMD_SHIFT - PAGE_SHIFT) < 2,
825 "We need more than 2 pages to do deferred thp split");
826
820 if (!mmu_has_feature(MMU_FTR_16M_PAGE)) 827 if (!mmu_has_feature(MMU_FTR_16M_PAGE))
821 return 0; 828 return 0;
822 /* 829 /*
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index 6b2f3e457171..2a049fb8523d 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -49,7 +49,7 @@ struct batrange { /* stores address ranges mapped by BATs */
49/* 49/*
50 * Return PA for this VA if it is mapped by a BAT, or 0 50 * Return PA for this VA if it is mapped by a BAT, or 0
51 */ 51 */
52phys_addr_t v_mapped_by_bats(unsigned long va) 52phys_addr_t v_block_mapped(unsigned long va)
53{ 53{
54 int b; 54 int b;
55 for (b = 0; b < 4; ++b) 55 for (b = 0; b < 4; ++b)
@@ -61,7 +61,7 @@ phys_addr_t v_mapped_by_bats(unsigned long va)
61/* 61/*
62 * Return VA for a given PA or 0 if not mapped 62 * Return VA for a given PA or 0 if not mapped
63 */ 63 */
64unsigned long p_mapped_by_bats(phys_addr_t pa) 64unsigned long p_block_mapped(phys_addr_t pa)
65{ 65{
66 int b; 66 int b;
67 for (b = 0; b < 4; ++b) 67 for (b = 0; b < 4; ++b)
diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S
index 29d6987c37ba..eb82d787d99a 100644
--- a/arch/powerpc/mm/tlb_low_64e.S
+++ b/arch/powerpc/mm/tlb_low_64e.S
@@ -895,7 +895,7 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_PAIRED_MAS)
895BEGIN_MMU_FTR_SECTION 895BEGIN_MMU_FTR_SECTION
896virt_page_table_tlb_miss_done: 896virt_page_table_tlb_miss_done:
897 897
898 /* We have overriden MAS2:EPN but currently our primary TLB miss 898 /* We have overridden MAS2:EPN but currently our primary TLB miss
899 * handler will always restore it so that should not be an issue, 899 * handler will always restore it so that should not be an issue,
900 * if we ever optimize the primary handler to not write MAS2 on 900 * if we ever optimize the primary handler to not write MAS2 on
901 * some cases, we'll have to restore MAS2:EPN here based on the 901 * some cases, we'll have to restore MAS2:EPN here based on the
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index bb04e4df3100..f4668488512c 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -640,9 +640,7 @@ static void early_init_this_mmu(void)
640 * transient mapping would cause problems. 640 * transient mapping would cause problems.
641 */ 641 */
642#ifdef CONFIG_SMP 642#ifdef CONFIG_SMP
643 if (cpu != boot_cpuid && 643 if (hweight32(get_tensr()) > 1)
644 (cpu != cpu_first_thread_sibling(cpu) ||
645 cpu == cpu_first_thread_sibling(boot_cpuid)))
646 map = false; 644 map = false;
647#endif 645#endif
648 646
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S
index 68c477592e43..eabecfcaef7c 100644
--- a/arch/powerpc/mm/tlb_nohash_low.S
+++ b/arch/powerpc/mm/tlb_nohash_low.S
@@ -108,7 +108,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
108 blr 108 blr
1092: 1092:
110#ifdef CONFIG_PPC_47x 110#ifdef CONFIG_PPC_47x
111 oris r7,r6,0x8000 /* specify way explicitely */ 111 oris r7,r6,0x8000 /* specify way explicitly */
112 clrrwi r4,r3,12 /* get an EPN for the hashing with V = 0 */ 112 clrrwi r4,r3,12 /* get an EPN for the hashing with V = 0 */
113 ori r4,r4,PPC47x_TLBE_SIZE 113 ori r4,r4,PPC47x_TLBE_SIZE
114 tlbwe r4,r7,0 /* write it */ 114 tlbwe r4,r7,0 /* write it */
@@ -149,7 +149,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
149 li r3,-1 /* Current set */ 149 li r3,-1 /* Current set */
150 lis r10,tlb_47x_boltmap@h 150 lis r10,tlb_47x_boltmap@h
151 ori r10,r10,tlb_47x_boltmap@l 151 ori r10,r10,tlb_47x_boltmap@l
152 lis r7,0x8000 /* Specify way explicitely */ 152 lis r7,0x8000 /* Specify way explicitly */
153 153
154 b 9f /* For each set */ 154 b 9f /* For each set */
155 155
diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c
index 863d89386f60..c82497a31c54 100644
--- a/arch/powerpc/oprofile/op_model_cell.c
+++ b/arch/powerpc/oprofile/op_model_cell.c
@@ -208,7 +208,7 @@ static void pm_rtas_reset_signals(u32 node)
208 208
209 /* 209 /*
210 * The debug bus is being set to the passthru disable state. 210 * The debug bus is being set to the passthru disable state.
211 * However, the FW still expects atleast one legal signal routing 211 * However, the FW still expects at least one legal signal routing
212 * entry or it will return an error on the arguments. If we don't 212 * entry or it will return an error on the arguments. If we don't
213 * supply a valid entry, we must ignore all return values. Ignoring 213 * supply a valid entry, we must ignore all return values. Ignoring
214 * all return values means we might miss an error we should be 214 * all return values means we might miss an error we should be
@@ -1008,7 +1008,7 @@ static int initial_lfsr[] = {
1008 * 1008 *
1009 * To avoid the time to compute the LFSR, a lookup table is used. The 24 bit 1009 * To avoid the time to compute the LFSR, a lookup table is used. The 24 bit
1010 * LFSR sequence is broken into four ranges. The spacing of the precomputed 1010 * LFSR sequence is broken into four ranges. The spacing of the precomputed
1011 * values is adjusted in each range so the error between the user specifed 1011 * values is adjusted in each range so the error between the user specified
1012 * number (N) of events between samples and the actual number of events based 1012 * number (N) of events between samples and the actual number of events based
1013 * on the precomputed value will be les then about 6.2%. Note, if the user 1013 * on the precomputed value will be les then about 6.2%. Note, if the user
1014 * specifies N < 2^16, the LFSR value that is 2^16 from the end will be used. 1014 * specifies N < 2^16, the LFSR value that is 2^16 from the end will be used.
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index d1e65ce545b3..97a1d40d8696 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -651,7 +651,7 @@ static void pmao_restore_workaround(bool ebb)
651 651
652 /* 652 /*
653 * We are already soft-disabled in power_pmu_enable(). We need to hard 653 * We are already soft-disabled in power_pmu_enable(). We need to hard
654 * enable to actually prevent the PMU exception from firing. 654 * disable to actually prevent the PMU exception from firing.
655 */ 655 */
656 hard_irq_disable(); 656 hard_irq_disable();
657 657
diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
index 3b09ecfd0aee..2da41b78cb6d 100644
--- a/arch/powerpc/perf/hv-24x7.c
+++ b/arch/powerpc/perf/hv-24x7.c
@@ -27,20 +27,6 @@
27#include "hv-24x7-catalog.h" 27#include "hv-24x7-catalog.h"
28#include "hv-common.h" 28#include "hv-common.h"
29 29
30static const char *event_domain_suffix(unsigned domain)
31{
32 switch (domain) {
33#define DOMAIN(n, v, x, c) \
34 case HV_PERF_DOMAIN_##n: \
35 return "__" #n;
36#include "hv-24x7-domains.h"
37#undef DOMAIN
38 default:
39 WARN(1, "unknown domain %d\n", domain);
40 return "__UNKNOWN_DOMAIN_SUFFIX";
41 }
42}
43
44static bool domain_is_valid(unsigned domain) 30static bool domain_is_valid(unsigned domain)
45{ 31{
46 switch (domain) { 32 switch (domain) {
@@ -68,6 +54,24 @@ static bool is_physical_domain(unsigned domain)
68 } 54 }
69} 55}
70 56
57static const char *domain_name(unsigned domain)
58{
59 if (!domain_is_valid(domain))
60 return NULL;
61
62 switch (domain) {
63 case HV_PERF_DOMAIN_PHYS_CHIP: return "Physical Chip";
64 case HV_PERF_DOMAIN_PHYS_CORE: return "Physical Core";
65 case HV_PERF_DOMAIN_VCPU_HOME_CORE: return "VCPU Home Core";
66 case HV_PERF_DOMAIN_VCPU_HOME_CHIP: return "VCPU Home Chip";
67 case HV_PERF_DOMAIN_VCPU_HOME_NODE: return "VCPU Home Node";
68 case HV_PERF_DOMAIN_VCPU_REMOTE_NODE: return "VCPU Remote Node";
69 }
70
71 WARN_ON_ONCE(domain);
72 return NULL;
73}
74
71static bool catalog_entry_domain_is_valid(unsigned domain) 75static bool catalog_entry_domain_is_valid(unsigned domain)
72{ 76{
73 return is_physical_domain(domain); 77 return is_physical_domain(domain);
@@ -101,6 +105,7 @@ static bool catalog_entry_domain_is_valid(unsigned domain)
101EVENT_DEFINE_RANGE_FORMAT(domain, config, 0, 3); 105EVENT_DEFINE_RANGE_FORMAT(domain, config, 0, 3);
102/* u16 */ 106/* u16 */
103EVENT_DEFINE_RANGE_FORMAT(core, config, 16, 31); 107EVENT_DEFINE_RANGE_FORMAT(core, config, 16, 31);
108EVENT_DEFINE_RANGE_FORMAT(chip, config, 16, 31);
104EVENT_DEFINE_RANGE_FORMAT(vcpu, config, 16, 31); 109EVENT_DEFINE_RANGE_FORMAT(vcpu, config, 16, 31);
105/* u32, see "data_offset" */ 110/* u32, see "data_offset" */
106EVENT_DEFINE_RANGE_FORMAT(offset, config, 32, 63); 111EVENT_DEFINE_RANGE_FORMAT(offset, config, 32, 63);
@@ -115,6 +120,7 @@ static struct attribute *format_attrs[] = {
115 &format_attr_domain.attr, 120 &format_attr_domain.attr,
116 &format_attr_offset.attr, 121 &format_attr_offset.attr,
117 &format_attr_core.attr, 122 &format_attr_core.attr,
123 &format_attr_chip.attr,
118 &format_attr_vcpu.attr, 124 &format_attr_vcpu.attr,
119 &format_attr_lpar.attr, 125 &format_attr_lpar.attr,
120 NULL, 126 NULL,
@@ -274,32 +280,70 @@ static unsigned long h_get_24x7_catalog_page(char page[],
274 version, index); 280 version, index);
275} 281}
276 282
277static unsigned core_domains[] = { 283/*
278 HV_PERF_DOMAIN_PHYS_CORE, 284 * Each event we find in the catalog, will have a sysfs entry. Format the
279 HV_PERF_DOMAIN_VCPU_HOME_CORE, 285 * data for this sysfs entry based on the event's domain.
280 HV_PERF_DOMAIN_VCPU_HOME_CHIP, 286 *
281 HV_PERF_DOMAIN_VCPU_HOME_NODE, 287 * Events belonging to the Chip domain can only be monitored in that domain.
282 HV_PERF_DOMAIN_VCPU_REMOTE_NODE, 288 * i.e the domain for these events is a fixed/knwon value.
283}; 289 *
284/* chip event data always yeilds a single event, core yeilds multiple */ 290 * Events belonging to the Core domain can be monitored either in the physical
285#define MAX_EVENTS_PER_EVENT_DATA ARRAY_SIZE(core_domains) 291 * core or in one of the virtual CPU domains. So the domain value for these
286 292 * events must be specified by the user (i.e is a required parameter). Format
293 * the Core events with 'domain=?' so the perf-tool can error check required
294 * parameters.
295 *
296 * NOTE: For the Core domain events, rather than making domain a required
297 * parameter we could default it to PHYS_CORE and allowe users to
298 * override the domain to one of the VCPU domains.
299 *
300 * However, this can make the interface a little inconsistent.
301 *
302 * If we set domain=2 (PHYS_CHIP) and allow user to override this field
303 * the user may be tempted to also modify the "offset=x" field in which
304 * can lead to confusing usage. Consider the HPM_PCYC (offset=0x18) and
305 * HPM_INST (offset=0x20) events. With:
306 *
307 * perf stat -e hv_24x7/HPM_PCYC,offset=0x20/
308 *
309 * we end up monitoring HPM_INST, while the command line has HPM_PCYC.
310 *
311 * By not assigning a default value to the domain for the Core events,
312 * we can have simple guidelines:
313 *
314 * - Specifying values for parameters with "=?" is required.
315 *
316 * - Specifying (i.e overriding) values for other parameters
317 * is undefined.
318 */
287static char *event_fmt(struct hv_24x7_event_data *event, unsigned domain) 319static char *event_fmt(struct hv_24x7_event_data *event, unsigned domain)
288{ 320{
289 const char *sindex; 321 const char *sindex;
290 const char *lpar; 322 const char *lpar;
323 const char *domain_str;
324 char buf[8];
291 325
292 if (is_physical_domain(domain)) { 326 switch (domain) {
327 case HV_PERF_DOMAIN_PHYS_CHIP:
328 snprintf(buf, sizeof(buf), "%d", domain);
329 domain_str = buf;
330 lpar = "0x0";
331 sindex = "chip";
332 break;
333 case HV_PERF_DOMAIN_PHYS_CORE:
334 domain_str = "?";
293 lpar = "0x0"; 335 lpar = "0x0";
294 sindex = "core"; 336 sindex = "core";
295 } else { 337 break;
338 default:
339 domain_str = "?";
296 lpar = "?"; 340 lpar = "?";
297 sindex = "vcpu"; 341 sindex = "vcpu";
298 } 342 }
299 343
300 return kasprintf(GFP_KERNEL, 344 return kasprintf(GFP_KERNEL,
301 "domain=0x%x,offset=0x%x,%s=?,lpar=%s", 345 "domain=%s,offset=0x%x,%s=?,lpar=%s",
302 domain, 346 domain_str,
303 be16_to_cpu(event->event_counter_offs) + 347 be16_to_cpu(event->event_counter_offs) +
304 be16_to_cpu(event->event_group_record_offs), 348 be16_to_cpu(event->event_group_record_offs),
305 sindex, 349 sindex,
@@ -339,6 +383,15 @@ static struct attribute *device_str_attr_create_(char *name, char *str)
339 return &attr->attr.attr; 383 return &attr->attr.attr;
340} 384}
341 385
386/*
387 * Allocate and initialize strings representing event attributes.
388 *
389 * NOTE: The strings allocated here are never destroyed and continue to
390 * exist till shutdown. This is to allow us to create as many events
391 * from the catalog as possible, even if we encounter errors with some.
392 * In case of changes to error paths in future, these may need to be
393 * freed by the caller.
394 */
342static struct attribute *device_str_attr_create(char *name, int name_max, 395static struct attribute *device_str_attr_create(char *name, int name_max,
343 int name_nonce, 396 int name_nonce,
344 char *str, size_t str_max) 397 char *str, size_t str_max)
@@ -370,16 +423,6 @@ out_s:
370 return NULL; 423 return NULL;
371} 424}
372 425
373static void device_str_attr_destroy(struct attribute *attr)
374{
375 struct dev_ext_attribute *d;
376
377 d = container_of(attr, struct dev_ext_attribute, attr.attr);
378 kfree(d->var);
379 kfree(d->attr.attr.name);
380 kfree(d);
381}
382
383static struct attribute *event_to_attr(unsigned ix, 426static struct attribute *event_to_attr(unsigned ix,
384 struct hv_24x7_event_data *event, 427 struct hv_24x7_event_data *event,
385 unsigned domain, 428 unsigned domain,
@@ -387,7 +430,6 @@ static struct attribute *event_to_attr(unsigned ix,
387{ 430{
388 int event_name_len; 431 int event_name_len;
389 char *ev_name, *a_ev_name, *val; 432 char *ev_name, *a_ev_name, *val;
390 const char *ev_suffix;
391 struct attribute *attr; 433 struct attribute *attr;
392 434
393 if (!domain_is_valid(domain)) { 435 if (!domain_is_valid(domain)) {
@@ -400,14 +442,13 @@ static struct attribute *event_to_attr(unsigned ix,
400 if (!val) 442 if (!val)
401 return NULL; 443 return NULL;
402 444
403 ev_suffix = event_domain_suffix(domain);
404 ev_name = event_name(event, &event_name_len); 445 ev_name = event_name(event, &event_name_len);
405 if (!nonce) 446 if (!nonce)
406 a_ev_name = kasprintf(GFP_KERNEL, "%.*s%s", 447 a_ev_name = kasprintf(GFP_KERNEL, "%.*s",
407 (int)event_name_len, ev_name, ev_suffix); 448 (int)event_name_len, ev_name);
408 else 449 else
409 a_ev_name = kasprintf(GFP_KERNEL, "%.*s%s__%d", 450 a_ev_name = kasprintf(GFP_KERNEL, "%.*s__%d",
410 (int)event_name_len, ev_name, ev_suffix, nonce); 451 (int)event_name_len, ev_name, nonce);
411 452
412 if (!a_ev_name) 453 if (!a_ev_name)
413 goto out_val; 454 goto out_val;
@@ -452,45 +493,14 @@ event_to_long_desc_attr(struct hv_24x7_event_data *event, int nonce)
452 return device_str_attr_create(name, nl, nonce, desc, dl); 493 return device_str_attr_create(name, nl, nonce, desc, dl);
453} 494}
454 495
455static ssize_t event_data_to_attrs(unsigned ix, struct attribute **attrs, 496static int event_data_to_attrs(unsigned ix, struct attribute **attrs,
456 struct hv_24x7_event_data *event, int nonce) 497 struct hv_24x7_event_data *event, int nonce)
457{ 498{
458 unsigned i; 499 *attrs = event_to_attr(ix, event, event->domain, nonce);
459 500 if (!*attrs)
460 switch (event->domain) {
461 case HV_PERF_DOMAIN_PHYS_CHIP:
462 *attrs = event_to_attr(ix, event, event->domain, nonce);
463 return 1;
464 case HV_PERF_DOMAIN_PHYS_CORE:
465 for (i = 0; i < ARRAY_SIZE(core_domains); i++) {
466 attrs[i] = event_to_attr(ix, event, core_domains[i],
467 nonce);
468 if (!attrs[i]) {
469 pr_warn("catalog event %u: individual attr %u "
470 "creation failure\n", ix, i);
471 for (; i; i--)
472 device_str_attr_destroy(attrs[i - 1]);
473 return -1;
474 }
475 }
476 return i;
477 default:
478 pr_warn("catalog event %u: domain %u is not allowed in the "
479 "catalog\n", ix, event->domain);
480 return -1; 501 return -1;
481 }
482}
483 502
484static size_t event_to_attr_ct(struct hv_24x7_event_data *event) 503 return 0;
485{
486 switch (event->domain) {
487 case HV_PERF_DOMAIN_PHYS_CHIP:
488 return 1;
489 case HV_PERF_DOMAIN_PHYS_CORE:
490 return ARRAY_SIZE(core_domains);
491 default:
492 return 0;
493 }
494} 504}
495 505
496/* */ 506/* */
@@ -718,9 +728,8 @@ static int create_events_from_catalog(struct attribute ***events_,
718 goto e_free; 728 goto e_free;
719 } 729 }
720 730
721 if (SIZE_MAX / MAX_EVENTS_PER_EVENT_DATA - 1 < event_entry_count) { 731 if (SIZE_MAX - 1 < event_entry_count) {
722 pr_err("event_entry_count %zu is invalid\n", 732 pr_err("event_entry_count %zu is invalid\n", event_entry_count);
723 event_entry_count);
724 ret = -EIO; 733 ret = -EIO;
725 goto e_free; 734 goto e_free;
726 } 735 }
@@ -793,7 +802,7 @@ static int create_events_from_catalog(struct attribute ***events_,
793 continue; 802 continue;
794 } 803 }
795 804
796 attr_max += event_to_attr_ct(event); 805 attr_max++;
797 } 806 }
798 807
799 event_idx_last = event_idx; 808 event_idx_last = event_idx;
@@ -843,12 +852,12 @@ static int create_events_from_catalog(struct attribute ***events_,
843 nonce = event_uniq_add(&ev_uniq, name, nl, event->domain); 852 nonce = event_uniq_add(&ev_uniq, name, nl, event->domain);
844 ct = event_data_to_attrs(event_idx, events + event_attr_ct, 853 ct = event_data_to_attrs(event_idx, events + event_attr_ct,
845 event, nonce); 854 event, nonce);
846 if (ct <= 0) { 855 if (ct < 0) {
847 pr_warn("event %zu (%.*s) creation failure, skipping\n", 856 pr_warn("event %zu (%.*s) creation failure, skipping\n",
848 event_idx, nl, name); 857 event_idx, nl, name);
849 junk_events++; 858 junk_events++;
850 } else { 859 } else {
851 event_attr_ct += ct; 860 event_attr_ct++;
852 event_descs[desc_ct] = event_to_desc_attr(event, nonce); 861 event_descs[desc_ct] = event_to_desc_attr(event, nonce);
853 if (event_descs[desc_ct]) 862 if (event_descs[desc_ct])
854 desc_ct++; 863 desc_ct++;
@@ -953,6 +962,27 @@ e_free:
953 return ret; 962 return ret;
954} 963}
955 964
965static ssize_t domains_show(struct device *dev, struct device_attribute *attr,
966 char *page)
967{
968 int d, n, count = 0;
969 const char *str;
970
971 for (d = 0; d < HV_PERF_DOMAIN_MAX; d++) {
972 str = domain_name(d);
973 if (!str)
974 continue;
975
976 n = sprintf(page, "%d: %s\n", d, str);
977 if (n < 0)
978 break;
979
980 count += n;
981 page += n;
982 }
983 return count;
984}
985
956#define PAGE_0_ATTR(_name, _fmt, _expr) \ 986#define PAGE_0_ATTR(_name, _fmt, _expr) \
957static ssize_t _name##_show(struct device *dev, \ 987static ssize_t _name##_show(struct device *dev, \
958 struct device_attribute *dev_attr, \ 988 struct device_attribute *dev_attr, \
@@ -981,6 +1011,7 @@ PAGE_0_ATTR(catalog_version, "%lld\n",
981PAGE_0_ATTR(catalog_len, "%lld\n", 1011PAGE_0_ATTR(catalog_len, "%lld\n",
982 (unsigned long long)be32_to_cpu(page_0->length) * 4096); 1012 (unsigned long long)be32_to_cpu(page_0->length) * 4096);
983static BIN_ATTR_RO(catalog, 0/* real length varies */); 1013static BIN_ATTR_RO(catalog, 0/* real length varies */);
1014static DEVICE_ATTR_RO(domains);
984 1015
985static struct bin_attribute *if_bin_attrs[] = { 1016static struct bin_attribute *if_bin_attrs[] = {
986 &bin_attr_catalog, 1017 &bin_attr_catalog,
@@ -990,6 +1021,7 @@ static struct bin_attribute *if_bin_attrs[] = {
990static struct attribute *if_attrs[] = { 1021static struct attribute *if_attrs[] = {
991 &dev_attr_catalog_len.attr, 1022 &dev_attr_catalog_len.attr,
992 &dev_attr_catalog_version.attr, 1023 &dev_attr_catalog_version.attr,
1024 &dev_attr_domains.attr,
993 NULL, 1025 NULL,
994}; 1026};
995 1027
@@ -1081,10 +1113,16 @@ static int add_event_to_24x7_request(struct perf_event *event,
1081 return -EINVAL; 1113 return -EINVAL;
1082 } 1114 }
1083 1115
1084 if (is_physical_domain(event_get_domain(event))) 1116 switch (event_get_domain(event)) {
1117 case HV_PERF_DOMAIN_PHYS_CHIP:
1118 idx = event_get_chip(event);
1119 break;
1120 case HV_PERF_DOMAIN_PHYS_CORE:
1085 idx = event_get_core(event); 1121 idx = event_get_core(event);
1086 else 1122 break;
1123 default:
1087 idx = event_get_vcpu(event); 1124 idx = event_get_vcpu(event);
1125 }
1088 1126
1089 i = request_buffer->num_requests++; 1127 i = request_buffer->num_requests++;
1090 req = &request_buffer->requests[i]; 1128 req = &request_buffer->requests[i];
@@ -1200,11 +1238,12 @@ static int h_24x7_event_init(struct perf_event *event)
1200 return -EACCES; 1238 return -EACCES;
1201 } 1239 }
1202 1240
1203 /* see if the event complains */ 1241 /* Get the initial value of the counter for this event */
1204 if (single_24x7_request(event, &ct)) { 1242 if (single_24x7_request(event, &ct)) {
1205 pr_devel("test hcall failed\n"); 1243 pr_devel("test hcall failed\n");
1206 return -EIO; 1244 return -EIO;
1207 } 1245 }
1246 (void)local64_xchg(&event->hw.prev_count, ct);
1208 1247
1209 return 0; 1248 return 0;
1210} 1249}
@@ -1267,6 +1306,16 @@ static void h_24x7_event_read(struct perf_event *event)
1267 h24x7hw = &get_cpu_var(hv_24x7_hw); 1306 h24x7hw = &get_cpu_var(hv_24x7_hw);
1268 h24x7hw->events[i] = event; 1307 h24x7hw->events[i] = event;
1269 put_cpu_var(h24x7hw); 1308 put_cpu_var(h24x7hw);
1309 /*
1310 * Clear the event count so we can compute the _change_
1311 * in the 24x7 raw counter value at the end of the txn.
1312 *
1313 * Note that we could alternatively read the 24x7 value
1314 * now and save its value in event->hw.prev_count. But
1315 * that would require issuing a hcall, which would then
1316 * defeat the purpose of using the txn interface.
1317 */
1318 local64_set(&event->count, 0);
1270 } 1319 }
1271 1320
1272 put_cpu_var(hv_24x7_reqb); 1321 put_cpu_var(hv_24x7_reqb);
diff --git a/arch/powerpc/perf/hv-24x7.h b/arch/powerpc/perf/hv-24x7.h
index 0f9fa21a29f2..791455e7f5cf 100644
--- a/arch/powerpc/perf/hv-24x7.h
+++ b/arch/powerpc/perf/hv-24x7.h
@@ -7,6 +7,7 @@ enum hv_perf_domains {
7#define DOMAIN(n, v, x, c) HV_PERF_DOMAIN_##n = v, 7#define DOMAIN(n, v, x, c) HV_PERF_DOMAIN_##n = v,
8#include "hv-24x7-domains.h" 8#include "hv-24x7-domains.h"
9#undef DOMAIN 9#undef DOMAIN
10 HV_PERF_DOMAIN_MAX,
10}; 11};
11 12
12struct hv_24x7_request { 13struct hv_24x7_request {
@@ -80,7 +81,7 @@ struct hv_24x7_result {
80 __u8 results_complete; 81 __u8 results_complete;
81 __be16 num_elements_returned; 82 __be16 num_elements_returned;
82 83
83 /* This is a copy of @data_size from the coresponding hv_24x7_request */ 84 /* This is a copy of @data_size from the corresponding hv_24x7_request */
84 __be16 result_element_data_size; 85 __be16 result_element_data_size;
85 __u8 reserved[0x2]; 86 __u8 reserved[0x2];
86 87
diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
index 856fe6e03c2a..7aa37236bb70 100644
--- a/arch/powerpc/perf/hv-gpci.c
+++ b/arch/powerpc/perf/hv-gpci.c
@@ -127,8 +127,16 @@ static const struct attribute_group *attr_groups[] = {
127 NULL, 127 NULL,
128}; 128};
129 129
130#define GPCI_MAX_DATA_BYTES \ 130#define HGPCI_REQ_BUFFER_SIZE 4096
131 (1024 - sizeof(struct hv_get_perf_counter_info_params)) 131#define HGPCI_MAX_DATA_BYTES \
132 (HGPCI_REQ_BUFFER_SIZE - sizeof(struct hv_get_perf_counter_info_params))
133
134DEFINE_PER_CPU(char, hv_gpci_reqb[HGPCI_REQ_BUFFER_SIZE]) __aligned(sizeof(uint64_t));
135
136struct hv_gpci_request_buffer {
137 struct hv_get_perf_counter_info_params params;
138 uint8_t bytes[HGPCI_MAX_DATA_BYTES];
139} __packed;
132 140
133static unsigned long single_gpci_request(u32 req, u32 starting_index, 141static unsigned long single_gpci_request(u32 req, u32 starting_index,
134 u16 secondary_index, u8 version_in, u32 offset, u8 length, 142 u16 secondary_index, u8 version_in, u32 offset, u8 length,
@@ -137,24 +145,21 @@ static unsigned long single_gpci_request(u32 req, u32 starting_index,
137 unsigned long ret; 145 unsigned long ret;
138 size_t i; 146 size_t i;
139 u64 count; 147 u64 count;
148 struct hv_gpci_request_buffer *arg;
149
150 arg = (void *)get_cpu_var(hv_gpci_reqb);
151 memset(arg, 0, HGPCI_REQ_BUFFER_SIZE);
140 152
141 struct { 153 arg->params.counter_request = cpu_to_be32(req);
142 struct hv_get_perf_counter_info_params params; 154 arg->params.starting_index = cpu_to_be32(starting_index);
143 uint8_t bytes[GPCI_MAX_DATA_BYTES]; 155 arg->params.secondary_index = cpu_to_be16(secondary_index);
144 } __packed __aligned(sizeof(uint64_t)) arg = { 156 arg->params.counter_info_version_in = version_in;
145 .params = {
146 .counter_request = cpu_to_be32(req),
147 .starting_index = cpu_to_be32(starting_index),
148 .secondary_index = cpu_to_be16(secondary_index),
149 .counter_info_version_in = version_in,
150 }
151 };
152 157
153 ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO, 158 ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
154 virt_to_phys(&arg), sizeof(arg)); 159 virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE);
155 if (ret) { 160 if (ret) {
156 pr_devel("hcall failed: 0x%lx\n", ret); 161 pr_devel("hcall failed: 0x%lx\n", ret);
157 return ret; 162 goto out;
158 } 163 }
159 164
160 /* 165 /*
@@ -163,9 +168,11 @@ static unsigned long single_gpci_request(u32 req, u32 starting_index,
163 */ 168 */
164 count = 0; 169 count = 0;
165 for (i = offset; i < offset + length; i++) 170 for (i = offset; i < offset + length; i++)
166 count |= arg.bytes[i] << (i - offset); 171 count |= arg->bytes[i] << (i - offset);
167 172
168 *value = count; 173 *value = count;
174out:
175 put_cpu_var(hv_gpci_reqb);
169 return ret; 176 return ret;
170} 177}
171 178
@@ -245,10 +252,10 @@ static int h_gpci_event_init(struct perf_event *event)
245 } 252 }
246 253
247 /* last byte within the buffer? */ 254 /* last byte within the buffer? */
248 if ((event_get_offset(event) + length) > GPCI_MAX_DATA_BYTES) { 255 if ((event_get_offset(event) + length) > HGPCI_MAX_DATA_BYTES) {
249 pr_devel("request outside of buffer: %zu > %zu\n", 256 pr_devel("request outside of buffer: %zu > %zu\n",
250 (size_t)event_get_offset(event) + length, 257 (size_t)event_get_offset(event) + length,
251 GPCI_MAX_DATA_BYTES); 258 HGPCI_MAX_DATA_BYTES);
252 return -EINVAL; 259 return -EINVAL;
253 } 260 }
254 261
diff --git a/arch/powerpc/perf/power7-pmu.c b/arch/powerpc/perf/power7-pmu.c
index 5b62f2389290..a383c23a9070 100644
--- a/arch/powerpc/perf/power7-pmu.c
+++ b/arch/powerpc/perf/power7-pmu.c
@@ -54,7 +54,7 @@
54 * Power7 event codes. 54 * Power7 event codes.
55 */ 55 */
56#define EVENT(_name, _code) \ 56#define EVENT(_name, _code) \
57 PME_##_name = _code, 57 _name = _code,
58 58
59enum { 59enum {
60#include "power7-events-list.h" 60#include "power7-events-list.h"
@@ -318,14 +318,14 @@ static void power7_disable_pmc(unsigned int pmc, unsigned long mmcr[])
318} 318}
319 319
320static int power7_generic_events[] = { 320static int power7_generic_events[] = {
321 [PERF_COUNT_HW_CPU_CYCLES] = PME_PM_CYC, 321 [PERF_COUNT_HW_CPU_CYCLES] = PM_CYC,
322 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = PME_PM_GCT_NOSLOT_CYC, 322 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = PM_GCT_NOSLOT_CYC,
323 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = PME_PM_CMPLU_STALL, 323 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = PM_CMPLU_STALL,
324 [PERF_COUNT_HW_INSTRUCTIONS] = PME_PM_INST_CMPL, 324 [PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL,
325 [PERF_COUNT_HW_CACHE_REFERENCES] = PME_PM_LD_REF_L1, 325 [PERF_COUNT_HW_CACHE_REFERENCES] = PM_LD_REF_L1,
326 [PERF_COUNT_HW_CACHE_MISSES] = PME_PM_LD_MISS_L1, 326 [PERF_COUNT_HW_CACHE_MISSES] = PM_LD_MISS_L1,
327 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PME_PM_BRU_FIN, 327 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BRU_FIN,
328 [PERF_COUNT_HW_BRANCH_MISSES] = PME_PM_BR_MPRED, 328 [PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED,
329}; 329};
330 330
331#define C(x) PERF_COUNT_HW_CACHE_##x 331#define C(x) PERF_COUNT_HW_CACHE_##x
diff --git a/arch/powerpc/perf/power8-events-list.h b/arch/powerpc/perf/power8-events-list.h
new file mode 100644
index 000000000000..741b77edd03e
--- /dev/null
+++ b/arch/powerpc/perf/power8-events-list.h
@@ -0,0 +1,51 @@
1/*
2 * Performance counter support for POWER8 processors.
3 *
4 * Copyright 2014 Sukadev Bhattiprolu, IBM Corporation.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12/*
13 * Power8 event codes.
14 */
15EVENT(PM_CYC, 0x0001e)
16EVENT(PM_GCT_NOSLOT_CYC, 0x100f8)
17EVENT(PM_CMPLU_STALL, 0x4000a)
18EVENT(PM_INST_CMPL, 0x00002)
19EVENT(PM_BRU_FIN, 0x10068)
20EVENT(PM_BR_MPRED_CMPL, 0x400f6)
21
22/* All L1 D cache load references counted at finish, gated by reject */
23EVENT(PM_LD_REF_L1, 0x100ee)
24/* Load Missed L1 */
25EVENT(PM_LD_MISS_L1, 0x3e054)
26/* Store Missed L1 */
27EVENT(PM_ST_MISS_L1, 0x300f0)
28/* L1 cache data prefetches */
29EVENT(PM_L1_PREF, 0x0d8b8)
30/* Instruction fetches from L1 */
31EVENT(PM_INST_FROM_L1, 0x04080)
32/* Demand iCache Miss */
33EVENT(PM_L1_ICACHE_MISS, 0x200fd)
34/* Instruction Demand sectors wriittent into IL1 */
35EVENT(PM_L1_DEMAND_WRITE, 0x0408c)
36/* Instruction prefetch written into IL1 */
37EVENT(PM_IC_PREF_WRITE, 0x0408e)
38/* The data cache was reloaded from local core's L3 due to a demand load */
39EVENT(PM_DATA_FROM_L3, 0x4c042)
40/* Demand LD - L3 Miss (not L2 hit and not L3 hit) */
41EVENT(PM_DATA_FROM_L3MISS, 0x300fe)
42/* All successful D-side store dispatches for this thread */
43EVENT(PM_L2_ST, 0x17080)
44/* All successful D-side store dispatches for this thread that were L2 Miss */
45EVENT(PM_L2_ST_MISS, 0x17082)
46/* Total HW L3 prefetches(Load+store) */
47EVENT(PM_L3_PREF_ALL, 0x4e052)
48/* Data PTEG reload */
49EVENT(PM_DTLB_MISS, 0x300fc)
50/* ITLB Reloaded */
51EVENT(PM_ITLB_MISS, 0x400fc)
diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
index 9958ba8bf0d2..690d9186a855 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -17,48 +17,16 @@
17#include <asm/firmware.h> 17#include <asm/firmware.h>
18#include <asm/cputable.h> 18#include <asm/cputable.h>
19 19
20
21/* 20/*
22 * Some power8 event codes. 21 * Some power8 event codes.
23 */ 22 */
24#define PM_CYC 0x0001e 23#define EVENT(_name, _code) _name = _code,
25#define PM_GCT_NOSLOT_CYC 0x100f8 24
26#define PM_CMPLU_STALL 0x4000a 25enum {
27#define PM_INST_CMPL 0x00002 26#include "power8-events-list.h"
28#define PM_BRU_FIN 0x10068 27};
29#define PM_BR_MPRED_CMPL 0x400f6
30
31/* All L1 D cache load references counted at finish, gated by reject */
32#define PM_LD_REF_L1 0x100ee
33/* Load Missed L1 */
34#define PM_LD_MISS_L1 0x3e054
35/* Store Missed L1 */
36#define PM_ST_MISS_L1 0x300f0
37/* L1 cache data prefetches */
38#define PM_L1_PREF 0x0d8b8
39/* Instruction fetches from L1 */
40#define PM_INST_FROM_L1 0x04080
41/* Demand iCache Miss */
42#define PM_L1_ICACHE_MISS 0x200fd
43/* Instruction Demand sectors wriittent into IL1 */
44#define PM_L1_DEMAND_WRITE 0x0408c
45/* Instruction prefetch written into IL1 */
46#define PM_IC_PREF_WRITE 0x0408e
47/* The data cache was reloaded from local core's L3 due to a demand load */
48#define PM_DATA_FROM_L3 0x4c042
49/* Demand LD - L3 Miss (not L2 hit and not L3 hit) */
50#define PM_DATA_FROM_L3MISS 0x300fe
51/* All successful D-side store dispatches for this thread */
52#define PM_L2_ST 0x17080
53/* All successful D-side store dispatches for this thread that were L2 Miss */
54#define PM_L2_ST_MISS 0x17082
55/* Total HW L3 prefetches(Load+store) */
56#define PM_L3_PREF_ALL 0x4e052
57/* Data PTEG reload */
58#define PM_DTLB_MISS 0x300fc
59/* ITLB Reloaded */
60#define PM_ITLB_MISS 0x400fc
61 28
29#undef EVENT
62 30
63/* 31/*
64 * Raw event encoding for POWER8: 32 * Raw event encoding for POWER8:
@@ -415,7 +383,7 @@ static int power8_compute_mmcr(u64 event[], int n_ev,
415 pmc_inuse |= 1 << pmc; 383 pmc_inuse |= 1 << pmc;
416 } 384 }
417 385
418 /* In continous sampling mode, update SDAR on TLB miss */ 386 /* In continuous sampling mode, update SDAR on TLB miss */
419 mmcra = MMCRA_SDAR_MODE_TLB; 387 mmcra = MMCRA_SDAR_MODE_TLB;
420 mmcr1 = mmcr2 = 0; 388 mmcr1 = mmcr2 = 0;
421 389
@@ -604,6 +572,71 @@ static void power8_disable_pmc(unsigned int pmc, unsigned long mmcr[])
604 mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SHIFT(pmc + 1)); 572 mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SHIFT(pmc + 1));
605} 573}
606 574
575GENERIC_EVENT_ATTR(cpu-cycles, PM_CYC);
576GENERIC_EVENT_ATTR(stalled-cycles-frontend, PM_GCT_NOSLOT_CYC);
577GENERIC_EVENT_ATTR(stalled-cycles-backend, PM_CMPLU_STALL);
578GENERIC_EVENT_ATTR(instructions, PM_INST_CMPL);
579GENERIC_EVENT_ATTR(branch-instructions, PM_BRU_FIN);
580GENERIC_EVENT_ATTR(branch-misses, PM_BR_MPRED_CMPL);
581GENERIC_EVENT_ATTR(cache-references, PM_LD_REF_L1);
582GENERIC_EVENT_ATTR(cache-misses, PM_LD_MISS_L1);
583
584CACHE_EVENT_ATTR(L1-dcache-load-misses, PM_LD_MISS_L1);
585CACHE_EVENT_ATTR(L1-dcache-loads, PM_LD_REF_L1);
586
587CACHE_EVENT_ATTR(L1-dcache-prefetches, PM_L1_PREF);
588CACHE_EVENT_ATTR(L1-dcache-store-misses, PM_ST_MISS_L1);
589CACHE_EVENT_ATTR(L1-icache-load-misses, PM_L1_ICACHE_MISS);
590CACHE_EVENT_ATTR(L1-icache-loads, PM_INST_FROM_L1);
591CACHE_EVENT_ATTR(L1-icache-prefetches, PM_IC_PREF_WRITE);
592
593CACHE_EVENT_ATTR(LLC-load-misses, PM_DATA_FROM_L3MISS);
594CACHE_EVENT_ATTR(LLC-loads, PM_DATA_FROM_L3);
595CACHE_EVENT_ATTR(LLC-prefetches, PM_L3_PREF_ALL);
596CACHE_EVENT_ATTR(LLC-store-misses, PM_L2_ST_MISS);
597CACHE_EVENT_ATTR(LLC-stores, PM_L2_ST);
598
599CACHE_EVENT_ATTR(branch-load-misses, PM_BR_MPRED_CMPL);
600CACHE_EVENT_ATTR(branch-loads, PM_BRU_FIN);
601CACHE_EVENT_ATTR(dTLB-load-misses, PM_DTLB_MISS);
602CACHE_EVENT_ATTR(iTLB-load-misses, PM_ITLB_MISS);
603
604static struct attribute *power8_events_attr[] = {
605 GENERIC_EVENT_PTR(PM_CYC),
606 GENERIC_EVENT_PTR(PM_GCT_NOSLOT_CYC),
607 GENERIC_EVENT_PTR(PM_CMPLU_STALL),
608 GENERIC_EVENT_PTR(PM_INST_CMPL),
609 GENERIC_EVENT_PTR(PM_BRU_FIN),
610 GENERIC_EVENT_PTR(PM_BR_MPRED_CMPL),
611 GENERIC_EVENT_PTR(PM_LD_REF_L1),
612 GENERIC_EVENT_PTR(PM_LD_MISS_L1),
613
614 CACHE_EVENT_PTR(PM_LD_MISS_L1),
615 CACHE_EVENT_PTR(PM_LD_REF_L1),
616 CACHE_EVENT_PTR(PM_L1_PREF),
617 CACHE_EVENT_PTR(PM_ST_MISS_L1),
618 CACHE_EVENT_PTR(PM_L1_ICACHE_MISS),
619 CACHE_EVENT_PTR(PM_INST_FROM_L1),
620 CACHE_EVENT_PTR(PM_IC_PREF_WRITE),
621 CACHE_EVENT_PTR(PM_DATA_FROM_L3MISS),
622 CACHE_EVENT_PTR(PM_DATA_FROM_L3),
623 CACHE_EVENT_PTR(PM_L3_PREF_ALL),
624 CACHE_EVENT_PTR(PM_L2_ST_MISS),
625 CACHE_EVENT_PTR(PM_L2_ST),
626
627 CACHE_EVENT_PTR(PM_BR_MPRED_CMPL),
628 CACHE_EVENT_PTR(PM_BRU_FIN),
629
630 CACHE_EVENT_PTR(PM_DTLB_MISS),
631 CACHE_EVENT_PTR(PM_ITLB_MISS),
632 NULL
633};
634
635static struct attribute_group power8_pmu_events_group = {
636 .name = "events",
637 .attrs = power8_events_attr,
638};
639
607PMU_FORMAT_ATTR(event, "config:0-49"); 640PMU_FORMAT_ATTR(event, "config:0-49");
608PMU_FORMAT_ATTR(pmcxsel, "config:0-7"); 641PMU_FORMAT_ATTR(pmcxsel, "config:0-7");
609PMU_FORMAT_ATTR(mark, "config:8"); 642PMU_FORMAT_ATTR(mark, "config:8");
@@ -640,6 +673,7 @@ struct attribute_group power8_pmu_format_group = {
640 673
641static const struct attribute_group *power8_pmu_attr_groups[] = { 674static const struct attribute_group *power8_pmu_attr_groups[] = {
642 &power8_pmu_format_group, 675 &power8_pmu_format_group,
676 &power8_pmu_events_group,
643 NULL, 677 NULL,
644}; 678};
645 679
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index 6eb3b2abae90..00282c2b0cae 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -319,7 +319,7 @@ mpc52xx_pci_setup(struct pci_controller *hose,
319 319
320 tmp = in_be32(&pci_regs->gscr); 320 tmp = in_be32(&pci_regs->gscr);
321#if 0 321#if 0
322 /* Reset the exteral bus ( internal PCI controller is NOT resetted ) */ 322 /* Reset the exteral bus ( internal PCI controller is NOT reset ) */
323 /* Not necessary and can be a bad thing if for example the bootloader 323 /* Not necessary and can be a bad thing if for example the bootloader
324 is displaying a splash screen or ... Just left here for 324 is displaying a splash screen or ... Just left here for
325 documentation purpose if anyone need it */ 325 documentation purpose if anyone need it */
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index 97915feffd42..e626461a63bd 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -8,6 +8,7 @@ menuconfig FSL_SOC_BOOKE
8 select FSL_PCI if PCI 8 select FSL_PCI if PCI
9 select SERIAL_8250_EXTENDED if SERIAL_8250 9 select SERIAL_8250_EXTENDED if SERIAL_8250
10 select SERIAL_8250_SHARE_IRQ if SERIAL_8250 10 select SERIAL_8250_SHARE_IRQ if SERIAL_8250
11 select FSL_CORENET_RCPM if PPC_E500MC
11 default y 12 default y
12 13
13if FSL_SOC_BOOKE 14if FSL_SOC_BOOKE
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index 1fe7fb95175a..7bc86dae9517 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -2,6 +2,7 @@
2# Makefile for the PowerPC 85xx linux kernel. 2# Makefile for the PowerPC 85xx linux kernel.
3# 3#
4obj-$(CONFIG_SMP) += smp.o 4obj-$(CONFIG_SMP) += smp.o
5obj-$(CONFIG_FSL_PMC) += mpc85xx_pm_ops.o
5 6
6obj-y += common.o 7obj-y += common.o
7 8
diff --git a/arch/powerpc/platforms/85xx/common.c b/arch/powerpc/platforms/85xx/common.c
index 949f22c86e61..28720a4ded7b 100644
--- a/arch/powerpc/platforms/85xx/common.c
+++ b/arch/powerpc/platforms/85xx/common.c
@@ -9,11 +9,14 @@
9#include <linux/of_irq.h> 9#include <linux/of_irq.h>
10#include <linux/of_platform.h> 10#include <linux/of_platform.h>
11 11
12#include <asm/fsl_pm.h>
12#include <soc/fsl/qe/qe.h> 13#include <soc/fsl/qe/qe.h>
13#include <sysdev/cpm2_pic.h> 14#include <sysdev/cpm2_pic.h>
14 15
15#include "mpc85xx.h" 16#include "mpc85xx.h"
16 17
18const struct fsl_pm_ops *qoriq_pm_ops;
19
17static const struct of_device_id mpc85xx_common_ids[] __initconst = { 20static const struct of_device_id mpc85xx_common_ids[] __initconst = {
18 { .type = "soc", }, 21 { .type = "soc", },
19 { .compatible = "soc", }, 22 { .compatible = "soc", },
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 5ac70de3e48a..d7e87ff912d7 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -99,7 +99,7 @@ static void mpc85xx_cds_restart(char *cmd)
99 pci_read_config_byte(dev, 0x47, &tmp); 99 pci_read_config_byte(dev, 0x47, &tmp);
100 100
101 /* 101 /*
102 * At this point, the harware reset should have triggered. 102 * At this point, the hardware reset should have triggered.
103 * However, if it doesn't work for some mysterious reason, 103 * However, if it doesn't work for some mysterious reason,
104 * just fall through to the default reset below. 104 * just fall through to the default reset below.
105 */ 105 */
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c
new file mode 100644
index 000000000000..f05325f0cc03
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c
@@ -0,0 +1,106 @@
1/*
2 * MPC85xx PM operators
3 *
4 * Copyright 2015 Freescale Semiconductor Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#define pr_fmt(fmt) "%s: " fmt, __func__
13
14#include <linux/kernel.h>
15#include <linux/of.h>
16#include <linux/of_address.h>
17#include <linux/fsl/guts.h>
18
19#include <asm/io.h>
20#include <asm/fsl_pm.h>
21
22static struct ccsr_guts __iomem *guts;
23
24static void mpc85xx_irq_mask(int cpu)
25{
26
27}
28
29static void mpc85xx_irq_unmask(int cpu)
30{
31
32}
33
34static void mpc85xx_cpu_die(int cpu)
35{
36 u32 tmp;
37
38 tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP;
39 mtspr(SPRN_HID0, tmp);
40
41 /* Enter NAP mode. */
42 tmp = mfmsr();
43 tmp |= MSR_WE;
44 asm volatile(
45 "msync\n"
46 "mtmsr %0\n"
47 "isync\n"
48 :
49 : "r" (tmp));
50}
51
52static void mpc85xx_cpu_up_prepare(int cpu)
53{
54
55}
56
57static void mpc85xx_freeze_time_base(bool freeze)
58{
59 uint32_t mask;
60
61 mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1;
62 if (freeze)
63 setbits32(&guts->devdisr, mask);
64 else
65 clrbits32(&guts->devdisr, mask);
66
67 in_be32(&guts->devdisr);
68}
69
70static const struct of_device_id mpc85xx_smp_guts_ids[] = {
71 { .compatible = "fsl,mpc8572-guts", },
72 { .compatible = "fsl,p1020-guts", },
73 { .compatible = "fsl,p1021-guts", },
74 { .compatible = "fsl,p1022-guts", },
75 { .compatible = "fsl,p1023-guts", },
76 { .compatible = "fsl,p2020-guts", },
77 { .compatible = "fsl,bsc9132-guts", },
78 {},
79};
80
81static const struct fsl_pm_ops mpc85xx_pm_ops = {
82 .freeze_time_base = mpc85xx_freeze_time_base,
83 .irq_mask = mpc85xx_irq_mask,
84 .irq_unmask = mpc85xx_irq_unmask,
85 .cpu_die = mpc85xx_cpu_die,
86 .cpu_up_prepare = mpc85xx_cpu_up_prepare,
87};
88
89int __init mpc85xx_setup_pmc(void)
90{
91 struct device_node *np;
92
93 np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids);
94 if (np) {
95 guts = of_iomap(np, 0);
96 of_node_put(np);
97 if (!guts) {
98 pr_err("Could not map guts node address\n");
99 return -ENOMEM;
100 }
101 }
102
103 qoriq_pm_ops = &mpc85xx_pm_ops;
104
105 return 0;
106}
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index 6b107cea1c08..fe9f19e5e935 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -2,7 +2,7 @@
2 * Author: Andy Fleming <afleming@freescale.com> 2 * Author: Andy Fleming <afleming@freescale.com>
3 * Kumar Gala <galak@kernel.crashing.org> 3 * Kumar Gala <galak@kernel.crashing.org>
4 * 4 *
5 * Copyright 2006-2008, 2011-2012 Freescale Semiconductor Inc. 5 * Copyright 2006-2008, 2011-2012, 2015 Freescale Semiconductor Inc.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
@@ -15,7 +15,6 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/of.h> 17#include <linux/of.h>
18#include <linux/of_address.h>
19#include <linux/kexec.h> 18#include <linux/kexec.h>
20#include <linux/highmem.h> 19#include <linux/highmem.h>
21#include <linux/cpu.h> 20#include <linux/cpu.h>
@@ -29,6 +28,7 @@
29#include <asm/dbell.h> 28#include <asm/dbell.h>
30#include <asm/code-patching.h> 29#include <asm/code-patching.h>
31#include <asm/cputhreads.h> 30#include <asm/cputhreads.h>
31#include <asm/fsl_pm.h>
32 32
33#include <sysdev/fsl_soc.h> 33#include <sysdev/fsl_soc.h>
34#include <sysdev/mpic.h> 34#include <sysdev/mpic.h>
@@ -43,35 +43,23 @@ struct epapr_spin_table {
43 u32 pir; 43 u32 pir;
44}; 44};
45 45
46static struct ccsr_guts __iomem *guts; 46#ifdef CONFIG_HOTPLUG_CPU
47static u64 timebase; 47static u64 timebase;
48static int tb_req; 48static int tb_req;
49static int tb_valid; 49static int tb_valid;
50 50
51static void mpc85xx_timebase_freeze(int freeze)
52{
53 uint32_t mask;
54
55 mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1;
56 if (freeze)
57 setbits32(&guts->devdisr, mask);
58 else
59 clrbits32(&guts->devdisr, mask);
60
61 in_be32(&guts->devdisr);
62}
63
64static void mpc85xx_give_timebase(void) 51static void mpc85xx_give_timebase(void)
65{ 52{
66 unsigned long flags; 53 unsigned long flags;
67 54
68 local_irq_save(flags); 55 local_irq_save(flags);
56 hard_irq_disable();
69 57
70 while (!tb_req) 58 while (!tb_req)
71 barrier(); 59 barrier();
72 tb_req = 0; 60 tb_req = 0;
73 61
74 mpc85xx_timebase_freeze(1); 62 qoriq_pm_ops->freeze_time_base(true);
75#ifdef CONFIG_PPC64 63#ifdef CONFIG_PPC64
76 /* 64 /*
77 * e5500/e6500 have a workaround for erratum A-006958 in place 65 * e5500/e6500 have a workaround for erratum A-006958 in place
@@ -104,7 +92,7 @@ static void mpc85xx_give_timebase(void)
104 while (tb_valid) 92 while (tb_valid)
105 barrier(); 93 barrier();
106 94
107 mpc85xx_timebase_freeze(0); 95 qoriq_pm_ops->freeze_time_base(false);
108 96
109 local_irq_restore(flags); 97 local_irq_restore(flags);
110} 98}
@@ -114,6 +102,7 @@ static void mpc85xx_take_timebase(void)
114 unsigned long flags; 102 unsigned long flags;
115 103
116 local_irq_save(flags); 104 local_irq_save(flags);
105 hard_irq_disable();
117 106
118 tb_req = 1; 107 tb_req = 1;
119 while (!tb_valid) 108 while (!tb_valid)
@@ -126,36 +115,54 @@ static void mpc85xx_take_timebase(void)
126 local_irq_restore(flags); 115 local_irq_restore(flags);
127} 116}
128 117
129#ifdef CONFIG_HOTPLUG_CPU
130static void smp_85xx_mach_cpu_die(void) 118static void smp_85xx_mach_cpu_die(void)
131{ 119{
132 unsigned int cpu = smp_processor_id(); 120 unsigned int cpu = smp_processor_id();
133 u32 tmp;
134 121
135 local_irq_disable(); 122 local_irq_disable();
123 hard_irq_disable();
124 /* mask all irqs to prevent cpu wakeup */
125 qoriq_pm_ops->irq_mask(cpu);
126
136 idle_task_exit(); 127 idle_task_exit();
137 generic_set_cpu_dead(cpu);
138 mb();
139 128
140 mtspr(SPRN_TCR, 0); 129 mtspr(SPRN_TCR, 0);
130 mtspr(SPRN_TSR, mfspr(SPRN_TSR));
141 131
142 __flush_disable_L1(); 132 generic_set_cpu_dead(cpu);
143 tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP;
144 mtspr(SPRN_HID0, tmp);
145 isync();
146 133
147 /* Enter NAP mode. */ 134 cur_cpu_spec->cpu_down_flush();
148 tmp = mfmsr(); 135
149 tmp |= MSR_WE; 136 qoriq_pm_ops->cpu_die(cpu);
150 mb();
151 mtmsr(tmp);
152 isync();
153 137
154 while (1) 138 while (1)
155 ; 139 ;
156} 140}
141
142static void qoriq_cpu_kill(unsigned int cpu)
143{
144 int i;
145
146 for (i = 0; i < 500; i++) {
147 if (is_cpu_dead(cpu)) {
148#ifdef CONFIG_PPC64
149 paca[cpu].cpu_start = 0;
150#endif
151 return;
152 }
153 msleep(20);
154 }
155 pr_err("CPU%d didn't die...\n", cpu);
156}
157#endif 157#endif
158 158
159/*
160 * To keep it compatible with old boot program which uses
161 * cache-inhibit spin table, we need to flush the cache
162 * before accessing spin table to invalidate any staled data.
163 * We also need to flush the cache after writing to spin
164 * table to push data out.
165 */
159static inline void flush_spin_table(void *spin_table) 166static inline void flush_spin_table(void *spin_table)
160{ 167{
161 flush_dcache_range((ulong)spin_table, 168 flush_dcache_range((ulong)spin_table,
@@ -173,78 +180,28 @@ static inline u32 read_spin_table_addr_l(void *spin_table)
173static void wake_hw_thread(void *info) 180static void wake_hw_thread(void *info)
174{ 181{
175 void fsl_secondary_thread_init(void); 182 void fsl_secondary_thread_init(void);
176 unsigned long imsr, inia; 183 unsigned long inia;
177 int nr = *(const int *)info; 184 int cpu = *(const int *)info;
178 185
179 imsr = MSR_KERNEL;
180 inia = *(unsigned long *)fsl_secondary_thread_init; 186 inia = *(unsigned long *)fsl_secondary_thread_init;
181 187 book3e_start_thread(cpu_thread_in_core(cpu), inia);
182 if (cpu_thread_in_core(nr) == 0) {
183 /* For when we boot on a secondary thread with kdump */
184 mttmr(TMRN_IMSR0, imsr);
185 mttmr(TMRN_INIA0, inia);
186 mtspr(SPRN_TENS, TEN_THREAD(0));
187 } else {
188 mttmr(TMRN_IMSR1, imsr);
189 mttmr(TMRN_INIA1, inia);
190 mtspr(SPRN_TENS, TEN_THREAD(1));
191 }
192
193 smp_generic_kick_cpu(nr);
194} 188}
195#endif 189#endif
196 190
197static int smp_85xx_kick_cpu(int nr) 191static int smp_85xx_start_cpu(int cpu)
198{ 192{
199 unsigned long flags; 193 int ret = 0;
200 const u64 *cpu_rel_addr;
201 __iomem struct epapr_spin_table *spin_table;
202 struct device_node *np; 194 struct device_node *np;
203 int hw_cpu = get_hard_smp_processor_id(nr); 195 const u64 *cpu_rel_addr;
196 unsigned long flags;
204 int ioremappable; 197 int ioremappable;
205 int ret = 0; 198 int hw_cpu = get_hard_smp_processor_id(cpu);
206 199 struct epapr_spin_table __iomem *spin_table;
207 WARN_ON(nr < 0 || nr >= NR_CPUS);
208 WARN_ON(hw_cpu < 0 || hw_cpu >= NR_CPUS);
209
210 pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr);
211
212#ifdef CONFIG_PPC64
213 /* Threads don't use the spin table */
214 if (cpu_thread_in_core(nr) != 0) {
215 int primary = cpu_first_thread_sibling(nr);
216
217 if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT)))
218 return -ENOENT;
219
220 if (cpu_thread_in_core(nr) != 1) {
221 pr_err("%s: cpu %d: invalid hw thread %d\n",
222 __func__, nr, cpu_thread_in_core(nr));
223 return -ENOENT;
224 }
225 200
226 if (!cpu_online(primary)) { 201 np = of_get_cpu_node(cpu, NULL);
227 pr_err("%s: cpu %d: primary %d not online\n",
228 __func__, nr, primary);
229 return -ENOENT;
230 }
231
232 smp_call_function_single(primary, wake_hw_thread, &nr, 0);
233 return 0;
234 } else if (cpu_thread_in_core(boot_cpuid) != 0 &&
235 cpu_first_thread_sibling(boot_cpuid) == nr) {
236 if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT)))
237 return -ENOENT;
238
239 smp_call_function_single(boot_cpuid, wake_hw_thread, &nr, 0);
240 }
241#endif
242
243 np = of_get_cpu_node(nr, NULL);
244 cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL); 202 cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL);
245 203 if (!cpu_rel_addr) {
246 if (cpu_rel_addr == NULL) { 204 pr_err("No cpu-release-addr for cpu %d\n", cpu);
247 printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr);
248 return -ENOENT; 205 return -ENOENT;
249 } 206 }
250 207
@@ -264,28 +221,18 @@ static int smp_85xx_kick_cpu(int nr)
264 spin_table = phys_to_virt(*cpu_rel_addr); 221 spin_table = phys_to_virt(*cpu_rel_addr);
265 222
266 local_irq_save(flags); 223 local_irq_save(flags);
267#ifdef CONFIG_PPC32 224 hard_irq_disable();
268#ifdef CONFIG_HOTPLUG_CPU
269 /* Corresponding to generic_set_cpu_dead() */
270 generic_set_cpu_up(nr);
271 225
272 if (system_state == SYSTEM_RUNNING) { 226 if (qoriq_pm_ops)
273 /* 227 qoriq_pm_ops->cpu_up_prepare(cpu);
274 * To keep it compatible with old boot program which uses
275 * cache-inhibit spin table, we need to flush the cache
276 * before accessing spin table to invalidate any staled data.
277 * We also need to flush the cache after writing to spin
278 * table to push data out.
279 */
280 flush_spin_table(spin_table);
281 out_be32(&spin_table->addr_l, 0);
282 flush_spin_table(spin_table);
283 228
229 /* if cpu is not spinning, reset it */
230 if (read_spin_table_addr_l(spin_table) != 1) {
284 /* 231 /*
285 * We don't set the BPTR register here since it already points 232 * We don't set the BPTR register here since it already points
286 * to the boot page properly. 233 * to the boot page properly.
287 */ 234 */
288 mpic_reset_core(nr); 235 mpic_reset_core(cpu);
289 236
290 /* 237 /*
291 * wait until core is ready... 238 * wait until core is ready...
@@ -295,40 +242,23 @@ static int smp_85xx_kick_cpu(int nr)
295 if (!spin_event_timeout( 242 if (!spin_event_timeout(
296 read_spin_table_addr_l(spin_table) == 1, 243 read_spin_table_addr_l(spin_table) == 1,
297 10000, 100)) { 244 10000, 100)) {
298 pr_err("%s: timeout waiting for core %d to reset\n", 245 pr_err("timeout waiting for cpu %d to reset\n",
299 __func__, hw_cpu); 246 hw_cpu);
300 ret = -ENOENT; 247 ret = -EAGAIN;
301 goto out; 248 goto err;
302 } 249 }
303
304 /* clear the acknowledge status */
305 __secondary_hold_acknowledge = -1;
306 } 250 }
307#endif
308 flush_spin_table(spin_table);
309 out_be32(&spin_table->pir, hw_cpu);
310 out_be32(&spin_table->addr_l, __pa(__early_start));
311 flush_spin_table(spin_table);
312
313 /* Wait a bit for the CPU to ack. */
314 if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu,
315 10000, 100)) {
316 pr_err("%s: timeout waiting for core %d to ack\n",
317 __func__, hw_cpu);
318 ret = -ENOENT;
319 goto out;
320 }
321out:
322#else
323 smp_generic_kick_cpu(nr);
324 251
325 flush_spin_table(spin_table); 252 flush_spin_table(spin_table);
326 out_be32(&spin_table->pir, hw_cpu); 253 out_be32(&spin_table->pir, hw_cpu);
254#ifdef CONFIG_PPC64
327 out_be64((u64 *)(&spin_table->addr_h), 255 out_be64((u64 *)(&spin_table->addr_h),
328 __pa(ppc_function_entry(generic_secondary_smp_init))); 256 __pa(ppc_function_entry(generic_secondary_smp_init)));
329 flush_spin_table(spin_table); 257#else
258 out_be32(&spin_table->addr_l, __pa(__early_start));
330#endif 259#endif
331 260 flush_spin_table(spin_table);
261err:
332 local_irq_restore(flags); 262 local_irq_restore(flags);
333 263
334 if (ioremappable) 264 if (ioremappable)
@@ -337,6 +267,81 @@ out:
337 return ret; 267 return ret;
338} 268}
339 269
270static int smp_85xx_kick_cpu(int nr)
271{
272 int ret = 0;
273#ifdef CONFIG_PPC64
274 int primary = nr;
275#endif
276
277 WARN_ON(nr < 0 || nr >= num_possible_cpus());
278
279 pr_debug("kick CPU #%d\n", nr);
280
281#ifdef CONFIG_PPC64
282 if (threads_per_core == 2) {
283 if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT)))
284 return -ENOENT;
285
286 booting_thread_hwid = cpu_thread_in_core(nr);
287 primary = cpu_first_thread_sibling(nr);
288
289 if (qoriq_pm_ops)
290 qoriq_pm_ops->cpu_up_prepare(nr);
291
292 /*
293 * If either thread in the core is online, use it to start
294 * the other.
295 */
296 if (cpu_online(primary)) {
297 smp_call_function_single(primary,
298 wake_hw_thread, &nr, 1);
299 goto done;
300 } else if (cpu_online(primary + 1)) {
301 smp_call_function_single(primary + 1,
302 wake_hw_thread, &nr, 1);
303 goto done;
304 }
305
306 /*
307 * If getting here, it means both threads in the core are
308 * offline. So start the primary thread, then it will start
309 * the thread specified in booting_thread_hwid, the one
310 * corresponding to nr.
311 */
312
313 } else if (threads_per_core == 1) {
314 /*
315 * If one core has only one thread, set booting_thread_hwid to
316 * an invalid value.
317 */
318 booting_thread_hwid = INVALID_THREAD_HWID;
319
320 } else if (threads_per_core > 2) {
321 pr_err("Do not support more than 2 threads per CPU.");
322 return -EINVAL;
323 }
324
325 ret = smp_85xx_start_cpu(primary);
326 if (ret)
327 return ret;
328
329done:
330 paca[nr].cpu_start = 1;
331 generic_set_cpu_up(nr);
332
333 return ret;
334#else
335 ret = smp_85xx_start_cpu(nr);
336 if (ret)
337 return ret;
338
339 generic_set_cpu_up(nr);
340
341 return ret;
342#endif
343}
344
340struct smp_ops_t smp_85xx_ops = { 345struct smp_ops_t smp_85xx_ops = {
341 .kick_cpu = smp_85xx_kick_cpu, 346 .kick_cpu = smp_85xx_kick_cpu,
342 .cpu_bootable = smp_generic_cpu_bootable, 347 .cpu_bootable = smp_generic_cpu_bootable,
@@ -359,7 +364,7 @@ void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary)
359 local_irq_disable(); 364 local_irq_disable();
360 365
361 if (secondary) { 366 if (secondary) {
362 __flush_disable_L1(); 367 cur_cpu_spec->cpu_down_flush();
363 atomic_inc(&kexec_down_cpus); 368 atomic_inc(&kexec_down_cpus);
364 /* loop forever */ 369 /* loop forever */
365 while (1); 370 while (1);
@@ -467,16 +472,6 @@ static void smp_85xx_setup_cpu(int cpu_nr)
467 smp_85xx_basic_setup(cpu_nr); 472 smp_85xx_basic_setup(cpu_nr);
468} 473}
469 474
470static const struct of_device_id mpc85xx_smp_guts_ids[] = {
471 { .compatible = "fsl,mpc8572-guts", },
472 { .compatible = "fsl,p1020-guts", },
473 { .compatible = "fsl,p1021-guts", },
474 { .compatible = "fsl,p1022-guts", },
475 { .compatible = "fsl,p1023-guts", },
476 { .compatible = "fsl,p2020-guts", },
477 {},
478};
479
480void __init mpc85xx_smp_init(void) 475void __init mpc85xx_smp_init(void)
481{ 476{
482 struct device_node *np; 477 struct device_node *np;
@@ -500,22 +495,21 @@ void __init mpc85xx_smp_init(void)
500 smp_85xx_ops.probe = NULL; 495 smp_85xx_ops.probe = NULL;
501 } 496 }
502 497
503 np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); 498#ifdef CONFIG_HOTPLUG_CPU
504 if (np) { 499#ifdef CONFIG_FSL_CORENET_RCPM
505 guts = of_iomap(np, 0); 500 fsl_rcpm_init();
506 of_node_put(np); 501#endif
507 if (!guts) { 502
508 pr_err("%s: Could not map guts node address\n", 503#ifdef CONFIG_FSL_PMC
509 __func__); 504 mpc85xx_setup_pmc();
510 return; 505#endif
511 } 506 if (qoriq_pm_ops) {
512 smp_85xx_ops.give_timebase = mpc85xx_give_timebase; 507 smp_85xx_ops.give_timebase = mpc85xx_give_timebase;
513 smp_85xx_ops.take_timebase = mpc85xx_take_timebase; 508 smp_85xx_ops.take_timebase = mpc85xx_take_timebase;
514#ifdef CONFIG_HOTPLUG_CPU
515 ppc_md.cpu_die = smp_85xx_mach_cpu_die; 509 ppc_md.cpu_die = smp_85xx_mach_cpu_die;
516#endif 510 smp_85xx_ops.cpu_die = qoriq_cpu_kill;
517 } 511 }
518 512#endif
519 smp_ops = &smp_85xx_ops; 513 smp_ops = &smp_85xx_ops;
520 514
521#ifdef CONFIG_KEXEC 515#ifdef CONFIG_KEXEC
diff --git a/arch/powerpc/platforms/85xx/smp.h b/arch/powerpc/platforms/85xx/smp.h
index e2b44933ff19..0b20ae315c53 100644
--- a/arch/powerpc/platforms/85xx/smp.h
+++ b/arch/powerpc/platforms/85xx/smp.h
@@ -5,6 +5,7 @@
5 5
6#ifdef CONFIG_SMP 6#ifdef CONFIG_SMP
7void __init mpc85xx_smp_init(void); 7void __init mpc85xx_smp_init(void);
8int __init mpc85xx_setup_pmc(void);
8#else 9#else
9static inline void mpc85xx_smp_init(void) 10static inline void mpc85xx_smp_init(void)
10{ 11{
diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile
index ede815d6489d..2d889ad7dc89 100644
--- a/arch/powerpc/platforms/86xx/Makefile
+++ b/arch/powerpc/platforms/86xx/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the PowerPC 86xx linux kernel. 2# Makefile for the PowerPC 86xx linux kernel.
3# 3#
4 4
5obj-y := pic.o 5obj-y := pic.o common.o
6obj-$(CONFIG_SMP) += mpc86xx_smp.o 6obj-$(CONFIG_SMP) += mpc86xx_smp.o
7obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o 7obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o
8obj-$(CONFIG_SBC8641D) += sbc8641d.o 8obj-$(CONFIG_SBC8641D) += sbc8641d.o
diff --git a/arch/powerpc/platforms/86xx/common.c b/arch/powerpc/platforms/86xx/common.c
new file mode 100644
index 000000000000..0f7b7fcf1ba2
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/common.c
@@ -0,0 +1,43 @@
1/*
2 * Routines common to most mpc86xx-based boards.
3 *
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/of_platform.h>
10#include <asm/synch.h>
11
12#include "mpc86xx.h"
13
14static const struct of_device_id mpc86xx_common_ids[] __initconst = {
15 { .type = "soc", },
16 { .compatible = "soc", },
17 { .compatible = "simple-bus", },
18 { .name = "localbus", },
19 { .compatible = "gianfar", },
20 { .compatible = "fsl,mpc8641-pcie", },
21 {},
22};
23
24int __init mpc86xx_common_publish_devices(void)
25{
26 return of_platform_bus_probe(NULL, mpc86xx_common_ids, NULL);
27}
28
29long __init mpc86xx_time_init(void)
30{
31 unsigned int temp;
32
33 /* Set the time base to zero */
34 mtspr(SPRN_TBWL, 0);
35 mtspr(SPRN_TBWU, 0);
36
37 temp = mfspr(SPRN_HID0);
38 temp |= HID0_TBEN;
39 mtspr(SPRN_HID0, temp);
40 isync();
41
42 return 0;
43}
diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c
index bf17933b20f3..8e63b752712c 100644
--- a/arch/powerpc/platforms/86xx/gef_ppc9a.c
+++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c
@@ -197,37 +197,7 @@ static int __init gef_ppc9a_probe(void)
197 return 0; 197 return 0;
198} 198}
199 199
200static long __init mpc86xx_time_init(void) 200machine_arch_initcall(gef_ppc9a, mpc86xx_common_publish_devices);
201{
202 unsigned int temp;
203
204 /* Set the time base to zero */
205 mtspr(SPRN_TBWL, 0);
206 mtspr(SPRN_TBWU, 0);
207
208 temp = mfspr(SPRN_HID0);
209 temp |= HID0_TBEN;
210 mtspr(SPRN_HID0, temp);
211 asm volatile("isync");
212
213 return 0;
214}
215
216static const struct of_device_id of_bus_ids[] __initconst = {
217 { .compatible = "simple-bus", },
218 { .compatible = "gianfar", },
219 { .compatible = "fsl,mpc8641-pcie", },
220 {},
221};
222
223static int __init declare_of_platform_devices(void)
224{
225 printk(KERN_DEBUG "Probe platform devices\n");
226 of_platform_bus_probe(NULL, of_bus_ids, NULL);
227
228 return 0;
229}
230machine_arch_initcall(gef_ppc9a, declare_of_platform_devices);
231 201
232define_machine(gef_ppc9a) { 202define_machine(gef_ppc9a) {
233 .name = "GE PPC9A", 203 .name = "GE PPC9A",
diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c
index 8facf5873866..0e0be94f551f 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc310.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc310.c
@@ -184,37 +184,7 @@ static int __init gef_sbc310_probe(void)
184 return 0; 184 return 0;
185} 185}
186 186
187static long __init mpc86xx_time_init(void) 187machine_arch_initcall(gef_sbc310, mpc86xx_common_publish_devices);
188{
189 unsigned int temp;
190
191 /* Set the time base to zero */
192 mtspr(SPRN_TBWL, 0);
193 mtspr(SPRN_TBWU, 0);
194
195 temp = mfspr(SPRN_HID0);
196 temp |= HID0_TBEN;
197 mtspr(SPRN_HID0, temp);
198 asm volatile("isync");
199
200 return 0;
201}
202
203static const struct of_device_id of_bus_ids[] __initconst = {
204 { .compatible = "simple-bus", },
205 { .compatible = "gianfar", },
206 { .compatible = "fsl,mpc8641-pcie", },
207 {},
208};
209
210static int __init declare_of_platform_devices(void)
211{
212 printk(KERN_DEBUG "Probe platform devices\n");
213 of_platform_bus_probe(NULL, of_bus_ids, NULL);
214
215 return 0;
216}
217machine_arch_initcall(gef_sbc310, declare_of_platform_devices);
218 188
219define_machine(gef_sbc310) { 189define_machine(gef_sbc310) {
220 .name = "GE SBC310", 190 .name = "GE SBC310",
diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c
index 8c9058df5642..e8292b492d7e 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc610.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc610.c
@@ -174,37 +174,7 @@ static int __init gef_sbc610_probe(void)
174 return 0; 174 return 0;
175} 175}
176 176
177static long __init mpc86xx_time_init(void) 177machine_arch_initcall(gef_sbc610, mpc86xx_common_publish_devices);
178{
179 unsigned int temp;
180
181 /* Set the time base to zero */
182 mtspr(SPRN_TBWL, 0);
183 mtspr(SPRN_TBWU, 0);
184
185 temp = mfspr(SPRN_HID0);
186 temp |= HID0_TBEN;
187 mtspr(SPRN_HID0, temp);
188 asm volatile("isync");
189
190 return 0;
191}
192
193static const struct of_device_id of_bus_ids[] __initconst = {
194 { .compatible = "simple-bus", },
195 { .compatible = "gianfar", },
196 { .compatible = "fsl,mpc8641-pcie", },
197 {},
198};
199
200static int __init declare_of_platform_devices(void)
201{
202 printk(KERN_DEBUG "Probe platform devices\n");
203 of_platform_bus_probe(NULL, of_bus_ids, NULL);
204
205 return 0;
206}
207machine_arch_initcall(gef_sbc610, declare_of_platform_devices);
208 178
209define_machine(gef_sbc610) { 179define_machine(gef_sbc610) {
210 .name = "GE SBC610", 180 .name = "GE SBC610",
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index 437a9c372ae1..957473e5c8e5 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -88,12 +88,10 @@ static inline void mpc8610_suspend_init(void) { }
88static const struct of_device_id mpc8610_ids[] __initconst = { 88static const struct of_device_id mpc8610_ids[] __initconst = {
89 { .compatible = "fsl,mpc8610-immr", }, 89 { .compatible = "fsl,mpc8610-immr", },
90 { .compatible = "fsl,mpc8610-guts", }, 90 { .compatible = "fsl,mpc8610-guts", },
91 { .compatible = "simple-bus", },
92 /* So that the DMA channel nodes can be probed individually: */ 91 /* So that the DMA channel nodes can be probed individually: */
93 { .compatible = "fsl,eloplus-dma", }, 92 { .compatible = "fsl,eloplus-dma", },
94 /* PCI controllers */ 93 /* PCI controllers */
95 { .compatible = "fsl,mpc8610-pci", }, 94 { .compatible = "fsl,mpc8610-pci", },
96 { .compatible = "fsl,mpc8641-pcie", },
97 {} 95 {}
98}; 96};
99 97
@@ -105,6 +103,8 @@ static int __init mpc8610_declare_of_platform_devices(void)
105 /* Enable wakeup on PIXIS' event IRQ. */ 103 /* Enable wakeup on PIXIS' event IRQ. */
106 mpc8610_suspend_init(); 104 mpc8610_suspend_init();
107 105
106 mpc86xx_common_publish_devices();
107
108 /* Without this call, the SSI device driver won't get probed. */ 108 /* Without this call, the SSI device driver won't get probed. */
109 of_platform_bus_probe(NULL, mpc8610_ids, NULL); 109 of_platform_bus_probe(NULL, mpc8610_ids, NULL);
110 110
@@ -327,22 +327,6 @@ static int __init mpc86xx_hpcd_probe(void)
327 return 0; 327 return 0;
328} 328}
329 329
330static long __init mpc86xx_time_init(void)
331{
332 unsigned int temp;
333
334 /* Set the time base to zero */
335 mtspr(SPRN_TBWL, 0);
336 mtspr(SPRN_TBWU, 0);
337
338 temp = mfspr(SPRN_HID0);
339 temp |= HID0_TBEN;
340 mtspr(SPRN_HID0, temp);
341 asm volatile("isync");
342
343 return 0;
344}
345
346define_machine(mpc86xx_hpcd) { 330define_machine(mpc86xx_hpcd) {
347 .name = "MPC86xx HPCD", 331 .name = "MPC86xx HPCD",
348 .probe = mpc86xx_hpcd_probe, 332 .probe = mpc86xx_hpcd_probe,
diff --git a/arch/powerpc/platforms/86xx/mpc86xx.h b/arch/powerpc/platforms/86xx/mpc86xx.h
index 08efb57559d1..53500db6b644 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx.h
+++ b/arch/powerpc/platforms/86xx/mpc86xx.h
@@ -17,5 +17,7 @@
17 17
18extern void mpc86xx_smp_init(void); 18extern void mpc86xx_smp_init(void);
19extern void mpc86xx_init_irq(void); 19extern void mpc86xx_init_irq(void);
20extern long mpc86xx_time_init(void);
21extern int mpc86xx_common_publish_devices(void);
20 22
21#endif /* __MPC86XX_H__ */ 23#endif /* __MPC86XX_H__ */
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 07ccb1b0cc7d..e5084811b9c6 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -110,33 +110,14 @@ static int __init mpc86xx_hpcn_probe(void)
110 return 0; 110 return 0;
111} 111}
112 112
113static long __init
114mpc86xx_time_init(void)
115{
116 unsigned int temp;
117
118 /* Set the time base to zero */
119 mtspr(SPRN_TBWL, 0);
120 mtspr(SPRN_TBWU, 0);
121
122 temp = mfspr(SPRN_HID0);
123 temp |= HID0_TBEN;
124 mtspr(SPRN_HID0, temp);
125 asm volatile("isync");
126
127 return 0;
128}
129
130static const struct of_device_id of_bus_ids[] __initconst = { 113static const struct of_device_id of_bus_ids[] __initconst = {
131 { .compatible = "simple-bus", },
132 { .compatible = "fsl,srio", }, 114 { .compatible = "fsl,srio", },
133 { .compatible = "gianfar", },
134 { .compatible = "fsl,mpc8641-pcie", },
135 {}, 115 {},
136}; 116};
137 117
138static int __init declare_of_platform_devices(void) 118static int __init declare_of_platform_devices(void)
139{ 119{
120 mpc86xx_common_publish_devices();
140 of_platform_bus_probe(NULL, of_bus_ids, NULL); 121 of_platform_bus_probe(NULL, of_bus_ids, NULL);
141 122
142 return 0; 123 return 0;
diff --git a/arch/powerpc/platforms/86xx/sbc8641d.c b/arch/powerpc/platforms/86xx/sbc8641d.c
index 6810b71d54a7..2a9cf278c12a 100644
--- a/arch/powerpc/platforms/86xx/sbc8641d.c
+++ b/arch/powerpc/platforms/86xx/sbc8641d.c
@@ -75,37 +75,7 @@ static int __init sbc8641_probe(void)
75 return 0; 75 return 0;
76} 76}
77 77
78static long __init 78machine_arch_initcall(sbc8641, mpc86xx_common_publish_devices);
79mpc86xx_time_init(void)
80{
81 unsigned int temp;
82
83 /* Set the time base to zero */
84 mtspr(SPRN_TBWL, 0);
85 mtspr(SPRN_TBWU, 0);
86
87 temp = mfspr(SPRN_HID0);
88 temp |= HID0_TBEN;
89 mtspr(SPRN_HID0, temp);
90 asm volatile("isync");
91
92 return 0;
93}
94
95static const struct of_device_id of_bus_ids[] __initconst = {
96 { .compatible = "simple-bus", },
97 { .compatible = "gianfar", },
98 { .compatible = "fsl,mpc8641-pcie", },
99 {},
100};
101
102static int __init declare_of_platform_devices(void)
103{
104 of_platform_bus_probe(NULL, of_bus_ids, NULL);
105
106 return 0;
107}
108machine_arch_initcall(sbc8641, declare_of_platform_devices);
109 79
110define_machine(sbc8641) { 80define_machine(sbc8641) {
111 .name = "SBC8641D", 81 .name = "SBC8641D",
diff --git a/arch/powerpc/platforms/embedded6xx/mpc10x.h b/arch/powerpc/platforms/embedded6xx/mpc10x.h
index b290b63661f1..5ad12023e562 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc10x.h
+++ b/arch/powerpc/platforms/embedded6xx/mpc10x.h
@@ -24,13 +24,11 @@
24 * Processor: 0x80000000 - 0x807fffff -> PCI I/O: 0x00000000 - 0x007fffff 24 * Processor: 0x80000000 - 0x807fffff -> PCI I/O: 0x00000000 - 0x007fffff
25 * Processor: 0xc0000000 - 0xdfffffff -> PCI MEM: 0x00000000 - 0x1fffffff 25 * Processor: 0xc0000000 - 0xdfffffff -> PCI MEM: 0x00000000 - 0x1fffffff
26 * PCI MEM: 0x80000000 -> Processor System Memory: 0x00000000 26 * PCI MEM: 0x80000000 -> Processor System Memory: 0x00000000
27 * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB)
28 * 27 *
29 * MAP B (CHRP Map) 28 * MAP B (CHRP Map)
30 * Processor: 0xfe000000 - 0xfebfffff -> PCI I/O: 0x00000000 - 0x00bfffff 29 * Processor: 0xfe000000 - 0xfebfffff -> PCI I/O: 0x00000000 - 0x00bfffff
31 * Processor: 0x80000000 - 0xbfffffff -> PCI MEM: 0x80000000 - 0xbfffffff 30 * Processor: 0x80000000 - 0xbfffffff -> PCI MEM: 0x80000000 - 0xbfffffff
32 * PCI MEM: 0x00000000 -> Processor System Memory: 0x00000000 31 * PCI MEM: 0x00000000 -> Processor System Memory: 0x00000000
33 * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB)
34 */ 32 */
35 33
36/* 34/*
@@ -138,14 +136,6 @@
138#define MPC10X_EUMB_WP_OFFSET 0x000ff000 /* Data path diagnostic, watchpoint reg offset */ 136#define MPC10X_EUMB_WP_OFFSET 0x000ff000 /* Data path diagnostic, watchpoint reg offset */
139#define MPC10X_EUMB_WP_SIZE 0x00001000 /* Data path diagnostic, watchpoint reg size */ 137#define MPC10X_EUMB_WP_SIZE 0x00001000 /* Data path diagnostic, watchpoint reg size */
140 138
141/*
142 * Define some recommended places to put the EUMB regs.
143 * For both maps, recommend putting the EUMB from 0xeff00000 to 0xefffffff.
144 */
145extern unsigned long ioremap_base;
146#define MPC10X_MAPA_EUMB_BASE (ioremap_base - MPC10X_EUMB_SIZE)
147#define MPC10X_MAPB_EUMB_BASE MPC10X_MAPA_EUMB_BASE
148
149enum ppc_sys_devices { 139enum ppc_sys_devices {
150 MPC10X_IIC1, 140 MPC10X_IIC1,
151 MPC10X_DMA0, 141 MPC10X_DMA0,
diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
index 52c6ce1cc985..1eb7b45e017d 100644
--- a/arch/powerpc/platforms/powermac/Makefile
+++ b/arch/powerpc/platforms/powermac/Makefile
@@ -2,7 +2,7 @@ CFLAGS_bootx_init.o += -fPIC
2 2
3ifdef CONFIG_FUNCTION_TRACER 3ifdef CONFIG_FUNCTION_TRACER
4# Do not trace early boot code 4# Do not trace early boot code
5CFLAGS_REMOVE_bootx_init.o = -pg -mno-sched-epilog 5CFLAGS_REMOVE_bootx_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
6endif 6endif
7 7
8obj-y += pic.o setup.o time.o feature.o pci.o \ 8obj-y += pic.o setup.o time.o feature.o pci.o \
diff --git a/arch/powerpc/platforms/powermac/cache.S b/arch/powerpc/platforms/powermac/cache.S
index 6be1a4af3359..cc5347eb1662 100644
--- a/arch/powerpc/platforms/powermac/cache.S
+++ b/arch/powerpc/platforms/powermac/cache.S
@@ -23,7 +23,7 @@
23 * when going to sleep, when doing a PMU based cpufreq transition, 23 * when going to sleep, when doing a PMU based cpufreq transition,
24 * or when "offlining" a CPU on SMP machines. This code is over 24 * or when "offlining" a CPU on SMP machines. This code is over
25 * paranoid, but I've had enough issues with various CPU revs and 25 * paranoid, but I've had enough issues with various CPU revs and
26 * bugs that I decided it was worth beeing over cautious 26 * bugs that I decided it was worth being over cautious
27 */ 27 */
28 28
29_GLOBAL(flush_disable_caches) 29_GLOBAL(flush_disable_caches)
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index 4882bfd90e27..1e02328c3f2d 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -198,7 +198,7 @@ static long ohare_htw_scc_enable(struct device_node *node, long param,
198 if (htw) { 198 if (htw) {
199 /* Side effect: this will also power up the 199 /* Side effect: this will also power up the
200 * modem, but it's too messy to figure out on which 200 * modem, but it's too messy to figure out on which
201 * ports this controls the tranceiver and on which 201 * ports this controls the transceiver and on which
202 * it controls the modem 202 * it controls the modem
203 */ 203 */
204 if (trans) 204 if (trans)
@@ -463,7 +463,7 @@ static long heathrow_sound_enable(struct device_node *node, long param,
463 unsigned long flags; 463 unsigned long flags;
464 464
465 /* B&W G3 and Yikes don't support that properly (the 465 /* B&W G3 and Yikes don't support that properly (the
466 * sound appear to never come back after beeing shut down). 466 * sound appear to never come back after being shut down).
467 */ 467 */
468 if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE || 468 if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE ||
469 pmac_mb.model_id == PMAC_TYPE_YIKES) 469 pmac_mb.model_id == PMAC_TYPE_YIKES)
@@ -2770,7 +2770,7 @@ set_initial_features(void)
2770 * but I'm not too sure it was audited for side-effects on other 2770 * but I'm not too sure it was audited for side-effects on other
2771 * ohare based machines... 2771 * ohare based machines...
2772 * Since I still have difficulties figuring the right way to 2772 * Since I still have difficulties figuring the right way to
2773 * differenciate them all and since that hack was there for a long 2773 * differentiate them all and since that hack was there for a long
2774 * time, I'll keep it around 2774 * time, I'll keep it around
2775 */ 2775 */
2776 if (macio_chips[0].type == macio_ohare) { 2776 if (macio_chips[0].type == macio_ohare) {
diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
index f1516b5ecec9..cd9711e72df6 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -5,7 +5,7 @@ obj-y += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o
5obj-y += opal-kmsg.o 5obj-y += opal-kmsg.o
6 6
7obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o 7obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o
8obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o npu-dma.o 8obj-$(CONFIG_PCI) += pci.o pci-ioda.o npu-dma.o
9obj-$(CONFIG_EEH) += eeh-powernv.o 9obj-$(CONFIG_EEH) += eeh-powernv.o
10obj-$(CONFIG_PPC_SCOM) += opal-xscom.o 10obj-$(CONFIG_PPC_SCOM) += opal-xscom.o
11obj-$(CONFIG_MEMORY_FAILURE) += opal-memory-errors.o 11obj-$(CONFIG_MEMORY_FAILURE) += opal-memory-errors.o
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
index 87f47e55aab6..950b3e539057 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -167,42 +167,26 @@ static int pnv_eeh_dbgfs_get(void *data, int offset, u64 *val)
167 return 0; 167 return 0;
168} 168}
169 169
170static int pnv_eeh_outb_dbgfs_set(void *data, u64 val) 170#define PNV_EEH_DBGFS_ENTRY(name, reg) \
171{ 171static int pnv_eeh_dbgfs_set_##name(void *data, u64 val) \
172 return pnv_eeh_dbgfs_set(data, 0xD10, val); 172{ \
173} 173 return pnv_eeh_dbgfs_set(data, reg, val); \
174 174} \
175static int pnv_eeh_outb_dbgfs_get(void *data, u64 *val) 175 \
176{ 176static int pnv_eeh_dbgfs_get_##name(void *data, u64 *val) \
177 return pnv_eeh_dbgfs_get(data, 0xD10, val); 177{ \
178} 178 return pnv_eeh_dbgfs_get(data, reg, val); \
179 179} \
180static int pnv_eeh_inbA_dbgfs_set(void *data, u64 val) 180 \
181{ 181DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_dbgfs_ops_##name, \
182 return pnv_eeh_dbgfs_set(data, 0xD90, val); 182 pnv_eeh_dbgfs_get_##name, \
183} 183 pnv_eeh_dbgfs_set_##name, \
184 184 "0x%llx\n")
185static int pnv_eeh_inbA_dbgfs_get(void *data, u64 *val) 185
186{ 186PNV_EEH_DBGFS_ENTRY(outb, 0xD10);
187 return pnv_eeh_dbgfs_get(data, 0xD90, val); 187PNV_EEH_DBGFS_ENTRY(inbA, 0xD90);
188} 188PNV_EEH_DBGFS_ENTRY(inbB, 0xE10);
189
190static int pnv_eeh_inbB_dbgfs_set(void *data, u64 val)
191{
192 return pnv_eeh_dbgfs_set(data, 0xE10, val);
193}
194 189
195static int pnv_eeh_inbB_dbgfs_get(void *data, u64 *val)
196{
197 return pnv_eeh_dbgfs_get(data, 0xE10, val);
198}
199
200DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_outb_dbgfs_ops, pnv_eeh_outb_dbgfs_get,
201 pnv_eeh_outb_dbgfs_set, "0x%llx\n");
202DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_inbA_dbgfs_ops, pnv_eeh_inbA_dbgfs_get,
203 pnv_eeh_inbA_dbgfs_set, "0x%llx\n");
204DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_inbB_dbgfs_ops, pnv_eeh_inbB_dbgfs_get,
205 pnv_eeh_inbB_dbgfs_set, "0x%llx\n");
206#endif /* CONFIG_DEBUG_FS */ 190#endif /* CONFIG_DEBUG_FS */
207 191
208/** 192/**
@@ -268,13 +252,13 @@ static int pnv_eeh_post_init(void)
268 252
269 debugfs_create_file("err_injct_outbound", 0600, 253 debugfs_create_file("err_injct_outbound", 0600,
270 phb->dbgfs, hose, 254 phb->dbgfs, hose,
271 &pnv_eeh_outb_dbgfs_ops); 255 &pnv_eeh_dbgfs_ops_outb);
272 debugfs_create_file("err_injct_inboundA", 0600, 256 debugfs_create_file("err_injct_inboundA", 0600,
273 phb->dbgfs, hose, 257 phb->dbgfs, hose,
274 &pnv_eeh_inbA_dbgfs_ops); 258 &pnv_eeh_dbgfs_ops_inbA);
275 debugfs_create_file("err_injct_inboundB", 0600, 259 debugfs_create_file("err_injct_inboundB", 0600,
276 phb->dbgfs, hose, 260 phb->dbgfs, hose,
277 &pnv_eeh_inbB_dbgfs_ops); 261 &pnv_eeh_dbgfs_ops_inbB);
278#endif /* CONFIG_DEBUG_FS */ 262#endif /* CONFIG_DEBUG_FS */
279 } 263 }
280 264
@@ -387,6 +371,7 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data)
387 edev->mode &= 0xFFFFFF00; 371 edev->mode &= 0xFFFFFF00;
388 edev->pcix_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_PCIX); 372 edev->pcix_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_PCIX);
389 edev->pcie_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_EXP); 373 edev->pcie_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_EXP);
374 edev->af_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_AF);
390 edev->aer_cap = pnv_eeh_find_ecap(pdn, PCI_EXT_CAP_ID_ERR); 375 edev->aer_cap = pnv_eeh_find_ecap(pdn, PCI_EXT_CAP_ID_ERR);
391 if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) { 376 if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) {
392 edev->mode |= EEH_DEV_BRIDGE; 377 edev->mode |= EEH_DEV_BRIDGE;
@@ -895,6 +880,120 @@ void pnv_pci_reset_secondary_bus(struct pci_dev *dev)
895 } 880 }
896} 881}
897 882
883static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, const char *type,
884 int pos, u16 mask)
885{
886 struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
887 int i, status = 0;
888
889 /* Wait for Transaction Pending bit to be cleared */
890 for (i = 0; i < 4; i++) {
891 eeh_ops->read_config(pdn, pos, 2, &status);
892 if (!(status & mask))
893 return;
894
895 msleep((1 << i) * 100);
896 }
897
898 pr_warn("%s: Pending transaction while issuing %sFLR to %04x:%02x:%02x.%01x\n",
899 __func__, type,
900 edev->phb->global_number, pdn->busno,
901 PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn));
902}
903
904static int pnv_eeh_do_flr(struct pci_dn *pdn, int option)
905{
906 struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
907 u32 reg = 0;
908
909 if (WARN_ON(!edev->pcie_cap))
910 return -ENOTTY;
911
912 eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCAP, 4, &reg);
913 if (!(reg & PCI_EXP_DEVCAP_FLR))
914 return -ENOTTY;
915
916 switch (option) {
917 case EEH_RESET_HOT:
918 case EEH_RESET_FUNDAMENTAL:
919 pnv_eeh_wait_for_pending(pdn, "",
920 edev->pcie_cap + PCI_EXP_DEVSTA,
921 PCI_EXP_DEVSTA_TRPND);
922 eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
923 4, &reg);
924 reg |= PCI_EXP_DEVCTL_BCR_FLR;
925 eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
926 4, reg);
927 msleep(EEH_PE_RST_HOLD_TIME);
928 break;
929 case EEH_RESET_DEACTIVATE:
930 eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
931 4, &reg);
932 reg &= ~PCI_EXP_DEVCTL_BCR_FLR;
933 eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
934 4, reg);
935 msleep(EEH_PE_RST_SETTLE_TIME);
936 break;
937 }
938
939 return 0;
940}
941
942static int pnv_eeh_do_af_flr(struct pci_dn *pdn, int option)
943{
944 struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
945 u32 cap = 0;
946
947 if (WARN_ON(!edev->af_cap))
948 return -ENOTTY;
949
950 eeh_ops->read_config(pdn, edev->af_cap + PCI_AF_CAP, 1, &cap);
951 if (!(cap & PCI_AF_CAP_TP) || !(cap & PCI_AF_CAP_FLR))
952 return -ENOTTY;
953
954 switch (option) {
955 case EEH_RESET_HOT:
956 case EEH_RESET_FUNDAMENTAL:
957 /*
958 * Wait for Transaction Pending bit to clear. A word-aligned
959 * test is used, so we use the conrol offset rather than status
960 * and shift the test bit to match.
961 */
962 pnv_eeh_wait_for_pending(pdn, "AF",
963 edev->af_cap + PCI_AF_CTRL,
964 PCI_AF_STATUS_TP << 8);
965 eeh_ops->write_config(pdn, edev->af_cap + PCI_AF_CTRL,
966 1, PCI_AF_CTRL_FLR);
967 msleep(EEH_PE_RST_HOLD_TIME);
968 break;
969 case EEH_RESET_DEACTIVATE:
970 eeh_ops->write_config(pdn, edev->af_cap + PCI_AF_CTRL, 1, 0);
971 msleep(EEH_PE_RST_SETTLE_TIME);
972 break;
973 }
974
975 return 0;
976}
977
978static int pnv_eeh_reset_vf_pe(struct eeh_pe *pe, int option)
979{
980 struct eeh_dev *edev;
981 struct pci_dn *pdn;
982 int ret;
983
984 /* The VF PE should have only one child device */
985 edev = list_first_entry_or_null(&pe->edevs, struct eeh_dev, list);
986 pdn = eeh_dev_to_pdn(edev);
987 if (!pdn)
988 return -ENXIO;
989
990 ret = pnv_eeh_do_flr(pdn, option);
991 if (!ret)
992 return ret;
993
994 return pnv_eeh_do_af_flr(pdn, option);
995}
996
898/** 997/**
899 * pnv_eeh_reset - Reset the specified PE 998 * pnv_eeh_reset - Reset the specified PE
900 * @pe: EEH PE 999 * @pe: EEH PE
@@ -956,7 +1055,9 @@ static int pnv_eeh_reset(struct eeh_pe *pe, int option)
956 } 1055 }
957 1056
958 bus = eeh_pe_bus_get(pe); 1057 bus = eeh_pe_bus_get(pe);
959 if (pci_is_root_bus(bus) || 1058 if (pe->type & EEH_PE_VF)
1059 ret = pnv_eeh_reset_vf_pe(pe, option);
1060 else if (pci_is_root_bus(bus) ||
960 pci_is_root_bus(bus->parent)) 1061 pci_is_root_bus(bus->parent))
961 ret = pnv_eeh_root_reset(hose, option); 1062 ret = pnv_eeh_root_reset(hose, option);
962 else 1063 else
@@ -1095,6 +1196,14 @@ static inline bool pnv_eeh_cfg_blocked(struct pci_dn *pdn)
1095 if (!edev || !edev->pe) 1196 if (!edev || !edev->pe)
1096 return false; 1197 return false;
1097 1198
1199 /*
1200 * We will issue FLR or AF FLR to all VFs, which are contained
1201 * in VF PE. It relies on the EEH PCI config accessors. So we
1202 * can't block them during the window.
1203 */
1204 if (edev->physfn && (edev->pe->state & EEH_PE_RESET))
1205 return false;
1206
1098 if (edev->pe->state & EEH_PE_CFG_BLOCKED) 1207 if (edev->pe->state & EEH_PE_CFG_BLOCKED)
1099 return true; 1208 return true;
1100 1209
@@ -1479,6 +1588,65 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
1479 return ret; 1588 return ret;
1480} 1589}
1481 1590
1591static int pnv_eeh_restore_vf_config(struct pci_dn *pdn)
1592{
1593 struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
1594 u32 devctl, cmd, cap2, aer_capctl;
1595 int old_mps;
1596
1597 if (edev->pcie_cap) {
1598 /* Restore MPS */
1599 old_mps = (ffs(pdn->mps) - 8) << 5;
1600 eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
1601 2, &devctl);
1602 devctl &= ~PCI_EXP_DEVCTL_PAYLOAD;
1603 devctl |= old_mps;
1604 eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
1605 2, devctl);
1606
1607 /* Disable Completion Timeout */
1608 eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCAP2,
1609 4, &cap2);
1610 if (cap2 & 0x10) {
1611 eeh_ops->read_config(pdn,
1612 edev->pcie_cap + PCI_EXP_DEVCTL2,
1613 4, &cap2);
1614 cap2 |= 0x10;
1615 eeh_ops->write_config(pdn,
1616 edev->pcie_cap + PCI_EXP_DEVCTL2,
1617 4, cap2);
1618 }
1619 }
1620
1621 /* Enable SERR and parity checking */
1622 eeh_ops->read_config(pdn, PCI_COMMAND, 2, &cmd);
1623 cmd |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1624 eeh_ops->write_config(pdn, PCI_COMMAND, 2, cmd);
1625
1626 /* Enable report various errors */
1627 if (edev->pcie_cap) {
1628 eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
1629 2, &devctl);
1630 devctl &= ~PCI_EXP_DEVCTL_CERE;
1631 devctl |= (PCI_EXP_DEVCTL_NFERE |
1632 PCI_EXP_DEVCTL_FERE |
1633 PCI_EXP_DEVCTL_URRE);
1634 eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
1635 2, devctl);
1636 }
1637
1638 /* Enable ECRC generation and check */
1639 if (edev->pcie_cap && edev->aer_cap) {
1640 eeh_ops->read_config(pdn, edev->aer_cap + PCI_ERR_CAP,
1641 4, &aer_capctl);
1642 aer_capctl |= (PCI_ERR_CAP_ECRC_GENE | PCI_ERR_CAP_ECRC_CHKE);
1643 eeh_ops->write_config(pdn, edev->aer_cap + PCI_ERR_CAP,
1644 4, aer_capctl);
1645 }
1646
1647 return 0;
1648}
1649
1482static int pnv_eeh_restore_config(struct pci_dn *pdn) 1650static int pnv_eeh_restore_config(struct pci_dn *pdn)
1483{ 1651{
1484 struct eeh_dev *edev = pdn_to_eeh_dev(pdn); 1652 struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
@@ -1488,9 +1656,21 @@ static int pnv_eeh_restore_config(struct pci_dn *pdn)
1488 if (!edev) 1656 if (!edev)
1489 return -EEXIST; 1657 return -EEXIST;
1490 1658
1491 phb = edev->phb->private_data; 1659 /*
1492 ret = opal_pci_reinit(phb->opal_id, 1660 * We have to restore the PCI config space after reset since the
1493 OPAL_REINIT_PCI_DEV, edev->config_addr); 1661 * firmware can't see SRIOV VFs.
1662 *
1663 * FIXME: The MPS, error routing rules, timeout setting are worthy
1664 * to be exported by firmware in extendible way.
1665 */
1666 if (edev->physfn) {
1667 ret = pnv_eeh_restore_vf_config(pdn);
1668 } else {
1669 phb = edev->phb->private_data;
1670 ret = opal_pci_reinit(phb->opal_id,
1671 OPAL_REINIT_PCI_DEV, edev->config_addr);
1672 }
1673
1494 if (ret) { 1674 if (ret) {
1495 pr_warn("%s: Can't reinit PCI dev 0x%x (%lld)\n", 1675 pr_warn("%s: Can't reinit PCI dev 0x%x (%lld)\n",
1496 __func__, edev->config_addr, ret); 1676 __func__, edev->config_addr, ret);
@@ -1519,6 +1699,40 @@ static struct eeh_ops pnv_eeh_ops = {
1519 .restore_config = pnv_eeh_restore_config 1699 .restore_config = pnv_eeh_restore_config
1520}; 1700};
1521 1701
1702void pcibios_bus_add_device(struct pci_dev *pdev)
1703{
1704 struct pci_dn *pdn = pci_get_pdn(pdev);
1705
1706 if (!pdev->is_virtfn)
1707 return;
1708
1709 /*
1710 * The following operations will fail if VF's sysfs files
1711 * aren't created or its resources aren't finalized.
1712 */
1713 eeh_add_device_early(pdn);
1714 eeh_add_device_late(pdev);
1715 eeh_sysfs_add_device(pdev);
1716}
1717
1718#ifdef CONFIG_PCI_IOV
1719static void pnv_pci_fixup_vf_mps(struct pci_dev *pdev)
1720{
1721 struct pci_dn *pdn = pci_get_pdn(pdev);
1722 int parent_mps;
1723
1724 if (!pdev->is_virtfn)
1725 return;
1726
1727 /* Synchronize MPS for VF and PF */
1728 parent_mps = pcie_get_mps(pdev->physfn);
1729 if ((128 << pdev->pcie_mpss) >= parent_mps)
1730 pcie_set_mps(pdev, parent_mps);
1731 pdn->mps = pcie_get_mps(pdev);
1732}
1733DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pnv_pci_fixup_vf_mps);
1734#endif /* CONFIG_PCI_IOV */
1735
1522/** 1736/**
1523 * eeh_powernv_init - Register platform dependent EEH operations 1737 * eeh_powernv_init - Register platform dependent EEH operations
1524 * 1738 *
diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c
index 15bfbcd5debc..fcc8b6861b63 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -35,9 +35,9 @@ int pnv_save_sprs_for_winkle(void)
35 int rc; 35 int rc;
36 36
37 /* 37 /*
38 * hid0, hid1, hid4, hid5, hmeer and lpcr values are symmetric accross 38 * hid0, hid1, hid4, hid5, hmeer and lpcr values are symmetric across
39 * all cpus at boot. Get these reg values of current cpu and use the 39 * all cpus at boot. Get these reg values of current cpu and use the
40 * same accross all cpus. 40 * same across all cpus.
41 */ 41 */
42 uint64_t lpcr_val = mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1; 42 uint64_t lpcr_val = mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1;
43 uint64_t hid0_val = mfspr(SPRN_HID0); 43 uint64_t hid0_val = mfspr(SPRN_HID0);
@@ -185,7 +185,7 @@ static ssize_t store_fastsleep_workaround_applyonce(struct device *dev,
185 * fastsleep workaround needs to be left in 'applied' state on all 185 * fastsleep workaround needs to be left in 'applied' state on all
186 * the cores. Do this by- 186 * the cores. Do this by-
187 * 1. Patching out the call to 'undo' workaround in fastsleep exit path 187 * 1. Patching out the call to 'undo' workaround in fastsleep exit path
188 * 2. Sending ipi to all the cores which have atleast one online thread 188 * 2. Sending ipi to all the cores which have at least one online thread
189 * 3. Patching out the call to 'apply' workaround in fastsleep entry 189 * 3. Patching out the call to 'apply' workaround in fastsleep entry
190 * path 190 * path
191 * There is no need to send ipi to cores which have all threads 191 * There is no need to send ipi to cores which have all threads
diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c
index e85aa900f5c0..7229acd9bb3a 100644
--- a/arch/powerpc/platforms/powernv/npu-dma.c
+++ b/arch/powerpc/platforms/powernv/npu-dma.c
@@ -278,7 +278,7 @@ static void pnv_npu_disable_bypass(struct pnv_ioda_pe *npe)
278 278
279/* 279/*
280 * Enable/disable bypass mode on the NPU. The NPU only supports one 280 * Enable/disable bypass mode on the NPU. The NPU only supports one
281 * window per link, so bypass needs to be explicity enabled or 281 * window per link, so bypass needs to be explicitly enabled or
282 * disabled. Unlike for a PHB3 bypass and non-bypass modes can't be 282 * disabled. Unlike for a PHB3 bypass and non-bypass modes can't be
283 * active at the same time. 283 * active at the same time.
284 */ 284 */
diff --git a/arch/powerpc/platforms/powernv/opal-msglog.c b/arch/powerpc/platforms/powernv/opal-msglog.c
index 44ed78af1a0d..39d6ff9e5630 100644
--- a/arch/powerpc/platforms/powernv/opal-msglog.c
+++ b/arch/powerpc/platforms/powernv/opal-msglog.c
@@ -31,26 +31,25 @@ struct memcons {
31 __be32 in_cons; 31 __be32 in_cons;
32}; 32};
33 33
34static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj, 34static struct memcons *opal_memcons = NULL;
35 struct bin_attribute *bin_attr, char *to, 35
36 loff_t pos, size_t count) 36ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count)
37{ 37{
38 struct memcons *mc = bin_attr->private;
39 const char *conbuf; 38 const char *conbuf;
40 ssize_t ret; 39 ssize_t ret;
41 size_t first_read = 0; 40 size_t first_read = 0;
42 uint32_t out_pos, avail; 41 uint32_t out_pos, avail;
43 42
44 if (!mc) 43 if (!opal_memcons)
45 return -ENODEV; 44 return -ENODEV;
46 45
47 out_pos = be32_to_cpu(ACCESS_ONCE(mc->out_pos)); 46 out_pos = be32_to_cpu(ACCESS_ONCE(opal_memcons->out_pos));
48 47
49 /* Now we've read out_pos, put a barrier in before reading the new 48 /* Now we've read out_pos, put a barrier in before reading the new
50 * data it points to in conbuf. */ 49 * data it points to in conbuf. */
51 smp_rmb(); 50 smp_rmb();
52 51
53 conbuf = phys_to_virt(be64_to_cpu(mc->obuf_phys)); 52 conbuf = phys_to_virt(be64_to_cpu(opal_memcons->obuf_phys));
54 53
55 /* When the buffer has wrapped, read from the out_pos marker to the end 54 /* When the buffer has wrapped, read from the out_pos marker to the end
56 * of the buffer, and then read the remaining data as in the un-wrapped 55 * of the buffer, and then read the remaining data as in the un-wrapped
@@ -58,7 +57,7 @@ static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj,
58 if (out_pos & MEMCONS_OUT_POS_WRAP) { 57 if (out_pos & MEMCONS_OUT_POS_WRAP) {
59 58
60 out_pos &= MEMCONS_OUT_POS_MASK; 59 out_pos &= MEMCONS_OUT_POS_MASK;
61 avail = be32_to_cpu(mc->obuf_size) - out_pos; 60 avail = be32_to_cpu(opal_memcons->obuf_size) - out_pos;
62 61
63 ret = memory_read_from_buffer(to, count, &pos, 62 ret = memory_read_from_buffer(to, count, &pos,
64 conbuf + out_pos, avail); 63 conbuf + out_pos, avail);
@@ -76,7 +75,7 @@ static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj,
76 } 75 }
77 76
78 /* Sanity check. The firmware should not do this to us. */ 77 /* Sanity check. The firmware should not do this to us. */
79 if (out_pos > be32_to_cpu(mc->obuf_size)) { 78 if (out_pos > be32_to_cpu(opal_memcons->obuf_size)) {
80 pr_err("OPAL: memory console corruption. Aborting read.\n"); 79 pr_err("OPAL: memory console corruption. Aborting read.\n");
81 return -EINVAL; 80 return -EINVAL;
82 } 81 }
@@ -91,6 +90,13 @@ out:
91 return ret; 90 return ret;
92} 91}
93 92
93static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj,
94 struct bin_attribute *bin_attr, char *to,
95 loff_t pos, size_t count)
96{
97 return opal_msglog_copy(to, pos, count);
98}
99
94static struct bin_attribute opal_msglog_attr = { 100static struct bin_attribute opal_msglog_attr = {
95 .attr = {.name = "msglog", .mode = 0444}, 101 .attr = {.name = "msglog", .mode = 0444},
96 .read = opal_msglog_read 102 .read = opal_msglog_read
@@ -117,7 +123,15 @@ void __init opal_msglog_init(void)
117 return; 123 return;
118 } 124 }
119 125
120 opal_msglog_attr.private = mc; 126 opal_memcons = mc;
127}
128
129void __init opal_msglog_sysfs_init(void)
130{
131 if (!opal_memcons) {
132 pr_warn("OPAL: message log initialisation failed, not creating sysfs entry\n");
133 return;
134 }
121 135
122 if (sysfs_create_bin_file(opal_kobj, &opal_msglog_attr) != 0) 136 if (sysfs_create_bin_file(opal_kobj, &opal_msglog_attr) != 0)
123 pr_warn("OPAL: sysfs file creation failed\n"); 137 pr_warn("OPAL: sysfs file creation failed\n");
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 4e0da5af94a1..0256d0729252 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -724,6 +724,9 @@ static int __init opal_init(void)
724 of_node_put(leds); 724 of_node_put(leds);
725 } 725 }
726 726
727 /* Initialise OPAL message log interface */
728 opal_msglog_init();
729
727 /* Create "opal" kobject under /sys/firmware */ 730 /* Create "opal" kobject under /sys/firmware */
728 rc = opal_sysfs_init(); 731 rc = opal_sysfs_init();
729 if (rc == 0) { 732 if (rc == 0) {
@@ -739,8 +742,8 @@ static int __init opal_init(void)
739 opal_platform_dump_init(); 742 opal_platform_dump_init();
740 /* Setup system parameters interface */ 743 /* Setup system parameters interface */
741 opal_sys_param_init(); 744 opal_sys_param_init();
742 /* Setup message log interface. */ 745 /* Setup message log sysfs interface. */
743 opal_msglog_init(); 746 opal_msglog_sysfs_init();
744 } 747 }
745 748
746 /* Initialize platform devices: IPMI backend, PRD & flash interface */ 749 /* Initialize platform devices: IPMI backend, PRD & flash interface */
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index f90dc04395bf..c5baaf3cc4e5 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -872,9 +872,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset)
872 if (!res->flags || !res->parent) 872 if (!res->flags || !res->parent)
873 continue; 873 continue;
874 874
875 if (!pnv_pci_is_mem_pref_64(res->flags))
876 continue;
877
878 /* 875 /*
879 * The actual IOV BAR range is determined by the start address 876 * The actual IOV BAR range is determined by the start address
880 * and the actual size for num_vfs VFs BAR. This check is to 877 * and the actual size for num_vfs VFs BAR. This check is to
@@ -903,9 +900,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset)
903 if (!res->flags || !res->parent) 900 if (!res->flags || !res->parent)
904 continue; 901 continue;
905 902
906 if (!pnv_pci_is_mem_pref_64(res->flags))
907 continue;
908
909 size = pci_iov_resource_size(dev, i + PCI_IOV_RESOURCES); 903 size = pci_iov_resource_size(dev, i + PCI_IOV_RESOURCES);
910 res2 = *res; 904 res2 = *res;
911 res->start += size * offset; 905 res->start += size * offset;
@@ -1196,29 +1190,36 @@ static void pnv_pci_ioda_setup_PEs(void)
1196} 1190}
1197 1191
1198#ifdef CONFIG_PCI_IOV 1192#ifdef CONFIG_PCI_IOV
1199static int pnv_pci_vf_release_m64(struct pci_dev *pdev) 1193static int pnv_pci_vf_release_m64(struct pci_dev *pdev, u16 num_vfs)
1200{ 1194{
1201 struct pci_bus *bus; 1195 struct pci_bus *bus;
1202 struct pci_controller *hose; 1196 struct pci_controller *hose;
1203 struct pnv_phb *phb; 1197 struct pnv_phb *phb;
1204 struct pci_dn *pdn; 1198 struct pci_dn *pdn;
1205 int i, j; 1199 int i, j;
1200 int m64_bars;
1206 1201
1207 bus = pdev->bus; 1202 bus = pdev->bus;
1208 hose = pci_bus_to_host(bus); 1203 hose = pci_bus_to_host(bus);
1209 phb = hose->private_data; 1204 phb = hose->private_data;
1210 pdn = pci_get_pdn(pdev); 1205 pdn = pci_get_pdn(pdev);
1211 1206
1207 if (pdn->m64_single_mode)
1208 m64_bars = num_vfs;
1209 else
1210 m64_bars = 1;
1211
1212 for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) 1212 for (i = 0; i < PCI_SRIOV_NUM_BARS; i++)
1213 for (j = 0; j < M64_PER_IOV; j++) { 1213 for (j = 0; j < m64_bars; j++) {
1214 if (pdn->m64_wins[i][j] == IODA_INVALID_M64) 1214 if (pdn->m64_map[j][i] == IODA_INVALID_M64)
1215 continue; 1215 continue;
1216 opal_pci_phb_mmio_enable(phb->opal_id, 1216 opal_pci_phb_mmio_enable(phb->opal_id,
1217 OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 0); 1217 OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 0);
1218 clear_bit(pdn->m64_wins[i][j], &phb->ioda.m64_bar_alloc); 1218 clear_bit(pdn->m64_map[j][i], &phb->ioda.m64_bar_alloc);
1219 pdn->m64_wins[i][j] = IODA_INVALID_M64; 1219 pdn->m64_map[j][i] = IODA_INVALID_M64;
1220 } 1220 }
1221 1221
1222 kfree(pdn->m64_map);
1222 return 0; 1223 return 0;
1223} 1224}
1224 1225
@@ -1235,8 +1236,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
1235 int total_vfs; 1236 int total_vfs;
1236 resource_size_t size, start; 1237 resource_size_t size, start;
1237 int pe_num; 1238 int pe_num;
1238 int vf_groups; 1239 int m64_bars;
1239 int vf_per_group;
1240 1240
1241 bus = pdev->bus; 1241 bus = pdev->bus;
1242 hose = pci_bus_to_host(bus); 1242 hose = pci_bus_to_host(bus);
@@ -1244,29 +1244,26 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
1244 pdn = pci_get_pdn(pdev); 1244 pdn = pci_get_pdn(pdev);
1245 total_vfs = pci_sriov_get_totalvfs(pdev); 1245 total_vfs = pci_sriov_get_totalvfs(pdev);
1246 1246
1247 /* Initialize the m64_wins to IODA_INVALID_M64 */ 1247 if (pdn->m64_single_mode)
1248 for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) 1248 m64_bars = num_vfs;
1249 for (j = 0; j < M64_PER_IOV; j++) 1249 else
1250 pdn->m64_wins[i][j] = IODA_INVALID_M64; 1250 m64_bars = 1;
1251
1252 pdn->m64_map = kmalloc(sizeof(*pdn->m64_map) * m64_bars, GFP_KERNEL);
1253 if (!pdn->m64_map)
1254 return -ENOMEM;
1255 /* Initialize the m64_map to IODA_INVALID_M64 */
1256 for (i = 0; i < m64_bars ; i++)
1257 for (j = 0; j < PCI_SRIOV_NUM_BARS; j++)
1258 pdn->m64_map[i][j] = IODA_INVALID_M64;
1251 1259
1252 if (pdn->m64_per_iov == M64_PER_IOV) {
1253 vf_groups = (num_vfs <= M64_PER_IOV) ? num_vfs: M64_PER_IOV;
1254 vf_per_group = (num_vfs <= M64_PER_IOV)? 1:
1255 roundup_pow_of_two(num_vfs) / pdn->m64_per_iov;
1256 } else {
1257 vf_groups = 1;
1258 vf_per_group = 1;
1259 }
1260 1260
1261 for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { 1261 for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
1262 res = &pdev->resource[i + PCI_IOV_RESOURCES]; 1262 res = &pdev->resource[i + PCI_IOV_RESOURCES];
1263 if (!res->flags || !res->parent) 1263 if (!res->flags || !res->parent)
1264 continue; 1264 continue;
1265 1265
1266 if (!pnv_pci_is_mem_pref_64(res->flags)) 1266 for (j = 0; j < m64_bars; j++) {
1267 continue;
1268
1269 for (j = 0; j < vf_groups; j++) {
1270 do { 1267 do {
1271 win = find_next_zero_bit(&phb->ioda.m64_bar_alloc, 1268 win = find_next_zero_bit(&phb->ioda.m64_bar_alloc,
1272 phb->ioda.m64_bar_idx + 1, 0); 1269 phb->ioda.m64_bar_idx + 1, 0);
@@ -1275,12 +1272,11 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
1275 goto m64_failed; 1272 goto m64_failed;
1276 } while (test_and_set_bit(win, &phb->ioda.m64_bar_alloc)); 1273 } while (test_and_set_bit(win, &phb->ioda.m64_bar_alloc));
1277 1274
1278 pdn->m64_wins[i][j] = win; 1275 pdn->m64_map[j][i] = win;
1279 1276
1280 if (pdn->m64_per_iov == M64_PER_IOV) { 1277 if (pdn->m64_single_mode) {
1281 size = pci_iov_resource_size(pdev, 1278 size = pci_iov_resource_size(pdev,
1282 PCI_IOV_RESOURCES + i); 1279 PCI_IOV_RESOURCES + i);
1283 size = size * vf_per_group;
1284 start = res->start + size * j; 1280 start = res->start + size * j;
1285 } else { 1281 } else {
1286 size = resource_size(res); 1282 size = resource_size(res);
@@ -1288,16 +1284,16 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
1288 } 1284 }
1289 1285
1290 /* Map the M64 here */ 1286 /* Map the M64 here */
1291 if (pdn->m64_per_iov == M64_PER_IOV) { 1287 if (pdn->m64_single_mode) {
1292 pe_num = pdn->offset + j; 1288 pe_num = pdn->pe_num_map[j];
1293 rc = opal_pci_map_pe_mmio_window(phb->opal_id, 1289 rc = opal_pci_map_pe_mmio_window(phb->opal_id,
1294 pe_num, OPAL_M64_WINDOW_TYPE, 1290 pe_num, OPAL_M64_WINDOW_TYPE,
1295 pdn->m64_wins[i][j], 0); 1291 pdn->m64_map[j][i], 0);
1296 } 1292 }
1297 1293
1298 rc = opal_pci_set_phb_mem_window(phb->opal_id, 1294 rc = opal_pci_set_phb_mem_window(phb->opal_id,
1299 OPAL_M64_WINDOW_TYPE, 1295 OPAL_M64_WINDOW_TYPE,
1300 pdn->m64_wins[i][j], 1296 pdn->m64_map[j][i],
1301 start, 1297 start,
1302 0, /* unused */ 1298 0, /* unused */
1303 size); 1299 size);
@@ -1309,12 +1305,12 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
1309 goto m64_failed; 1305 goto m64_failed;
1310 } 1306 }
1311 1307
1312 if (pdn->m64_per_iov == M64_PER_IOV) 1308 if (pdn->m64_single_mode)
1313 rc = opal_pci_phb_mmio_enable(phb->opal_id, 1309 rc = opal_pci_phb_mmio_enable(phb->opal_id,
1314 OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 2); 1310 OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 2);
1315 else 1311 else
1316 rc = opal_pci_phb_mmio_enable(phb->opal_id, 1312 rc = opal_pci_phb_mmio_enable(phb->opal_id,
1317 OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 1); 1313 OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 1);
1318 1314
1319 if (rc != OPAL_SUCCESS) { 1315 if (rc != OPAL_SUCCESS) {
1320 dev_err(&pdev->dev, "Failed to enable M64 window #%d: %llx\n", 1316 dev_err(&pdev->dev, "Failed to enable M64 window #%d: %llx\n",
@@ -1326,7 +1322,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
1326 return 0; 1322 return 0;
1327 1323
1328m64_failed: 1324m64_failed:
1329 pnv_pci_vf_release_m64(pdev); 1325 pnv_pci_vf_release_m64(pdev, num_vfs);
1330 return -EBUSY; 1326 return -EBUSY;
1331} 1327}
1332 1328
@@ -1353,15 +1349,13 @@ static void pnv_pci_ioda2_release_dma_pe(struct pci_dev *dev, struct pnv_ioda_pe
1353 iommu_free_table(tbl, of_node_full_name(dev->dev.of_node)); 1349 iommu_free_table(tbl, of_node_full_name(dev->dev.of_node));
1354} 1350}
1355 1351
1356static void pnv_ioda_release_vf_PE(struct pci_dev *pdev, u16 num_vfs) 1352static void pnv_ioda_release_vf_PE(struct pci_dev *pdev)
1357{ 1353{
1358 struct pci_bus *bus; 1354 struct pci_bus *bus;
1359 struct pci_controller *hose; 1355 struct pci_controller *hose;
1360 struct pnv_phb *phb; 1356 struct pnv_phb *phb;
1361 struct pnv_ioda_pe *pe, *pe_n; 1357 struct pnv_ioda_pe *pe, *pe_n;
1362 struct pci_dn *pdn; 1358 struct pci_dn *pdn;
1363 u16 vf_index;
1364 int64_t rc;
1365 1359
1366 bus = pdev->bus; 1360 bus = pdev->bus;
1367 hose = pci_bus_to_host(bus); 1361 hose = pci_bus_to_host(bus);
@@ -1371,35 +1365,6 @@ static void pnv_ioda_release_vf_PE(struct pci_dev *pdev, u16 num_vfs)
1371 if (!pdev->is_physfn) 1365 if (!pdev->is_physfn)
1372 return; 1366 return;
1373 1367
1374 if (pdn->m64_per_iov == M64_PER_IOV && num_vfs > M64_PER_IOV) {
1375 int vf_group;
1376 int vf_per_group;
1377 int vf_index1;
1378
1379 vf_per_group = roundup_pow_of_two(num_vfs) / pdn->m64_per_iov;
1380
1381 for (vf_group = 0; vf_group < M64_PER_IOV; vf_group++)
1382 for (vf_index = vf_group * vf_per_group;
1383 vf_index < (vf_group + 1) * vf_per_group &&
1384 vf_index < num_vfs;
1385 vf_index++)
1386 for (vf_index1 = vf_group * vf_per_group;
1387 vf_index1 < (vf_group + 1) * vf_per_group &&
1388 vf_index1 < num_vfs;
1389 vf_index1++){
1390
1391 rc = opal_pci_set_peltv(phb->opal_id,
1392 pdn->offset + vf_index,
1393 pdn->offset + vf_index1,
1394 OPAL_REMOVE_PE_FROM_DOMAIN);
1395
1396 if (rc)
1397 dev_warn(&pdev->dev, "%s: Failed to unlink same group PE#%d(%lld)\n",
1398 __func__,
1399 pdn->offset + vf_index1, rc);
1400 }
1401 }
1402
1403 list_for_each_entry_safe(pe, pe_n, &phb->ioda.pe_list, list) { 1368 list_for_each_entry_safe(pe, pe_n, &phb->ioda.pe_list, list) {
1404 if (pe->parent_dev != pdev) 1369 if (pe->parent_dev != pdev)
1405 continue; 1370 continue;
@@ -1424,7 +1389,7 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev)
1424 struct pnv_phb *phb; 1389 struct pnv_phb *phb;
1425 struct pci_dn *pdn; 1390 struct pci_dn *pdn;
1426 struct pci_sriov *iov; 1391 struct pci_sriov *iov;
1427 u16 num_vfs; 1392 u16 num_vfs, i;
1428 1393
1429 bus = pdev->bus; 1394 bus = pdev->bus;
1430 hose = pci_bus_to_host(bus); 1395 hose = pci_bus_to_host(bus);
@@ -1434,18 +1399,25 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev)
1434 num_vfs = pdn->num_vfs; 1399 num_vfs = pdn->num_vfs;
1435 1400
1436 /* Release VF PEs */ 1401 /* Release VF PEs */
1437 pnv_ioda_release_vf_PE(pdev, num_vfs); 1402 pnv_ioda_release_vf_PE(pdev);
1438 1403
1439 if (phb->type == PNV_PHB_IODA2) { 1404 if (phb->type == PNV_PHB_IODA2) {
1440 if (pdn->m64_per_iov == 1) 1405 if (!pdn->m64_single_mode)
1441 pnv_pci_vf_resource_shift(pdev, -pdn->offset); 1406 pnv_pci_vf_resource_shift(pdev, -*pdn->pe_num_map);
1442 1407
1443 /* Release M64 windows */ 1408 /* Release M64 windows */
1444 pnv_pci_vf_release_m64(pdev); 1409 pnv_pci_vf_release_m64(pdev, num_vfs);
1445 1410
1446 /* Release PE numbers */ 1411 /* Release PE numbers */
1447 bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs); 1412 if (pdn->m64_single_mode) {
1448 pdn->offset = 0; 1413 for (i = 0; i < num_vfs; i++) {
1414 if (pdn->pe_num_map[i] != IODA_INVALID_PE)
1415 pnv_ioda_free_pe(phb, pdn->pe_num_map[i]);
1416 }
1417 } else
1418 bitmap_clear(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs);
1419 /* Releasing pe_num_map */
1420 kfree(pdn->pe_num_map);
1449 } 1421 }
1450} 1422}
1451 1423
@@ -1460,7 +1432,6 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
1460 int pe_num; 1432 int pe_num;
1461 u16 vf_index; 1433 u16 vf_index;
1462 struct pci_dn *pdn; 1434 struct pci_dn *pdn;
1463 int64_t rc;
1464 1435
1465 bus = pdev->bus; 1436 bus = pdev->bus;
1466 hose = pci_bus_to_host(bus); 1437 hose = pci_bus_to_host(bus);
@@ -1472,7 +1443,10 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
1472 1443
1473 /* Reserve PE for each VF */ 1444 /* Reserve PE for each VF */
1474 for (vf_index = 0; vf_index < num_vfs; vf_index++) { 1445 for (vf_index = 0; vf_index < num_vfs; vf_index++) {
1475 pe_num = pdn->offset + vf_index; 1446 if (pdn->m64_single_mode)
1447 pe_num = pdn->pe_num_map[vf_index];
1448 else
1449 pe_num = *pdn->pe_num_map + vf_index;
1476 1450
1477 pe = &phb->ioda.pe_array[pe_num]; 1451 pe = &phb->ioda.pe_array[pe_num];
1478 pe->pe_number = pe_num; 1452 pe->pe_number = pe_num;
@@ -1505,37 +1479,6 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
1505 1479
1506 pnv_pci_ioda2_setup_dma_pe(phb, pe); 1480 pnv_pci_ioda2_setup_dma_pe(phb, pe);
1507 } 1481 }
1508
1509 if (pdn->m64_per_iov == M64_PER_IOV && num_vfs > M64_PER_IOV) {
1510 int vf_group;
1511 int vf_per_group;
1512 int vf_index1;
1513
1514 vf_per_group = roundup_pow_of_two(num_vfs) / pdn->m64_per_iov;
1515
1516 for (vf_group = 0; vf_group < M64_PER_IOV; vf_group++) {
1517 for (vf_index = vf_group * vf_per_group;
1518 vf_index < (vf_group + 1) * vf_per_group &&
1519 vf_index < num_vfs;
1520 vf_index++) {
1521 for (vf_index1 = vf_group * vf_per_group;
1522 vf_index1 < (vf_group + 1) * vf_per_group &&
1523 vf_index1 < num_vfs;
1524 vf_index1++) {
1525
1526 rc = opal_pci_set_peltv(phb->opal_id,
1527 pdn->offset + vf_index,
1528 pdn->offset + vf_index1,
1529 OPAL_ADD_PE_TO_DOMAIN);
1530
1531 if (rc)
1532 dev_warn(&pdev->dev, "%s: Failed to link same group PE#%d(%lld)\n",
1533 __func__,
1534 pdn->offset + vf_index1, rc);
1535 }
1536 }
1537 }
1538 }
1539} 1482}
1540 1483
1541int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) 1484int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
@@ -1545,6 +1488,7 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
1545 struct pnv_phb *phb; 1488 struct pnv_phb *phb;
1546 struct pci_dn *pdn; 1489 struct pci_dn *pdn;
1547 int ret; 1490 int ret;
1491 u16 i;
1548 1492
1549 bus = pdev->bus; 1493 bus = pdev->bus;
1550 hose = pci_bus_to_host(bus); 1494 hose = pci_bus_to_host(bus);
@@ -1552,20 +1496,59 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
1552 pdn = pci_get_pdn(pdev); 1496 pdn = pci_get_pdn(pdev);
1553 1497
1554 if (phb->type == PNV_PHB_IODA2) { 1498 if (phb->type == PNV_PHB_IODA2) {
1499 if (!pdn->vfs_expanded) {
1500 dev_info(&pdev->dev, "don't support this SRIOV device"
1501 " with non 64bit-prefetchable IOV BAR\n");
1502 return -ENOSPC;
1503 }
1504
1505 /*
1506 * When M64 BARs functions in Single PE mode, the number of VFs
1507 * could be enabled must be less than the number of M64 BARs.
1508 */
1509 if (pdn->m64_single_mode && num_vfs > phb->ioda.m64_bar_idx) {
1510 dev_info(&pdev->dev, "Not enough M64 BAR for VFs\n");
1511 return -EBUSY;
1512 }
1513
1514 /* Allocating pe_num_map */
1515 if (pdn->m64_single_mode)
1516 pdn->pe_num_map = kmalloc(sizeof(*pdn->pe_num_map) * num_vfs,
1517 GFP_KERNEL);
1518 else
1519 pdn->pe_num_map = kmalloc(sizeof(*pdn->pe_num_map), GFP_KERNEL);
1520
1521 if (!pdn->pe_num_map)
1522 return -ENOMEM;
1523
1524 if (pdn->m64_single_mode)
1525 for (i = 0; i < num_vfs; i++)
1526 pdn->pe_num_map[i] = IODA_INVALID_PE;
1527
1555 /* Calculate available PE for required VFs */ 1528 /* Calculate available PE for required VFs */
1556 mutex_lock(&phb->ioda.pe_alloc_mutex); 1529 if (pdn->m64_single_mode) {
1557 pdn->offset = bitmap_find_next_zero_area( 1530 for (i = 0; i < num_vfs; i++) {
1558 phb->ioda.pe_alloc, phb->ioda.total_pe, 1531 pdn->pe_num_map[i] = pnv_ioda_alloc_pe(phb);
1559 0, num_vfs, 0); 1532 if (pdn->pe_num_map[i] == IODA_INVALID_PE) {
1560 if (pdn->offset >= phb->ioda.total_pe) { 1533 ret = -EBUSY;
1534 goto m64_failed;
1535 }
1536 }
1537 } else {
1538 mutex_lock(&phb->ioda.pe_alloc_mutex);
1539 *pdn->pe_num_map = bitmap_find_next_zero_area(
1540 phb->ioda.pe_alloc, phb->ioda.total_pe,
1541 0, num_vfs, 0);
1542 if (*pdn->pe_num_map >= phb->ioda.total_pe) {
1543 mutex_unlock(&phb->ioda.pe_alloc_mutex);
1544 dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs);
1545 kfree(pdn->pe_num_map);
1546 return -EBUSY;
1547 }
1548 bitmap_set(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs);
1561 mutex_unlock(&phb->ioda.pe_alloc_mutex); 1549 mutex_unlock(&phb->ioda.pe_alloc_mutex);
1562 dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs);
1563 pdn->offset = 0;
1564 return -EBUSY;
1565 } 1550 }
1566 bitmap_set(phb->ioda.pe_alloc, pdn->offset, num_vfs);
1567 pdn->num_vfs = num_vfs; 1551 pdn->num_vfs = num_vfs;
1568 mutex_unlock(&phb->ioda.pe_alloc_mutex);
1569 1552
1570 /* Assign M64 window accordingly */ 1553 /* Assign M64 window accordingly */
1571 ret = pnv_pci_vf_assign_m64(pdev, num_vfs); 1554 ret = pnv_pci_vf_assign_m64(pdev, num_vfs);
@@ -1579,8 +1562,8 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
1579 * the IOV BAR according to the PE# allocated to the VFs. 1562 * the IOV BAR according to the PE# allocated to the VFs.
1580 * Otherwise, the PE# for the VF will conflict with others. 1563 * Otherwise, the PE# for the VF will conflict with others.
1581 */ 1564 */
1582 if (pdn->m64_per_iov == 1) { 1565 if (!pdn->m64_single_mode) {
1583 ret = pnv_pci_vf_resource_shift(pdev, pdn->offset); 1566 ret = pnv_pci_vf_resource_shift(pdev, *pdn->pe_num_map);
1584 if (ret) 1567 if (ret)
1585 goto m64_failed; 1568 goto m64_failed;
1586 } 1569 }
@@ -1592,8 +1575,16 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
1592 return 0; 1575 return 0;
1593 1576
1594m64_failed: 1577m64_failed:
1595 bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs); 1578 if (pdn->m64_single_mode) {
1596 pdn->offset = 0; 1579 for (i = 0; i < num_vfs; i++) {
1580 if (pdn->pe_num_map[i] != IODA_INVALID_PE)
1581 pnv_ioda_free_pe(phb, pdn->pe_num_map[i]);
1582 }
1583 } else
1584 bitmap_clear(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs);
1585
1586 /* Releasing pe_num_map */
1587 kfree(pdn->pe_num_map);
1597 1588
1598 return ret; 1589 return ret;
1599} 1590}
@@ -1612,8 +1603,7 @@ int pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
1612 /* Allocate PCI data */ 1603 /* Allocate PCI data */
1613 add_dev_pci_data(pdev); 1604 add_dev_pci_data(pdev);
1614 1605
1615 pnv_pci_sriov_enable(pdev, num_vfs); 1606 return pnv_pci_sriov_enable(pdev, num_vfs);
1616 return 0;
1617} 1607}
1618#endif /* CONFIG_PCI_IOV */ 1608#endif /* CONFIG_PCI_IOV */
1619 1609
@@ -2851,45 +2841,58 @@ static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { }
2851#ifdef CONFIG_PCI_IOV 2841#ifdef CONFIG_PCI_IOV
2852static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) 2842static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
2853{ 2843{
2854 struct pci_controller *hose; 2844 struct pci_controller *hose = pci_bus_to_host(pdev->bus);
2855 struct pnv_phb *phb; 2845 struct pnv_phb *phb = hose->private_data;
2846 const resource_size_t gate = phb->ioda.m64_segsize >> 2;
2856 struct resource *res; 2847 struct resource *res;
2857 int i; 2848 int i;
2858 resource_size_t size; 2849 resource_size_t size, total_vf_bar_sz;
2859 struct pci_dn *pdn; 2850 struct pci_dn *pdn;
2860 int mul, total_vfs; 2851 int mul, total_vfs;
2861 2852
2862 if (!pdev->is_physfn || pdev->is_added) 2853 if (!pdev->is_physfn || pdev->is_added)
2863 return; 2854 return;
2864 2855
2865 hose = pci_bus_to_host(pdev->bus);
2866 phb = hose->private_data;
2867
2868 pdn = pci_get_pdn(pdev); 2856 pdn = pci_get_pdn(pdev);
2869 pdn->vfs_expanded = 0; 2857 pdn->vfs_expanded = 0;
2858 pdn->m64_single_mode = false;
2870 2859
2871 total_vfs = pci_sriov_get_totalvfs(pdev); 2860 total_vfs = pci_sriov_get_totalvfs(pdev);
2872 pdn->m64_per_iov = 1;
2873 mul = phb->ioda.total_pe; 2861 mul = phb->ioda.total_pe;
2862 total_vf_bar_sz = 0;
2874 2863
2875 for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { 2864 for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
2876 res = &pdev->resource[i + PCI_IOV_RESOURCES]; 2865 res = &pdev->resource[i + PCI_IOV_RESOURCES];
2877 if (!res->flags || res->parent) 2866 if (!res->flags || res->parent)
2878 continue; 2867 continue;
2879 if (!pnv_pci_is_mem_pref_64(res->flags)) { 2868 if (!pnv_pci_is_mem_pref_64(res->flags)) {
2880 dev_warn(&pdev->dev, " non M64 VF BAR%d: %pR\n", 2869 dev_warn(&pdev->dev, "Don't support SR-IOV with"
2870 " non M64 VF BAR%d: %pR. \n",
2881 i, res); 2871 i, res);
2882 continue; 2872 goto truncate_iov;
2883 } 2873 }
2884 2874
2885 size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES); 2875 total_vf_bar_sz += pci_iov_resource_size(pdev,
2876 i + PCI_IOV_RESOURCES);
2886 2877
2887 /* bigger than 64M */ 2878 /*
2888 if (size > (1 << 26)) { 2879 * If bigger than quarter of M64 segment size, just round up
2889 dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size is bigger than 64M, roundup power2\n", 2880 * power of two.
2890 i, res); 2881 *
2891 pdn->m64_per_iov = M64_PER_IOV; 2882 * Generally, one M64 BAR maps one IOV BAR. To avoid conflict
2883 * with other devices, IOV BAR size is expanded to be
2884 * (total_pe * VF_BAR_size). When VF_BAR_size is half of M64
2885 * segment size , the expanded size would equal to half of the
2886 * whole M64 space size, which will exhaust the M64 Space and
2887 * limit the system flexibility. This is a design decision to
2888 * set the boundary to quarter of the M64 segment size.
2889 */
2890 if (total_vf_bar_sz > gate) {
2892 mul = roundup_pow_of_two(total_vfs); 2891 mul = roundup_pow_of_two(total_vfs);
2892 dev_info(&pdev->dev,
2893 "VF BAR Total IOV size %llx > %llx, roundup to %d VFs\n",
2894 total_vf_bar_sz, gate, mul);
2895 pdn->m64_single_mode = true;
2893 break; 2896 break;
2894 } 2897 }
2895 } 2898 }
@@ -2898,20 +2901,31 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
2898 res = &pdev->resource[i + PCI_IOV_RESOURCES]; 2901 res = &pdev->resource[i + PCI_IOV_RESOURCES];
2899 if (!res->flags || res->parent) 2902 if (!res->flags || res->parent)
2900 continue; 2903 continue;
2901 if (!pnv_pci_is_mem_pref_64(res->flags)) {
2902 dev_warn(&pdev->dev, "Skipping expanding VF BAR%d: %pR\n",
2903 i, res);
2904 continue;
2905 }
2906 2904
2907 dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res);
2908 size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES); 2905 size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
2906 /*
2907 * On PHB3, the minimum size alignment of M64 BAR in single
2908 * mode is 32MB.
2909 */
2910 if (pdn->m64_single_mode && (size < SZ_32M))
2911 goto truncate_iov;
2912 dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res);
2909 res->end = res->start + size * mul - 1; 2913 res->end = res->start + size * mul - 1;
2910 dev_dbg(&pdev->dev, " %pR\n", res); 2914 dev_dbg(&pdev->dev, " %pR\n", res);
2911 dev_info(&pdev->dev, "VF BAR%d: %pR (expanded to %d VFs for PE alignment)", 2915 dev_info(&pdev->dev, "VF BAR%d: %pR (expanded to %d VFs for PE alignment)",
2912 i, res, mul); 2916 i, res, mul);
2913 } 2917 }
2914 pdn->vfs_expanded = mul; 2918 pdn->vfs_expanded = mul;
2919
2920 return;
2921
2922truncate_iov:
2923 /* To save MMIO space, IOV BAR is truncated. */
2924 for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
2925 res = &pdev->resource[i + PCI_IOV_RESOURCES];
2926 res->flags = 0;
2927 res->end = res->start - 1;
2928 }
2915} 2929}
2916#endif /* CONFIG_PCI_IOV */ 2930#endif /* CONFIG_PCI_IOV */
2917 2931
@@ -3125,18 +3139,35 @@ static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus,
3125static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev, 3139static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev,
3126 int resno) 3140 int resno)
3127{ 3141{
3142 struct pci_controller *hose = pci_bus_to_host(pdev->bus);
3143 struct pnv_phb *phb = hose->private_data;
3128 struct pci_dn *pdn = pci_get_pdn(pdev); 3144 struct pci_dn *pdn = pci_get_pdn(pdev);
3129 resource_size_t align, iov_align; 3145 resource_size_t align;
3130
3131 iov_align = resource_size(&pdev->resource[resno]);
3132 if (iov_align)
3133 return iov_align;
3134 3146
3147 /*
3148 * On PowerNV platform, IOV BAR is mapped by M64 BAR to enable the
3149 * SR-IOV. While from hardware perspective, the range mapped by M64
3150 * BAR should be size aligned.
3151 *
3152 * When IOV BAR is mapped with M64 BAR in Single PE mode, the extra
3153 * powernv-specific hardware restriction is gone. But if just use the
3154 * VF BAR size as the alignment, PF BAR / VF BAR may be allocated with
3155 * in one segment of M64 #15, which introduces the PE conflict between
3156 * PF and VF. Based on this, the minimum alignment of an IOV BAR is
3157 * m64_segsize.
3158 *
3159 * This function returns the total IOV BAR size if M64 BAR is in
3160 * Shared PE mode or just VF BAR size if not.
3161 * If the M64 BAR is in Single PE mode, return the VF BAR size or
3162 * M64 segment size if IOV BAR size is less.
3163 */
3135 align = pci_iov_resource_size(pdev, resno); 3164 align = pci_iov_resource_size(pdev, resno);
3136 if (pdn->vfs_expanded) 3165 if (!pdn->vfs_expanded)
3137 return pdn->vfs_expanded * align; 3166 return align;
3167 if (pdn->m64_single_mode)
3168 return max(align, (resource_size_t)phb->ioda.m64_segsize);
3138 3169
3139 return align; 3170 return pdn->vfs_expanded * align;
3140} 3171}
3141#endif /* CONFIG_PCI_IOV */ 3172#endif /* CONFIG_PCI_IOV */
3142 3173
diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
deleted file mode 100644
index f2bdfea3b68d..000000000000
--- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c
+++ /dev/null
@@ -1,271 +0,0 @@
1/*
2 * Support PCI/PCIe on PowerNV platforms
3 *
4 * Currently supports only P5IOC2
5 *
6 * Copyright 2011 Benjamin Herrenschmidt, IBM Corp.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13
14#include <linux/kernel.h>
15#include <linux/pci.h>
16#include <linux/delay.h>
17#include <linux/string.h>
18#include <linux/init.h>
19#include <linux/bootmem.h>
20#include <linux/irq.h>
21#include <linux/io.h>
22#include <linux/msi.h>
23
24#include <asm/sections.h>
25#include <asm/io.h>
26#include <asm/prom.h>
27#include <asm/pci-bridge.h>
28#include <asm/machdep.h>
29#include <asm/msi_bitmap.h>
30#include <asm/ppc-pci.h>
31#include <asm/opal.h>
32#include <asm/iommu.h>
33#include <asm/tce.h>
34
35#include "powernv.h"
36#include "pci.h"
37
38/* For now, use a fixed amount of TCE memory for each p5ioc2
39 * hub, 16M will do
40 */
41#define P5IOC2_TCE_MEMORY 0x01000000
42
43#ifdef CONFIG_PCI_MSI
44static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
45 unsigned int hwirq, unsigned int virq,
46 unsigned int is_64, struct msi_msg *msg)
47{
48 if (WARN_ON(!is_64))
49 return -ENXIO;
50 msg->data = hwirq - phb->msi_base;
51 msg->address_hi = 0x10000000;
52 msg->address_lo = 0;
53
54 return 0;
55}
56
57static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb)
58{
59 unsigned int count;
60 const __be32 *prop = of_get_property(phb->hose->dn,
61 "ibm,opal-msi-ranges", NULL);
62 if (!prop)
63 return;
64
65 /* Don't do MSI's on p5ioc2 PCI-X are they are not properly
66 * verified in HW
67 */
68 if (of_device_is_compatible(phb->hose->dn, "ibm,p5ioc2-pcix"))
69 return;
70 phb->msi_base = be32_to_cpup(prop);
71 count = be32_to_cpup(prop + 1);
72 if (msi_bitmap_alloc(&phb->msi_bmp, count, phb->hose->dn)) {
73 pr_err("PCI %d: Failed to allocate MSI bitmap !\n",
74 phb->hose->global_number);
75 return;
76 }
77 phb->msi_setup = pnv_pci_p5ioc2_msi_setup;
78 phb->msi32_support = 0;
79 pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n",
80 count, phb->msi_base);
81}
82#else
83static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) { }
84#endif /* CONFIG_PCI_MSI */
85
86static struct iommu_table_ops pnv_p5ioc2_iommu_ops = {
87 .set = pnv_tce_build,
88#ifdef CONFIG_IOMMU_API
89 .exchange = pnv_tce_xchg,
90#endif
91 .clear = pnv_tce_free,
92 .get = pnv_tce_get,
93};
94
95static void pnv_pci_p5ioc2_dma_dev_setup(struct pnv_phb *phb,
96 struct pci_dev *pdev)
97{
98 struct iommu_table *tbl = phb->p5ioc2.table_group.tables[0];
99
100 if (!tbl->it_map) {
101 tbl->it_ops = &pnv_p5ioc2_iommu_ops;
102 iommu_init_table(tbl, phb->hose->node);
103 iommu_register_group(&phb->p5ioc2.table_group,
104 pci_domain_nr(phb->hose->bus), phb->opal_id);
105 INIT_LIST_HEAD_RCU(&tbl->it_group_list);
106 pnv_pci_link_table_and_group(phb->hose->node, 0,
107 tbl, &phb->p5ioc2.table_group);
108 }
109
110 set_iommu_table_base(&pdev->dev, tbl);
111 iommu_add_device(&pdev->dev);
112}
113
114static const struct pci_controller_ops pnv_pci_p5ioc2_controller_ops = {
115 .dma_dev_setup = pnv_pci_dma_dev_setup,
116#ifdef CONFIG_PCI_MSI
117 .setup_msi_irqs = pnv_setup_msi_irqs,
118 .teardown_msi_irqs = pnv_teardown_msi_irqs,
119#endif
120};
121
122static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id,
123 void *tce_mem, u64 tce_size)
124{
125 struct pnv_phb *phb;
126 const __be64 *prop64;
127 u64 phb_id;
128 int64_t rc;
129 static int primary = 1;
130 struct iommu_table_group *table_group;
131 struct iommu_table *tbl;
132
133 pr_info(" Initializing p5ioc2 PHB %s\n", np->full_name);
134
135 prop64 = of_get_property(np, "ibm,opal-phbid", NULL);
136 if (!prop64) {
137 pr_err(" Missing \"ibm,opal-phbid\" property !\n");
138 return;
139 }
140 phb_id = be64_to_cpup(prop64);
141 pr_devel(" PHB-ID : 0x%016llx\n", phb_id);
142 pr_devel(" TCE AT : 0x%016lx\n", __pa(tce_mem));
143 pr_devel(" TCE SZ : 0x%016llx\n", tce_size);
144
145 rc = opal_pci_set_phb_tce_memory(phb_id, __pa(tce_mem), tce_size);
146 if (rc != OPAL_SUCCESS) {
147 pr_err(" Failed to set TCE memory, OPAL error %lld\n", rc);
148 return;
149 }
150
151 phb = memblock_virt_alloc(sizeof(struct pnv_phb), 0);
152 phb->hose = pcibios_alloc_controller(np);
153 if (!phb->hose) {
154 pr_err(" Failed to allocate PCI controller\n");
155 return;
156 }
157
158 spin_lock_init(&phb->lock);
159 phb->hose->first_busno = 0;
160 phb->hose->last_busno = 0xff;
161 phb->hose->private_data = phb;
162 phb->hose->controller_ops = pnv_pci_p5ioc2_controller_ops;
163 phb->hub_id = hub_id;
164 phb->opal_id = phb_id;
165 phb->type = PNV_PHB_P5IOC2;
166 phb->model = PNV_PHB_MODEL_P5IOC2;
167
168 phb->regs = of_iomap(np, 0);
169
170 if (phb->regs == NULL)
171 pr_err(" Failed to map registers !\n");
172 else {
173 pr_devel(" P_BUID = 0x%08x\n", in_be32(phb->regs + 0x100));
174 pr_devel(" P_IOSZ = 0x%08x\n", in_be32(phb->regs + 0x1b0));
175 pr_devel(" P_IO_ST = 0x%08x\n", in_be32(phb->regs + 0x1e0));
176 pr_devel(" P_MEM1_H = 0x%08x\n", in_be32(phb->regs + 0x1a0));
177 pr_devel(" P_MEM1_L = 0x%08x\n", in_be32(phb->regs + 0x190));
178 pr_devel(" P_MSZ1_L = 0x%08x\n", in_be32(phb->regs + 0x1c0));
179 pr_devel(" P_MEM_ST = 0x%08x\n", in_be32(phb->regs + 0x1d0));
180 pr_devel(" P_MEM2_H = 0x%08x\n", in_be32(phb->regs + 0x2c0));
181 pr_devel(" P_MEM2_L = 0x%08x\n", in_be32(phb->regs + 0x2b0));
182 pr_devel(" P_MSZ2_H = 0x%08x\n", in_be32(phb->regs + 0x2d0));
183 pr_devel(" P_MSZ2_L = 0x%08x\n", in_be32(phb->regs + 0x2e0));
184 }
185
186 /* Interpret the "ranges" property */
187 /* This also maps the I/O region and sets isa_io/mem_base */
188 pci_process_bridge_OF_ranges(phb->hose, np, primary);
189 primary = 0;
190
191 phb->hose->ops = &pnv_pci_ops;
192
193 /* Setup MSI support */
194 pnv_pci_init_p5ioc2_msis(phb);
195
196 /* Setup TCEs */
197 phb->dma_dev_setup = pnv_pci_p5ioc2_dma_dev_setup;
198 pnv_pci_setup_iommu_table(&phb->p5ioc2.iommu_table,
199 tce_mem, tce_size, 0,
200 IOMMU_PAGE_SHIFT_4K);
201 /*
202 * We do not allocate iommu_table as we do not support
203 * hotplug or SRIOV on P5IOC2 and therefore iommu_free_table()
204 * should not be called for phb->p5ioc2.table_group.tables[0] ever.
205 */
206 tbl = phb->p5ioc2.table_group.tables[0] = &phb->p5ioc2.iommu_table;
207 table_group = &phb->p5ioc2.table_group;
208 table_group->tce32_start = tbl->it_offset << tbl->it_page_shift;
209 table_group->tce32_size = tbl->it_size << tbl->it_page_shift;
210}
211
212void __init pnv_pci_init_p5ioc2_hub(struct device_node *np)
213{
214 struct device_node *phbn;
215 const __be64 *prop64;
216 u64 hub_id;
217 void *tce_mem;
218 uint64_t tce_per_phb;
219 int64_t rc;
220 int phb_count = 0;
221
222 pr_info("Probing p5ioc2 IO-Hub %s\n", np->full_name);
223
224 prop64 = of_get_property(np, "ibm,opal-hubid", NULL);
225 if (!prop64) {
226 pr_err(" Missing \"ibm,opal-hubid\" property !\n");
227 return;
228 }
229 hub_id = be64_to_cpup(prop64);
230 pr_info(" HUB-ID : 0x%016llx\n", hub_id);
231
232 /* Count child PHBs and calculate TCE space per PHB */
233 for_each_child_of_node(np, phbn) {
234 if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") ||
235 of_device_is_compatible(phbn, "ibm,p5ioc2-pciex"))
236 phb_count++;
237 }
238
239 if (phb_count <= 0) {
240 pr_info(" No PHBs for Hub %s\n", np->full_name);
241 return;
242 }
243
244 tce_per_phb = __rounddown_pow_of_two(P5IOC2_TCE_MEMORY / phb_count);
245 pr_info(" Allocating %lld MB of TCE memory per PHB\n",
246 tce_per_phb >> 20);
247
248 /* Currently allocate 16M of TCE memory for every Hub
249 *
250 * XXX TODO: Make it chip local if possible
251 */
252 tce_mem = memblock_virt_alloc(P5IOC2_TCE_MEMORY, P5IOC2_TCE_MEMORY);
253 pr_debug(" TCE : 0x%016lx..0x%016lx\n",
254 __pa(tce_mem), __pa(tce_mem) + P5IOC2_TCE_MEMORY - 1);
255 rc = opal_pci_set_hub_tce_memory(hub_id, __pa(tce_mem),
256 P5IOC2_TCE_MEMORY);
257 if (rc != OPAL_SUCCESS) {
258 pr_err(" Failed to allocate TCE memory, OPAL error %lld\n", rc);
259 return;
260 }
261
262 /* Initialize PHBs */
263 for_each_child_of_node(np, phbn) {
264 if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") ||
265 of_device_is_compatible(phbn, "ibm,p5ioc2-pciex")) {
266 pnv_pci_init_p5ioc2_phb(phbn, hub_id,
267 tce_mem, tce_per_phb);
268 tce_mem += tce_per_phb;
269 }
270 }
271}
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index b1ef84a6c9d1..73c8dc2a353f 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -380,10 +380,7 @@ static void pnv_pci_config_check_eeh(struct pci_dn *pdn)
380 */ 380 */
381 pe_no = pdn->pe_number; 381 pe_no = pdn->pe_number;
382 if (pe_no == IODA_INVALID_PE) { 382 if (pe_no == IODA_INVALID_PE) {
383 if (phb->type == PNV_PHB_P5IOC2) 383 pe_no = phb->ioda.reserved_pe;
384 pe_no = 0;
385 else
386 pe_no = phb->ioda.reserved_pe;
387 } 384 }
388 385
389 /* 386 /*
@@ -805,7 +802,6 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IBM, 0x3b9, pnv_p7ioc_rc_quirk);
805void __init pnv_pci_init(void) 802void __init pnv_pci_init(void)
806{ 803{
807 struct device_node *np; 804 struct device_node *np;
808 bool found_ioda = false;
809 805
810 pci_add_flags(PCI_CAN_SKIP_ISA_ALIGN); 806 pci_add_flags(PCI_CAN_SKIP_ISA_ALIGN);
811 807
@@ -813,20 +809,11 @@ void __init pnv_pci_init(void)
813 if (!firmware_has_feature(FW_FEATURE_OPAL)) 809 if (!firmware_has_feature(FW_FEATURE_OPAL))
814 return; 810 return;
815 811
816 /* Look for IODA IO-Hubs. We don't support mixing IODA 812 /* Look for IODA IO-Hubs. */
817 * and p5ioc2 due to the need to change some global
818 * probing flags
819 */
820 for_each_compatible_node(np, NULL, "ibm,ioda-hub") { 813 for_each_compatible_node(np, NULL, "ibm,ioda-hub") {
821 pnv_pci_init_ioda_hub(np); 814 pnv_pci_init_ioda_hub(np);
822 found_ioda = true;
823 } 815 }
824 816
825 /* Look for p5ioc2 IO-Hubs */
826 if (!found_ioda)
827 for_each_compatible_node(np, NULL, "ibm,p5ioc2")
828 pnv_pci_init_p5ioc2_hub(np);
829
830 /* Look for ioda2 built-in PHB3's */ 817 /* Look for ioda2 built-in PHB3's */
831 for_each_compatible_node(np, NULL, "ibm,ioda2-phb") 818 for_each_compatible_node(np, NULL, "ibm,ioda2-phb")
832 pnv_pci_init_ioda2_phb(np); 819 pnv_pci_init_ioda2_phb(np);
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index 00691a9b99af..3f814f382b2e 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -4,16 +4,14 @@
4struct pci_dn; 4struct pci_dn;
5 5
6enum pnv_phb_type { 6enum pnv_phb_type {
7 PNV_PHB_P5IOC2 = 0, 7 PNV_PHB_IODA1 = 0,
8 PNV_PHB_IODA1 = 1, 8 PNV_PHB_IODA2 = 1,
9 PNV_PHB_IODA2 = 2, 9 PNV_PHB_NPU = 2,
10 PNV_PHB_NPU = 3,
11}; 10};
12 11
13/* Precise PHB model for error management */ 12/* Precise PHB model for error management */
14enum pnv_phb_model { 13enum pnv_phb_model {
15 PNV_PHB_MODEL_UNKNOWN, 14 PNV_PHB_MODEL_UNKNOWN,
16 PNV_PHB_MODEL_P5IOC2,
17 PNV_PHB_MODEL_P7IOC, 15 PNV_PHB_MODEL_P7IOC,
18 PNV_PHB_MODEL_PHB3, 16 PNV_PHB_MODEL_PHB3,
19 PNV_PHB_MODEL_NPU, 17 PNV_PHB_MODEL_NPU,
@@ -121,81 +119,74 @@ struct pnv_phb {
121 void (*freeze_pe)(struct pnv_phb *phb, int pe_no); 119 void (*freeze_pe)(struct pnv_phb *phb, int pe_no);
122 int (*unfreeze_pe)(struct pnv_phb *phb, int pe_no, int opt); 120 int (*unfreeze_pe)(struct pnv_phb *phb, int pe_no, int opt);
123 121
124 union { 122 struct {
125 struct { 123 /* Global bridge info */
126 struct iommu_table iommu_table; 124 unsigned int total_pe;
127 struct iommu_table_group table_group; 125 unsigned int reserved_pe;
128 } p5ioc2; 126
129 127 /* 32-bit MMIO window */
130 struct { 128 unsigned int m32_size;
131 /* Global bridge info */ 129 unsigned int m32_segsize;
132 unsigned int total_pe; 130 unsigned int m32_pci_base;
133 unsigned int reserved_pe; 131
134 132 /* 64-bit MMIO window */
135 /* 32-bit MMIO window */ 133 unsigned int m64_bar_idx;
136 unsigned int m32_size; 134 unsigned long m64_size;
137 unsigned int m32_segsize; 135 unsigned long m64_segsize;
138 unsigned int m32_pci_base; 136 unsigned long m64_base;
139 137 unsigned long m64_bar_alloc;
140 /* 64-bit MMIO window */ 138
141 unsigned int m64_bar_idx; 139 /* IO ports */
142 unsigned long m64_size; 140 unsigned int io_size;
143 unsigned long m64_segsize; 141 unsigned int io_segsize;
144 unsigned long m64_base; 142 unsigned int io_pci_base;
145 unsigned long m64_bar_alloc; 143
146 144 /* PE allocation bitmap */
147 /* IO ports */ 145 unsigned long *pe_alloc;
148 unsigned int io_size; 146 /* PE allocation mutex */
149 unsigned int io_segsize; 147 struct mutex pe_alloc_mutex;
150 unsigned int io_pci_base; 148
151 149 /* M32 & IO segment maps */
152 /* PE allocation bitmap */ 150 unsigned int *m32_segmap;
153 unsigned long *pe_alloc; 151 unsigned int *io_segmap;
154 /* PE allocation mutex */ 152 struct pnv_ioda_pe *pe_array;
155 struct mutex pe_alloc_mutex; 153
156 154 /* IRQ chip */
157 /* M32 & IO segment maps */ 155 int irq_chip_init;
158 unsigned int *m32_segmap; 156 struct irq_chip irq_chip;
159 unsigned int *io_segmap; 157
160 struct pnv_ioda_pe *pe_array; 158 /* Sorted list of used PE's based
161 159 * on the sequence of creation
162 /* IRQ chip */ 160 */
163 int irq_chip_init; 161 struct list_head pe_list;
164 struct irq_chip irq_chip; 162 struct mutex pe_list_mutex;
165 163
166 /* Sorted list of used PE's based 164 /* Reverse map of PEs, will have to extend if
167 * on the sequence of creation 165 * we are to support more than 256 PEs, indexed
168 */ 166 * bus { bus, devfn }
169 struct list_head pe_list; 167 */
170 struct mutex pe_list_mutex; 168 unsigned char pe_rmap[0x10000];
171 169
172 /* Reverse map of PEs, will have to extend if 170 /* 32-bit TCE tables allocation */
173 * we are to support more than 256 PEs, indexed 171 unsigned long tce32_count;
174 * bus { bus, devfn } 172
175 */ 173 /* Total "weight" for the sake of DMA resources
176 unsigned char pe_rmap[0x10000]; 174 * allocation
177 175 */
178 /* 32-bit TCE tables allocation */ 176 unsigned int dma_weight;
179 unsigned long tce32_count; 177 unsigned int dma_pe_count;
180 178
181 /* Total "weight" for the sake of DMA resources 179 /* Sorted list of used PE's, sorted at
182 * allocation 180 * boot for resource allocation purposes
183 */ 181 */
184 unsigned int dma_weight; 182 struct list_head pe_dma_list;
185 unsigned int dma_pe_count; 183
186 184 /* TCE cache invalidate registers (physical and
187 /* Sorted list of used PE's, sorted at 185 * remapped)
188 * boot for resource allocation purposes 186 */
189 */ 187 phys_addr_t tce_inval_reg_phys;
190 struct list_head pe_dma_list; 188 __be64 __iomem *tce_inval_reg;
191 189 } ioda;
192 /* TCE cache invalidate registers (physical and
193 * remapped)
194 */
195 phys_addr_t tce_inval_reg_phys;
196 __be64 __iomem *tce_inval_reg;
197 } ioda;
198 };
199 190
200 /* PHB and hub status structure */ 191 /* PHB and hub status structure */
201 union { 192 union {
@@ -232,7 +223,6 @@ extern void pnv_pci_unlink_table_and_group(struct iommu_table *tbl,
232extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl, 223extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
233 void *tce_mem, u64 tce_size, 224 void *tce_mem, u64 tce_size,
234 u64 dma_offset, unsigned page_shift); 225 u64 dma_offset, unsigned page_shift);
235extern void pnv_pci_init_p5ioc2_hub(struct device_node *np);
236extern void pnv_pci_init_ioda_hub(struct device_node *np); 226extern void pnv_pci_init_ioda_hub(struct device_node *np);
237extern void pnv_pci_init_ioda2_phb(struct device_node *np); 227extern void pnv_pci_init_ioda2_phb(struct device_node *np);
238extern void pnv_pci_init_npu_phb(struct device_node *np); 228extern void pnv_pci_init_npu_phb(struct device_node *np);
diff --git a/arch/powerpc/platforms/powernv/subcore.c b/arch/powerpc/platforms/powernv/subcore.c
index 503a73f59359..0babef11136f 100644
--- a/arch/powerpc/platforms/powernv/subcore.c
+++ b/arch/powerpc/platforms/powernv/subcore.c
@@ -407,7 +407,7 @@ static DEVICE_ATTR(subcores_per_core, 0644,
407 407
408static int subcore_init(void) 408static int subcore_init(void)
409{ 409{
410 if (!cpu_has_feature(CPU_FTR_ARCH_207S)) 410 if (!cpu_has_feature(CPU_FTR_SUBCORE))
411 return 0; 411 return 0;
412 412
413 /* 413 /*
diff --git a/arch/powerpc/platforms/ps3/gelic_udbg.c b/arch/powerpc/platforms/ps3/gelic_udbg.c
index 20b46a19a48f..09bf24d616a5 100644
--- a/arch/powerpc/platforms/ps3/gelic_udbg.c
+++ b/arch/powerpc/platforms/ps3/gelic_udbg.c
@@ -13,6 +13,12 @@
13 * 13 *
14 */ 14 */
15 15
16#include <linux/if_ether.h>
17#include <linux/etherdevice.h>
18#include <linux/if_vlan.h>
19#include <linux/ip.h>
20#include <linux/udp.h>
21
16#include <asm/io.h> 22#include <asm/io.h>
17#include <asm/udbg.h> 23#include <asm/udbg.h>
18#include <asm/lv1call.h> 24#include <asm/lv1call.h>
@@ -56,39 +62,8 @@ struct debug_block {
56 u8 pkt[1520]; 62 u8 pkt[1520];
57} __packed; 63} __packed;
58 64
59struct ethhdr {
60 u8 dest[6];
61 u8 src[6];
62 u16 type;
63} __packed;
64
65struct vlantag {
66 u16 vlan;
67 u16 subtype;
68} __packed;
69
70struct iphdr {
71 u8 ver_len;
72 u8 dscp_ecn;
73 u16 total_length;
74 u16 ident;
75 u16 frag_off_flags;
76 u8 ttl;
77 u8 proto;
78 u16 checksum;
79 u32 src;
80 u32 dest;
81} __packed;
82
83struct udphdr {
84 u16 src;
85 u16 dest;
86 u16 len;
87 u16 checksum;
88} __packed;
89
90static __iomem struct ethhdr *h_eth; 65static __iomem struct ethhdr *h_eth;
91static __iomem struct vlantag *h_vlan; 66static __iomem struct vlan_hdr *h_vlan;
92static __iomem struct iphdr *h_ip; 67static __iomem struct iphdr *h_ip;
93static __iomem struct udphdr *h_udp; 68static __iomem struct udphdr *h_udp;
94 69
@@ -173,8 +148,8 @@ static void gelic_debug_init(void)
173 148
174 h_eth = (struct ethhdr *)dbg.pkt; 149 h_eth = (struct ethhdr *)dbg.pkt;
175 150
176 memset(&h_eth->dest, 0xff, 6); 151 eth_broadcast_addr(h_eth->h_dest);
177 memcpy(&h_eth->src, &mac, 6); 152 memcpy(&h_eth->h_source, &mac, ETH_ALEN);
178 153
179 header_size = sizeof(struct ethhdr); 154 header_size = sizeof(struct ethhdr);
180 155
@@ -183,28 +158,29 @@ static void gelic_debug_init(void)
183 GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0, 158 GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0,
184 &vlan_id, &v2); 159 &vlan_id, &v2);
185 if (!result) { 160 if (!result) {
186 h_eth->type = 0x8100; 161 h_eth->h_proto= ETH_P_8021Q;
187 162
188 header_size += sizeof(struct vlantag); 163 header_size += sizeof(struct vlan_hdr);
189 h_vlan = (struct vlantag *)(h_eth + 1); 164 h_vlan = (struct vlan_hdr *)(h_eth + 1);
190 h_vlan->vlan = vlan_id; 165 h_vlan->h_vlan_TCI = vlan_id;
191 h_vlan->subtype = 0x0800; 166 h_vlan->h_vlan_encapsulated_proto = ETH_P_IP;
192 h_ip = (struct iphdr *)(h_vlan + 1); 167 h_ip = (struct iphdr *)(h_vlan + 1);
193 } else { 168 } else {
194 h_eth->type = 0x0800; 169 h_eth->h_proto= 0x0800;
195 h_ip = (struct iphdr *)(h_eth + 1); 170 h_ip = (struct iphdr *)(h_eth + 1);
196 } 171 }
197 172
198 header_size += sizeof(struct iphdr); 173 header_size += sizeof(struct iphdr);
199 h_ip->ver_len = 0x45; 174 h_ip->version = 4;
175 h_ip->ihl = 5;
200 h_ip->ttl = 10; 176 h_ip->ttl = 10;
201 h_ip->proto = 0x11; 177 h_ip->protocol = 0x11;
202 h_ip->src = 0x00000000; 178 h_ip->saddr = 0x00000000;
203 h_ip->dest = 0xffffffff; 179 h_ip->daddr = 0xffffffff;
204 180
205 header_size += sizeof(struct udphdr); 181 header_size += sizeof(struct udphdr);
206 h_udp = (struct udphdr *)(h_ip + 1); 182 h_udp = (struct udphdr *)(h_ip + 1);
207 h_udp->src = GELIC_DEBUG_PORT; 183 h_udp->source = GELIC_DEBUG_PORT;
208 h_udp->dest = GELIC_DEBUG_PORT; 184 h_udp->dest = GELIC_DEBUG_PORT;
209 185
210 pmsgc = pmsg = (char *)(h_udp + 1); 186 pmsgc = pmsg = (char *)(h_udp + 1);
@@ -225,16 +201,16 @@ static void gelic_sendbuf(int msgsize)
225 int i; 201 int i;
226 202
227 dbg.descr.buf_size = header_size + msgsize; 203 dbg.descr.buf_size = header_size + msgsize;
228 h_ip->total_length = msgsize + sizeof(struct udphdr) + 204 h_ip->tot_len = msgsize + sizeof(struct udphdr) +
229 sizeof(struct iphdr); 205 sizeof(struct iphdr);
230 h_udp->len = msgsize + sizeof(struct udphdr); 206 h_udp->len = msgsize + sizeof(struct udphdr);
231 207
232 h_ip->checksum = 0; 208 h_ip->check = 0;
233 sum = 0; 209 sum = 0;
234 p = (u16 *)h_ip; 210 p = (u16 *)h_ip;
235 for (i = 0; i < 5; i++) 211 for (i = 0; i < 5; i++)
236 sum += *p++; 212 sum += *p++;
237 h_ip->checksum = ~(sum + (sum >> 16)); 213 h_ip->check = ~(sum + (sum >> 16));
238 214
239 dbg.descr.dmac_cmd_status = GELIC_DESCR_DMA_CMD_NO_CHKSUM | 215 dbg.descr.dmac_cmd_status = GELIC_DESCR_DMA_CMD_NO_CHKSUM |
240 GELIC_DESCR_TX_DMA_FRAME_TAIL; 216 GELIC_DESCR_TX_DMA_FRAME_TAIL;
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 638c4060938e..b831638e6f4a 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -78,7 +78,7 @@ struct ps3_bmp {
78/** 78/**
79 * struct ps3_private - a per cpu data structure 79 * struct ps3_private - a per cpu data structure
80 * @bmp: ps3_bmp structure 80 * @bmp: ps3_bmp structure
81 * @bmp_lock: Syncronize access to bmp. 81 * @bmp_lock: Synchronize access to bmp.
82 * @ipi_debug_brk_mask: Mask for debug break IPIs 82 * @ipi_debug_brk_mask: Mask for debug break IPIs
83 * @ppe_id: HV logical_ppe_id 83 * @ppe_id: HV logical_ppe_id
84 * @thread_id: HV thread_id 84 * @thread_id: HV thread_id
diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c
index 849b29b3e9ae..74da18de853a 100644
--- a/arch/powerpc/platforms/pseries/hvconsole.c
+++ b/arch/powerpc/platforms/pseries/hvconsole.c
@@ -31,7 +31,7 @@
31#include <asm/plpar_wrappers.h> 31#include <asm/plpar_wrappers.h>
32 32
33/** 33/**
34 * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper 34 * hvc_get_chars - retrieve characters from firmware for denoted vterm adapter
35 * @vtermno: The vtermno or unit_address of the adapter from which to fetch the 35 * @vtermno: The vtermno or unit_address of the adapter from which to fetch the
36 * data. 36 * data.
37 * @buf: The character buffer into which to put the character data fetched from 37 * @buf: The character buffer into which to put the character data fetched from
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 477290ad855e..2415a0d31f8f 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -505,8 +505,8 @@ static void pSeries_lpar_hugepage_invalidate(unsigned long vsid,
505} 505}
506#endif 506#endif
507 507
508static void pSeries_lpar_hpte_removebolted(unsigned long ea, 508static int pSeries_lpar_hpte_removebolted(unsigned long ea,
509 int psize, int ssize) 509 int psize, int ssize)
510{ 510{
511 unsigned long vpn; 511 unsigned long vpn;
512 unsigned long slot, vsid; 512 unsigned long slot, vsid;
@@ -515,11 +515,14 @@ static void pSeries_lpar_hpte_removebolted(unsigned long ea,
515 vpn = hpt_vpn(ea, vsid, ssize); 515 vpn = hpt_vpn(ea, vsid, ssize);
516 516
517 slot = pSeries_lpar_hpte_find(vpn, psize, ssize); 517 slot = pSeries_lpar_hpte_find(vpn, psize, ssize);
518 BUG_ON(slot == -1); 518 if (slot == -1)
519 return -ENOENT;
520
519 /* 521 /*
520 * lpar doesn't use the passed actual page size 522 * lpar doesn't use the passed actual page size
521 */ 523 */
522 pSeries_lpar_hpte_invalidate(slot, vpn, psize, 0, ssize, 0); 524 pSeries_lpar_hpte_invalidate(slot, vpn, psize, 0, ssize, 0);
525 return 0;
523} 526}
524 527
525/* 528/*
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 36df46eaba24..6e944fc6e5f9 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -515,7 +515,7 @@ static void __init pSeries_setup_arch(void)
515 515
516 fwnmi_init(); 516 fwnmi_init();
517 517
518 /* By default, only probe PCI (can be overriden by rtas_pci) */ 518 /* By default, only probe PCI (can be overridden by rtas_pci) */
519 pci_add_flags(PCI_PROBE_ONLY); 519 pci_add_flags(PCI_PROBE_ONLY);
520 520
521 /* Find and initialize PCI host bridges */ 521 /* Find and initialize PCI host bridges */
diff --git a/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh b/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh
new file mode 100755
index 000000000000..c658d8cf760b
--- /dev/null
+++ b/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh
@@ -0,0 +1,23 @@
1#!/bin/bash
2
3set -e
4set -o pipefail
5
6# To debug, uncomment the following line
7# set -x
8
9# Test whether the compile option -mprofile-kernel exists and generates
10# profiling code (ie. a call to _mcount()).
11echo "int func() { return 0; }" | \
12 $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
13 grep -q "_mcount"
14
15# Test whether the notrace attribute correctly suppresses calls to _mcount().
16
17echo -e "#include <linux/compiler.h>\nnotrace int func() { return 0; }" | \
18 $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
19 grep -q "_mcount" && \
20 exit 1
21
22echo "OK"
23exit 0
diff --git a/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig
index a19332a38715..52dc165c0efb 100644
--- a/arch/powerpc/sysdev/Kconfig
+++ b/arch/powerpc/sysdev/Kconfig
@@ -40,3 +40,8 @@ config SCOM_DEBUGFS
40config GE_FPGA 40config GE_FPGA
41 bool 41 bool
42 default n 42 default n
43
44config FSL_CORENET_RCPM
45 bool
46 help
47 This option enables support for RCPM (Run Control/Power Management).
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index bd6bd729969c..a254824719f1 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
20obj-$(CONFIG_FSL_SOC) += fsl_soc.o fsl_mpic_err.o 20obj-$(CONFIG_FSL_SOC) += fsl_soc.o fsl_mpic_err.o
21obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y) 21obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y)
22obj-$(CONFIG_FSL_PMC) += fsl_pmc.o 22obj-$(CONFIG_FSL_PMC) += fsl_pmc.o
23obj-$(CONFIG_FSL_CORENET_RCPM) += fsl_rcpm.o
23obj-$(CONFIG_FSL_LBC) += fsl_lbc.o 24obj-$(CONFIG_FSL_LBC) += fsl_lbc.o
24obj-$(CONFIG_FSL_GTM) += fsl_gtm.o 25obj-$(CONFIG_FSL_GTM) += fsl_gtm.o
25obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o 26obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index 5e6ff38ea69f..8ed65365be50 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -228,7 +228,10 @@ void __init cpm_reset(void)
228 * Bit 25, FAM can also be set to use FEC aggressive mode (860T). 228 * Bit 25, FAM can also be set to use FEC aggressive mode (860T).
229 */ 229 */
230 siu_conf = immr_map(im_siu_conf); 230 siu_conf = immr_map(im_siu_conf);
231 out_be32(&siu_conf->sc_sdcr, 1); 231 if ((mfspr(SPRN_IMMR) & 0xffff) == 0x0900) /* MPC885 */
232 out_be32(&siu_conf->sc_sdcr, 0x40);
233 else
234 out_be32(&siu_conf->sc_sdcr, 1);
232 immr_unmap(siu_conf); 235 immr_unmap(siu_conf);
233 236
234 cpm_muram_init(); 237 cpm_muram_init();
diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c
index 47f781059eeb..424b67fdb57f 100644
--- a/arch/powerpc/sysdev/fsl_lbc.c
+++ b/arch/powerpc/sysdev/fsl_lbc.c
@@ -27,6 +27,7 @@
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/mod_devicetable.h> 29#include <linux/mod_devicetable.h>
30#include <linux/syscore_ops.h>
30#include <asm/prom.h> 31#include <asm/prom.h>
31#include <asm/fsl_lbc.h> 32#include <asm/fsl_lbc.h>
32 33
@@ -352,24 +353,42 @@ err:
352#ifdef CONFIG_SUSPEND 353#ifdef CONFIG_SUSPEND
353 354
354/* save lbc registers */ 355/* save lbc registers */
355static int fsl_lbc_suspend(struct platform_device *pdev, pm_message_t state) 356static int fsl_lbc_syscore_suspend(void)
356{ 357{
357 struct fsl_lbc_ctrl *ctrl = dev_get_drvdata(&pdev->dev); 358 struct fsl_lbc_ctrl *ctrl;
358 struct fsl_lbc_regs __iomem *lbc = ctrl->regs; 359 struct fsl_lbc_regs __iomem *lbc;
360
361 ctrl = fsl_lbc_ctrl_dev;
362 if (!ctrl)
363 goto out;
364
365 lbc = ctrl->regs;
366 if (!lbc)
367 goto out;
359 368
360 ctrl->saved_regs = kmalloc(sizeof(struct fsl_lbc_regs), GFP_KERNEL); 369 ctrl->saved_regs = kmalloc(sizeof(struct fsl_lbc_regs), GFP_KERNEL);
361 if (!ctrl->saved_regs) 370 if (!ctrl->saved_regs)
362 return -ENOMEM; 371 return -ENOMEM;
363 372
364 _memcpy_fromio(ctrl->saved_regs, lbc, sizeof(struct fsl_lbc_regs)); 373 _memcpy_fromio(ctrl->saved_regs, lbc, sizeof(struct fsl_lbc_regs));
374
375out:
365 return 0; 376 return 0;
366} 377}
367 378
368/* restore lbc registers */ 379/* restore lbc registers */
369static int fsl_lbc_resume(struct platform_device *pdev) 380static void fsl_lbc_syscore_resume(void)
370{ 381{
371 struct fsl_lbc_ctrl *ctrl = dev_get_drvdata(&pdev->dev); 382 struct fsl_lbc_ctrl *ctrl;
372 struct fsl_lbc_regs __iomem *lbc = ctrl->regs; 383 struct fsl_lbc_regs __iomem *lbc;
384
385 ctrl = fsl_lbc_ctrl_dev;
386 if (!ctrl)
387 goto out;
388
389 lbc = ctrl->regs;
390 if (!lbc)
391 goto out;
373 392
374 if (ctrl->saved_regs) { 393 if (ctrl->saved_regs) {
375 _memcpy_toio(lbc, ctrl->saved_regs, 394 _memcpy_toio(lbc, ctrl->saved_regs,
@@ -377,7 +396,9 @@ static int fsl_lbc_resume(struct platform_device *pdev)
377 kfree(ctrl->saved_regs); 396 kfree(ctrl->saved_regs);
378 ctrl->saved_regs = NULL; 397 ctrl->saved_regs = NULL;
379 } 398 }
380 return 0; 399
400out:
401 return;
381} 402}
382#endif /* CONFIG_SUSPEND */ 403#endif /* CONFIG_SUSPEND */
383 404
@@ -389,20 +410,26 @@ static const struct of_device_id fsl_lbc_match[] = {
389 {}, 410 {},
390}; 411};
391 412
413#ifdef CONFIG_SUSPEND
414static struct syscore_ops lbc_syscore_pm_ops = {
415 .suspend = fsl_lbc_syscore_suspend,
416 .resume = fsl_lbc_syscore_resume,
417};
418#endif
419
392static struct platform_driver fsl_lbc_ctrl_driver = { 420static struct platform_driver fsl_lbc_ctrl_driver = {
393 .driver = { 421 .driver = {
394 .name = "fsl-lbc", 422 .name = "fsl-lbc",
395 .of_match_table = fsl_lbc_match, 423 .of_match_table = fsl_lbc_match,
396 }, 424 },
397 .probe = fsl_lbc_ctrl_probe, 425 .probe = fsl_lbc_ctrl_probe,
398#ifdef CONFIG_SUSPEND
399 .suspend = fsl_lbc_suspend,
400 .resume = fsl_lbc_resume,
401#endif
402}; 426};
403 427
404static int __init fsl_lbc_init(void) 428static int __init fsl_lbc_init(void)
405{ 429{
430#ifdef CONFIG_SUSPEND
431 register_syscore_ops(&lbc_syscore_pm_ops);
432#endif
406 return platform_driver_register(&fsl_lbc_ctrl_driver); 433 return platform_driver_register(&fsl_lbc_ctrl_driver);
407} 434}
408subsys_initcall(fsl_lbc_init); 435subsys_initcall(fsl_lbc_init);
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index c69e88e91459..85729f49764f 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -575,7 +575,7 @@ int fsl_add_bridge(struct platform_device *pdev, int is_primary)
575 if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { 575 if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
576 /* use fsl_indirect_read_config for PCIe */ 576 /* use fsl_indirect_read_config for PCIe */
577 hose->ops = &fsl_indirect_pcie_ops; 577 hose->ops = &fsl_indirect_pcie_ops;
578 /* For PCIE read HEADER_TYPE to identify controler mode */ 578 /* For PCIE read HEADER_TYPE to identify controller mode */
579 early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type); 579 early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type);
580 if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) 580 if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
581 goto no_bridge; 581 goto no_bridge;
diff --git a/arch/powerpc/sysdev/fsl_rcpm.c b/arch/powerpc/sysdev/fsl_rcpm.c
new file mode 100644
index 000000000000..9259a94f70e1
--- /dev/null
+++ b/arch/powerpc/sysdev/fsl_rcpm.c
@@ -0,0 +1,386 @@
1/*
2 * RCPM(Run Control/Power Management) support
3 *
4 * Copyright 2012-2015 Freescale Semiconductor Inc.
5 *
6 * Author: Chenhui Zhao <chenhui.zhao@freescale.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#define pr_fmt(fmt) "%s: " fmt, __func__
15
16#include <linux/types.h>
17#include <linux/errno.h>
18#include <linux/of_address.h>
19#include <linux/export.h>
20
21#include <asm/io.h>
22#include <linux/fsl/guts.h>
23#include <asm/cputhreads.h>
24#include <asm/fsl_pm.h>
25#include <asm/smp.h>
26
27static struct ccsr_rcpm_v1 __iomem *rcpm_v1_regs;
28static struct ccsr_rcpm_v2 __iomem *rcpm_v2_regs;
29static unsigned int fsl_supported_pm_modes;
30
31static void rcpm_v1_irq_mask(int cpu)
32{
33 int hw_cpu = get_hard_smp_processor_id(cpu);
34 unsigned int mask = 1 << hw_cpu;
35
36 setbits32(&rcpm_v1_regs->cpmimr, mask);
37 setbits32(&rcpm_v1_regs->cpmcimr, mask);
38 setbits32(&rcpm_v1_regs->cpmmcmr, mask);
39 setbits32(&rcpm_v1_regs->cpmnmimr, mask);
40}
41
42static void rcpm_v2_irq_mask(int cpu)
43{
44 int hw_cpu = get_hard_smp_processor_id(cpu);
45 unsigned int mask = 1 << hw_cpu;
46
47 setbits32(&rcpm_v2_regs->tpmimr0, mask);
48 setbits32(&rcpm_v2_regs->tpmcimr0, mask);
49 setbits32(&rcpm_v2_regs->tpmmcmr0, mask);
50 setbits32(&rcpm_v2_regs->tpmnmimr0, mask);
51}
52
53static void rcpm_v1_irq_unmask(int cpu)
54{
55 int hw_cpu = get_hard_smp_processor_id(cpu);
56 unsigned int mask = 1 << hw_cpu;
57
58 clrbits32(&rcpm_v1_regs->cpmimr, mask);
59 clrbits32(&rcpm_v1_regs->cpmcimr, mask);
60 clrbits32(&rcpm_v1_regs->cpmmcmr, mask);
61 clrbits32(&rcpm_v1_regs->cpmnmimr, mask);
62}
63
64static void rcpm_v2_irq_unmask(int cpu)
65{
66 int hw_cpu = get_hard_smp_processor_id(cpu);
67 unsigned int mask = 1 << hw_cpu;
68
69 clrbits32(&rcpm_v2_regs->tpmimr0, mask);
70 clrbits32(&rcpm_v2_regs->tpmcimr0, mask);
71 clrbits32(&rcpm_v2_regs->tpmmcmr0, mask);
72 clrbits32(&rcpm_v2_regs->tpmnmimr0, mask);
73}
74
75static void rcpm_v1_set_ip_power(bool enable, u32 mask)
76{
77 if (enable)
78 setbits32(&rcpm_v1_regs->ippdexpcr, mask);
79 else
80 clrbits32(&rcpm_v1_regs->ippdexpcr, mask);
81}
82
83static void rcpm_v2_set_ip_power(bool enable, u32 mask)
84{
85 if (enable)
86 setbits32(&rcpm_v2_regs->ippdexpcr[0], mask);
87 else
88 clrbits32(&rcpm_v2_regs->ippdexpcr[0], mask);
89}
90
91static void rcpm_v1_cpu_enter_state(int cpu, int state)
92{
93 int hw_cpu = get_hard_smp_processor_id(cpu);
94 unsigned int mask = 1 << hw_cpu;
95
96 switch (state) {
97 case E500_PM_PH10:
98 setbits32(&rcpm_v1_regs->cdozcr, mask);
99 break;
100 case E500_PM_PH15:
101 setbits32(&rcpm_v1_regs->cnapcr, mask);
102 break;
103 default:
104 pr_warn("Unknown cpu PM state (%d)\n", state);
105 break;
106 }
107}
108
109static void rcpm_v2_cpu_enter_state(int cpu, int state)
110{
111 int hw_cpu = get_hard_smp_processor_id(cpu);
112 u32 mask = 1 << cpu_core_index_of_thread(cpu);
113
114 switch (state) {
115 case E500_PM_PH10:
116 /* one bit corresponds to one thread for PH10 of 6500 */
117 setbits32(&rcpm_v2_regs->tph10setr0, 1 << hw_cpu);
118 break;
119 case E500_PM_PH15:
120 setbits32(&rcpm_v2_regs->pcph15setr, mask);
121 break;
122 case E500_PM_PH20:
123 setbits32(&rcpm_v2_regs->pcph20setr, mask);
124 break;
125 case E500_PM_PH30:
126 setbits32(&rcpm_v2_regs->pcph30setr, mask);
127 break;
128 default:
129 pr_warn("Unknown cpu PM state (%d)\n", state);
130 }
131}
132
133static void rcpm_v1_cpu_die(int cpu)
134{
135 rcpm_v1_cpu_enter_state(cpu, E500_PM_PH15);
136}
137
138#ifdef CONFIG_PPC64
139static void qoriq_disable_thread(int cpu)
140{
141 int thread = cpu_thread_in_core(cpu);
142
143 book3e_stop_thread(thread);
144}
145#endif
146
147static void rcpm_v2_cpu_die(int cpu)
148{
149#ifdef CONFIG_PPC64
150 int primary;
151
152 if (threads_per_core == 2) {
153 primary = cpu_first_thread_sibling(cpu);
154 if (cpu_is_offline(primary) && cpu_is_offline(primary + 1)) {
155 /* if both threads are offline, put the cpu in PH20 */
156 rcpm_v2_cpu_enter_state(cpu, E500_PM_PH20);
157 } else {
158 /* if only one thread is offline, disable the thread */
159 qoriq_disable_thread(cpu);
160 }
161 }
162#endif
163
164 if (threads_per_core == 1)
165 rcpm_v2_cpu_enter_state(cpu, E500_PM_PH20);
166}
167
168static void rcpm_v1_cpu_exit_state(int cpu, int state)
169{
170 int hw_cpu = get_hard_smp_processor_id(cpu);
171 unsigned int mask = 1 << hw_cpu;
172
173 switch (state) {
174 case E500_PM_PH10:
175 clrbits32(&rcpm_v1_regs->cdozcr, mask);
176 break;
177 case E500_PM_PH15:
178 clrbits32(&rcpm_v1_regs->cnapcr, mask);
179 break;
180 default:
181 pr_warn("Unknown cpu PM state (%d)\n", state);
182 break;
183 }
184}
185
186static void rcpm_v1_cpu_up_prepare(int cpu)
187{
188 rcpm_v1_cpu_exit_state(cpu, E500_PM_PH15);
189 rcpm_v1_irq_unmask(cpu);
190}
191
192static void rcpm_v2_cpu_exit_state(int cpu, int state)
193{
194 int hw_cpu = get_hard_smp_processor_id(cpu);
195 u32 mask = 1 << cpu_core_index_of_thread(cpu);
196
197 switch (state) {
198 case E500_PM_PH10:
199 setbits32(&rcpm_v2_regs->tph10clrr0, 1 << hw_cpu);
200 break;
201 case E500_PM_PH15:
202 setbits32(&rcpm_v2_regs->pcph15clrr, mask);
203 break;
204 case E500_PM_PH20:
205 setbits32(&rcpm_v2_regs->pcph20clrr, mask);
206 break;
207 case E500_PM_PH30:
208 setbits32(&rcpm_v2_regs->pcph30clrr, mask);
209 break;
210 default:
211 pr_warn("Unknown cpu PM state (%d)\n", state);
212 }
213}
214
215static void rcpm_v2_cpu_up_prepare(int cpu)
216{
217 rcpm_v2_cpu_exit_state(cpu, E500_PM_PH20);
218 rcpm_v2_irq_unmask(cpu);
219}
220
221static int rcpm_v1_plat_enter_state(int state)
222{
223 u32 *pmcsr_reg = &rcpm_v1_regs->powmgtcsr;
224 int ret = 0;
225 int result;
226
227 switch (state) {
228 case PLAT_PM_SLEEP:
229 setbits32(pmcsr_reg, RCPM_POWMGTCSR_SLP);
230
231 /* Upon resume, wait for RCPM_POWMGTCSR_SLP bit to be clear. */
232 result = spin_event_timeout(
233 !(in_be32(pmcsr_reg) & RCPM_POWMGTCSR_SLP), 10000, 10);
234 if (!result) {
235 pr_err("timeout waiting for SLP bit to be cleared\n");
236 ret = -ETIMEDOUT;
237 }
238 break;
239 default:
240 pr_warn("Unknown platform PM state (%d)", state);
241 ret = -EINVAL;
242 }
243
244 return ret;
245}
246
247static int rcpm_v2_plat_enter_state(int state)
248{
249 u32 *pmcsr_reg = &rcpm_v2_regs->powmgtcsr;
250 int ret = 0;
251 int result;
252
253 switch (state) {
254 case PLAT_PM_LPM20:
255 /* clear previous LPM20 status */
256 setbits32(pmcsr_reg, RCPM_POWMGTCSR_P_LPM20_ST);
257 /* enter LPM20 status */
258 setbits32(pmcsr_reg, RCPM_POWMGTCSR_LPM20_RQ);
259
260 /* At this point, the device is in LPM20 status. */
261
262 /* resume ... */
263 result = spin_event_timeout(
264 !(in_be32(pmcsr_reg) & RCPM_POWMGTCSR_LPM20_ST), 10000, 10);
265 if (!result) {
266 pr_err("timeout waiting for LPM20 bit to be cleared\n");
267 ret = -ETIMEDOUT;
268 }
269 break;
270 default:
271 pr_warn("Unknown platform PM state (%d)\n", state);
272 ret = -EINVAL;
273 }
274
275 return ret;
276}
277
278static int rcpm_v1_plat_enter_sleep(void)
279{
280 return rcpm_v1_plat_enter_state(PLAT_PM_SLEEP);
281}
282
283static int rcpm_v2_plat_enter_sleep(void)
284{
285 return rcpm_v2_plat_enter_state(PLAT_PM_LPM20);
286}
287
288static void rcpm_common_freeze_time_base(u32 *tben_reg, int freeze)
289{
290 static u32 mask;
291
292 if (freeze) {
293 mask = in_be32(tben_reg);
294 clrbits32(tben_reg, mask);
295 } else {
296 setbits32(tben_reg, mask);
297 }
298
299 /* read back to push the previous write */
300 in_be32(tben_reg);
301}
302
303static void rcpm_v1_freeze_time_base(bool freeze)
304{
305 rcpm_common_freeze_time_base(&rcpm_v1_regs->ctbenr, freeze);
306}
307
308static void rcpm_v2_freeze_time_base(bool freeze)
309{
310 rcpm_common_freeze_time_base(&rcpm_v2_regs->pctbenr, freeze);
311}
312
313static unsigned int rcpm_get_pm_modes(void)
314{
315 return fsl_supported_pm_modes;
316}
317
318static const struct fsl_pm_ops qoriq_rcpm_v1_ops = {
319 .irq_mask = rcpm_v1_irq_mask,
320 .irq_unmask = rcpm_v1_irq_unmask,
321 .cpu_enter_state = rcpm_v1_cpu_enter_state,
322 .cpu_exit_state = rcpm_v1_cpu_exit_state,
323 .cpu_up_prepare = rcpm_v1_cpu_up_prepare,
324 .cpu_die = rcpm_v1_cpu_die,
325 .plat_enter_sleep = rcpm_v1_plat_enter_sleep,
326 .set_ip_power = rcpm_v1_set_ip_power,
327 .freeze_time_base = rcpm_v1_freeze_time_base,
328 .get_pm_modes = rcpm_get_pm_modes,
329};
330
331static const struct fsl_pm_ops qoriq_rcpm_v2_ops = {
332 .irq_mask = rcpm_v2_irq_mask,
333 .irq_unmask = rcpm_v2_irq_unmask,
334 .cpu_enter_state = rcpm_v2_cpu_enter_state,
335 .cpu_exit_state = rcpm_v2_cpu_exit_state,
336 .cpu_up_prepare = rcpm_v2_cpu_up_prepare,
337 .cpu_die = rcpm_v2_cpu_die,
338 .plat_enter_sleep = rcpm_v2_plat_enter_sleep,
339 .set_ip_power = rcpm_v2_set_ip_power,
340 .freeze_time_base = rcpm_v2_freeze_time_base,
341 .get_pm_modes = rcpm_get_pm_modes,
342};
343
344static const struct of_device_id rcpm_matches[] = {
345 {
346 .compatible = "fsl,qoriq-rcpm-1.0",
347 .data = &qoriq_rcpm_v1_ops,
348 },
349 {
350 .compatible = "fsl,qoriq-rcpm-2.0",
351 .data = &qoriq_rcpm_v2_ops,
352 },
353 {
354 .compatible = "fsl,qoriq-rcpm-2.1",
355 .data = &qoriq_rcpm_v2_ops,
356 },
357 {},
358};
359
360int __init fsl_rcpm_init(void)
361{
362 struct device_node *np;
363 const struct of_device_id *match;
364 void __iomem *base;
365
366 np = of_find_matching_node_and_match(NULL, rcpm_matches, &match);
367 if (!np)
368 return 0;
369
370 base = of_iomap(np, 0);
371 of_node_put(np);
372 if (!base) {
373 pr_err("of_iomap() error.\n");
374 return -ENOMEM;
375 }
376
377 rcpm_v1_regs = base;
378 rcpm_v2_regs = base;
379
380 /* support sleep by default */
381 fsl_supported_pm_modes = FSL_PM_SLEEP;
382
383 qoriq_pm_ops = match->data;
384
385 return 0;
386}
diff --git a/arch/powerpc/sysdev/fsl_rmu.c b/arch/powerpc/sysdev/fsl_rmu.c
index b48197ae44d0..ffe0ee832768 100644
--- a/arch/powerpc/sysdev/fsl_rmu.c
+++ b/arch/powerpc/sysdev/fsl_rmu.c
@@ -570,7 +570,7 @@ int fsl_rio_port_write_init(struct fsl_rio_pw *pw)
570 out_be32(&pw->pw_regs->pwsr, 570 out_be32(&pw->pw_regs->pwsr,
571 (RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD)); 571 (RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD));
572 572
573 /* Configure port write contoller for snooping enable all reporting, 573 /* Configure port write controller for snooping enable all reporting,
574 clear queue full */ 574 clear queue full */
575 out_be32(&pw->pw_regs->pwmr, 575 out_be32(&pw->pw_regs->pwmr,
576 RIO_IPWMR_SEN | RIO_IPWMR_QFIE | RIO_IPWMR_EIE | RIO_IPWMR_CQ); 576 RIO_IPWMR_SEN | RIO_IPWMR_QFIE | RIO_IPWMR_EIE | RIO_IPWMR_CQ);
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index 6f99ed3967fd..aa2c186d3115 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -238,7 +238,7 @@ void i8259_init(struct device_node *node, unsigned long intack_addr)
238 /* init master interrupt controller */ 238 /* init master interrupt controller */
239 outb(0x11, 0x20); /* Start init sequence */ 239 outb(0x11, 0x20); /* Start init sequence */
240 outb(0x00, 0x21); /* Vector base */ 240 outb(0x00, 0x21); /* Vector base */
241 outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */ 241 outb(0x04, 0x21); /* edge triggered, Cascade (slave) on IRQ2 */
242 outb(0x01, 0x21); /* Select 8086 mode */ 242 outb(0x01, 0x21); /* Select 8086 mode */
243 243
244 /* init slave interrupt controller */ 244 /* init slave interrupt controller */
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 2a0452e364ba..afe3c7cd395d 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -2,7 +2,7 @@
2 * arch/powerpc/kernel/mpic.c 2 * arch/powerpc/kernel/mpic.c
3 * 3 *
4 * Driver for interrupt controllers following the OpenPIC standard, the 4 * Driver for interrupt controllers following the OpenPIC standard, the
5 * common implementation beeing IBM's MPIC. This driver also can deal 5 * common implementation being IBM's MPIC. This driver also can deal
6 * with various broken implementations of this HW. 6 * with various broken implementations of this HW.
7 * 7 *
8 * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. 8 * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
@@ -1657,7 +1657,7 @@ void __init mpic_init(struct mpic *mpic)
1657 } 1657 }
1658 } 1658 }
1659 1659
1660 /* FSL mpic error interrupt intialization */ 1660 /* FSL mpic error interrupt initialization */
1661 if (mpic->flags & MPIC_FSL_HAS_EIMR) 1661 if (mpic->flags & MPIC_FSL_HAS_EIMR)
1662 mpic_err_int_init(mpic, MPIC_FSL_ERR_INT); 1662 mpic_err_int_init(mpic, MPIC_FSL_ERR_INT);
1663} 1663}
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 07a8508cb7fa..942796fa4767 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -47,6 +47,9 @@
47#include <asm/debug.h> 47#include <asm/debug.h>
48#include <asm/hw_breakpoint.h> 48#include <asm/hw_breakpoint.h>
49 49
50#include <asm/opal.h>
51#include <asm/firmware.h>
52
50#ifdef CONFIG_PPC64 53#ifdef CONFIG_PPC64
51#include <asm/hvcall.h> 54#include <asm/hvcall.h>
52#include <asm/paca.h> 55#include <asm/paca.h>
@@ -119,6 +122,16 @@ static void dump(void);
119static void prdump(unsigned long, long); 122static void prdump(unsigned long, long);
120static int ppc_inst_dump(unsigned long, long, int); 123static int ppc_inst_dump(unsigned long, long, int);
121static void dump_log_buf(void); 124static void dump_log_buf(void);
125
126#ifdef CONFIG_PPC_POWERNV
127static void dump_opal_msglog(void);
128#else
129static inline void dump_opal_msglog(void)
130{
131 printf("Machine is not running OPAL firmware.\n");
132}
133#endif
134
122static void backtrace(struct pt_regs *); 135static void backtrace(struct pt_regs *);
123static void excprint(struct pt_regs *); 136static void excprint(struct pt_regs *);
124static void prregs(struct pt_regs *); 137static void prregs(struct pt_regs *);
@@ -150,6 +163,7 @@ static int cpu_cmd(void);
150static void csum(void); 163static void csum(void);
151static void bootcmds(void); 164static void bootcmds(void);
152static void proccall(void); 165static void proccall(void);
166static void show_tasks(void);
153void dump_segments(void); 167void dump_segments(void);
154static void symbol_lookup(void); 168static void symbol_lookup(void);
155static void xmon_show_stack(unsigned long sp, unsigned long lr, 169static void xmon_show_stack(unsigned long sp, unsigned long lr,
@@ -202,6 +216,10 @@ Commands:\n\
202 df dump float values\n\ 216 df dump float values\n\
203 dd dump double values\n\ 217 dd dump double values\n\
204 dl dump the kernel log buffer\n" 218 dl dump the kernel log buffer\n"
219#ifdef CONFIG_PPC_POWERNV
220 "\
221 do dump the OPAL message log\n"
222#endif
205#ifdef CONFIG_PPC64 223#ifdef CONFIG_PPC64
206 "\ 224 "\
207 dp[#] dump paca for current cpu, or cpu #\n\ 225 dp[#] dump paca for current cpu, or cpu #\n\
@@ -221,6 +239,7 @@ Commands:\n\
221 mz zero a block of memory\n\ 239 mz zero a block of memory\n\
222 mi show information about memory allocation\n\ 240 mi show information about memory allocation\n\
223 p call a procedure\n\ 241 p call a procedure\n\
242 P list processes/tasks\n\
224 r print registers\n\ 243 r print registers\n\
225 s single step\n" 244 s single step\n"
226#ifdef CONFIG_SPU_BASE 245#ifdef CONFIG_SPU_BASE
@@ -233,7 +252,7 @@ Commands:\n\
233" S print special registers\n\ 252" S print special registers\n\
234 t print backtrace\n\ 253 t print backtrace\n\
235 x exit monitor and recover\n\ 254 x exit monitor and recover\n\
236 X exit monitor and dont recover\n" 255 X exit monitor and don't recover\n"
237#if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E) 256#if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
238" u dump segment table or SLB\n" 257" u dump segment table or SLB\n"
239#elif defined(CONFIG_PPC_STD_MMU_32) 258#elif defined(CONFIG_PPC_STD_MMU_32)
@@ -950,6 +969,9 @@ cmds(struct pt_regs *excp)
950 case 'p': 969 case 'p':
951 proccall(); 970 proccall();
952 break; 971 break;
972 case 'P':
973 show_tasks();
974 break;
953#ifdef CONFIG_PPC_STD_MMU 975#ifdef CONFIG_PPC_STD_MMU
954 case 'u': 976 case 'u':
955 dump_segments(); 977 dump_segments();
@@ -2253,6 +2275,8 @@ dump(void)
2253 last_cmd = "di\n"; 2275 last_cmd = "di\n";
2254 } else if (c == 'l') { 2276 } else if (c == 'l') {
2255 dump_log_buf(); 2277 dump_log_buf();
2278 } else if (c == 'o') {
2279 dump_opal_msglog();
2256 } else if (c == 'r') { 2280 } else if (c == 'r') {
2257 scanhex(&ndump); 2281 scanhex(&ndump);
2258 if (ndump == 0) 2282 if (ndump == 0)
@@ -2395,6 +2419,45 @@ dump_log_buf(void)
2395 catch_memory_errors = 0; 2419 catch_memory_errors = 0;
2396} 2420}
2397 2421
2422#ifdef CONFIG_PPC_POWERNV
2423static void dump_opal_msglog(void)
2424{
2425 unsigned char buf[128];
2426 ssize_t res;
2427 loff_t pos = 0;
2428
2429 if (!firmware_has_feature(FW_FEATURE_OPAL)) {
2430 printf("Machine is not running OPAL firmware.\n");
2431 return;
2432 }
2433
2434 if (setjmp(bus_error_jmp) != 0) {
2435 printf("Error dumping OPAL msglog!\n");
2436 return;
2437 }
2438
2439 catch_memory_errors = 1;
2440 sync();
2441
2442 xmon_start_pagination();
2443 while ((res = opal_msglog_copy(buf, pos, sizeof(buf) - 1))) {
2444 if (res < 0) {
2445 printf("Error dumping OPAL msglog! Error: %zd\n", res);
2446 break;
2447 }
2448 buf[res] = '\0';
2449 printf("%s", buf);
2450 pos += res;
2451 }
2452 xmon_end_pagination();
2453
2454 sync();
2455 /* wait a little while to see if we get a machine check */
2456 __delay(200);
2457 catch_memory_errors = 0;
2458}
2459#endif
2460
2398/* 2461/*
2399 * Memory operations - move, set, print differences 2462 * Memory operations - move, set, print differences
2400 */ 2463 */
@@ -2508,6 +2571,61 @@ memzcan(void)
2508 printf("%.8x\n", a - mskip); 2571 printf("%.8x\n", a - mskip);
2509} 2572}
2510 2573
2574static void show_task(struct task_struct *tsk)
2575{
2576 char state;
2577
2578 /*
2579 * Cloned from kdb_task_state_char(), which is not entirely
2580 * appropriate for calling from xmon. This could be moved
2581 * to a common, generic, routine used by both.
2582 */
2583 state = (tsk->state == 0) ? 'R' :
2584 (tsk->state < 0) ? 'U' :
2585 (tsk->state & TASK_UNINTERRUPTIBLE) ? 'D' :
2586 (tsk->state & TASK_STOPPED) ? 'T' :
2587 (tsk->state & TASK_TRACED) ? 'C' :
2588 (tsk->exit_state & EXIT_ZOMBIE) ? 'Z' :
2589 (tsk->exit_state & EXIT_DEAD) ? 'E' :
2590 (tsk->state & TASK_INTERRUPTIBLE) ? 'S' : '?';
2591
2592 printf("%p %016lx %6d %6d %c %2d %s\n", tsk,
2593 tsk->thread.ksp,
2594 tsk->pid, tsk->parent->pid,
2595 state, task_thread_info(tsk)->cpu,
2596 tsk->comm);
2597}
2598
2599static void show_tasks(void)
2600{
2601 unsigned long tskv;
2602 struct task_struct *tsk = NULL;
2603
2604 printf(" task_struct ->thread.ksp PID PPID S P CMD\n");
2605
2606 if (scanhex(&tskv))
2607 tsk = (struct task_struct *)tskv;
2608
2609 if (setjmp(bus_error_jmp) != 0) {
2610 catch_memory_errors = 0;
2611 printf("*** Error dumping task %p\n", tsk);
2612 return;
2613 }
2614
2615 catch_memory_errors = 1;
2616 sync();
2617
2618 if (tsk)
2619 show_task(tsk);
2620 else
2621 for_each_process(tsk)
2622 show_task(tsk);
2623
2624 sync();
2625 __delay(200);
2626 catch_memory_errors = 0;
2627}
2628
2511static void proccall(void) 2629static void proccall(void)
2512{ 2630{
2513 unsigned long args[8]; 2631 unsigned long args[8];
diff --git a/drivers/misc/cxl/Makefile b/drivers/misc/cxl/Makefile
index be2ac5ce349f..8a55c1aa11aa 100644
--- a/drivers/misc/cxl/Makefile
+++ b/drivers/misc/cxl/Makefile
@@ -4,6 +4,7 @@ ccflags-$(CONFIG_PPC_WERROR) += -Werror
4cxl-y += main.o file.o irq.o fault.o native.o 4cxl-y += main.o file.o irq.o fault.o native.o
5cxl-y += context.o sysfs.o debugfs.o pci.o trace.o 5cxl-y += context.o sysfs.o debugfs.o pci.o trace.o
6cxl-y += vphb.o api.o 6cxl-y += vphb.o api.o
7cxl-$(CONFIG_PPC_PSERIES) += flash.o guest.o of.o hcalls.o
7obj-$(CONFIG_CXL) += cxl.o 8obj-$(CONFIG_CXL) += cxl.o
8obj-$(CONFIG_CXL_BASE) += base.o 9obj-$(CONFIG_CXL_BASE) += base.o
9 10
diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c
index ea3eeb7011e1..2107c948406d 100644
--- a/drivers/misc/cxl/api.c
+++ b/drivers/misc/cxl/api.c
@@ -51,8 +51,6 @@ struct cxl_context *cxl_dev_context_init(struct pci_dev *dev)
51 if (rc) 51 if (rc)
52 goto err_mapping; 52 goto err_mapping;
53 53
54 cxl_assign_psn_space(ctx);
55
56 return ctx; 54 return ctx;
57 55
58err_mapping: 56err_mapping:
@@ -78,7 +76,6 @@ struct device *cxl_get_phys_dev(struct pci_dev *dev)
78 76
79 return afu->adapter->dev.parent; 77 return afu->adapter->dev.parent;
80} 78}
81EXPORT_SYMBOL_GPL(cxl_get_phys_dev);
82 79
83int cxl_release_context(struct cxl_context *ctx) 80int cxl_release_context(struct cxl_context *ctx)
84{ 81{
@@ -91,28 +88,11 @@ int cxl_release_context(struct cxl_context *ctx)
91} 88}
92EXPORT_SYMBOL_GPL(cxl_release_context); 89EXPORT_SYMBOL_GPL(cxl_release_context);
93 90
94int cxl_allocate_afu_irqs(struct cxl_context *ctx, int num)
95{
96 if (num == 0)
97 num = ctx->afu->pp_irqs;
98 return afu_allocate_irqs(ctx, num);
99}
100EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs);
101
102void cxl_free_afu_irqs(struct cxl_context *ctx)
103{
104 afu_irq_name_free(ctx);
105 cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
106}
107EXPORT_SYMBOL_GPL(cxl_free_afu_irqs);
108
109static irq_hw_number_t cxl_find_afu_irq(struct cxl_context *ctx, int num) 91static irq_hw_number_t cxl_find_afu_irq(struct cxl_context *ctx, int num)
110{ 92{
111 __u16 range; 93 __u16 range;
112 int r; 94 int r;
113 95
114 WARN_ON(num == 0);
115
116 for (r = 0; r < CXL_IRQ_RANGES; r++) { 96 for (r = 0; r < CXL_IRQ_RANGES; r++) {
117 range = ctx->irqs.range[r]; 97 range = ctx->irqs.range[r];
118 if (num < range) { 98 if (num < range) {
@@ -123,6 +103,44 @@ static irq_hw_number_t cxl_find_afu_irq(struct cxl_context *ctx, int num)
123 return 0; 103 return 0;
124} 104}
125 105
106int cxl_allocate_afu_irqs(struct cxl_context *ctx, int num)
107{
108 int res;
109 irq_hw_number_t hwirq;
110
111 if (num == 0)
112 num = ctx->afu->pp_irqs;
113 res = afu_allocate_irqs(ctx, num);
114 if (!res && !cpu_has_feature(CPU_FTR_HVMODE)) {
115 /* In a guest, the PSL interrupt is not multiplexed. It was
116 * allocated above, and we need to set its handler
117 */
118 hwirq = cxl_find_afu_irq(ctx, 0);
119 if (hwirq)
120 cxl_map_irq(ctx->afu->adapter, hwirq, cxl_ops->psl_interrupt, ctx, "psl");
121 }
122 return res;
123}
124EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs);
125
126void cxl_free_afu_irqs(struct cxl_context *ctx)
127{
128 irq_hw_number_t hwirq;
129 unsigned int virq;
130
131 if (!cpu_has_feature(CPU_FTR_HVMODE)) {
132 hwirq = cxl_find_afu_irq(ctx, 0);
133 if (hwirq) {
134 virq = irq_find_mapping(NULL, hwirq);
135 if (virq)
136 cxl_unmap_irq(virq, ctx);
137 }
138 }
139 afu_irq_name_free(ctx);
140 cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
141}
142EXPORT_SYMBOL_GPL(cxl_free_afu_irqs);
143
126int cxl_map_afu_irq(struct cxl_context *ctx, int num, 144int cxl_map_afu_irq(struct cxl_context *ctx, int num,
127 irq_handler_t handler, void *cookie, char *name) 145 irq_handler_t handler, void *cookie, char *name)
128{ 146{
@@ -178,7 +196,7 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed,
178 196
179 cxl_ctx_get(); 197 cxl_ctx_get();
180 198
181 if ((rc = cxl_attach_process(ctx, kernel, wed , 0))) { 199 if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) {
182 put_pid(ctx->pid); 200 put_pid(ctx->pid);
183 cxl_ctx_put(); 201 cxl_ctx_put();
184 goto out; 202 goto out;
@@ -193,7 +211,7 @@ EXPORT_SYMBOL_GPL(cxl_start_context);
193 211
194int cxl_process_element(struct cxl_context *ctx) 212int cxl_process_element(struct cxl_context *ctx)
195{ 213{
196 return ctx->pe; 214 return ctx->external_pe;
197} 215}
198EXPORT_SYMBOL_GPL(cxl_process_element); 216EXPORT_SYMBOL_GPL(cxl_process_element);
199 217
@@ -207,7 +225,6 @@ EXPORT_SYMBOL_GPL(cxl_stop_context);
207void cxl_set_master(struct cxl_context *ctx) 225void cxl_set_master(struct cxl_context *ctx)
208{ 226{
209 ctx->master = true; 227 ctx->master = true;
210 cxl_assign_psn_space(ctx);
211} 228}
212EXPORT_SYMBOL_GPL(cxl_set_master); 229EXPORT_SYMBOL_GPL(cxl_set_master);
213 230
@@ -325,15 +342,11 @@ EXPORT_SYMBOL_GPL(cxl_start_work);
325 342
326void __iomem *cxl_psa_map(struct cxl_context *ctx) 343void __iomem *cxl_psa_map(struct cxl_context *ctx)
327{ 344{
328 struct cxl_afu *afu = ctx->afu; 345 if (ctx->status != STARTED)
329 int rc;
330
331 rc = cxl_afu_check_and_enable(afu);
332 if (rc)
333 return NULL; 346 return NULL;
334 347
335 pr_devel("%s: psn_phys%llx size:%llx\n", 348 pr_devel("%s: psn_phys%llx size:%llx\n",
336 __func__, afu->psn_phys, afu->adapter->ps_size); 349 __func__, ctx->psn_phys, ctx->psn_size);
337 return ioremap(ctx->psn_phys, ctx->psn_size); 350 return ioremap(ctx->psn_phys, ctx->psn_size);
338} 351}
339EXPORT_SYMBOL_GPL(cxl_psa_map); 352EXPORT_SYMBOL_GPL(cxl_psa_map);
@@ -349,11 +362,11 @@ int cxl_afu_reset(struct cxl_context *ctx)
349 struct cxl_afu *afu = ctx->afu; 362 struct cxl_afu *afu = ctx->afu;
350 int rc; 363 int rc;
351 364
352 rc = __cxl_afu_reset(afu); 365 rc = cxl_ops->afu_reset(afu);
353 if (rc) 366 if (rc)
354 return rc; 367 return rc;
355 368
356 return cxl_afu_check_and_enable(afu); 369 return cxl_ops->afu_check_and_enable(afu);
357} 370}
358EXPORT_SYMBOL_GPL(cxl_afu_reset); 371EXPORT_SYMBOL_GPL(cxl_afu_reset);
359 372
@@ -363,3 +376,11 @@ void cxl_perst_reloads_same_image(struct cxl_afu *afu,
363 afu->adapter->perst_same_image = perst_reloads_same_image; 376 afu->adapter->perst_same_image = perst_reloads_same_image;
364} 377}
365EXPORT_SYMBOL_GPL(cxl_perst_reloads_same_image); 378EXPORT_SYMBOL_GPL(cxl_perst_reloads_same_image);
379
380ssize_t cxl_read_adapter_vpd(struct pci_dev *dev, void *buf, size_t count)
381{
382 struct cxl_afu *afu = cxl_pci_to_afu(dev);
383
384 return cxl_ops->read_adapter_vpd(afu->adapter, buf, count);
385}
386EXPORT_SYMBOL_GPL(cxl_read_adapter_vpd);
diff --git a/drivers/misc/cxl/base.c b/drivers/misc/cxl/base.c
index a9f0dd3255a2..9b90ec6c07cd 100644
--- a/drivers/misc/cxl/base.c
+++ b/drivers/misc/cxl/base.c
@@ -11,6 +11,7 @@
11#include <linux/rcupdate.h> 11#include <linux/rcupdate.h>
12#include <asm/errno.h> 12#include <asm/errno.h>
13#include <misc/cxl-base.h> 13#include <misc/cxl-base.h>
14#include <linux/of_platform.h>
14#include "cxl.h" 15#include "cxl.h"
15 16
16/* protected by rcu */ 17/* protected by rcu */
@@ -84,3 +85,34 @@ void unregister_cxl_calls(struct cxl_calls *calls)
84 synchronize_rcu(); 85 synchronize_rcu();
85} 86}
86EXPORT_SYMBOL_GPL(unregister_cxl_calls); 87EXPORT_SYMBOL_GPL(unregister_cxl_calls);
88
89int cxl_update_properties(struct device_node *dn,
90 struct property *new_prop)
91{
92 return of_update_property(dn, new_prop);
93}
94EXPORT_SYMBOL_GPL(cxl_update_properties);
95
96static int __init cxl_base_init(void)
97{
98 struct device_node *np = NULL;
99 struct platform_device *dev;
100 int count = 0;
101
102 /*
103 * Scan for compatible devices in guest only
104 */
105 if (cpu_has_feature(CPU_FTR_HVMODE))
106 return 0;
107
108 while ((np = of_find_compatible_node(np, NULL,
109 "ibm,coherent-platform-facility"))) {
110 dev = of_platform_device_create(np, NULL, NULL);
111 if (dev)
112 count++;
113 }
114 pr_devel("Found %d cxl device(s)\n", count);
115 return 0;
116}
117
118module_init(cxl_base_init);
diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c
index 262b88eac414..10370f280500 100644
--- a/drivers/misc/cxl/context.c
+++ b/drivers/misc/cxl/context.c
@@ -95,7 +95,12 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master,
95 return i; 95 return i;
96 96
97 ctx->pe = i; 97 ctx->pe = i;
98 ctx->elem = &ctx->afu->spa[i]; 98 if (cpu_has_feature(CPU_FTR_HVMODE)) {
99 ctx->elem = &ctx->afu->native->spa[i];
100 ctx->external_pe = ctx->pe;
101 } else {
102 ctx->external_pe = -1; /* assigned when attaching */
103 }
99 ctx->pe_inserted = false; 104 ctx->pe_inserted = false;
100 105
101 /* 106 /*
@@ -214,8 +219,8 @@ int __detach_context(struct cxl_context *ctx)
214 /* Only warn if we detached while the link was OK. 219 /* Only warn if we detached while the link was OK.
215 * If detach fails when hw is down, we don't care. 220 * If detach fails when hw is down, we don't care.
216 */ 221 */
217 WARN_ON(cxl_detach_process(ctx) && 222 WARN_ON(cxl_ops->detach_process(ctx) &&
218 cxl_adapter_link_ok(ctx->afu->adapter)); 223 cxl_ops->link_ok(ctx->afu->adapter, ctx->afu));
219 flush_work(&ctx->fault_work); /* Only needed for dedicated process */ 224 flush_work(&ctx->fault_work); /* Only needed for dedicated process */
220 225
221 /* release the reference to the group leader and mm handling pid */ 226 /* release the reference to the group leader and mm handling pid */
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index a521bc72cec2..38e21cf7806e 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -324,6 +324,10 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0};
324#define CXL_MODE_TIME_SLICED 0x4 324#define CXL_MODE_TIME_SLICED 0x4
325#define CXL_SUPPORTED_MODES (CXL_MODE_DEDICATED | CXL_MODE_DIRECTED) 325#define CXL_SUPPORTED_MODES (CXL_MODE_DEDICATED | CXL_MODE_DIRECTED)
326 326
327#define CXL_DEV_MINORS 13 /* 1 control + 4 AFUs * 3 (dedicated/master/shared) */
328#define CXL_CARD_MINOR(adapter) (adapter->adapter_num * CXL_DEV_MINORS)
329#define CXL_DEVT_ADAPTER(dev) (MINOR(dev) / CXL_DEV_MINORS)
330
327enum cxl_context_status { 331enum cxl_context_status {
328 CLOSED, 332 CLOSED,
329 OPENED, 333 OPENED,
@@ -336,6 +340,12 @@ enum prefault_modes {
336 CXL_PREFAULT_ALL, 340 CXL_PREFAULT_ALL,
337}; 341};
338 342
343enum cxl_attrs {
344 CXL_ADAPTER_ATTRS,
345 CXL_AFU_MASTER_ATTRS,
346 CXL_AFU_ATTRS,
347};
348
339struct cxl_sste { 349struct cxl_sste {
340 __be64 esid_data; 350 __be64 esid_data;
341 __be64 vsid_data; 351 __be64 vsid_data;
@@ -344,18 +354,46 @@ struct cxl_sste {
344#define to_cxl_adapter(d) container_of(d, struct cxl, dev) 354#define to_cxl_adapter(d) container_of(d, struct cxl, dev)
345#define to_cxl_afu(d) container_of(d, struct cxl_afu, dev) 355#define to_cxl_afu(d) container_of(d, struct cxl_afu, dev)
346 356
347struct cxl_afu { 357struct cxl_afu_native {
358 void __iomem *p1n_mmio;
359 void __iomem *afu_desc_mmio;
348 irq_hw_number_t psl_hwirq; 360 irq_hw_number_t psl_hwirq;
361 unsigned int psl_virq;
362 struct mutex spa_mutex;
363 /*
364 * Only the first part of the SPA is used for the process element
365 * linked list. The only other part that software needs to worry about
366 * is sw_command_status, which we store a separate pointer to.
367 * Everything else in the SPA is only used by hardware
368 */
369 struct cxl_process_element *spa;
370 __be64 *sw_command_status;
371 unsigned int spa_size;
372 int spa_order;
373 int spa_max_procs;
374 u64 pp_offset;
375};
376
377struct cxl_afu_guest {
378 u64 handle;
379 phys_addr_t p2n_phys;
380 u64 p2n_size;
381 int max_ints;
382 struct mutex recovery_lock;
383 int previous_state;
384};
385
386struct cxl_afu {
387 struct cxl_afu_native *native;
388 struct cxl_afu_guest *guest;
349 irq_hw_number_t serr_hwirq; 389 irq_hw_number_t serr_hwirq;
350 char *err_irq_name;
351 char *psl_irq_name;
352 unsigned int serr_virq; 390 unsigned int serr_virq;
353 void __iomem *p1n_mmio; 391 char *psl_irq_name;
392 char *err_irq_name;
354 void __iomem *p2n_mmio; 393 void __iomem *p2n_mmio;
355 phys_addr_t psn_phys; 394 phys_addr_t psn_phys;
356 u64 pp_offset;
357 u64 pp_size; 395 u64 pp_size;
358 void __iomem *afu_desc_mmio; 396
359 struct cxl *adapter; 397 struct cxl *adapter;
360 struct device dev; 398 struct device dev;
361 struct cdev afu_cdev_s, afu_cdev_m, afu_cdev_d; 399 struct cdev afu_cdev_s, afu_cdev_m, afu_cdev_d;
@@ -363,26 +401,12 @@ struct cxl_afu {
363 struct idr contexts_idr; 401 struct idr contexts_idr;
364 struct dentry *debugfs; 402 struct dentry *debugfs;
365 struct mutex contexts_lock; 403 struct mutex contexts_lock;
366 struct mutex spa_mutex;
367 spinlock_t afu_cntl_lock; 404 spinlock_t afu_cntl_lock;
368 405
369 /* AFU error buffer fields and bin attribute for sysfs */ 406 /* AFU error buffer fields and bin attribute for sysfs */
370 u64 eb_len, eb_offset; 407 u64 eb_len, eb_offset;
371 struct bin_attribute attr_eb; 408 struct bin_attribute attr_eb;
372 409
373 /*
374 * Only the first part of the SPA is used for the process element
375 * linked list. The only other part that software needs to worry about
376 * is sw_command_status, which we store a separate pointer to.
377 * Everything else in the SPA is only used by hardware
378 */
379 struct cxl_process_element *spa;
380 __be64 *sw_command_status;
381 unsigned int spa_size;
382 int spa_order;
383 int spa_max_procs;
384 unsigned int psl_virq;
385
386 /* pointer to the vphb */ 410 /* pointer to the vphb */
387 struct pci_controller *phb; 411 struct pci_controller *phb;
388 412
@@ -421,6 +445,12 @@ struct cxl_irq_name {
421 char *name; 445 char *name;
422}; 446};
423 447
448struct irq_avail {
449 irq_hw_number_t offset;
450 irq_hw_number_t range;
451 unsigned long *bitmap;
452};
453
424/* 454/*
425 * This is a cxl context. If the PSL is in dedicated mode, there will be one 455 * This is a cxl context. If the PSL is in dedicated mode, there will be one
426 * of these per AFU. If in AFU directed there can be lots of these. 456 * of these per AFU. If in AFU directed there can be lots of these.
@@ -476,7 +506,19 @@ struct cxl_context {
476 506
477 struct cxl_process_element *elem; 507 struct cxl_process_element *elem;
478 508
479 int pe; /* process element handle */ 509 /*
510 * pe is the process element handle, assigned by this driver when the
511 * context is initialized.
512 *
513 * external_pe is the PE shown outside of cxl.
514 * On bare-metal, pe=external_pe, because we decide what the handle is.
515 * In a guest, we only find out about the pe used by pHyp when the
516 * context is attached, and that's the value we want to report outside
517 * of cxl.
518 */
519 int pe;
520 int external_pe;
521
480 u32 irq_count; 522 u32 irq_count;
481 bool pe_inserted; 523 bool pe_inserted;
482 bool master; 524 bool master;
@@ -488,11 +530,34 @@ struct cxl_context {
488 struct rcu_head rcu; 530 struct rcu_head rcu;
489}; 531};
490 532
491struct cxl { 533struct cxl_native {
534 u64 afu_desc_off;
535 u64 afu_desc_size;
492 void __iomem *p1_mmio; 536 void __iomem *p1_mmio;
493 void __iomem *p2_mmio; 537 void __iomem *p2_mmio;
494 irq_hw_number_t err_hwirq; 538 irq_hw_number_t err_hwirq;
495 unsigned int err_virq; 539 unsigned int err_virq;
540 u64 ps_off;
541};
542
543struct cxl_guest {
544 struct platform_device *pdev;
545 int irq_nranges;
546 struct cdev cdev;
547 irq_hw_number_t irq_base_offset;
548 struct irq_avail *irq_avail;
549 spinlock_t irq_alloc_lock;
550 u64 handle;
551 char *status;
552 u16 vendor;
553 u16 device;
554 u16 subsystem_vendor;
555 u16 subsystem;
556};
557
558struct cxl {
559 struct cxl_native *native;
560 struct cxl_guest *guest;
496 spinlock_t afu_list_lock; 561 spinlock_t afu_list_lock;
497 struct cxl_afu *afu[CXL_MAX_SLICES]; 562 struct cxl_afu *afu[CXL_MAX_SLICES];
498 struct device dev; 563 struct device dev;
@@ -503,9 +568,6 @@ struct cxl {
503 struct bin_attribute cxl_attr; 568 struct bin_attribute cxl_attr;
504 int adapter_num; 569 int adapter_num;
505 int user_irqs; 570 int user_irqs;
506 u64 afu_desc_off;
507 u64 afu_desc_size;
508 u64 ps_off;
509 u64 ps_size; 571 u64 ps_size;
510 u16 psl_rev; 572 u16 psl_rev;
511 u16 base_image; 573 u16 base_image;
@@ -519,13 +581,15 @@ struct cxl {
519 bool perst_same_image; 581 bool perst_same_image;
520}; 582};
521 583
522int cxl_alloc_one_irq(struct cxl *adapter); 584int cxl_pci_alloc_one_irq(struct cxl *adapter);
523void cxl_release_one_irq(struct cxl *adapter, int hwirq); 585void cxl_pci_release_one_irq(struct cxl *adapter, int hwirq);
524int cxl_alloc_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter, unsigned int num); 586int cxl_pci_alloc_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter, unsigned int num);
525void cxl_release_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter); 587void cxl_pci_release_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter);
526int cxl_setup_irq(struct cxl *adapter, unsigned int hwirq, unsigned int virq); 588int cxl_pci_setup_irq(struct cxl *adapter, unsigned int hwirq, unsigned int virq);
527int cxl_update_image_control(struct cxl *adapter); 589int cxl_update_image_control(struct cxl *adapter);
528int cxl_reset(struct cxl *adapter); 590int cxl_pci_reset(struct cxl *adapter);
591void cxl_pci_release_afu(struct device *dev);
592ssize_t cxl_pci_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len);
529 593
530/* common == phyp + powernv */ 594/* common == phyp + powernv */
531struct cxl_process_element_common { 595struct cxl_process_element_common {
@@ -555,29 +619,32 @@ struct cxl_process_element {
555 __be32 software_state; 619 __be32 software_state;
556} __packed; 620} __packed;
557 621
558static inline bool cxl_adapter_link_ok(struct cxl *cxl) 622static inline bool cxl_adapter_link_ok(struct cxl *cxl, struct cxl_afu *afu)
559{ 623{
560 struct pci_dev *pdev; 624 struct pci_dev *pdev;
561 625
562 pdev = to_pci_dev(cxl->dev.parent); 626 if (cpu_has_feature(CPU_FTR_HVMODE)) {
563 return !pci_channel_offline(pdev); 627 pdev = to_pci_dev(cxl->dev.parent);
628 return !pci_channel_offline(pdev);
629 }
630 return true;
564} 631}
565 632
566static inline void __iomem *_cxl_p1_addr(struct cxl *cxl, cxl_p1_reg_t reg) 633static inline void __iomem *_cxl_p1_addr(struct cxl *cxl, cxl_p1_reg_t reg)
567{ 634{
568 WARN_ON(!cpu_has_feature(CPU_FTR_HVMODE)); 635 WARN_ON(!cpu_has_feature(CPU_FTR_HVMODE));
569 return cxl->p1_mmio + cxl_reg_off(reg); 636 return cxl->native->p1_mmio + cxl_reg_off(reg);
570} 637}
571 638
572static inline void cxl_p1_write(struct cxl *cxl, cxl_p1_reg_t reg, u64 val) 639static inline void cxl_p1_write(struct cxl *cxl, cxl_p1_reg_t reg, u64 val)
573{ 640{
574 if (likely(cxl_adapter_link_ok(cxl))) 641 if (likely(cxl_adapter_link_ok(cxl, NULL)))
575 out_be64(_cxl_p1_addr(cxl, reg), val); 642 out_be64(_cxl_p1_addr(cxl, reg), val);
576} 643}
577 644
578static inline u64 cxl_p1_read(struct cxl *cxl, cxl_p1_reg_t reg) 645static inline u64 cxl_p1_read(struct cxl *cxl, cxl_p1_reg_t reg)
579{ 646{
580 if (likely(cxl_adapter_link_ok(cxl))) 647 if (likely(cxl_adapter_link_ok(cxl, NULL)))
581 return in_be64(_cxl_p1_addr(cxl, reg)); 648 return in_be64(_cxl_p1_addr(cxl, reg));
582 else 649 else
583 return ~0ULL; 650 return ~0ULL;
@@ -586,18 +653,18 @@ static inline u64 cxl_p1_read(struct cxl *cxl, cxl_p1_reg_t reg)
586static inline void __iomem *_cxl_p1n_addr(struct cxl_afu *afu, cxl_p1n_reg_t reg) 653static inline void __iomem *_cxl_p1n_addr(struct cxl_afu *afu, cxl_p1n_reg_t reg)
587{ 654{
588 WARN_ON(!cpu_has_feature(CPU_FTR_HVMODE)); 655 WARN_ON(!cpu_has_feature(CPU_FTR_HVMODE));
589 return afu->p1n_mmio + cxl_reg_off(reg); 656 return afu->native->p1n_mmio + cxl_reg_off(reg);
590} 657}
591 658
592static inline void cxl_p1n_write(struct cxl_afu *afu, cxl_p1n_reg_t reg, u64 val) 659static inline void cxl_p1n_write(struct cxl_afu *afu, cxl_p1n_reg_t reg, u64 val)
593{ 660{
594 if (likely(cxl_adapter_link_ok(afu->adapter))) 661 if (likely(cxl_adapter_link_ok(afu->adapter, afu)))
595 out_be64(_cxl_p1n_addr(afu, reg), val); 662 out_be64(_cxl_p1n_addr(afu, reg), val);
596} 663}
597 664
598static inline u64 cxl_p1n_read(struct cxl_afu *afu, cxl_p1n_reg_t reg) 665static inline u64 cxl_p1n_read(struct cxl_afu *afu, cxl_p1n_reg_t reg)
599{ 666{
600 if (likely(cxl_adapter_link_ok(afu->adapter))) 667 if (likely(cxl_adapter_link_ok(afu->adapter, afu)))
601 return in_be64(_cxl_p1n_addr(afu, reg)); 668 return in_be64(_cxl_p1n_addr(afu, reg));
602 else 669 else
603 return ~0ULL; 670 return ~0ULL;
@@ -610,39 +677,19 @@ static inline void __iomem *_cxl_p2n_addr(struct cxl_afu *afu, cxl_p2n_reg_t reg
610 677
611static inline void cxl_p2n_write(struct cxl_afu *afu, cxl_p2n_reg_t reg, u64 val) 678static inline void cxl_p2n_write(struct cxl_afu *afu, cxl_p2n_reg_t reg, u64 val)
612{ 679{
613 if (likely(cxl_adapter_link_ok(afu->adapter))) 680 if (likely(cxl_adapter_link_ok(afu->adapter, afu)))
614 out_be64(_cxl_p2n_addr(afu, reg), val); 681 out_be64(_cxl_p2n_addr(afu, reg), val);
615} 682}
616 683
617static inline u64 cxl_p2n_read(struct cxl_afu *afu, cxl_p2n_reg_t reg) 684static inline u64 cxl_p2n_read(struct cxl_afu *afu, cxl_p2n_reg_t reg)
618{ 685{
619 if (likely(cxl_adapter_link_ok(afu->adapter))) 686 if (likely(cxl_adapter_link_ok(afu->adapter, afu)))
620 return in_be64(_cxl_p2n_addr(afu, reg)); 687 return in_be64(_cxl_p2n_addr(afu, reg));
621 else 688 else
622 return ~0ULL; 689 return ~0ULL;
623} 690}
624 691
625static inline u64 cxl_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off) 692ssize_t cxl_pci_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
626{
627 if (likely(cxl_adapter_link_ok(afu->adapter)))
628 return in_le64((afu)->afu_desc_mmio + (afu)->crs_offset +
629 ((cr) * (afu)->crs_len) + (off));
630 else
631 return ~0ULL;
632}
633
634static inline u32 cxl_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off)
635{
636 if (likely(cxl_adapter_link_ok(afu->adapter)))
637 return in_le32((afu)->afu_desc_mmio + (afu)->crs_offset +
638 ((cr) * (afu)->crs_len) + (off));
639 else
640 return 0xffffffff;
641}
642u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off);
643u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off);
644
645ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
646 loff_t off, size_t count); 693 loff_t off, size_t count);
647 694
648 695
@@ -652,13 +699,14 @@ struct cxl_calls {
652}; 699};
653int register_cxl_calls(struct cxl_calls *calls); 700int register_cxl_calls(struct cxl_calls *calls);
654void unregister_cxl_calls(struct cxl_calls *calls); 701void unregister_cxl_calls(struct cxl_calls *calls);
702int cxl_update_properties(struct device_node *dn, struct property *new_prop);
655 703
656int cxl_alloc_adapter_nr(struct cxl *adapter);
657void cxl_remove_adapter_nr(struct cxl *adapter); 704void cxl_remove_adapter_nr(struct cxl *adapter);
658 705
659int cxl_alloc_spa(struct cxl_afu *afu); 706int cxl_alloc_spa(struct cxl_afu *afu);
660void cxl_release_spa(struct cxl_afu *afu); 707void cxl_release_spa(struct cxl_afu *afu);
661 708
709dev_t cxl_get_dev(void);
662int cxl_file_init(void); 710int cxl_file_init(void);
663void cxl_file_exit(void); 711void cxl_file_exit(void);
664int cxl_register_adapter(struct cxl *adapter); 712int cxl_register_adapter(struct cxl *adapter);
@@ -679,21 +727,19 @@ void cxl_sysfs_afu_remove(struct cxl_afu *afu);
679int cxl_sysfs_afu_m_add(struct cxl_afu *afu); 727int cxl_sysfs_afu_m_add(struct cxl_afu *afu);
680void cxl_sysfs_afu_m_remove(struct cxl_afu *afu); 728void cxl_sysfs_afu_m_remove(struct cxl_afu *afu);
681 729
682int cxl_afu_activate_mode(struct cxl_afu *afu, int mode); 730struct cxl *cxl_alloc_adapter(void);
683int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode); 731struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice);
684int cxl_afu_deactivate_mode(struct cxl_afu *afu);
685int cxl_afu_select_best_mode(struct cxl_afu *afu); 732int cxl_afu_select_best_mode(struct cxl_afu *afu);
686 733
687int cxl_register_psl_irq(struct cxl_afu *afu); 734int cxl_native_register_psl_irq(struct cxl_afu *afu);
688void cxl_release_psl_irq(struct cxl_afu *afu); 735void cxl_native_release_psl_irq(struct cxl_afu *afu);
689int cxl_register_psl_err_irq(struct cxl *adapter); 736int cxl_native_register_psl_err_irq(struct cxl *adapter);
690void cxl_release_psl_err_irq(struct cxl *adapter); 737void cxl_native_release_psl_err_irq(struct cxl *adapter);
691int cxl_register_serr_irq(struct cxl_afu *afu); 738int cxl_native_register_serr_irq(struct cxl_afu *afu);
692void cxl_release_serr_irq(struct cxl_afu *afu); 739void cxl_native_release_serr_irq(struct cxl_afu *afu);
693int afu_register_irqs(struct cxl_context *ctx, u32 count); 740int afu_register_irqs(struct cxl_context *ctx, u32 count);
694void afu_release_irqs(struct cxl_context *ctx, void *cookie); 741void afu_release_irqs(struct cxl_context *ctx, void *cookie);
695void afu_irq_name_free(struct cxl_context *ctx); 742void afu_irq_name_free(struct cxl_context *ctx);
696irqreturn_t cxl_slice_irq_err(int irq, void *data);
697 743
698int cxl_debugfs_init(void); 744int cxl_debugfs_init(void);
699void cxl_debugfs_exit(void); 745void cxl_debugfs_exit(void);
@@ -707,6 +753,7 @@ void cxl_prefault(struct cxl_context *ctx, u64 wed);
707 753
708struct cxl *get_cxl_adapter(int num); 754struct cxl *get_cxl_adapter(int num);
709int cxl_alloc_sst(struct cxl_context *ctx); 755int cxl_alloc_sst(struct cxl_context *ctx);
756void cxl_dump_debug_buffer(void *addr, size_t size);
710 757
711void init_cxl_native(void); 758void init_cxl_native(void);
712 759
@@ -720,40 +767,54 @@ unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq,
720void cxl_unmap_irq(unsigned int virq, void *cookie); 767void cxl_unmap_irq(unsigned int virq, void *cookie);
721int __detach_context(struct cxl_context *ctx); 768int __detach_context(struct cxl_context *ctx);
722 769
723/* This matches the layout of the H_COLLECT_CA_INT_INFO retbuf */ 770/*
771 * This must match the layout of the H_COLLECT_CA_INT_INFO retbuf defined
772 * in PAPR.
773 * A word about endianness: a pointer to this structure is passed when
774 * calling the hcall. However, it is not a block of memory filled up by
775 * the hypervisor. The return values are found in registers, and copied
776 * one by one when returning from the hcall. See the end of the call to
777 * plpar_hcall9() in hvCall.S
778 * As a consequence:
779 * - we don't need to do any endianness conversion
780 * - the pid and tid are an exception. They are 32-bit values returned in
781 * the same 64-bit register. So we do need to worry about byte ordering.
782 */
724struct cxl_irq_info { 783struct cxl_irq_info {
725 u64 dsisr; 784 u64 dsisr;
726 u64 dar; 785 u64 dar;
727 u64 dsr; 786 u64 dsr;
787#ifndef CONFIG_CPU_LITTLE_ENDIAN
728 u32 pid; 788 u32 pid;
729 u32 tid; 789 u32 tid;
790#else
791 u32 tid;
792 u32 pid;
793#endif
730 u64 afu_err; 794 u64 afu_err;
731 u64 errstat; 795 u64 errstat;
732 u64 padding[3]; /* to match the expected retbuf size for plpar_hcall9 */ 796 u64 proc_handle;
797 u64 padding[2]; /* to match the expected retbuf size for plpar_hcall9 */
733}; 798};
734 799
735void cxl_assign_psn_space(struct cxl_context *ctx); 800void cxl_assign_psn_space(struct cxl_context *ctx);
736int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, 801irqreturn_t cxl_irq(int irq, struct cxl_context *ctx, struct cxl_irq_info *irq_info);
737 u64 amr); 802int cxl_register_one_irq(struct cxl *adapter, irq_handler_t handler,
738int cxl_detach_process(struct cxl_context *ctx); 803 void *cookie, irq_hw_number_t *dest_hwirq,
739 804 unsigned int *dest_virq, const char *name);
740int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info);
741int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask);
742 805
743int cxl_check_error(struct cxl_afu *afu); 806int cxl_check_error(struct cxl_afu *afu);
744int cxl_afu_slbia(struct cxl_afu *afu); 807int cxl_afu_slbia(struct cxl_afu *afu);
745int cxl_tlb_slb_invalidate(struct cxl *adapter); 808int cxl_tlb_slb_invalidate(struct cxl *adapter);
746int cxl_afu_disable(struct cxl_afu *afu); 809int cxl_afu_disable(struct cxl_afu *afu);
747int __cxl_afu_reset(struct cxl_afu *afu);
748int cxl_afu_check_and_enable(struct cxl_afu *afu);
749int cxl_psl_purge(struct cxl_afu *afu); 810int cxl_psl_purge(struct cxl_afu *afu);
750 811
751void cxl_stop_trace(struct cxl *cxl); 812void cxl_stop_trace(struct cxl *cxl);
752int cxl_pci_vphb_add(struct cxl_afu *afu); 813int cxl_pci_vphb_add(struct cxl_afu *afu);
753void cxl_pci_vphb_reconfigure(struct cxl_afu *afu);
754void cxl_pci_vphb_remove(struct cxl_afu *afu); 814void cxl_pci_vphb_remove(struct cxl_afu *afu);
755 815
756extern struct pci_driver cxl_pci_driver; 816extern struct pci_driver cxl_pci_driver;
817extern struct platform_driver cxl_of_driver;
757int afu_allocate_irqs(struct cxl_context *ctx, u32 count); 818int afu_allocate_irqs(struct cxl_context *ctx, u32 count);
758 819
759int afu_open(struct inode *inode, struct file *file); 820int afu_open(struct inode *inode, struct file *file);
@@ -764,4 +825,61 @@ unsigned int afu_poll(struct file *file, struct poll_table_struct *poll);
764ssize_t afu_read(struct file *file, char __user *buf, size_t count, loff_t *off); 825ssize_t afu_read(struct file *file, char __user *buf, size_t count, loff_t *off);
765extern const struct file_operations afu_fops; 826extern const struct file_operations afu_fops;
766 827
828struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_device *dev);
829void cxl_guest_remove_adapter(struct cxl *adapter);
830int cxl_of_read_adapter_handle(struct cxl *adapter, struct device_node *np);
831int cxl_of_read_adapter_properties(struct cxl *adapter, struct device_node *np);
832ssize_t cxl_guest_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len);
833ssize_t cxl_guest_read_afu_vpd(struct cxl_afu *afu, void *buf, size_t len);
834int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_np);
835void cxl_guest_remove_afu(struct cxl_afu *afu);
836int cxl_of_read_afu_handle(struct cxl_afu *afu, struct device_node *afu_np);
837int cxl_of_read_afu_properties(struct cxl_afu *afu, struct device_node *afu_np);
838int cxl_guest_add_chardev(struct cxl *adapter);
839void cxl_guest_remove_chardev(struct cxl *adapter);
840void cxl_guest_reload_module(struct cxl *adapter);
841int cxl_of_probe(struct platform_device *pdev);
842
843struct cxl_backend_ops {
844 struct module *module;
845 int (*adapter_reset)(struct cxl *adapter);
846 int (*alloc_one_irq)(struct cxl *adapter);
847 void (*release_one_irq)(struct cxl *adapter, int hwirq);
848 int (*alloc_irq_ranges)(struct cxl_irq_ranges *irqs,
849 struct cxl *adapter, unsigned int num);
850 void (*release_irq_ranges)(struct cxl_irq_ranges *irqs,
851 struct cxl *adapter);
852 int (*setup_irq)(struct cxl *adapter, unsigned int hwirq,
853 unsigned int virq);
854 irqreturn_t (*handle_psl_slice_error)(struct cxl_context *ctx,
855 u64 dsisr, u64 errstat);
856 irqreturn_t (*psl_interrupt)(int irq, void *data);
857 int (*ack_irq)(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask);
858 int (*attach_process)(struct cxl_context *ctx, bool kernel,
859 u64 wed, u64 amr);
860 int (*detach_process)(struct cxl_context *ctx);
861 bool (*support_attributes)(const char *attr_name, enum cxl_attrs type);
862 bool (*link_ok)(struct cxl *cxl, struct cxl_afu *afu);
863 void (*release_afu)(struct device *dev);
864 ssize_t (*afu_read_err_buffer)(struct cxl_afu *afu, char *buf,
865 loff_t off, size_t count);
866 int (*afu_check_and_enable)(struct cxl_afu *afu);
867 int (*afu_activate_mode)(struct cxl_afu *afu, int mode);
868 int (*afu_deactivate_mode)(struct cxl_afu *afu, int mode);
869 int (*afu_reset)(struct cxl_afu *afu);
870 int (*afu_cr_read8)(struct cxl_afu *afu, int cr_idx, u64 offset, u8 *val);
871 int (*afu_cr_read16)(struct cxl_afu *afu, int cr_idx, u64 offset, u16 *val);
872 int (*afu_cr_read32)(struct cxl_afu *afu, int cr_idx, u64 offset, u32 *val);
873 int (*afu_cr_read64)(struct cxl_afu *afu, int cr_idx, u64 offset, u64 *val);
874 int (*afu_cr_write8)(struct cxl_afu *afu, int cr_idx, u64 offset, u8 val);
875 int (*afu_cr_write16)(struct cxl_afu *afu, int cr_idx, u64 offset, u16 val);
876 int (*afu_cr_write32)(struct cxl_afu *afu, int cr_idx, u64 offset, u32 val);
877 ssize_t (*read_adapter_vpd)(struct cxl *adapter, void *buf, size_t count);
878};
879extern const struct cxl_backend_ops cxl_native_ops;
880extern const struct cxl_backend_ops cxl_guest_ops;
881extern const struct cxl_backend_ops *cxl_ops;
882
883/* check if the given pci_dev is on the the cxl vphb bus */
884bool cxl_pci_is_vphb_device(struct pci_dev *dev);
767#endif 885#endif
diff --git a/drivers/misc/cxl/debugfs.c b/drivers/misc/cxl/debugfs.c
index 18df6f44af2a..5751899e0c17 100644
--- a/drivers/misc/cxl/debugfs.c
+++ b/drivers/misc/cxl/debugfs.c
@@ -118,6 +118,10 @@ void cxl_debugfs_afu_remove(struct cxl_afu *afu)
118int __init cxl_debugfs_init(void) 118int __init cxl_debugfs_init(void)
119{ 119{
120 struct dentry *ent; 120 struct dentry *ent;
121
122 if (!cpu_has_feature(CPU_FTR_HVMODE))
123 return 0;
124
121 ent = debugfs_create_dir("cxl", NULL); 125 ent = debugfs_create_dir("cxl", NULL);
122 if (IS_ERR(ent)) 126 if (IS_ERR(ent))
123 return PTR_ERR(ent); 127 return PTR_ERR(ent);
diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c
index 81c3f75b7330..9a8650bcb042 100644
--- a/drivers/misc/cxl/fault.c
+++ b/drivers/misc/cxl/fault.c
@@ -101,7 +101,7 @@ static void cxl_ack_ae(struct cxl_context *ctx)
101{ 101{
102 unsigned long flags; 102 unsigned long flags;
103 103
104 cxl_ack_irq(ctx, CXL_PSL_TFC_An_AE, 0); 104 cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_AE, 0);
105 105
106 spin_lock_irqsave(&ctx->lock, flags); 106 spin_lock_irqsave(&ctx->lock, flags);
107 ctx->pending_fault = true; 107 ctx->pending_fault = true;
@@ -125,7 +125,7 @@ static int cxl_handle_segment_miss(struct cxl_context *ctx,
125 else { 125 else {
126 126
127 mb(); /* Order seg table write to TFC MMIO write */ 127 mb(); /* Order seg table write to TFC MMIO write */
128 cxl_ack_irq(ctx, CXL_PSL_TFC_An_R, 0); 128 cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
129 } 129 }
130 130
131 return IRQ_HANDLED; 131 return IRQ_HANDLED;
@@ -163,7 +163,7 @@ static void cxl_handle_page_fault(struct cxl_context *ctx,
163 local_irq_restore(flags); 163 local_irq_restore(flags);
164 164
165 pr_devel("Page fault successfully handled for pe: %i!\n", ctx->pe); 165 pr_devel("Page fault successfully handled for pe: %i!\n", ctx->pe);
166 cxl_ack_irq(ctx, CXL_PSL_TFC_An_R, 0); 166 cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
167} 167}
168 168
169/* 169/*
@@ -254,14 +254,17 @@ void cxl_handle_fault(struct work_struct *fault_work)
254 u64 dar = ctx->dar; 254 u64 dar = ctx->dar;
255 struct mm_struct *mm = NULL; 255 struct mm_struct *mm = NULL;
256 256
257 if (cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An) != dsisr || 257 if (cpu_has_feature(CPU_FTR_HVMODE)) {
258 cxl_p2n_read(ctx->afu, CXL_PSL_DAR_An) != dar || 258 if (cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An) != dsisr ||
259 cxl_p2n_read(ctx->afu, CXL_PSL_PEHandle_An) != ctx->pe) { 259 cxl_p2n_read(ctx->afu, CXL_PSL_DAR_An) != dar ||
260 /* Most likely explanation is harmless - a dedicated process 260 cxl_p2n_read(ctx->afu, CXL_PSL_PEHandle_An) != ctx->pe) {
261 * has detached and these were cleared by the PSL purge, but 261 /* Most likely explanation is harmless - a dedicated
262 * warn about it just in case */ 262 * process has detached and these were cleared by the
263 dev_notice(&ctx->afu->dev, "cxl_handle_fault: Translation fault regs changed\n"); 263 * PSL purge, but warn about it just in case
264 return; 264 */
265 dev_notice(&ctx->afu->dev, "cxl_handle_fault: Translation fault regs changed\n");
266 return;
267 }
265 } 268 }
266 269
267 /* Early return if the context is being / has been detached */ 270 /* Early return if the context is being / has been detached */
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
index 783337d22f36..eec468f1612f 100644
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -26,9 +26,7 @@
26#include "trace.h" 26#include "trace.h"
27 27
28#define CXL_NUM_MINORS 256 /* Total to reserve */ 28#define CXL_NUM_MINORS 256 /* Total to reserve */
29#define CXL_DEV_MINORS 13 /* 1 control + 4 AFUs * 3 (dedicated/master/shared) */
30 29
31#define CXL_CARD_MINOR(adapter) (adapter->adapter_num * CXL_DEV_MINORS)
32#define CXL_AFU_MINOR_D(afu) (CXL_CARD_MINOR(afu->adapter) + 1 + (3 * afu->slice)) 30#define CXL_AFU_MINOR_D(afu) (CXL_CARD_MINOR(afu->adapter) + 1 + (3 * afu->slice))
33#define CXL_AFU_MINOR_M(afu) (CXL_AFU_MINOR_D(afu) + 1) 31#define CXL_AFU_MINOR_M(afu) (CXL_AFU_MINOR_D(afu) + 1)
34#define CXL_AFU_MINOR_S(afu) (CXL_AFU_MINOR_D(afu) + 2) 32#define CXL_AFU_MINOR_S(afu) (CXL_AFU_MINOR_D(afu) + 2)
@@ -36,7 +34,6 @@
36#define CXL_AFU_MKDEV_M(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_M(afu)) 34#define CXL_AFU_MKDEV_M(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_M(afu))
37#define CXL_AFU_MKDEV_S(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_S(afu)) 35#define CXL_AFU_MKDEV_S(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_S(afu))
38 36
39#define CXL_DEVT_ADAPTER(dev) (MINOR(dev) / CXL_DEV_MINORS)
40#define CXL_DEVT_AFU(dev) ((MINOR(dev) % CXL_DEV_MINORS - 1) / 3) 37#define CXL_DEVT_AFU(dev) ((MINOR(dev) % CXL_DEV_MINORS - 1) / 3)
41 38
42#define CXL_DEVT_IS_CARD(dev) (MINOR(dev) % CXL_DEV_MINORS == 0) 39#define CXL_DEVT_IS_CARD(dev) (MINOR(dev) % CXL_DEV_MINORS == 0)
@@ -79,7 +76,7 @@ static int __afu_open(struct inode *inode, struct file *file, bool master)
79 if (!afu->current_mode) 76 if (!afu->current_mode)
80 goto err_put_afu; 77 goto err_put_afu;
81 78
82 if (!cxl_adapter_link_ok(adapter)) { 79 if (!cxl_ops->link_ok(adapter, afu)) {
83 rc = -EIO; 80 rc = -EIO;
84 goto err_put_afu; 81 goto err_put_afu;
85 } 82 }
@@ -210,8 +207,8 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
210 207
211 trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr); 208 trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);
212 209
213 if ((rc = cxl_attach_process(ctx, false, work.work_element_descriptor, 210 if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor,
214 amr))) { 211 amr))) {
215 afu_release_irqs(ctx, ctx); 212 afu_release_irqs(ctx, ctx);
216 goto out; 213 goto out;
217 } 214 }
@@ -222,12 +219,13 @@ out:
222 mutex_unlock(&ctx->status_mutex); 219 mutex_unlock(&ctx->status_mutex);
223 return rc; 220 return rc;
224} 221}
222
225static long afu_ioctl_process_element(struct cxl_context *ctx, 223static long afu_ioctl_process_element(struct cxl_context *ctx,
226 int __user *upe) 224 int __user *upe)
227{ 225{
228 pr_devel("%s: pe: %i\n", __func__, ctx->pe); 226 pr_devel("%s: pe: %i\n", __func__, ctx->pe);
229 227
230 if (copy_to_user(upe, &ctx->pe, sizeof(__u32))) 228 if (copy_to_user(upe, &ctx->external_pe, sizeof(__u32)))
231 return -EFAULT; 229 return -EFAULT;
232 230
233 return 0; 231 return 0;
@@ -259,7 +257,7 @@ long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
259 if (ctx->status == CLOSED) 257 if (ctx->status == CLOSED)
260 return -EIO; 258 return -EIO;
261 259
262 if (!cxl_adapter_link_ok(ctx->afu->adapter)) 260 if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
263 return -EIO; 261 return -EIO;
264 262
265 pr_devel("afu_ioctl\n"); 263 pr_devel("afu_ioctl\n");
@@ -289,7 +287,7 @@ int afu_mmap(struct file *file, struct vm_area_struct *vm)
289 if (ctx->status != STARTED) 287 if (ctx->status != STARTED)
290 return -EIO; 288 return -EIO;
291 289
292 if (!cxl_adapter_link_ok(ctx->afu->adapter)) 290 if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
293 return -EIO; 291 return -EIO;
294 292
295 return cxl_context_iomap(ctx, vm); 293 return cxl_context_iomap(ctx, vm);
@@ -336,7 +334,7 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count,
336 int rc; 334 int rc;
337 DEFINE_WAIT(wait); 335 DEFINE_WAIT(wait);
338 336
339 if (!cxl_adapter_link_ok(ctx->afu->adapter)) 337 if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
340 return -EIO; 338 return -EIO;
341 339
342 if (count < CXL_READ_MIN_SIZE) 340 if (count < CXL_READ_MIN_SIZE)
@@ -349,7 +347,7 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count,
349 if (ctx_event_pending(ctx)) 347 if (ctx_event_pending(ctx))
350 break; 348 break;
351 349
352 if (!cxl_adapter_link_ok(ctx->afu->adapter)) { 350 if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) {
353 rc = -EIO; 351 rc = -EIO;
354 goto out; 352 goto out;
355 } 353 }
@@ -445,7 +443,8 @@ static const struct file_operations afu_master_fops = {
445 443
446static char *cxl_devnode(struct device *dev, umode_t *mode) 444static char *cxl_devnode(struct device *dev, umode_t *mode)
447{ 445{
448 if (CXL_DEVT_IS_CARD(dev->devt)) { 446 if (cpu_has_feature(CPU_FTR_HVMODE) &&
447 CXL_DEVT_IS_CARD(dev->devt)) {
449 /* 448 /*
450 * These minor numbers will eventually be used to program the 449 * These minor numbers will eventually be used to program the
451 * PSL and AFUs once we have dynamic reprogramming support 450 * PSL and AFUs once we have dynamic reprogramming support
@@ -546,6 +545,11 @@ int cxl_register_adapter(struct cxl *adapter)
546 return device_register(&adapter->dev); 545 return device_register(&adapter->dev);
547} 546}
548 547
548dev_t cxl_get_dev(void)
549{
550 return cxl_dev;
551}
552
549int __init cxl_file_init(void) 553int __init cxl_file_init(void)
550{ 554{
551 int rc; 555 int rc;
diff --git a/drivers/misc/cxl/flash.c b/drivers/misc/cxl/flash.c
new file mode 100644
index 000000000000..68dd0b7da471
--- /dev/null
+++ b/drivers/misc/cxl/flash.c
@@ -0,0 +1,538 @@
1#include <linux/kernel.h>
2#include <linux/fs.h>
3#include <linux/semaphore.h>
4#include <linux/slab.h>
5#include <linux/uaccess.h>
6#include <asm/rtas.h>
7
8#include "cxl.h"
9#include "hcalls.h"
10
11#define DOWNLOAD_IMAGE 1
12#define VALIDATE_IMAGE 2
13
14struct ai_header {
15 u16 version;
16 u8 reserved0[6];
17 u16 vendor;
18 u16 device;
19 u16 subsystem_vendor;
20 u16 subsystem;
21 u64 image_offset;
22 u64 image_length;
23 u8 reserved1[96];
24};
25
26static struct semaphore sem;
27unsigned long *buffer[CXL_AI_MAX_ENTRIES];
28struct sg_list *le;
29static u64 continue_token;
30static unsigned int transfer;
31
32struct update_props_workarea {
33 __be32 phandle;
34 __be32 state;
35 __be64 reserved;
36 __be32 nprops;
37} __packed;
38
39struct update_nodes_workarea {
40 __be32 state;
41 __be64 unit_address;
42 __be32 reserved;
43} __packed;
44
45#define DEVICE_SCOPE 3
46#define NODE_ACTION_MASK 0xff000000
47#define NODE_COUNT_MASK 0x00ffffff
48#define OPCODE_DELETE 0x01000000
49#define OPCODE_UPDATE 0x02000000
50#define OPCODE_ADD 0x03000000
51
52static int rcall(int token, char *buf, s32 scope)
53{
54 int rc;
55
56 spin_lock(&rtas_data_buf_lock);
57
58 memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE);
59 rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, scope);
60 memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE);
61
62 spin_unlock(&rtas_data_buf_lock);
63 return rc;
64}
65
66static int update_property(struct device_node *dn, const char *name,
67 u32 vd, char *value)
68{
69 struct property *new_prop;
70 u32 *val;
71 int rc;
72
73 new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
74 if (!new_prop)
75 return -ENOMEM;
76
77 new_prop->name = kstrdup(name, GFP_KERNEL);
78 if (!new_prop->name) {
79 kfree(new_prop);
80 return -ENOMEM;
81 }
82
83 new_prop->length = vd;
84 new_prop->value = kzalloc(new_prop->length, GFP_KERNEL);
85 if (!new_prop->value) {
86 kfree(new_prop->name);
87 kfree(new_prop);
88 return -ENOMEM;
89 }
90 memcpy(new_prop->value, value, vd);
91
92 val = (u32 *)new_prop->value;
93 rc = cxl_update_properties(dn, new_prop);
94 pr_devel("%s: update property (%s, length: %i, value: %#x)\n",
95 dn->name, name, vd, be32_to_cpu(*val));
96
97 if (rc) {
98 kfree(new_prop->name);
99 kfree(new_prop->value);
100 kfree(new_prop);
101 }
102 return rc;
103}
104
105static int update_node(__be32 phandle, s32 scope)
106{
107 struct update_props_workarea *upwa;
108 struct device_node *dn;
109 int i, rc, ret;
110 char *prop_data;
111 char *buf;
112 int token;
113 u32 nprops;
114 u32 vd;
115
116 token = rtas_token("ibm,update-properties");
117 if (token == RTAS_UNKNOWN_SERVICE)
118 return -EINVAL;
119
120 buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
121 if (!buf)
122 return -ENOMEM;
123
124 dn = of_find_node_by_phandle(be32_to_cpu(phandle));
125 if (!dn) {
126 kfree(buf);
127 return -ENOENT;
128 }
129
130 upwa = (struct update_props_workarea *)&buf[0];
131 upwa->phandle = phandle;
132 do {
133 rc = rcall(token, buf, scope);
134 if (rc < 0)
135 break;
136
137 prop_data = buf + sizeof(*upwa);
138 nprops = be32_to_cpu(upwa->nprops);
139
140 if (*prop_data == 0) {
141 prop_data++;
142 vd = be32_to_cpu(*(__be32 *)prop_data);
143 prop_data += vd + sizeof(vd);
144 nprops--;
145 }
146
147 for (i = 0; i < nprops; i++) {
148 char *prop_name;
149
150 prop_name = prop_data;
151 prop_data += strlen(prop_name) + 1;
152 vd = be32_to_cpu(*(__be32 *)prop_data);
153 prop_data += sizeof(vd);
154
155 if ((vd != 0x00000000) && (vd != 0x80000000)) {
156 ret = update_property(dn, prop_name, vd,
157 prop_data);
158 if (ret)
159 pr_err("cxl: Could not update property %s - %i\n",
160 prop_name, ret);
161
162 prop_data += vd;
163 }
164 }
165 } while (rc == 1);
166
167 of_node_put(dn);
168 kfree(buf);
169 return rc;
170}
171
172static int update_devicetree(struct cxl *adapter, s32 scope)
173{
174 struct update_nodes_workarea *unwa;
175 u32 action, node_count;
176 int token, rc, i;
177 __be32 *data, drc_index, phandle;
178 char *buf;
179
180 token = rtas_token("ibm,update-nodes");
181 if (token == RTAS_UNKNOWN_SERVICE)
182 return -EINVAL;
183
184 buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
185 if (!buf)
186 return -ENOMEM;
187
188 unwa = (struct update_nodes_workarea *)&buf[0];
189 unwa->unit_address = cpu_to_be64(adapter->guest->handle);
190 do {
191 rc = rcall(token, buf, scope);
192 if (rc && rc != 1)
193 break;
194
195 data = (__be32 *)buf + 4;
196 while (be32_to_cpu(*data) & NODE_ACTION_MASK) {
197 action = be32_to_cpu(*data) & NODE_ACTION_MASK;
198 node_count = be32_to_cpu(*data) & NODE_COUNT_MASK;
199 pr_devel("device reconfiguration - action: %#x, nodes: %#x\n",
200 action, node_count);
201 data++;
202
203 for (i = 0; i < node_count; i++) {
204 phandle = *data++;
205
206 switch (action) {
207 case OPCODE_DELETE:
208 /* nothing to do */
209 break;
210 case OPCODE_UPDATE:
211 update_node(phandle, scope);
212 break;
213 case OPCODE_ADD:
214 /* nothing to do, just move pointer */
215 drc_index = *data++;
216 break;
217 }
218 }
219 }
220 } while (rc == 1);
221
222 kfree(buf);
223 return 0;
224}
225
226static int handle_image(struct cxl *adapter, int operation,
227 long (*fct)(u64, u64, u64, u64 *),
228 struct cxl_adapter_image *ai)
229{
230 size_t mod, s_copy, len_chunk = 0;
231 struct ai_header *header = NULL;
232 unsigned int entries = 0, i;
233 void *dest, *from;
234 int rc = 0, need_header;
235
236 /* base adapter image header */
237 need_header = (ai->flags & CXL_AI_NEED_HEADER);
238 if (need_header) {
239 header = kzalloc(sizeof(struct ai_header), GFP_KERNEL);
240 if (!header)
241 return -ENOMEM;
242 header->version = cpu_to_be16(1);
243 header->vendor = cpu_to_be16(adapter->guest->vendor);
244 header->device = cpu_to_be16(adapter->guest->device);
245 header->subsystem_vendor = cpu_to_be16(adapter->guest->subsystem_vendor);
246 header->subsystem = cpu_to_be16(adapter->guest->subsystem);
247 header->image_offset = cpu_to_be64(CXL_AI_HEADER_SIZE);
248 header->image_length = cpu_to_be64(ai->len_image);
249 }
250
251 /* number of entries in the list */
252 len_chunk = ai->len_data;
253 if (need_header)
254 len_chunk += CXL_AI_HEADER_SIZE;
255
256 entries = len_chunk / CXL_AI_BUFFER_SIZE;
257 mod = len_chunk % CXL_AI_BUFFER_SIZE;
258 if (mod)
259 entries++;
260
261 if (entries > CXL_AI_MAX_ENTRIES) {
262 rc = -EINVAL;
263 goto err;
264 }
265
266 /* < -- MAX_CHUNK_SIZE = 4096 * 256 = 1048576 bytes -->
267 * chunk 0 ----------------------------------------------------
268 * | header | data |
269 * ----------------------------------------------------
270 * chunk 1 ----------------------------------------------------
271 * | data |
272 * ----------------------------------------------------
273 * ....
274 * chunk n ----------------------------------------------------
275 * | data |
276 * ----------------------------------------------------
277 */
278 from = (void *) ai->data;
279 for (i = 0; i < entries; i++) {
280 dest = buffer[i];
281 s_copy = CXL_AI_BUFFER_SIZE;
282
283 if ((need_header) && (i == 0)) {
284 /* add adapter image header */
285 memcpy(buffer[i], header, sizeof(struct ai_header));
286 s_copy = CXL_AI_BUFFER_SIZE - CXL_AI_HEADER_SIZE;
287 dest += CXL_AI_HEADER_SIZE; /* image offset */
288 }
289 if ((i == (entries - 1)) && mod)
290 s_copy = mod;
291
292 /* copy data */
293 if (copy_from_user(dest, from, s_copy))
294 goto err;
295
296 /* fill in the list */
297 le[i].phys_addr = cpu_to_be64(virt_to_phys(buffer[i]));
298 le[i].len = cpu_to_be64(CXL_AI_BUFFER_SIZE);
299 if ((i == (entries - 1)) && mod)
300 le[i].len = cpu_to_be64(mod);
301 from += s_copy;
302 }
303 pr_devel("%s (op: %i, need header: %i, entries: %i, token: %#llx)\n",
304 __func__, operation, need_header, entries, continue_token);
305
306 /*
307 * download/validate the adapter image to the coherent
308 * platform facility
309 */
310 rc = fct(adapter->guest->handle, virt_to_phys(le), entries,
311 &continue_token);
312 if (rc == 0) /* success of download/validation operation */
313 continue_token = 0;
314
315err:
316 kfree(header);
317
318 return rc;
319}
320
321static int transfer_image(struct cxl *adapter, int operation,
322 struct cxl_adapter_image *ai)
323{
324 int rc = 0;
325 int afu;
326
327 switch (operation) {
328 case DOWNLOAD_IMAGE:
329 rc = handle_image(adapter, operation,
330 &cxl_h_download_adapter_image, ai);
331 if (rc < 0) {
332 pr_devel("resetting adapter\n");
333 cxl_h_reset_adapter(adapter->guest->handle);
334 }
335 return rc;
336
337 case VALIDATE_IMAGE:
338 rc = handle_image(adapter, operation,
339 &cxl_h_validate_adapter_image, ai);
340 if (rc < 0) {
341 pr_devel("resetting adapter\n");
342 cxl_h_reset_adapter(adapter->guest->handle);
343 return rc;
344 }
345 if (rc == 0) {
346 pr_devel("remove curent afu\n");
347 for (afu = 0; afu < adapter->slices; afu++)
348 cxl_guest_remove_afu(adapter->afu[afu]);
349
350 pr_devel("resetting adapter\n");
351 cxl_h_reset_adapter(adapter->guest->handle);
352
353 /* The entire image has now been
354 * downloaded and the validation has
355 * been successfully performed.
356 * After that, the partition should call
357 * ibm,update-nodes and
358 * ibm,update-properties to receive the
359 * current configuration
360 */
361 rc = update_devicetree(adapter, DEVICE_SCOPE);
362 transfer = 1;
363 }
364 return rc;
365 }
366
367 return -EINVAL;
368}
369
370static long ioctl_transfer_image(struct cxl *adapter, int operation,
371 struct cxl_adapter_image __user *uai)
372{
373 struct cxl_adapter_image ai;
374
375 pr_devel("%s\n", __func__);
376
377 if (copy_from_user(&ai, uai, sizeof(struct cxl_adapter_image)))
378 return -EFAULT;
379
380 /*
381 * Make sure reserved fields and bits are set to 0
382 */
383 if (ai.reserved1 || ai.reserved2 || ai.reserved3 || ai.reserved4 ||
384 (ai.flags & ~CXL_AI_ALL))
385 return -EINVAL;
386
387 return transfer_image(adapter, operation, &ai);
388}
389
390static int device_open(struct inode *inode, struct file *file)
391{
392 int adapter_num = CXL_DEVT_ADAPTER(inode->i_rdev);
393 struct cxl *adapter;
394 int rc = 0, i;
395
396 pr_devel("in %s\n", __func__);
397
398 BUG_ON(sizeof(struct ai_header) != CXL_AI_HEADER_SIZE);
399
400 /* Allows one process to open the device by using a semaphore */
401 if (down_interruptible(&sem) != 0)
402 return -EPERM;
403
404 if (!(adapter = get_cxl_adapter(adapter_num)))
405 return -ENODEV;
406
407 file->private_data = adapter;
408 continue_token = 0;
409 transfer = 0;
410
411 for (i = 0; i < CXL_AI_MAX_ENTRIES; i++)
412 buffer[i] = NULL;
413
414 /* aligned buffer containing list entries which describes up to
415 * 1 megabyte of data (256 entries of 4096 bytes each)
416 * Logical real address of buffer 0 - Buffer 0 length in bytes
417 * Logical real address of buffer 1 - Buffer 1 length in bytes
418 * Logical real address of buffer 2 - Buffer 2 length in bytes
419 * ....
420 * ....
421 * Logical real address of buffer N - Buffer N length in bytes
422 */
423 le = (struct sg_list *)get_zeroed_page(GFP_KERNEL);
424 if (!le) {
425 rc = -ENOMEM;
426 goto err;
427 }
428
429 for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) {
430 buffer[i] = (unsigned long *)get_zeroed_page(GFP_KERNEL);
431 if (!buffer[i]) {
432 rc = -ENOMEM;
433 goto err1;
434 }
435 }
436
437 return 0;
438
439err1:
440 for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) {
441 if (buffer[i])
442 free_page((unsigned long) buffer[i]);
443 }
444
445 if (le)
446 free_page((unsigned long) le);
447err:
448 put_device(&adapter->dev);
449
450 return rc;
451}
452
453static long device_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
454{
455 struct cxl *adapter = file->private_data;
456
457 pr_devel("in %s\n", __func__);
458
459 if (cmd == CXL_IOCTL_DOWNLOAD_IMAGE)
460 return ioctl_transfer_image(adapter,
461 DOWNLOAD_IMAGE,
462 (struct cxl_adapter_image __user *)arg);
463 else if (cmd == CXL_IOCTL_VALIDATE_IMAGE)
464 return ioctl_transfer_image(adapter,
465 VALIDATE_IMAGE,
466 (struct cxl_adapter_image __user *)arg);
467 else
468 return -EINVAL;
469}
470
471static long device_compat_ioctl(struct file *file, unsigned int cmd,
472 unsigned long arg)
473{
474 return device_ioctl(file, cmd, arg);
475}
476
477static int device_close(struct inode *inode, struct file *file)
478{
479 struct cxl *adapter = file->private_data;
480 int i;
481
482 pr_devel("in %s\n", __func__);
483
484 for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) {
485 if (buffer[i])
486 free_page((unsigned long) buffer[i]);
487 }
488
489 if (le)
490 free_page((unsigned long) le);
491
492 up(&sem);
493 put_device(&adapter->dev);
494 continue_token = 0;
495
496 /* reload the module */
497 if (transfer)
498 cxl_guest_reload_module(adapter);
499 else {
500 pr_devel("resetting adapter\n");
501 cxl_h_reset_adapter(adapter->guest->handle);
502 }
503
504 transfer = 0;
505 return 0;
506}
507
508static const struct file_operations fops = {
509 .owner = THIS_MODULE,
510 .open = device_open,
511 .unlocked_ioctl = device_ioctl,
512 .compat_ioctl = device_compat_ioctl,
513 .release = device_close,
514};
515
516void cxl_guest_remove_chardev(struct cxl *adapter)
517{
518 cdev_del(&adapter->guest->cdev);
519}
520
521int cxl_guest_add_chardev(struct cxl *adapter)
522{
523 dev_t devt;
524 int rc;
525
526 devt = MKDEV(MAJOR(cxl_get_dev()), CXL_CARD_MINOR(adapter));
527 cdev_init(&adapter->guest->cdev, &fops);
528 if ((rc = cdev_add(&adapter->guest->cdev, devt, 1))) {
529 dev_err(&adapter->dev,
530 "Unable to add chardev on adapter (card%i): %i\n",
531 adapter->adapter_num, rc);
532 goto err;
533 }
534 adapter->dev.devt = devt;
535 sema_init(&sem, 1);
536err:
537 return rc;
538}
diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c
new file mode 100644
index 000000000000..8213372de2b7
--- /dev/null
+++ b/drivers/misc/cxl/guest.c
@@ -0,0 +1,1177 @@
1/*
2 * Copyright 2015 IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#include <linux/spinlock.h>
11#include <linux/uaccess.h>
12#include <linux/delay.h>
13
14#include "cxl.h"
15#include "hcalls.h"
16#include "trace.h"
17
18#define CXL_ERROR_DETECTED_EVENT 1
19#define CXL_SLOT_RESET_EVENT 2
20#define CXL_RESUME_EVENT 3
21
22static void pci_error_handlers(struct cxl_afu *afu,
23 int bus_error_event,
24 pci_channel_state_t state)
25{
26 struct pci_dev *afu_dev;
27
28 if (afu->phb == NULL)
29 return;
30
31 list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
32 if (!afu_dev->driver)
33 continue;
34
35 switch (bus_error_event) {
36 case CXL_ERROR_DETECTED_EVENT:
37 afu_dev->error_state = state;
38
39 if (afu_dev->driver->err_handler &&
40 afu_dev->driver->err_handler->error_detected)
41 afu_dev->driver->err_handler->error_detected(afu_dev, state);
42 break;
43 case CXL_SLOT_RESET_EVENT:
44 afu_dev->error_state = state;
45
46 if (afu_dev->driver->err_handler &&
47 afu_dev->driver->err_handler->slot_reset)
48 afu_dev->driver->err_handler->slot_reset(afu_dev);
49 break;
50 case CXL_RESUME_EVENT:
51 if (afu_dev->driver->err_handler &&
52 afu_dev->driver->err_handler->resume)
53 afu_dev->driver->err_handler->resume(afu_dev);
54 break;
55 }
56 }
57}
58
59static irqreturn_t guest_handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr,
60 u64 errstat)
61{
62 pr_devel("in %s\n", __func__);
63 dev_crit(&ctx->afu->dev, "PSL ERROR STATUS: 0x%.16llx\n", errstat);
64
65 return cxl_ops->ack_irq(ctx, 0, errstat);
66}
67
68static ssize_t guest_collect_vpd(struct cxl *adapter, struct cxl_afu *afu,
69 void *buf, size_t len)
70{
71 unsigned int entries, mod;
72 unsigned long **vpd_buf = NULL;
73 struct sg_list *le;
74 int rc = 0, i, tocopy;
75 u64 out = 0;
76
77 if (buf == NULL)
78 return -EINVAL;
79
80 /* number of entries in the list */
81 entries = len / SG_BUFFER_SIZE;
82 mod = len % SG_BUFFER_SIZE;
83 if (mod)
84 entries++;
85
86 if (entries > SG_MAX_ENTRIES) {
87 entries = SG_MAX_ENTRIES;
88 len = SG_MAX_ENTRIES * SG_BUFFER_SIZE;
89 mod = 0;
90 }
91
92 vpd_buf = kzalloc(entries * sizeof(unsigned long *), GFP_KERNEL);
93 if (!vpd_buf)
94 return -ENOMEM;
95
96 le = (struct sg_list *)get_zeroed_page(GFP_KERNEL);
97 if (!le) {
98 rc = -ENOMEM;
99 goto err1;
100 }
101
102 for (i = 0; i < entries; i++) {
103 vpd_buf[i] = (unsigned long *)get_zeroed_page(GFP_KERNEL);
104 if (!vpd_buf[i]) {
105 rc = -ENOMEM;
106 goto err2;
107 }
108 le[i].phys_addr = cpu_to_be64(virt_to_phys(vpd_buf[i]));
109 le[i].len = cpu_to_be64(SG_BUFFER_SIZE);
110 if ((i == (entries - 1)) && mod)
111 le[i].len = cpu_to_be64(mod);
112 }
113
114 if (adapter)
115 rc = cxl_h_collect_vpd_adapter(adapter->guest->handle,
116 virt_to_phys(le), entries, &out);
117 else
118 rc = cxl_h_collect_vpd(afu->guest->handle, 0,
119 virt_to_phys(le), entries, &out);
120 pr_devel("length of available (entries: %i), vpd: %#llx\n",
121 entries, out);
122
123 if (!rc) {
124 /*
125 * hcall returns in 'out' the size of available VPDs.
126 * It fills the buffer with as much data as possible.
127 */
128 if (out < len)
129 len = out;
130 rc = len;
131 if (out) {
132 for (i = 0; i < entries; i++) {
133 if (len < SG_BUFFER_SIZE)
134 tocopy = len;
135 else
136 tocopy = SG_BUFFER_SIZE;
137 memcpy(buf, vpd_buf[i], tocopy);
138 buf += tocopy;
139 len -= tocopy;
140 }
141 }
142 }
143err2:
144 for (i = 0; i < entries; i++) {
145 if (vpd_buf[i])
146 free_page((unsigned long) vpd_buf[i]);
147 }
148 free_page((unsigned long) le);
149err1:
150 kfree(vpd_buf);
151 return rc;
152}
153
154static int guest_get_irq_info(struct cxl_context *ctx, struct cxl_irq_info *info)
155{
156 return cxl_h_collect_int_info(ctx->afu->guest->handle, ctx->process_token, info);
157}
158
159static irqreturn_t guest_psl_irq(int irq, void *data)
160{
161 struct cxl_context *ctx = data;
162 struct cxl_irq_info irq_info;
163 int rc;
164
165 pr_devel("%d: received PSL interrupt %i\n", ctx->pe, irq);
166 rc = guest_get_irq_info(ctx, &irq_info);
167 if (rc) {
168 WARN(1, "Unable to get IRQ info: %i\n", rc);
169 return IRQ_HANDLED;
170 }
171
172 rc = cxl_irq(irq, ctx, &irq_info);
173 return rc;
174}
175
176static int afu_read_error_state(struct cxl_afu *afu, int *state_out)
177{
178 u64 state;
179 int rc = 0;
180
181 rc = cxl_h_read_error_state(afu->guest->handle, &state);
182 if (!rc) {
183 WARN_ON(state != H_STATE_NORMAL &&
184 state != H_STATE_DISABLE &&
185 state != H_STATE_TEMP_UNAVAILABLE &&
186 state != H_STATE_PERM_UNAVAILABLE);
187 *state_out = state & 0xffffffff;
188 }
189 return rc;
190}
191
192static irqreturn_t guest_slice_irq_err(int irq, void *data)
193{
194 struct cxl_afu *afu = data;
195 int rc;
196 u64 serr;
197
198 WARN(irq, "CXL SLICE ERROR interrupt %i\n", irq);
199 rc = cxl_h_get_fn_error_interrupt(afu->guest->handle, &serr);
200 if (rc) {
201 dev_crit(&afu->dev, "Couldn't read PSL_SERR_An: %d\n", rc);
202 return IRQ_HANDLED;
203 }
204 dev_crit(&afu->dev, "PSL_SERR_An: 0x%.16llx\n", serr);
205
206 rc = cxl_h_ack_fn_error_interrupt(afu->guest->handle, serr);
207 if (rc)
208 dev_crit(&afu->dev, "Couldn't ack slice error interrupt: %d\n",
209 rc);
210
211 return IRQ_HANDLED;
212}
213
214
215static int irq_alloc_range(struct cxl *adapter, int len, int *irq)
216{
217 int i, n;
218 struct irq_avail *cur;
219
220 for (i = 0; i < adapter->guest->irq_nranges; i++) {
221 cur = &adapter->guest->irq_avail[i];
222 n = bitmap_find_next_zero_area(cur->bitmap, cur->range,
223 0, len, 0);
224 if (n < cur->range) {
225 bitmap_set(cur->bitmap, n, len);
226 *irq = cur->offset + n;
227 pr_devel("guest: allocate IRQs %#x->%#x\n",
228 *irq, *irq + len - 1);
229
230 return 0;
231 }
232 }
233 return -ENOSPC;
234}
235
236static int irq_free_range(struct cxl *adapter, int irq, int len)
237{
238 int i, n;
239 struct irq_avail *cur;
240
241 if (len == 0)
242 return -ENOENT;
243
244 for (i = 0; i < adapter->guest->irq_nranges; i++) {
245 cur = &adapter->guest->irq_avail[i];
246 if (irq >= cur->offset &&
247 (irq + len) <= (cur->offset + cur->range)) {
248 n = irq - cur->offset;
249 bitmap_clear(cur->bitmap, n, len);
250 pr_devel("guest: release IRQs %#x->%#x\n",
251 irq, irq + len - 1);
252 return 0;
253 }
254 }
255 return -ENOENT;
256}
257
258static int guest_reset(struct cxl *adapter)
259{
260 struct cxl_afu *afu = NULL;
261 int i, rc;
262
263 pr_devel("Adapter reset request\n");
264 for (i = 0; i < adapter->slices; i++) {
265 if ((afu = adapter->afu[i])) {
266 pci_error_handlers(afu, CXL_ERROR_DETECTED_EVENT,
267 pci_channel_io_frozen);
268 cxl_context_detach_all(afu);
269 }
270 }
271
272 rc = cxl_h_reset_adapter(adapter->guest->handle);
273 for (i = 0; i < adapter->slices; i++) {
274 if (!rc && (afu = adapter->afu[i])) {
275 pci_error_handlers(afu, CXL_SLOT_RESET_EVENT,
276 pci_channel_io_normal);
277 pci_error_handlers(afu, CXL_RESUME_EVENT, 0);
278 }
279 }
280 return rc;
281}
282
283static int guest_alloc_one_irq(struct cxl *adapter)
284{
285 int irq;
286
287 spin_lock(&adapter->guest->irq_alloc_lock);
288 if (irq_alloc_range(adapter, 1, &irq))
289 irq = -ENOSPC;
290 spin_unlock(&adapter->guest->irq_alloc_lock);
291 return irq;
292}
293
294static void guest_release_one_irq(struct cxl *adapter, int irq)
295{
296 spin_lock(&adapter->guest->irq_alloc_lock);
297 irq_free_range(adapter, irq, 1);
298 spin_unlock(&adapter->guest->irq_alloc_lock);
299}
300
301static int guest_alloc_irq_ranges(struct cxl_irq_ranges *irqs,
302 struct cxl *adapter, unsigned int num)
303{
304 int i, try, irq;
305
306 memset(irqs, 0, sizeof(struct cxl_irq_ranges));
307
308 spin_lock(&adapter->guest->irq_alloc_lock);
309 for (i = 0; i < CXL_IRQ_RANGES && num; i++) {
310 try = num;
311 while (try) {
312 if (irq_alloc_range(adapter, try, &irq) == 0)
313 break;
314 try /= 2;
315 }
316 if (!try)
317 goto error;
318 irqs->offset[i] = irq;
319 irqs->range[i] = try;
320 num -= try;
321 }
322 if (num)
323 goto error;
324 spin_unlock(&adapter->guest->irq_alloc_lock);
325 return 0;
326
327error:
328 for (i = 0; i < CXL_IRQ_RANGES; i++)
329 irq_free_range(adapter, irqs->offset[i], irqs->range[i]);
330 spin_unlock(&adapter->guest->irq_alloc_lock);
331 return -ENOSPC;
332}
333
334static void guest_release_irq_ranges(struct cxl_irq_ranges *irqs,
335 struct cxl *adapter)
336{
337 int i;
338
339 spin_lock(&adapter->guest->irq_alloc_lock);
340 for (i = 0; i < CXL_IRQ_RANGES; i++)
341 irq_free_range(adapter, irqs->offset[i], irqs->range[i]);
342 spin_unlock(&adapter->guest->irq_alloc_lock);
343}
344
345static int guest_register_serr_irq(struct cxl_afu *afu)
346{
347 afu->err_irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
348 dev_name(&afu->dev));
349 if (!afu->err_irq_name)
350 return -ENOMEM;
351
352 if (!(afu->serr_virq = cxl_map_irq(afu->adapter, afu->serr_hwirq,
353 guest_slice_irq_err, afu, afu->err_irq_name))) {
354 kfree(afu->err_irq_name);
355 afu->err_irq_name = NULL;
356 return -ENOMEM;
357 }
358
359 return 0;
360}
361
362static void guest_release_serr_irq(struct cxl_afu *afu)
363{
364 cxl_unmap_irq(afu->serr_virq, afu);
365 cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq);
366 kfree(afu->err_irq_name);
367}
368
369static int guest_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask)
370{
371 return cxl_h_control_faults(ctx->afu->guest->handle, ctx->process_token,
372 tfc >> 32, (psl_reset_mask != 0));
373}
374
375static void disable_afu_irqs(struct cxl_context *ctx)
376{
377 irq_hw_number_t hwirq;
378 unsigned int virq;
379 int r, i;
380
381 pr_devel("Disabling AFU(%d) interrupts\n", ctx->afu->slice);
382 for (r = 0; r < CXL_IRQ_RANGES; r++) {
383 hwirq = ctx->irqs.offset[r];
384 for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
385 virq = irq_find_mapping(NULL, hwirq);
386 disable_irq(virq);
387 }
388 }
389}
390
391static void enable_afu_irqs(struct cxl_context *ctx)
392{
393 irq_hw_number_t hwirq;
394 unsigned int virq;
395 int r, i;
396
397 pr_devel("Enabling AFU(%d) interrupts\n", ctx->afu->slice);
398 for (r = 0; r < CXL_IRQ_RANGES; r++) {
399 hwirq = ctx->irqs.offset[r];
400 for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
401 virq = irq_find_mapping(NULL, hwirq);
402 enable_irq(virq);
403 }
404 }
405}
406
407static int _guest_afu_cr_readXX(int sz, struct cxl_afu *afu, int cr_idx,
408 u64 offset, u64 *val)
409{
410 unsigned long cr;
411 char c;
412 int rc = 0;
413
414 if (afu->crs_len < sz)
415 return -ENOENT;
416
417 if (unlikely(offset >= afu->crs_len))
418 return -ERANGE;
419
420 cr = get_zeroed_page(GFP_KERNEL);
421 if (!cr)
422 return -ENOMEM;
423
424 rc = cxl_h_get_config(afu->guest->handle, cr_idx, offset,
425 virt_to_phys((void *)cr), sz);
426 if (rc)
427 goto err;
428
429 switch (sz) {
430 case 1:
431 c = *((char *) cr);
432 *val = c;
433 break;
434 case 2:
435 *val = in_le16((u16 *)cr);
436 break;
437 case 4:
438 *val = in_le32((unsigned *)cr);
439 break;
440 case 8:
441 *val = in_le64((u64 *)cr);
442 break;
443 default:
444 WARN_ON(1);
445 }
446err:
447 free_page(cr);
448 return rc;
449}
450
451static int guest_afu_cr_read32(struct cxl_afu *afu, int cr_idx, u64 offset,
452 u32 *out)
453{
454 int rc;
455 u64 val;
456
457 rc = _guest_afu_cr_readXX(4, afu, cr_idx, offset, &val);
458 if (!rc)
459 *out = (u32) val;
460 return rc;
461}
462
463static int guest_afu_cr_read16(struct cxl_afu *afu, int cr_idx, u64 offset,
464 u16 *out)
465{
466 int rc;
467 u64 val;
468
469 rc = _guest_afu_cr_readXX(2, afu, cr_idx, offset, &val);
470 if (!rc)
471 *out = (u16) val;
472 return rc;
473}
474
475static int guest_afu_cr_read8(struct cxl_afu *afu, int cr_idx, u64 offset,
476 u8 *out)
477{
478 int rc;
479 u64 val;
480
481 rc = _guest_afu_cr_readXX(1, afu, cr_idx, offset, &val);
482 if (!rc)
483 *out = (u8) val;
484 return rc;
485}
486
487static int guest_afu_cr_read64(struct cxl_afu *afu, int cr_idx, u64 offset,
488 u64 *out)
489{
490 return _guest_afu_cr_readXX(8, afu, cr_idx, offset, out);
491}
492
493static int guest_afu_cr_write32(struct cxl_afu *afu, int cr, u64 off, u32 in)
494{
495 /* config record is not writable from guest */
496 return -EPERM;
497}
498
499static int guest_afu_cr_write16(struct cxl_afu *afu, int cr, u64 off, u16 in)
500{
501 /* config record is not writable from guest */
502 return -EPERM;
503}
504
505static int guest_afu_cr_write8(struct cxl_afu *afu, int cr, u64 off, u8 in)
506{
507 /* config record is not writable from guest */
508 return -EPERM;
509}
510
511static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)
512{
513 struct cxl_process_element_hcall *elem;
514 struct cxl *adapter = ctx->afu->adapter;
515 const struct cred *cred;
516 u32 pid, idx;
517 int rc, r, i;
518 u64 mmio_addr, mmio_size;
519 __be64 flags = 0;
520
521 /* Must be 8 byte aligned and cannot cross a 4096 byte boundary */
522 if (!(elem = (struct cxl_process_element_hcall *)
523 get_zeroed_page(GFP_KERNEL)))
524 return -ENOMEM;
525
526 elem->version = cpu_to_be64(CXL_PROCESS_ELEMENT_VERSION);
527 if (ctx->kernel) {
528 pid = 0;
529 flags |= CXL_PE_TRANSLATION_ENABLED;
530 flags |= CXL_PE_PRIVILEGED_PROCESS;
531 if (mfmsr() & MSR_SF)
532 flags |= CXL_PE_64_BIT;
533 } else {
534 pid = current->pid;
535 flags |= CXL_PE_PROBLEM_STATE;
536 flags |= CXL_PE_TRANSLATION_ENABLED;
537 if (!test_tsk_thread_flag(current, TIF_32BIT))
538 flags |= CXL_PE_64_BIT;
539 cred = get_current_cred();
540 if (uid_eq(cred->euid, GLOBAL_ROOT_UID))
541 flags |= CXL_PE_PRIVILEGED_PROCESS;
542 put_cred(cred);
543 }
544 elem->flags = cpu_to_be64(flags);
545 elem->common.tid = cpu_to_be32(0); /* Unused */
546 elem->common.pid = cpu_to_be32(pid);
547 elem->common.csrp = cpu_to_be64(0); /* disable */
548 elem->common.aurp0 = cpu_to_be64(0); /* disable */
549 elem->common.aurp1 = cpu_to_be64(0); /* disable */
550
551 cxl_prefault(ctx, wed);
552
553 elem->common.sstp0 = cpu_to_be64(ctx->sstp0);
554 elem->common.sstp1 = cpu_to_be64(ctx->sstp1);
555 for (r = 0; r < CXL_IRQ_RANGES; r++) {
556 for (i = 0; i < ctx->irqs.range[r]; i++) {
557 if (r == 0 && i == 0) {
558 elem->pslVirtualIsn = cpu_to_be32(ctx->irqs.offset[0]);
559 } else {
560 idx = ctx->irqs.offset[r] + i - adapter->guest->irq_base_offset;
561 elem->applicationVirtualIsnBitmap[idx / 8] |= 0x80 >> (idx % 8);
562 }
563 }
564 }
565 elem->common.amr = cpu_to_be64(amr);
566 elem->common.wed = cpu_to_be64(wed);
567
568 disable_afu_irqs(ctx);
569
570 rc = cxl_h_attach_process(ctx->afu->guest->handle, elem,
571 &ctx->process_token, &mmio_addr, &mmio_size);
572 if (rc == H_SUCCESS) {
573 if (ctx->master || !ctx->afu->pp_psa) {
574 ctx->psn_phys = ctx->afu->psn_phys;
575 ctx->psn_size = ctx->afu->adapter->ps_size;
576 } else {
577 ctx->psn_phys = mmio_addr;
578 ctx->psn_size = mmio_size;
579 }
580 if (ctx->afu->pp_psa && mmio_size &&
581 ctx->afu->pp_size == 0) {
582 /*
583 * There's no property in the device tree to read the
584 * pp_size. We only find out at the 1st attach.
585 * Compared to bare-metal, it is too late and we
586 * should really lock here. However, on powerVM,
587 * pp_size is really only used to display in /sys.
588 * Being discussed with pHyp for their next release.
589 */
590 ctx->afu->pp_size = mmio_size;
591 }
592 /* from PAPR: process element is bytes 4-7 of process token */
593 ctx->external_pe = ctx->process_token & 0xFFFFFFFF;
594 pr_devel("CXL pe=%i is known as %i for pHyp, mmio_size=%#llx",
595 ctx->pe, ctx->external_pe, ctx->psn_size);
596 ctx->pe_inserted = true;
597 enable_afu_irqs(ctx);
598 }
599
600 free_page((u64)elem);
601 return rc;
602}
603
604static int guest_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr)
605{
606 pr_devel("in %s\n", __func__);
607
608 ctx->kernel = kernel;
609 if (ctx->afu->current_mode == CXL_MODE_DIRECTED)
610 return attach_afu_directed(ctx, wed, amr);
611
612 /* dedicated mode not supported on FW840 */
613
614 return -EINVAL;
615}
616
617static int detach_afu_directed(struct cxl_context *ctx)
618{
619 if (!ctx->pe_inserted)
620 return 0;
621 if (cxl_h_detach_process(ctx->afu->guest->handle, ctx->process_token))
622 return -1;
623 return 0;
624}
625
626static int guest_detach_process(struct cxl_context *ctx)
627{
628 pr_devel("in %s\n", __func__);
629 trace_cxl_detach(ctx);
630
631 if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
632 return -EIO;
633
634 if (ctx->afu->current_mode == CXL_MODE_DIRECTED)
635 return detach_afu_directed(ctx);
636
637 return -EINVAL;
638}
639
640static void guest_release_afu(struct device *dev)
641{
642 struct cxl_afu *afu = to_cxl_afu(dev);
643
644 pr_devel("%s\n", __func__);
645
646 idr_destroy(&afu->contexts_idr);
647
648 kfree(afu->guest);
649 kfree(afu);
650}
651
652ssize_t cxl_guest_read_afu_vpd(struct cxl_afu *afu, void *buf, size_t len)
653{
654 return guest_collect_vpd(NULL, afu, buf, len);
655}
656
657#define ERR_BUFF_MAX_COPY_SIZE PAGE_SIZE
658static ssize_t guest_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
659 loff_t off, size_t count)
660{
661 void *tbuf = NULL;
662 int rc = 0;
663
664 tbuf = (void *) get_zeroed_page(GFP_KERNEL);
665 if (!tbuf)
666 return -ENOMEM;
667
668 rc = cxl_h_get_afu_err(afu->guest->handle,
669 off & 0x7,
670 virt_to_phys(tbuf),
671 count);
672 if (rc)
673 goto err;
674
675 if (count > ERR_BUFF_MAX_COPY_SIZE)
676 count = ERR_BUFF_MAX_COPY_SIZE - (off & 0x7);
677 memcpy(buf, tbuf, count);
678err:
679 free_page((u64)tbuf);
680
681 return rc;
682}
683
684static int guest_afu_check_and_enable(struct cxl_afu *afu)
685{
686 return 0;
687}
688
689static bool guest_support_attributes(const char *attr_name,
690 enum cxl_attrs type)
691{
692 switch (type) {
693 case CXL_ADAPTER_ATTRS:
694 if ((strcmp(attr_name, "base_image") == 0) ||
695 (strcmp(attr_name, "load_image_on_perst") == 0) ||
696 (strcmp(attr_name, "perst_reloads_same_image") == 0) ||
697 (strcmp(attr_name, "image_loaded") == 0))
698 return false;
699 break;
700 case CXL_AFU_MASTER_ATTRS:
701 if ((strcmp(attr_name, "pp_mmio_off") == 0))
702 return false;
703 break;
704 case CXL_AFU_ATTRS:
705 break;
706 default:
707 break;
708 }
709
710 return true;
711}
712
713static int activate_afu_directed(struct cxl_afu *afu)
714{
715 int rc;
716
717 dev_info(&afu->dev, "Activating AFU(%d) directed mode\n", afu->slice);
718
719 afu->current_mode = CXL_MODE_DIRECTED;
720
721 afu->num_procs = afu->max_procs_virtualised;
722
723 if ((rc = cxl_chardev_m_afu_add(afu)))
724 return rc;
725
726 if ((rc = cxl_sysfs_afu_m_add(afu)))
727 goto err;
728
729 if ((rc = cxl_chardev_s_afu_add(afu)))
730 goto err1;
731
732 return 0;
733err1:
734 cxl_sysfs_afu_m_remove(afu);
735err:
736 cxl_chardev_afu_remove(afu);
737 return rc;
738}
739
740static int guest_afu_activate_mode(struct cxl_afu *afu, int mode)
741{
742 if (!mode)
743 return 0;
744 if (!(mode & afu->modes_supported))
745 return -EINVAL;
746
747 if (mode == CXL_MODE_DIRECTED)
748 return activate_afu_directed(afu);
749
750 if (mode == CXL_MODE_DEDICATED)
751 dev_err(&afu->dev, "Dedicated mode not supported\n");
752
753 return -EINVAL;
754}
755
756static int deactivate_afu_directed(struct cxl_afu *afu)
757{
758 dev_info(&afu->dev, "Deactivating AFU(%d) directed mode\n", afu->slice);
759
760 afu->current_mode = 0;
761 afu->num_procs = 0;
762
763 cxl_sysfs_afu_m_remove(afu);
764 cxl_chardev_afu_remove(afu);
765
766 cxl_ops->afu_reset(afu);
767
768 return 0;
769}
770
771static int guest_afu_deactivate_mode(struct cxl_afu *afu, int mode)
772{
773 if (!mode)
774 return 0;
775 if (!(mode & afu->modes_supported))
776 return -EINVAL;
777
778 if (mode == CXL_MODE_DIRECTED)
779 return deactivate_afu_directed(afu);
780 return 0;
781}
782
783static int guest_afu_reset(struct cxl_afu *afu)
784{
785 pr_devel("AFU(%d) reset request\n", afu->slice);
786 return cxl_h_reset_afu(afu->guest->handle);
787}
788
789static int guest_map_slice_regs(struct cxl_afu *afu)
790{
791 if (!(afu->p2n_mmio = ioremap(afu->guest->p2n_phys, afu->guest->p2n_size))) {
792 dev_err(&afu->dev, "Error mapping AFU(%d) MMIO regions\n",
793 afu->slice);
794 return -ENOMEM;
795 }
796 return 0;
797}
798
799static void guest_unmap_slice_regs(struct cxl_afu *afu)
800{
801 if (afu->p2n_mmio)
802 iounmap(afu->p2n_mmio);
803}
804
805static int afu_update_state(struct cxl_afu *afu)
806{
807 int rc, cur_state;
808
809 rc = afu_read_error_state(afu, &cur_state);
810 if (rc)
811 return rc;
812
813 if (afu->guest->previous_state == cur_state)
814 return 0;
815
816 pr_devel("AFU(%d) update state to %#x\n", afu->slice, cur_state);
817
818 switch (cur_state) {
819 case H_STATE_NORMAL:
820 afu->guest->previous_state = cur_state;
821 rc = 1;
822 break;
823
824 case H_STATE_DISABLE:
825 pci_error_handlers(afu, CXL_ERROR_DETECTED_EVENT,
826 pci_channel_io_frozen);
827
828 cxl_context_detach_all(afu);
829 if ((rc = cxl_ops->afu_reset(afu)))
830 pr_devel("reset hcall failed %d\n", rc);
831
832 rc = afu_read_error_state(afu, &cur_state);
833 if (!rc && cur_state == H_STATE_NORMAL) {
834 pci_error_handlers(afu, CXL_SLOT_RESET_EVENT,
835 pci_channel_io_normal);
836 pci_error_handlers(afu, CXL_RESUME_EVENT, 0);
837 rc = 1;
838 }
839 afu->guest->previous_state = 0;
840 break;
841
842 case H_STATE_TEMP_UNAVAILABLE:
843 afu->guest->previous_state = cur_state;
844 break;
845
846 case H_STATE_PERM_UNAVAILABLE:
847 dev_err(&afu->dev, "AFU is in permanent error state\n");
848 pci_error_handlers(afu, CXL_ERROR_DETECTED_EVENT,
849 pci_channel_io_perm_failure);
850 afu->guest->previous_state = cur_state;
851 break;
852
853 default:
854 pr_err("Unexpected AFU(%d) error state: %#x\n",
855 afu->slice, cur_state);
856 return -EINVAL;
857 }
858
859 return rc;
860}
861
862static int afu_do_recovery(struct cxl_afu *afu)
863{
864 int rc;
865
866 /* many threads can arrive here, in case of detach_all for example.
867 * Only one needs to drive the recovery
868 */
869 if (mutex_trylock(&afu->guest->recovery_lock)) {
870 rc = afu_update_state(afu);
871 mutex_unlock(&afu->guest->recovery_lock);
872 return rc;
873 }
874 return 0;
875}
876
877static bool guest_link_ok(struct cxl *cxl, struct cxl_afu *afu)
878{
879 int state;
880
881 if (afu) {
882 if (afu_read_error_state(afu, &state) ||
883 state != H_STATE_NORMAL) {
884 if (afu_do_recovery(afu) > 0) {
885 /* check again in case we've just fixed it */
886 if (!afu_read_error_state(afu, &state) &&
887 state == H_STATE_NORMAL)
888 return true;
889 }
890 return false;
891 }
892 }
893
894 return true;
895}
896
897static int afu_properties_look_ok(struct cxl_afu *afu)
898{
899 if (afu->pp_irqs < 0) {
900 dev_err(&afu->dev, "Unexpected per-process minimum interrupt value\n");
901 return -EINVAL;
902 }
903
904 if (afu->max_procs_virtualised < 1) {
905 dev_err(&afu->dev, "Unexpected max number of processes virtualised value\n");
906 return -EINVAL;
907 }
908
909 if (afu->crs_len < 0) {
910 dev_err(&afu->dev, "Unexpected configuration record size value\n");
911 return -EINVAL;
912 }
913
914 return 0;
915}
916
917int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_np)
918{
919 struct cxl_afu *afu;
920 bool free = true;
921 int rc;
922
923 pr_devel("in %s - AFU(%d)\n", __func__, slice);
924 if (!(afu = cxl_alloc_afu(adapter, slice)))
925 return -ENOMEM;
926
927 if (!(afu->guest = kzalloc(sizeof(struct cxl_afu_guest), GFP_KERNEL))) {
928 kfree(afu);
929 return -ENOMEM;
930 }
931
932 mutex_init(&afu->guest->recovery_lock);
933
934 if ((rc = dev_set_name(&afu->dev, "afu%i.%i",
935 adapter->adapter_num,
936 slice)))
937 goto err1;
938
939 adapter->slices++;
940
941 if ((rc = cxl_of_read_afu_handle(afu, afu_np)))
942 goto err1;
943
944 if ((rc = cxl_ops->afu_reset(afu)))
945 goto err1;
946
947 if ((rc = cxl_of_read_afu_properties(afu, afu_np)))
948 goto err1;
949
950 if ((rc = afu_properties_look_ok(afu)))
951 goto err1;
952
953 if ((rc = guest_map_slice_regs(afu)))
954 goto err1;
955
956 if ((rc = guest_register_serr_irq(afu)))
957 goto err2;
958
959 /*
960 * After we call this function we must not free the afu directly, even
961 * if it returns an error!
962 */
963 if ((rc = cxl_register_afu(afu)))
964 goto err_put1;
965
966 if ((rc = cxl_sysfs_afu_add(afu)))
967 goto err_put1;
968
969 /*
970 * pHyp doesn't expose the programming models supported by the
971 * AFU. pHyp currently only supports directed mode. If it adds
972 * dedicated mode later, this version of cxl has no way to
973 * detect it. So we'll initialize the driver, but the first
974 * attach will fail.
975 * Being discussed with pHyp to do better (likely new property)
976 */
977 if (afu->max_procs_virtualised == 1)
978 afu->modes_supported = CXL_MODE_DEDICATED;
979 else
980 afu->modes_supported = CXL_MODE_DIRECTED;
981
982 if ((rc = cxl_afu_select_best_mode(afu)))
983 goto err_put2;
984
985 adapter->afu[afu->slice] = afu;
986
987 afu->enabled = true;
988
989 if ((rc = cxl_pci_vphb_add(afu)))
990 dev_info(&afu->dev, "Can't register vPHB\n");
991
992 return 0;
993
994err_put2:
995 cxl_sysfs_afu_remove(afu);
996err_put1:
997 device_unregister(&afu->dev);
998 free = false;
999 guest_release_serr_irq(afu);
1000err2:
1001 guest_unmap_slice_regs(afu);
1002err1:
1003 if (free) {
1004 kfree(afu->guest);
1005 kfree(afu);
1006 }
1007 return rc;
1008}
1009
1010void cxl_guest_remove_afu(struct cxl_afu *afu)
1011{
1012 pr_devel("in %s - AFU(%d)\n", __func__, afu->slice);
1013
1014 if (!afu)
1015 return;
1016
1017 cxl_pci_vphb_remove(afu);
1018 cxl_sysfs_afu_remove(afu);
1019
1020 spin_lock(&afu->adapter->afu_list_lock);
1021 afu->adapter->afu[afu->slice] = NULL;
1022 spin_unlock(&afu->adapter->afu_list_lock);
1023
1024 cxl_context_detach_all(afu);
1025 cxl_ops->afu_deactivate_mode(afu, afu->current_mode);
1026 guest_release_serr_irq(afu);
1027 guest_unmap_slice_regs(afu);
1028
1029 device_unregister(&afu->dev);
1030}
1031
1032static void free_adapter(struct cxl *adapter)
1033{
1034 struct irq_avail *cur;
1035 int i;
1036
1037 if (adapter->guest->irq_avail) {
1038 for (i = 0; i < adapter->guest->irq_nranges; i++) {
1039 cur = &adapter->guest->irq_avail[i];
1040 kfree(cur->bitmap);
1041 }
1042 kfree(adapter->guest->irq_avail);
1043 }
1044 kfree(adapter->guest->status);
1045 cxl_remove_adapter_nr(adapter);
1046 kfree(adapter->guest);
1047 kfree(adapter);
1048}
1049
1050static int properties_look_ok(struct cxl *adapter)
1051{
1052 /* The absence of this property means that the operational
1053 * status is unknown or okay
1054 */
1055 if (strlen(adapter->guest->status) &&
1056 strcmp(adapter->guest->status, "okay")) {
1057 pr_err("ABORTING:Bad operational status of the device\n");
1058 return -EINVAL;
1059 }
1060
1061 return 0;
1062}
1063
1064ssize_t cxl_guest_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len)
1065{
1066 return guest_collect_vpd(adapter, NULL, buf, len);
1067}
1068
1069void cxl_guest_remove_adapter(struct cxl *adapter)
1070{
1071 pr_devel("in %s\n", __func__);
1072
1073 cxl_sysfs_adapter_remove(adapter);
1074
1075 cxl_guest_remove_chardev(adapter);
1076 device_unregister(&adapter->dev);
1077}
1078
1079static void release_adapter(struct device *dev)
1080{
1081 free_adapter(to_cxl_adapter(dev));
1082}
1083
1084struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_device *pdev)
1085{
1086 struct cxl *adapter;
1087 bool free = true;
1088 int rc;
1089
1090 if (!(adapter = cxl_alloc_adapter()))
1091 return ERR_PTR(-ENOMEM);
1092
1093 if (!(adapter->guest = kzalloc(sizeof(struct cxl_guest), GFP_KERNEL))) {
1094 free_adapter(adapter);
1095 return ERR_PTR(-ENOMEM);
1096 }
1097
1098 adapter->slices = 0;
1099 adapter->guest->pdev = pdev;
1100 adapter->dev.parent = &pdev->dev;
1101 adapter->dev.release = release_adapter;
1102 dev_set_drvdata(&pdev->dev, adapter);
1103
1104 if ((rc = cxl_of_read_adapter_handle(adapter, np)))
1105 goto err1;
1106
1107 if ((rc = cxl_of_read_adapter_properties(adapter, np)))
1108 goto err1;
1109
1110 if ((rc = properties_look_ok(adapter)))
1111 goto err1;
1112
1113 if ((rc = cxl_guest_add_chardev(adapter)))
1114 goto err1;
1115
1116 /*
1117 * After we call this function we must not free the adapter directly,
1118 * even if it returns an error!
1119 */
1120 if ((rc = cxl_register_adapter(adapter)))
1121 goto err_put1;
1122
1123 if ((rc = cxl_sysfs_adapter_add(adapter)))
1124 goto err_put1;
1125
1126 return adapter;
1127
1128err_put1:
1129 device_unregister(&adapter->dev);
1130 free = false;
1131 cxl_guest_remove_chardev(adapter);
1132err1:
1133 if (free)
1134 free_adapter(adapter);
1135 return ERR_PTR(rc);
1136}
1137
1138void cxl_guest_reload_module(struct cxl *adapter)
1139{
1140 struct platform_device *pdev;
1141
1142 pdev = adapter->guest->pdev;
1143 cxl_guest_remove_adapter(adapter);
1144
1145 cxl_of_probe(pdev);
1146}
1147
1148const struct cxl_backend_ops cxl_guest_ops = {
1149 .module = THIS_MODULE,
1150 .adapter_reset = guest_reset,
1151 .alloc_one_irq = guest_alloc_one_irq,
1152 .release_one_irq = guest_release_one_irq,
1153 .alloc_irq_ranges = guest_alloc_irq_ranges,
1154 .release_irq_ranges = guest_release_irq_ranges,
1155 .setup_irq = NULL,
1156 .handle_psl_slice_error = guest_handle_psl_slice_error,
1157 .psl_interrupt = guest_psl_irq,
1158 .ack_irq = guest_ack_irq,
1159 .attach_process = guest_attach_process,
1160 .detach_process = guest_detach_process,
1161 .support_attributes = guest_support_attributes,
1162 .link_ok = guest_link_ok,
1163 .release_afu = guest_release_afu,
1164 .afu_read_err_buffer = guest_afu_read_err_buffer,
1165 .afu_check_and_enable = guest_afu_check_and_enable,
1166 .afu_activate_mode = guest_afu_activate_mode,
1167 .afu_deactivate_mode = guest_afu_deactivate_mode,
1168 .afu_reset = guest_afu_reset,
1169 .afu_cr_read8 = guest_afu_cr_read8,
1170 .afu_cr_read16 = guest_afu_cr_read16,
1171 .afu_cr_read32 = guest_afu_cr_read32,
1172 .afu_cr_read64 = guest_afu_cr_read64,
1173 .afu_cr_write8 = guest_afu_cr_write8,
1174 .afu_cr_write16 = guest_afu_cr_write16,
1175 .afu_cr_write32 = guest_afu_cr_write32,
1176 .read_adapter_vpd = cxl_guest_read_adapter_vpd,
1177};
diff --git a/drivers/misc/cxl/hcalls.c b/drivers/misc/cxl/hcalls.c
new file mode 100644
index 000000000000..d6d11f4056d7
--- /dev/null
+++ b/drivers/misc/cxl/hcalls.c
@@ -0,0 +1,647 @@
1/*
2 * Copyright 2015 IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10
11#include <linux/compiler.h>
12#include <linux/types.h>
13#include <linux/delay.h>
14#include <asm/byteorder.h>
15#include "hcalls.h"
16#include "trace.h"
17
18#define CXL_HCALL_TIMEOUT 60000
19#define CXL_HCALL_TIMEOUT_DOWNLOAD 120000
20
21#define H_ATTACH_CA_PROCESS 0x344
22#define H_CONTROL_CA_FUNCTION 0x348
23#define H_DETACH_CA_PROCESS 0x34C
24#define H_COLLECT_CA_INT_INFO 0x350
25#define H_CONTROL_CA_FAULTS 0x354
26#define H_DOWNLOAD_CA_FUNCTION 0x35C
27#define H_DOWNLOAD_CA_FACILITY 0x364
28#define H_CONTROL_CA_FACILITY 0x368
29
30#define H_CONTROL_CA_FUNCTION_RESET 1 /* perform a reset */
31#define H_CONTROL_CA_FUNCTION_SUSPEND_PROCESS 2 /* suspend a process from being executed */
32#define H_CONTROL_CA_FUNCTION_RESUME_PROCESS 3 /* resume a process to be executed */
33#define H_CONTROL_CA_FUNCTION_READ_ERR_STATE 4 /* read the error state */
34#define H_CONTROL_CA_FUNCTION_GET_AFU_ERR 5 /* collect the AFU error buffer */
35#define H_CONTROL_CA_FUNCTION_GET_CONFIG 6 /* collect configuration record */
36#define H_CONTROL_CA_FUNCTION_GET_DOWNLOAD_STATE 7 /* query to return download status */
37#define H_CONTROL_CA_FUNCTION_TERMINATE_PROCESS 8 /* terminate the process before completion */
38#define H_CONTROL_CA_FUNCTION_COLLECT_VPD 9 /* collect VPD */
39#define H_CONTROL_CA_FUNCTION_GET_FUNCTION_ERR_INT 11 /* read the function-wide error data based on an interrupt */
40#define H_CONTROL_CA_FUNCTION_ACK_FUNCTION_ERR_INT 12 /* acknowledge function-wide error data based on an interrupt */
41#define H_CONTROL_CA_FUNCTION_GET_ERROR_LOG 13 /* retrieve the Platform Log ID (PLID) of an error log */
42
43#define H_CONTROL_CA_FAULTS_RESPOND_PSL 1
44#define H_CONTROL_CA_FAULTS_RESPOND_AFU 2
45
46#define H_CONTROL_CA_FACILITY_RESET 1 /* perform a reset */
47#define H_CONTROL_CA_FACILITY_COLLECT_VPD 2 /* collect VPD */
48
49#define H_DOWNLOAD_CA_FACILITY_DOWNLOAD 1 /* download adapter image */
50#define H_DOWNLOAD_CA_FACILITY_VALIDATE 2 /* validate adapter image */
51
52
53#define _CXL_LOOP_HCALL(call, rc, retbuf, fn, ...) \
54 { \
55 unsigned int delay, total_delay = 0; \
56 u64 token = 0; \
57 \
58 memset(retbuf, 0, sizeof(retbuf)); \
59 while (1) { \
60 rc = call(fn, retbuf, __VA_ARGS__, token); \
61 token = retbuf[0]; \
62 if (rc != H_BUSY && !H_IS_LONG_BUSY(rc)) \
63 break; \
64 \
65 if (rc == H_BUSY) \
66 delay = 10; \
67 else \
68 delay = get_longbusy_msecs(rc); \
69 \
70 total_delay += delay; \
71 if (total_delay > CXL_HCALL_TIMEOUT) { \
72 WARN(1, "Warning: Giving up waiting for CXL hcall " \
73 "%#x after %u msec\n", fn, total_delay); \
74 rc = H_BUSY; \
75 break; \
76 } \
77 msleep(delay); \
78 } \
79 }
80#define CXL_H_WAIT_UNTIL_DONE(...) _CXL_LOOP_HCALL(plpar_hcall, __VA_ARGS__)
81#define CXL_H9_WAIT_UNTIL_DONE(...) _CXL_LOOP_HCALL(plpar_hcall9, __VA_ARGS__)
82
83#define _PRINT_MSG(rc, format, ...) \
84 { \
85 if ((rc != H_SUCCESS) && (rc != H_CONTINUE)) \
86 pr_err(format, __VA_ARGS__); \
87 else \
88 pr_devel(format, __VA_ARGS__); \
89 } \
90
91
92static char *afu_op_names[] = {
93 "UNKNOWN_OP", /* 0 undefined */
94 "RESET", /* 1 */
95 "SUSPEND_PROCESS", /* 2 */
96 "RESUME_PROCESS", /* 3 */
97 "READ_ERR_STATE", /* 4 */
98 "GET_AFU_ERR", /* 5 */
99 "GET_CONFIG", /* 6 */
100 "GET_DOWNLOAD_STATE", /* 7 */
101 "TERMINATE_PROCESS", /* 8 */
102 "COLLECT_VPD", /* 9 */
103 "UNKNOWN_OP", /* 10 undefined */
104 "GET_FUNCTION_ERR_INT", /* 11 */
105 "ACK_FUNCTION_ERR_INT", /* 12 */
106 "GET_ERROR_LOG", /* 13 */
107};
108
109static char *control_adapter_op_names[] = {
110 "UNKNOWN_OP", /* 0 undefined */
111 "RESET", /* 1 */
112 "COLLECT_VPD", /* 2 */
113};
114
115static char *download_op_names[] = {
116 "UNKNOWN_OP", /* 0 undefined */
117 "DOWNLOAD", /* 1 */
118 "VALIDATE", /* 2 */
119};
120
121static char *op_str(unsigned int op, char *name_array[], int array_len)
122{
123 if (op >= array_len)
124 return "UNKNOWN_OP";
125 return name_array[op];
126}
127
128#define OP_STR(op, name_array) op_str(op, name_array, ARRAY_SIZE(name_array))
129
130#define OP_STR_AFU(op) OP_STR(op, afu_op_names)
131#define OP_STR_CONTROL_ADAPTER(op) OP_STR(op, control_adapter_op_names)
132#define OP_STR_DOWNLOAD_ADAPTER(op) OP_STR(op, download_op_names)
133
134
135long cxl_h_attach_process(u64 unit_address,
136 struct cxl_process_element_hcall *element,
137 u64 *process_token, u64 *mmio_addr, u64 *mmio_size)
138{
139 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
140 long rc;
141
142 CXL_H_WAIT_UNTIL_DONE(rc, retbuf, H_ATTACH_CA_PROCESS, unit_address, virt_to_phys(element));
143 _PRINT_MSG(rc, "cxl_h_attach_process(%#.16llx, %#.16lx): %li\n",
144 unit_address, virt_to_phys(element), rc);
145 trace_cxl_hcall_attach(unit_address, virt_to_phys(element), retbuf[0], retbuf[1], retbuf[2], rc);
146
147 pr_devel("token: 0x%.8lx mmio_addr: 0x%lx mmio_size: 0x%lx\nProcess Element Structure:\n",
148 retbuf[0], retbuf[1], retbuf[2]);
149 cxl_dump_debug_buffer(element, sizeof(*element));
150
151 switch (rc) {
152 case H_SUCCESS: /* The process info is attached to the coherent platform function */
153 *process_token = retbuf[0];
154 if (mmio_addr)
155 *mmio_addr = retbuf[1];
156 if (mmio_size)
157 *mmio_size = retbuf[2];
158 return 0;
159 case H_PARAMETER: /* An incorrect parameter was supplied. */
160 case H_FUNCTION: /* The function is not supported. */
161 return -EINVAL;
162 case H_AUTHORITY: /* The partition does not have authority to perform this hcall */
163 case H_RESOURCE: /* The coherent platform function does not have enough additional resource to attach the process */
164 case H_HARDWARE: /* A hardware event prevented the attach operation */
165 case H_STATE: /* The coherent platform function is not in a valid state */
166 case H_BUSY:
167 return -EBUSY;
168 default:
169 WARN(1, "Unexpected return code: %lx", rc);
170 return -EINVAL;
171 }
172}
173
174/**
175 * cxl_h_detach_process - Detach a process element from a coherent
176 * platform function.
177 */
178long cxl_h_detach_process(u64 unit_address, u64 process_token)
179{
180 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
181 long rc;
182
183 CXL_H_WAIT_UNTIL_DONE(rc, retbuf, H_DETACH_CA_PROCESS, unit_address, process_token);
184 _PRINT_MSG(rc, "cxl_h_detach_process(%#.16llx, 0x%.8llx): %li\n", unit_address, process_token, rc);
185 trace_cxl_hcall_detach(unit_address, process_token, rc);
186
187 switch (rc) {
188 case H_SUCCESS: /* The process was detached from the coherent platform function */
189 return 0;
190 case H_PARAMETER: /* An incorrect parameter was supplied. */
191 return -EINVAL;
192 case H_AUTHORITY: /* The partition does not have authority to perform this hcall */
193 case H_RESOURCE: /* The function has page table mappings for MMIO */
194 case H_HARDWARE: /* A hardware event prevented the detach operation */
195 case H_STATE: /* The coherent platform function is not in a valid state */
196 case H_BUSY:
197 return -EBUSY;
198 default:
199 WARN(1, "Unexpected return code: %lx", rc);
200 return -EINVAL;
201 }
202}
203
204/**
205 * cxl_h_control_function - This H_CONTROL_CA_FUNCTION hypervisor call allows
206 * the partition to manipulate or query
207 * certain coherent platform function behaviors.
208 */
209static long cxl_h_control_function(u64 unit_address, u64 op,
210 u64 p1, u64 p2, u64 p3, u64 p4, u64 *out)
211{
212 unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
213 long rc;
214
215 CXL_H9_WAIT_UNTIL_DONE(rc, retbuf, H_CONTROL_CA_FUNCTION, unit_address, op, p1, p2, p3, p4);
216 _PRINT_MSG(rc, "cxl_h_control_function(%#.16llx, %s(%#llx, %#llx, %#llx, %#llx, R4: %#lx)): %li\n",
217 unit_address, OP_STR_AFU(op), p1, p2, p3, p4, retbuf[0], rc);
218 trace_cxl_hcall_control_function(unit_address, OP_STR_AFU(op), p1, p2, p3, p4, retbuf[0], rc);
219
220 switch (rc) {
221 case H_SUCCESS: /* The operation is completed for the coherent platform function */
222 if ((op == H_CONTROL_CA_FUNCTION_GET_FUNCTION_ERR_INT ||
223 op == H_CONTROL_CA_FUNCTION_READ_ERR_STATE ||
224 op == H_CONTROL_CA_FUNCTION_COLLECT_VPD))
225 *out = retbuf[0];
226 return 0;
227 case H_PARAMETER: /* An incorrect parameter was supplied. */
228 case H_FUNCTION: /* The function is not supported. */
229 case H_NOT_FOUND: /* The operation supplied was not valid */
230 case H_NOT_AVAILABLE: /* The operation cannot be performed because the AFU has not been downloaded */
231 case H_SG_LIST: /* An block list entry was invalid */
232 return -EINVAL;
233 case H_AUTHORITY: /* The partition does not have authority to perform this hcall */
234 case H_RESOURCE: /* The function has page table mappings for MMIO */
235 case H_HARDWARE: /* A hardware event prevented the attach operation */
236 case H_STATE: /* The coherent platform function is not in a valid state */
237 case H_BUSY:
238 return -EBUSY;
239 default:
240 WARN(1, "Unexpected return code: %lx", rc);
241 return -EINVAL;
242 }
243}
244
245/**
246 * cxl_h_reset_afu - Perform a reset to the coherent platform function.
247 */
248long cxl_h_reset_afu(u64 unit_address)
249{
250 return cxl_h_control_function(unit_address,
251 H_CONTROL_CA_FUNCTION_RESET,
252 0, 0, 0, 0,
253 NULL);
254}
255
256/**
257 * cxl_h_suspend_process - Suspend a process from being executed
258 * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
259 * process was attached.
260 */
261long cxl_h_suspend_process(u64 unit_address, u64 process_token)
262{
263 return cxl_h_control_function(unit_address,
264 H_CONTROL_CA_FUNCTION_SUSPEND_PROCESS,
265 process_token, 0, 0, 0,
266 NULL);
267}
268
269/**
270 * cxl_h_resume_process - Resume a process to be executed
271 * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
272 * process was attached.
273 */
274long cxl_h_resume_process(u64 unit_address, u64 process_token)
275{
276 return cxl_h_control_function(unit_address,
277 H_CONTROL_CA_FUNCTION_RESUME_PROCESS,
278 process_token, 0, 0, 0,
279 NULL);
280}
281
282/**
283 * cxl_h_read_error_state - Checks the error state of the coherent
284 * platform function.
285 * R4 contains the error state
286 */
287long cxl_h_read_error_state(u64 unit_address, u64 *state)
288{
289 return cxl_h_control_function(unit_address,
290 H_CONTROL_CA_FUNCTION_READ_ERR_STATE,
291 0, 0, 0, 0,
292 state);
293}
294
295/**
296 * cxl_h_get_afu_err - collect the AFU error buffer
297 * Parameter1 = byte offset into error buffer to retrieve, valid values
298 * are between 0 and (ibm,error-buffer-size - 1)
299 * Parameter2 = 4K aligned real address of error buffer, to be filled in
300 * Parameter3 = length of error buffer, valid values are 4K or less
301 */
302long cxl_h_get_afu_err(u64 unit_address, u64 offset,
303 u64 buf_address, u64 len)
304{
305 return cxl_h_control_function(unit_address,
306 H_CONTROL_CA_FUNCTION_GET_AFU_ERR,
307 offset, buf_address, len, 0,
308 NULL);
309}
310
311/**
312 * cxl_h_get_config - collect configuration record for the
313 * coherent platform function
314 * Parameter1 = # of configuration record to retrieve, valid values are
315 * between 0 and (ibm,#config-records - 1)
316 * Parameter2 = byte offset into configuration record to retrieve,
317 * valid values are between 0 and (ibm,config-record-size - 1)
318 * Parameter3 = 4K aligned real address of configuration record buffer,
319 * to be filled in
320 * Parameter4 = length of configuration buffer, valid values are 4K or less
321 */
322long cxl_h_get_config(u64 unit_address, u64 cr_num, u64 offset,
323 u64 buf_address, u64 len)
324{
325 return cxl_h_control_function(unit_address,
326 H_CONTROL_CA_FUNCTION_GET_CONFIG,
327 cr_num, offset, buf_address, len,
328 NULL);
329}
330
331/**
332 * cxl_h_terminate_process - Terminate the process before completion
333 * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
334 * process was attached.
335 */
336long cxl_h_terminate_process(u64 unit_address, u64 process_token)
337{
338 return cxl_h_control_function(unit_address,
339 H_CONTROL_CA_FUNCTION_TERMINATE_PROCESS,
340 process_token, 0, 0, 0,
341 NULL);
342}
343
344/**
345 * cxl_h_collect_vpd - Collect VPD for the coherent platform function.
346 * Parameter1 = # of VPD record to retrieve, valid values are between 0
347 * and (ibm,#config-records - 1).
348 * Parameter2 = 4K naturally aligned real buffer containing block
349 * list entries
350 * Parameter3 = number of block list entries in the block list, valid
351 * values are between 0 and 256
352 */
353long cxl_h_collect_vpd(u64 unit_address, u64 record, u64 list_address,
354 u64 num, u64 *out)
355{
356 return cxl_h_control_function(unit_address,
357 H_CONTROL_CA_FUNCTION_COLLECT_VPD,
358 record, list_address, num, 0,
359 out);
360}
361
362/**
363 * cxl_h_get_fn_error_interrupt - Read the function-wide error data based on an interrupt
364 */
365long cxl_h_get_fn_error_interrupt(u64 unit_address, u64 *reg)
366{
367 return cxl_h_control_function(unit_address,
368 H_CONTROL_CA_FUNCTION_GET_FUNCTION_ERR_INT,
369 0, 0, 0, 0, reg);
370}
371
372/**
373 * cxl_h_ack_fn_error_interrupt - Acknowledge function-wide error data
374 * based on an interrupt
375 * Parameter1 = value to write to the function-wide error interrupt register
376 */
377long cxl_h_ack_fn_error_interrupt(u64 unit_address, u64 value)
378{
379 return cxl_h_control_function(unit_address,
380 H_CONTROL_CA_FUNCTION_ACK_FUNCTION_ERR_INT,
381 value, 0, 0, 0,
382 NULL);
383}
384
385/**
386 * cxl_h_get_error_log - Retrieve the Platform Log ID (PLID) of
387 * an error log
388 */
389long cxl_h_get_error_log(u64 unit_address, u64 value)
390{
391 return cxl_h_control_function(unit_address,
392 H_CONTROL_CA_FUNCTION_GET_ERROR_LOG,
393 0, 0, 0, 0,
394 NULL);
395}
396
397/**
398 * cxl_h_collect_int_info - Collect interrupt info about a coherent
399 * platform function after an interrupt occurred.
400 */
401long cxl_h_collect_int_info(u64 unit_address, u64 process_token,
402 struct cxl_irq_info *info)
403{
404 long rc;
405
406 BUG_ON(sizeof(*info) != sizeof(unsigned long[PLPAR_HCALL9_BUFSIZE]));
407
408 rc = plpar_hcall9(H_COLLECT_CA_INT_INFO, (unsigned long *) info,
409 unit_address, process_token);
410 _PRINT_MSG(rc, "cxl_h_collect_int_info(%#.16llx, 0x%llx): %li\n",
411 unit_address, process_token, rc);
412 trace_cxl_hcall_collect_int_info(unit_address, process_token, rc);
413
414 switch (rc) {
415 case H_SUCCESS: /* The interrupt info is returned in return registers. */
416 pr_devel("dsisr:%#llx, dar:%#llx, dsr:%#llx, pid:%u, tid:%u, afu_err:%#llx, errstat:%#llx\n",
417 info->dsisr, info->dar, info->dsr, info->pid,
418 info->tid, info->afu_err, info->errstat);
419 return 0;
420 case H_PARAMETER: /* An incorrect parameter was supplied. */
421 return -EINVAL;
422 case H_AUTHORITY: /* The partition does not have authority to perform this hcall. */
423 case H_HARDWARE: /* A hardware event prevented the collection of the interrupt info.*/
424 case H_STATE: /* The coherent platform function is not in a valid state to collect interrupt info. */
425 return -EBUSY;
426 default:
427 WARN(1, "Unexpected return code: %lx", rc);
428 return -EINVAL;
429 }
430}
431
432/**
433 * cxl_h_control_faults - Control the operation of a coherent platform
434 * function after a fault occurs.
435 *
436 * Parameters
437 * control-mask: value to control the faults
438 * looks like PSL_TFC_An shifted >> 32
439 * reset-mask: mask to control reset of function faults
440 * Set reset_mask = 1 to reset PSL errors
441 */
442long cxl_h_control_faults(u64 unit_address, u64 process_token,
443 u64 control_mask, u64 reset_mask)
444{
445 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
446 long rc;
447
448 memset(retbuf, 0, sizeof(retbuf));
449
450 rc = plpar_hcall(H_CONTROL_CA_FAULTS, retbuf, unit_address,
451 H_CONTROL_CA_FAULTS_RESPOND_PSL, process_token,
452 control_mask, reset_mask);
453 _PRINT_MSG(rc, "cxl_h_control_faults(%#.16llx, 0x%llx, %#llx, %#llx): %li (%#lx)\n",
454 unit_address, process_token, control_mask, reset_mask,
455 rc, retbuf[0]);
456 trace_cxl_hcall_control_faults(unit_address, process_token,
457 control_mask, reset_mask, retbuf[0], rc);
458
459 switch (rc) {
460 case H_SUCCESS: /* Faults were successfully controlled for the function. */
461 return 0;
462 case H_PARAMETER: /* An incorrect parameter was supplied. */
463 return -EINVAL;
464 case H_HARDWARE: /* A hardware event prevented the control of faults. */
465 case H_STATE: /* The function was in an invalid state. */
466 case H_AUTHORITY: /* The partition does not have authority to perform this hcall; the coherent platform facilities may need to be licensed. */
467 return -EBUSY;
468 case H_FUNCTION: /* The function is not supported */
469 case H_NOT_FOUND: /* The operation supplied was not valid */
470 return -EINVAL;
471 default:
472 WARN(1, "Unexpected return code: %lx", rc);
473 return -EINVAL;
474 }
475}
476
477/**
478 * cxl_h_control_facility - This H_CONTROL_CA_FACILITY hypervisor call
479 * allows the partition to manipulate or query
480 * certain coherent platform facility behaviors.
481 */
482static long cxl_h_control_facility(u64 unit_address, u64 op,
483 u64 p1, u64 p2, u64 p3, u64 p4, u64 *out)
484{
485 unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
486 long rc;
487
488 CXL_H9_WAIT_UNTIL_DONE(rc, retbuf, H_CONTROL_CA_FACILITY, unit_address, op, p1, p2, p3, p4);
489 _PRINT_MSG(rc, "cxl_h_control_facility(%#.16llx, %s(%#llx, %#llx, %#llx, %#llx, R4: %#lx)): %li\n",
490 unit_address, OP_STR_CONTROL_ADAPTER(op), p1, p2, p3, p4, retbuf[0], rc);
491 trace_cxl_hcall_control_facility(unit_address, OP_STR_CONTROL_ADAPTER(op), p1, p2, p3, p4, retbuf[0], rc);
492
493 switch (rc) {
494 case H_SUCCESS: /* The operation is completed for the coherent platform facility */
495 if (op == H_CONTROL_CA_FACILITY_COLLECT_VPD)
496 *out = retbuf[0];
497 return 0;
498 case H_PARAMETER: /* An incorrect parameter was supplied. */
499 case H_FUNCTION: /* The function is not supported. */
500 case H_NOT_FOUND: /* The operation supplied was not valid */
501 case H_NOT_AVAILABLE: /* The operation cannot be performed because the AFU has not been downloaded */
502 case H_SG_LIST: /* An block list entry was invalid */
503 return -EINVAL;
504 case H_AUTHORITY: /* The partition does not have authority to perform this hcall */
505 case H_RESOURCE: /* The function has page table mappings for MMIO */
506 case H_HARDWARE: /* A hardware event prevented the attach operation */
507 case H_STATE: /* The coherent platform facility is not in a valid state */
508 case H_BUSY:
509 return -EBUSY;
510 default:
511 WARN(1, "Unexpected return code: %lx", rc);
512 return -EINVAL;
513 }
514}
515
516/**
517 * cxl_h_reset_adapter - Perform a reset to the coherent platform facility.
518 */
519long cxl_h_reset_adapter(u64 unit_address)
520{
521 return cxl_h_control_facility(unit_address,
522 H_CONTROL_CA_FACILITY_RESET,
523 0, 0, 0, 0,
524 NULL);
525}
526
527/**
528 * cxl_h_collect_vpd - Collect VPD for the coherent platform function.
529 * Parameter1 = 4K naturally aligned real buffer containing block
530 * list entries
531 * Parameter2 = number of block list entries in the block list, valid
532 * values are between 0 and 256
533 */
534long cxl_h_collect_vpd_adapter(u64 unit_address, u64 list_address,
535 u64 num, u64 *out)
536{
537 return cxl_h_control_facility(unit_address,
538 H_CONTROL_CA_FACILITY_COLLECT_VPD,
539 list_address, num, 0, 0,
540 out);
541}
542
543/**
544 * cxl_h_download_facility - This H_DOWNLOAD_CA_FACILITY
545 * hypervisor call provide platform support for
546 * downloading a base adapter image to the coherent
547 * platform facility, and for validating the entire
548 * image after the download.
549 * Parameters
550 * op: operation to perform to the coherent platform function
551 * Download: operation = 1, the base image in the coherent platform
552 * facility is first erased, and then
553 * programmed using the image supplied
554 * in the scatter/gather list.
555 * Validate: operation = 2, the base image in the coherent platform
556 * facility is compared with the image
557 * supplied in the scatter/gather list.
558 * list_address: 4K naturally aligned real buffer containing
559 * scatter/gather list entries.
560 * num: number of block list entries in the scatter/gather list.
561 */
562static long cxl_h_download_facility(u64 unit_address, u64 op,
563 u64 list_address, u64 num,
564 u64 *out)
565{
566 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
567 unsigned int delay, total_delay = 0;
568 u64 token = 0;
569 long rc;
570
571 if (*out != 0)
572 token = *out;
573
574 memset(retbuf, 0, sizeof(retbuf));
575 while (1) {
576 rc = plpar_hcall(H_DOWNLOAD_CA_FACILITY, retbuf,
577 unit_address, op, list_address, num,
578 token);
579 token = retbuf[0];
580 if (rc != H_BUSY && !H_IS_LONG_BUSY(rc))
581 break;
582
583 if (rc != H_BUSY) {
584 delay = get_longbusy_msecs(rc);
585 total_delay += delay;
586 if (total_delay > CXL_HCALL_TIMEOUT_DOWNLOAD) {
587 WARN(1, "Warning: Giving up waiting for CXL hcall "
588 "%#x after %u msec\n",
589 H_DOWNLOAD_CA_FACILITY, total_delay);
590 rc = H_BUSY;
591 break;
592 }
593 msleep(delay);
594 }
595 }
596 _PRINT_MSG(rc, "cxl_h_download_facility(%#.16llx, %s(%#llx, %#llx), %#lx): %li\n",
597 unit_address, OP_STR_DOWNLOAD_ADAPTER(op), list_address, num, retbuf[0], rc);
598 trace_cxl_hcall_download_facility(unit_address, OP_STR_DOWNLOAD_ADAPTER(op), list_address, num, retbuf[0], rc);
599
600 switch (rc) {
601 case H_SUCCESS: /* The operation is completed for the coherent platform facility */
602 return 0;
603 case H_PARAMETER: /* An incorrect parameter was supplied */
604 case H_FUNCTION: /* The function is not supported. */
605 case H_SG_LIST: /* An block list entry was invalid */
606 case H_BAD_DATA: /* Image verification failed */
607 return -EINVAL;
608 case H_AUTHORITY: /* The partition does not have authority to perform this hcall */
609 case H_RESOURCE: /* The function has page table mappings for MMIO */
610 case H_HARDWARE: /* A hardware event prevented the attach operation */
611 case H_STATE: /* The coherent platform facility is not in a valid state */
612 case H_BUSY:
613 return -EBUSY;
614 case H_CONTINUE:
615 *out = retbuf[0];
616 return 1; /* More data is needed for the complete image */
617 default:
618 WARN(1, "Unexpected return code: %lx", rc);
619 return -EINVAL;
620 }
621}
622
623/**
624 * cxl_h_download_adapter_image - Download the base image to the coherent
625 * platform facility.
626 */
627long cxl_h_download_adapter_image(u64 unit_address,
628 u64 list_address, u64 num,
629 u64 *out)
630{
631 return cxl_h_download_facility(unit_address,
632 H_DOWNLOAD_CA_FACILITY_DOWNLOAD,
633 list_address, num, out);
634}
635
636/**
637 * cxl_h_validate_adapter_image - Validate the base image in the coherent
638 * platform facility.
639 */
640long cxl_h_validate_adapter_image(u64 unit_address,
641 u64 list_address, u64 num,
642 u64 *out)
643{
644 return cxl_h_download_facility(unit_address,
645 H_DOWNLOAD_CA_FACILITY_VALIDATE,
646 list_address, num, out);
647}
diff --git a/drivers/misc/cxl/hcalls.h b/drivers/misc/cxl/hcalls.h
new file mode 100644
index 000000000000..3e25522a5df6
--- /dev/null
+++ b/drivers/misc/cxl/hcalls.h
@@ -0,0 +1,204 @@
1/*
2 * Copyright 2015 IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#ifndef _HCALLS_H
11#define _HCALLS_H
12
13#include <linux/types.h>
14#include <asm/byteorder.h>
15#include <asm/hvcall.h>
16#include "cxl.h"
17
18#define SG_BUFFER_SIZE 4096
19#define SG_MAX_ENTRIES 256
20
21struct sg_list {
22 u64 phys_addr;
23 u64 len;
24};
25
26/*
27 * This is straight out of PAPR, but replacing some of the compound fields with
28 * a single field, where they were identical to the register layout.
29 *
30 * The 'flags' parameter regroups the various bit-fields
31 */
32#define CXL_PE_CSRP_VALID (1ULL << 63)
33#define CXL_PE_PROBLEM_STATE (1ULL << 62)
34#define CXL_PE_SECONDARY_SEGMENT_TBL_SRCH (1ULL << 61)
35#define CXL_PE_TAGS_ACTIVE (1ULL << 60)
36#define CXL_PE_USER_STATE (1ULL << 59)
37#define CXL_PE_TRANSLATION_ENABLED (1ULL << 58)
38#define CXL_PE_64_BIT (1ULL << 57)
39#define CXL_PE_PRIVILEGED_PROCESS (1ULL << 56)
40
41#define CXL_PROCESS_ELEMENT_VERSION 1
42struct cxl_process_element_hcall {
43 __be64 version;
44 __be64 flags;
45 u8 reserved0[12];
46 __be32 pslVirtualIsn;
47 u8 applicationVirtualIsnBitmap[256];
48 u8 reserved1[144];
49 struct cxl_process_element_common common;
50 u8 reserved4[12];
51} __packed;
52
53#define H_STATE_NORMAL 1
54#define H_STATE_DISABLE 2
55#define H_STATE_TEMP_UNAVAILABLE 3
56#define H_STATE_PERM_UNAVAILABLE 4
57
58/* NOTE: element must be a logical real address, and must be pinned */
59long cxl_h_attach_process(u64 unit_address, struct cxl_process_element_hcall *element,
60 u64 *process_token, u64 *mmio_addr, u64 *mmio_size);
61
62/**
63 * cxl_h_detach_process - Detach a process element from a coherent
64 * platform function.
65 */
66long cxl_h_detach_process(u64 unit_address, u64 process_token);
67
68/**
69 * cxl_h_reset_afu - Perform a reset to the coherent platform function.
70 */
71long cxl_h_reset_afu(u64 unit_address);
72
73/**
74 * cxl_h_suspend_process - Suspend a process from being executed
75 * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
76 * process was attached.
77 */
78long cxl_h_suspend_process(u64 unit_address, u64 process_token);
79
80/**
81 * cxl_h_resume_process - Resume a process to be executed
82 * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
83 * process was attached.
84 */
85long cxl_h_resume_process(u64 unit_address, u64 process_token);
86
87/**
88 * cxl_h_read_error_state - Reads the error state of the coherent
89 * platform function.
90 * R4 contains the error state
91 */
92long cxl_h_read_error_state(u64 unit_address, u64 *state);
93
94/**
95 * cxl_h_get_afu_err - collect the AFU error buffer
96 * Parameter1 = byte offset into error buffer to retrieve, valid values
97 * are between 0 and (ibm,error-buffer-size - 1)
98 * Parameter2 = 4K aligned real address of error buffer, to be filled in
99 * Parameter3 = length of error buffer, valid values are 4K or less
100 */
101long cxl_h_get_afu_err(u64 unit_address, u64 offset, u64 buf_address, u64 len);
102
103/**
104 * cxl_h_get_config - collect configuration record for the
105 * coherent platform function
106 * Parameter1 = # of configuration record to retrieve, valid values are
107 * between 0 and (ibm,#config-records - 1)
108 * Parameter2 = byte offset into configuration record to retrieve,
109 * valid values are between 0 and (ibm,config-record-size - 1)
110 * Parameter3 = 4K aligned real address of configuration record buffer,
111 * to be filled in
112 * Parameter4 = length of configuration buffer, valid values are 4K or less
113 */
114long cxl_h_get_config(u64 unit_address, u64 cr_num, u64 offset,
115 u64 buf_address, u64 len);
116
117/**
118 * cxl_h_terminate_process - Terminate the process before completion
119 * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
120 * process was attached.
121 */
122long cxl_h_terminate_process(u64 unit_address, u64 process_token);
123
124/**
125 * cxl_h_collect_vpd - Collect VPD for the coherent platform function.
126 * Parameter1 = # of VPD record to retrieve, valid values are between 0
127 * and (ibm,#config-records - 1).
128 * Parameter2 = 4K naturally aligned real buffer containing block
129 * list entries
130 * Parameter3 = number of block list entries in the block list, valid
131 * values are between 0 and 256
132 */
133long cxl_h_collect_vpd(u64 unit_address, u64 record, u64 list_address,
134 u64 num, u64 *out);
135
136/**
137 * cxl_h_get_fn_error_interrupt - Read the function-wide error data based on an interrupt
138 */
139long cxl_h_get_fn_error_interrupt(u64 unit_address, u64 *reg);
140
141/**
142 * cxl_h_ack_fn_error_interrupt - Acknowledge function-wide error data
143 * based on an interrupt
144 * Parameter1 = value to write to the function-wide error interrupt register
145 */
146long cxl_h_ack_fn_error_interrupt(u64 unit_address, u64 value);
147
148/**
149 * cxl_h_get_error_log - Retrieve the Platform Log ID (PLID) of
150 * an error log
151 */
152long cxl_h_get_error_log(u64 unit_address, u64 value);
153
154/**
155 * cxl_h_collect_int_info - Collect interrupt info about a coherent
156 * platform function after an interrupt occurred.
157 */
158long cxl_h_collect_int_info(u64 unit_address, u64 process_token,
159 struct cxl_irq_info *info);
160
161/**
162 * cxl_h_control_faults - Control the operation of a coherent platform
163 * function after a fault occurs.
164 *
165 * Parameters
166 * control-mask: value to control the faults
167 * looks like PSL_TFC_An shifted >> 32
168 * reset-mask: mask to control reset of function faults
169 * Set reset_mask = 1 to reset PSL errors
170 */
171long cxl_h_control_faults(u64 unit_address, u64 process_token,
172 u64 control_mask, u64 reset_mask);
173
174/**
175 * cxl_h_reset_adapter - Perform a reset to the coherent platform facility.
176 */
177long cxl_h_reset_adapter(u64 unit_address);
178
179/**
180 * cxl_h_collect_vpd - Collect VPD for the coherent platform function.
181 * Parameter1 = 4K naturally aligned real buffer containing block
182 * list entries
183 * Parameter2 = number of block list entries in the block list, valid
184 * values are between 0 and 256
185 */
186long cxl_h_collect_vpd_adapter(u64 unit_address, u64 list_address,
187 u64 num, u64 *out);
188
189/**
190 * cxl_h_download_adapter_image - Download the base image to the coherent
191 * platform facility.
192 */
193long cxl_h_download_adapter_image(u64 unit_address,
194 u64 list_address, u64 num,
195 u64 *out);
196
197/**
198 * cxl_h_validate_adapter_image - Validate the base image in the coherent
199 * platform facility.
200 */
201long cxl_h_validate_adapter_image(u64 unit_address,
202 u64 list_address, u64 num,
203 u64 *out);
204#endif /* _HCALLS_H */
diff --git a/drivers/misc/cxl/irq.c b/drivers/misc/cxl/irq.c
index 09a406058c46..be646dc41a2c 100644
--- a/drivers/misc/cxl/irq.c
+++ b/drivers/misc/cxl/irq.c
@@ -19,70 +19,11 @@
19#include "cxl.h" 19#include "cxl.h"
20#include "trace.h" 20#include "trace.h"
21 21
22/* XXX: This is implementation specific */ 22static int afu_irq_range_start(void)
23static irqreturn_t handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr, u64 errstat)
24{ 23{
25 u64 fir1, fir2, fir_slice, serr, afu_debug; 24 if (cpu_has_feature(CPU_FTR_HVMODE))
26 25 return 1;
27 fir1 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR1); 26 return 0;
28 fir2 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR2);
29 fir_slice = cxl_p1n_read(ctx->afu, CXL_PSL_FIR_SLICE_An);
30 serr = cxl_p1n_read(ctx->afu, CXL_PSL_SERR_An);
31 afu_debug = cxl_p1n_read(ctx->afu, CXL_AFU_DEBUG_An);
32
33 dev_crit(&ctx->afu->dev, "PSL ERROR STATUS: 0x%016llx\n", errstat);
34 dev_crit(&ctx->afu->dev, "PSL_FIR1: 0x%016llx\n", fir1);
35 dev_crit(&ctx->afu->dev, "PSL_FIR2: 0x%016llx\n", fir2);
36 dev_crit(&ctx->afu->dev, "PSL_SERR_An: 0x%016llx\n", serr);
37 dev_crit(&ctx->afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice);
38 dev_crit(&ctx->afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug);
39
40 dev_crit(&ctx->afu->dev, "STOPPING CXL TRACE\n");
41 cxl_stop_trace(ctx->afu->adapter);
42
43 return cxl_ack_irq(ctx, 0, errstat);
44}
45
46irqreturn_t cxl_slice_irq_err(int irq, void *data)
47{
48 struct cxl_afu *afu = data;
49 u64 fir_slice, errstat, serr, afu_debug;
50
51 WARN(irq, "CXL SLICE ERROR interrupt %i\n", irq);
52
53 serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
54 fir_slice = cxl_p1n_read(afu, CXL_PSL_FIR_SLICE_An);
55 errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An);
56 afu_debug = cxl_p1n_read(afu, CXL_AFU_DEBUG_An);
57 dev_crit(&afu->dev, "PSL_SERR_An: 0x%016llx\n", serr);
58 dev_crit(&afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice);
59 dev_crit(&afu->dev, "CXL_PSL_ErrStat_An: 0x%016llx\n", errstat);
60 dev_crit(&afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug);
61
62 cxl_p1n_write(afu, CXL_PSL_SERR_An, serr);
63
64 return IRQ_HANDLED;
65}
66
67static irqreturn_t cxl_irq_err(int irq, void *data)
68{
69 struct cxl *adapter = data;
70 u64 fir1, fir2, err_ivte;
71
72 WARN(1, "CXL ERROR interrupt %i\n", irq);
73
74 err_ivte = cxl_p1_read(adapter, CXL_PSL_ErrIVTE);
75 dev_crit(&adapter->dev, "PSL_ErrIVTE: 0x%016llx\n", err_ivte);
76
77 dev_crit(&adapter->dev, "STOPPING CXL TRACE\n");
78 cxl_stop_trace(adapter);
79
80 fir1 = cxl_p1_read(adapter, CXL_PSL_FIR1);
81 fir2 = cxl_p1_read(adapter, CXL_PSL_FIR2);
82
83 dev_crit(&adapter->dev, "PSL_FIR1: 0x%016llx\nPSL_FIR2: 0x%016llx\n", fir1, fir2);
84
85 return IRQ_HANDLED;
86} 27}
87 28
88static irqreturn_t schedule_cxl_fault(struct cxl_context *ctx, u64 dsisr, u64 dar) 29static irqreturn_t schedule_cxl_fault(struct cxl_context *ctx, u64 dsisr, u64 dar)
@@ -93,9 +34,8 @@ static irqreturn_t schedule_cxl_fault(struct cxl_context *ctx, u64 dsisr, u64 da
93 return IRQ_HANDLED; 34 return IRQ_HANDLED;
94} 35}
95 36
96static irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info) 37irqreturn_t cxl_irq(int irq, struct cxl_context *ctx, struct cxl_irq_info *irq_info)
97{ 38{
98 struct cxl_context *ctx = data;
99 u64 dsisr, dar; 39 u64 dsisr, dar;
100 40
101 dsisr = irq_info->dsisr; 41 dsisr = irq_info->dsisr;
@@ -145,7 +85,8 @@ static irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info)
145 if (dsisr & CXL_PSL_DSISR_An_UR) 85 if (dsisr & CXL_PSL_DSISR_An_UR)
146 pr_devel("CXL interrupt: AURP PTE not found\n"); 86 pr_devel("CXL interrupt: AURP PTE not found\n");
147 if (dsisr & CXL_PSL_DSISR_An_PE) 87 if (dsisr & CXL_PSL_DSISR_An_PE)
148 return handle_psl_slice_error(ctx, dsisr, irq_info->errstat); 88 return cxl_ops->handle_psl_slice_error(ctx, dsisr,
89 irq_info->errstat);
149 if (dsisr & CXL_PSL_DSISR_An_AE) { 90 if (dsisr & CXL_PSL_DSISR_An_AE) {
150 pr_devel("CXL interrupt: AFU Error 0x%016llx\n", irq_info->afu_err); 91 pr_devel("CXL interrupt: AFU Error 0x%016llx\n", irq_info->afu_err);
151 92
@@ -169,7 +110,7 @@ static irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info)
169 wake_up_all(&ctx->wq); 110 wake_up_all(&ctx->wq);
170 } 111 }
171 112
172 cxl_ack_irq(ctx, CXL_PSL_TFC_An_A, 0); 113 cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_A, 0);
173 return IRQ_HANDLED; 114 return IRQ_HANDLED;
174 } 115 }
175 if (dsisr & CXL_PSL_DSISR_An_OC) 116 if (dsisr & CXL_PSL_DSISR_An_OC)
@@ -179,54 +120,27 @@ static irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info)
179 return IRQ_HANDLED; 120 return IRQ_HANDLED;
180} 121}
181 122
182static irqreturn_t fail_psl_irq(struct cxl_afu *afu, struct cxl_irq_info *irq_info)
183{
184 if (irq_info->dsisr & CXL_PSL_DSISR_TRANS)
185 cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);
186 else
187 cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A);
188
189 return IRQ_HANDLED;
190}
191
192static irqreturn_t cxl_irq_multiplexed(int irq, void *data)
193{
194 struct cxl_afu *afu = data;
195 struct cxl_context *ctx;
196 struct cxl_irq_info irq_info;
197 int ph = cxl_p2n_read(afu, CXL_PSL_PEHandle_An) & 0xffff;
198 int ret;
199
200 if ((ret = cxl_get_irq(afu, &irq_info))) {
201 WARN(1, "Unable to get CXL IRQ Info: %i\n", ret);
202 return fail_psl_irq(afu, &irq_info);
203 }
204
205 rcu_read_lock();
206 ctx = idr_find(&afu->contexts_idr, ph);
207 if (ctx) {
208 ret = cxl_irq(irq, ctx, &irq_info);
209 rcu_read_unlock();
210 return ret;
211 }
212 rcu_read_unlock();
213
214 WARN(1, "Unable to demultiplex CXL PSL IRQ for PE %i DSISR %016llx DAR"
215 " %016llx\n(Possible AFU HW issue - was a term/remove acked"
216 " with outstanding transactions?)\n", ph, irq_info.dsisr,
217 irq_info.dar);
218 return fail_psl_irq(afu, &irq_info);
219}
220
221static irqreturn_t cxl_irq_afu(int irq, void *data) 123static irqreturn_t cxl_irq_afu(int irq, void *data)
222{ 124{
223 struct cxl_context *ctx = data; 125 struct cxl_context *ctx = data;
224 irq_hw_number_t hwirq = irqd_to_hwirq(irq_get_irq_data(irq)); 126 irq_hw_number_t hwirq = irqd_to_hwirq(irq_get_irq_data(irq));
225 int irq_off, afu_irq = 1; 127 int irq_off, afu_irq = 0;
226 __u16 range; 128 __u16 range;
227 int r; 129 int r;
228 130
229 for (r = 1; r < CXL_IRQ_RANGES; r++) { 131 /*
132 * Look for the interrupt number.
133 * On bare-metal, we know range 0 only contains the PSL
134 * interrupt so we could start counting at range 1 and initialize
135 * afu_irq at 1.
136 * In a guest, range 0 also contains AFU interrupts, so it must
137 * be counted for. Therefore we initialize afu_irq at 0 to take into
138 * account the PSL interrupt.
139 *
140 * For code-readability, it just seems easier to go over all
141 * the ranges on bare-metal and guest. The end result is the same.
142 */
143 for (r = 0; r < CXL_IRQ_RANGES; r++) {
230 irq_off = hwirq - ctx->irqs.offset[r]; 144 irq_off = hwirq - ctx->irqs.offset[r];
231 range = ctx->irqs.range[r]; 145 range = ctx->irqs.range[r];
232 if (irq_off >= 0 && irq_off < range) { 146 if (irq_off >= 0 && irq_off < range) {
@@ -236,7 +150,7 @@ static irqreturn_t cxl_irq_afu(int irq, void *data)
236 afu_irq += range; 150 afu_irq += range;
237 } 151 }
238 if (unlikely(r >= CXL_IRQ_RANGES)) { 152 if (unlikely(r >= CXL_IRQ_RANGES)) {
239 WARN(1, "Recieved AFU IRQ out of range for pe %i (virq %i hwirq %lx)\n", 153 WARN(1, "Received AFU IRQ out of range for pe %i (virq %i hwirq %lx)\n",
240 ctx->pe, irq, hwirq); 154 ctx->pe, irq, hwirq);
241 return IRQ_HANDLED; 155 return IRQ_HANDLED;
242 } 156 }
@@ -246,7 +160,7 @@ static irqreturn_t cxl_irq_afu(int irq, void *data)
246 afu_irq, ctx->pe, irq, hwirq); 160 afu_irq, ctx->pe, irq, hwirq);
247 161
248 if (unlikely(!ctx->irq_bitmap)) { 162 if (unlikely(!ctx->irq_bitmap)) {
249 WARN(1, "Recieved AFU IRQ for context with no IRQ bitmap\n"); 163 WARN(1, "Received AFU IRQ for context with no IRQ bitmap\n");
250 return IRQ_HANDLED; 164 return IRQ_HANDLED;
251 } 165 }
252 spin_lock(&ctx->lock); 166 spin_lock(&ctx->lock);
@@ -272,7 +186,8 @@ unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq,
272 return 0; 186 return 0;
273 } 187 }
274 188
275 cxl_setup_irq(adapter, hwirq, virq); 189 if (cxl_ops->setup_irq)
190 cxl_ops->setup_irq(adapter, hwirq, virq);
276 191
277 pr_devel("hwirq %#lx mapped to virq %u\n", hwirq, virq); 192 pr_devel("hwirq %#lx mapped to virq %u\n", hwirq, virq);
278 193
@@ -291,16 +206,16 @@ void cxl_unmap_irq(unsigned int virq, void *cookie)
291 irq_dispose_mapping(virq); 206 irq_dispose_mapping(virq);
292} 207}
293 208
294static int cxl_register_one_irq(struct cxl *adapter, 209int cxl_register_one_irq(struct cxl *adapter,
295 irq_handler_t handler, 210 irq_handler_t handler,
296 void *cookie, 211 void *cookie,
297 irq_hw_number_t *dest_hwirq, 212 irq_hw_number_t *dest_hwirq,
298 unsigned int *dest_virq, 213 unsigned int *dest_virq,
299 const char *name) 214 const char *name)
300{ 215{
301 int hwirq, virq; 216 int hwirq, virq;
302 217
303 if ((hwirq = cxl_alloc_one_irq(adapter)) < 0) 218 if ((hwirq = cxl_ops->alloc_one_irq(adapter)) < 0)
304 return hwirq; 219 return hwirq;
305 220
306 if (!(virq = cxl_map_irq(adapter, hwirq, handler, cookie, name))) 221 if (!(virq = cxl_map_irq(adapter, hwirq, handler, cookie, name)))
@@ -312,108 +227,10 @@ static int cxl_register_one_irq(struct cxl *adapter,
312 return 0; 227 return 0;
313 228
314err: 229err:
315 cxl_release_one_irq(adapter, hwirq); 230 cxl_ops->release_one_irq(adapter, hwirq);
316 return -ENOMEM; 231 return -ENOMEM;
317} 232}
318 233
319int cxl_register_psl_err_irq(struct cxl *adapter)
320{
321 int rc;
322
323 adapter->irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
324 dev_name(&adapter->dev));
325 if (!adapter->irq_name)
326 return -ENOMEM;
327
328 if ((rc = cxl_register_one_irq(adapter, cxl_irq_err, adapter,
329 &adapter->err_hwirq,
330 &adapter->err_virq,
331 adapter->irq_name))) {
332 kfree(adapter->irq_name);
333 adapter->irq_name = NULL;
334 return rc;
335 }
336
337 cxl_p1_write(adapter, CXL_PSL_ErrIVTE, adapter->err_hwirq & 0xffff);
338
339 return 0;
340}
341
342void cxl_release_psl_err_irq(struct cxl *adapter)
343{
344 if (adapter->err_virq != irq_find_mapping(NULL, adapter->err_hwirq))
345 return;
346
347 cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000);
348 cxl_unmap_irq(adapter->err_virq, adapter);
349 cxl_release_one_irq(adapter, adapter->err_hwirq);
350 kfree(adapter->irq_name);
351}
352
353int cxl_register_serr_irq(struct cxl_afu *afu)
354{
355 u64 serr;
356 int rc;
357
358 afu->err_irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
359 dev_name(&afu->dev));
360 if (!afu->err_irq_name)
361 return -ENOMEM;
362
363 if ((rc = cxl_register_one_irq(afu->adapter, cxl_slice_irq_err, afu,
364 &afu->serr_hwirq,
365 &afu->serr_virq, afu->err_irq_name))) {
366 kfree(afu->err_irq_name);
367 afu->err_irq_name = NULL;
368 return rc;
369 }
370
371 serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
372 serr = (serr & 0x00ffffffffff0000ULL) | (afu->serr_hwirq & 0xffff);
373 cxl_p1n_write(afu, CXL_PSL_SERR_An, serr);
374
375 return 0;
376}
377
378void cxl_release_serr_irq(struct cxl_afu *afu)
379{
380 if (afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq))
381 return;
382
383 cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000);
384 cxl_unmap_irq(afu->serr_virq, afu);
385 cxl_release_one_irq(afu->adapter, afu->serr_hwirq);
386 kfree(afu->err_irq_name);
387}
388
389int cxl_register_psl_irq(struct cxl_afu *afu)
390{
391 int rc;
392
393 afu->psl_irq_name = kasprintf(GFP_KERNEL, "cxl-%s",
394 dev_name(&afu->dev));
395 if (!afu->psl_irq_name)
396 return -ENOMEM;
397
398 if ((rc = cxl_register_one_irq(afu->adapter, cxl_irq_multiplexed, afu,
399 &afu->psl_hwirq, &afu->psl_virq,
400 afu->psl_irq_name))) {
401 kfree(afu->psl_irq_name);
402 afu->psl_irq_name = NULL;
403 }
404 return rc;
405}
406
407void cxl_release_psl_irq(struct cxl_afu *afu)
408{
409 if (afu->psl_virq != irq_find_mapping(NULL, afu->psl_hwirq))
410 return;
411
412 cxl_unmap_irq(afu->psl_virq, afu);
413 cxl_release_one_irq(afu->adapter, afu->psl_hwirq);
414 kfree(afu->psl_irq_name);
415}
416
417void afu_irq_name_free(struct cxl_context *ctx) 234void afu_irq_name_free(struct cxl_context *ctx)
418{ 235{
419 struct cxl_irq_name *irq_name, *tmp; 236 struct cxl_irq_name *irq_name, *tmp;
@@ -429,16 +246,33 @@ int afu_allocate_irqs(struct cxl_context *ctx, u32 count)
429{ 246{
430 int rc, r, i, j = 1; 247 int rc, r, i, j = 1;
431 struct cxl_irq_name *irq_name; 248 struct cxl_irq_name *irq_name;
249 int alloc_count;
250
251 /*
252 * In native mode, range 0 is reserved for the multiplexed
253 * PSL interrupt. It has been allocated when the AFU was initialized.
254 *
255 * In a guest, the PSL interrupt is not mutliplexed, but per-context,
256 * and is the first interrupt from range 0. It still needs to be
257 * allocated, so bump the count by one.
258 */
259 if (cpu_has_feature(CPU_FTR_HVMODE))
260 alloc_count = count;
261 else
262 alloc_count = count + 1;
432 263
433 /* Initialize the list head to hold irq names */ 264 /* Initialize the list head to hold irq names */
434 INIT_LIST_HEAD(&ctx->irq_names); 265 INIT_LIST_HEAD(&ctx->irq_names);
435 266
436 if ((rc = cxl_alloc_irq_ranges(&ctx->irqs, ctx->afu->adapter, count))) 267 if ((rc = cxl_ops->alloc_irq_ranges(&ctx->irqs, ctx->afu->adapter,
268 alloc_count)))
437 return rc; 269 return rc;
438 270
439 /* Multiplexed PSL Interrupt */ 271 if (cpu_has_feature(CPU_FTR_HVMODE)) {
440 ctx->irqs.offset[0] = ctx->afu->psl_hwirq; 272 /* Multiplexed PSL Interrupt */
441 ctx->irqs.range[0] = 1; 273 ctx->irqs.offset[0] = ctx->afu->native->psl_hwirq;
274 ctx->irqs.range[0] = 1;
275 }
442 276
443 ctx->irq_count = count; 277 ctx->irq_count = count;
444 ctx->irq_bitmap = kcalloc(BITS_TO_LONGS(count), 278 ctx->irq_bitmap = kcalloc(BITS_TO_LONGS(count),
@@ -450,7 +284,7 @@ int afu_allocate_irqs(struct cxl_context *ctx, u32 count)
450 * Allocate names first. If any fail, bail out before allocating 284 * Allocate names first. If any fail, bail out before allocating
451 * actual hardware IRQs. 285 * actual hardware IRQs.
452 */ 286 */
453 for (r = 1; r < CXL_IRQ_RANGES; r++) { 287 for (r = afu_irq_range_start(); r < CXL_IRQ_RANGES; r++) {
454 for (i = 0; i < ctx->irqs.range[r]; i++) { 288 for (i = 0; i < ctx->irqs.range[r]; i++) {
455 irq_name = kmalloc(sizeof(struct cxl_irq_name), 289 irq_name = kmalloc(sizeof(struct cxl_irq_name),
456 GFP_KERNEL); 290 GFP_KERNEL);
@@ -471,7 +305,7 @@ int afu_allocate_irqs(struct cxl_context *ctx, u32 count)
471 return 0; 305 return 0;
472 306
473out: 307out:
474 cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter); 308 cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
475 afu_irq_name_free(ctx); 309 afu_irq_name_free(ctx);
476 return -ENOMEM; 310 return -ENOMEM;
477} 311}
@@ -480,15 +314,30 @@ static void afu_register_hwirqs(struct cxl_context *ctx)
480{ 314{
481 irq_hw_number_t hwirq; 315 irq_hw_number_t hwirq;
482 struct cxl_irq_name *irq_name; 316 struct cxl_irq_name *irq_name;
483 int r,i; 317 int r, i;
318 irqreturn_t (*handler)(int irq, void *data);
484 319
485 /* We've allocated all memory now, so let's do the irq allocations */ 320 /* We've allocated all memory now, so let's do the irq allocations */
486 irq_name = list_first_entry(&ctx->irq_names, struct cxl_irq_name, list); 321 irq_name = list_first_entry(&ctx->irq_names, struct cxl_irq_name, list);
487 for (r = 1; r < CXL_IRQ_RANGES; r++) { 322 for (r = afu_irq_range_start(); r < CXL_IRQ_RANGES; r++) {
488 hwirq = ctx->irqs.offset[r]; 323 hwirq = ctx->irqs.offset[r];
489 for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) { 324 for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
490 cxl_map_irq(ctx->afu->adapter, hwirq, 325 if (r == 0 && i == 0)
491 cxl_irq_afu, ctx, irq_name->name); 326 /*
327 * The very first interrupt of range 0 is
328 * always the PSL interrupt, but we only
329 * need to connect a handler for guests,
330 * because there's one PSL interrupt per
331 * context.
332 * On bare-metal, the PSL interrupt is
333 * multiplexed and was setup when the AFU
334 * was configured.
335 */
336 handler = cxl_ops->psl_interrupt;
337 else
338 handler = cxl_irq_afu;
339 cxl_map_irq(ctx->afu->adapter, hwirq, handler, ctx,
340 irq_name->name);
492 irq_name = list_next_entry(irq_name, list); 341 irq_name = list_next_entry(irq_name, list);
493 } 342 }
494 } 343 }
@@ -504,7 +353,7 @@ int afu_register_irqs(struct cxl_context *ctx, u32 count)
504 353
505 afu_register_hwirqs(ctx); 354 afu_register_hwirqs(ctx);
506 return 0; 355 return 0;
507 } 356}
508 357
509void afu_release_irqs(struct cxl_context *ctx, void *cookie) 358void afu_release_irqs(struct cxl_context *ctx, void *cookie)
510{ 359{
@@ -512,7 +361,7 @@ void afu_release_irqs(struct cxl_context *ctx, void *cookie)
512 unsigned int virq; 361 unsigned int virq;
513 int r, i; 362 int r, i;
514 363
515 for (r = 1; r < CXL_IRQ_RANGES; r++) { 364 for (r = afu_irq_range_start(); r < CXL_IRQ_RANGES; r++) {
516 hwirq = ctx->irqs.offset[r]; 365 hwirq = ctx->irqs.offset[r];
517 for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) { 366 for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
518 virq = irq_find_mapping(NULL, hwirq); 367 virq = irq_find_mapping(NULL, hwirq);
@@ -522,7 +371,7 @@ void afu_release_irqs(struct cxl_context *ctx, void *cookie)
522 } 371 }
523 372
524 afu_irq_name_free(ctx); 373 afu_irq_name_free(ctx);
525 cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter); 374 cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
526 375
527 ctx->irq_count = 0; 376 ctx->irq_count = 0;
528} 377}
diff --git a/drivers/misc/cxl/main.c b/drivers/misc/cxl/main.c
index 9fde75ed4fac..ae68c3201156 100644
--- a/drivers/misc/cxl/main.c
+++ b/drivers/misc/cxl/main.c
@@ -32,6 +32,29 @@ uint cxl_verbose;
32module_param_named(verbose, cxl_verbose, uint, 0600); 32module_param_named(verbose, cxl_verbose, uint, 0600);
33MODULE_PARM_DESC(verbose, "Enable verbose dmesg output"); 33MODULE_PARM_DESC(verbose, "Enable verbose dmesg output");
34 34
35const struct cxl_backend_ops *cxl_ops;
36
37int cxl_afu_slbia(struct cxl_afu *afu)
38{
39 unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
40
41 pr_devel("cxl_afu_slbia issuing SLBIA command\n");
42 cxl_p2n_write(afu, CXL_SLBIA_An, CXL_TLB_SLB_IQ_ALL);
43 while (cxl_p2n_read(afu, CXL_SLBIA_An) & CXL_TLB_SLB_P) {
44 if (time_after_eq(jiffies, timeout)) {
45 dev_warn(&afu->dev, "WARNING: CXL AFU SLBIA timed out!\n");
46 return -EBUSY;
47 }
48 /* If the adapter has gone down, we can assume that we
49 * will PERST it and that will invalidate everything.
50 */
51 if (!cxl_ops->link_ok(afu->adapter, afu))
52 return -EIO;
53 cpu_relax();
54 }
55 return 0;
56}
57
35static inline void _cxl_slbia(struct cxl_context *ctx, struct mm_struct *mm) 58static inline void _cxl_slbia(struct cxl_context *ctx, struct mm_struct *mm)
36{ 59{
37 struct task_struct *task; 60 struct task_struct *task;
@@ -139,6 +162,32 @@ int cxl_alloc_sst(struct cxl_context *ctx)
139 return 0; 162 return 0;
140} 163}
141 164
165/* print buffer content as integers when debugging */
166void cxl_dump_debug_buffer(void *buf, size_t buf_len)
167{
168#ifdef DEBUG
169 int i, *ptr;
170
171 /*
172 * We want to regroup up to 4 integers per line, which means they
173 * need to be in the same pr_devel() statement
174 */
175 ptr = (int *) buf;
176 for (i = 0; i * 4 < buf_len; i += 4) {
177 if ((i + 3) * 4 < buf_len)
178 pr_devel("%.8x %.8x %.8x %.8x\n", ptr[i], ptr[i + 1],
179 ptr[i + 2], ptr[i + 3]);
180 else if ((i + 2) * 4 < buf_len)
181 pr_devel("%.8x %.8x %.8x\n", ptr[i], ptr[i + 1],
182 ptr[i + 2]);
183 else if ((i + 1) * 4 < buf_len)
184 pr_devel("%.8x %.8x\n", ptr[i], ptr[i + 1]);
185 else
186 pr_devel("%.8x\n", ptr[i]);
187 }
188#endif /* DEBUG */
189}
190
142/* Find a CXL adapter by it's number and increase it's refcount */ 191/* Find a CXL adapter by it's number and increase it's refcount */
143struct cxl *get_cxl_adapter(int num) 192struct cxl *get_cxl_adapter(int num)
144{ 193{
@@ -152,7 +201,7 @@ struct cxl *get_cxl_adapter(int num)
152 return adapter; 201 return adapter;
153} 202}
154 203
155int cxl_alloc_adapter_nr(struct cxl *adapter) 204static int cxl_alloc_adapter_nr(struct cxl *adapter)
156{ 205{
157 int i; 206 int i;
158 207
@@ -174,13 +223,58 @@ void cxl_remove_adapter_nr(struct cxl *adapter)
174 idr_remove(&cxl_adapter_idr, adapter->adapter_num); 223 idr_remove(&cxl_adapter_idr, adapter->adapter_num);
175} 224}
176 225
226struct cxl *cxl_alloc_adapter(void)
227{
228 struct cxl *adapter;
229
230 if (!(adapter = kzalloc(sizeof(struct cxl), GFP_KERNEL)))
231 return NULL;
232
233 spin_lock_init(&adapter->afu_list_lock);
234
235 if (cxl_alloc_adapter_nr(adapter))
236 goto err1;
237
238 if (dev_set_name(&adapter->dev, "card%i", adapter->adapter_num))
239 goto err2;
240
241 return adapter;
242
243err2:
244 cxl_remove_adapter_nr(adapter);
245err1:
246 kfree(adapter);
247 return NULL;
248}
249
250struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice)
251{
252 struct cxl_afu *afu;
253
254 if (!(afu = kzalloc(sizeof(struct cxl_afu), GFP_KERNEL)))
255 return NULL;
256
257 afu->adapter = adapter;
258 afu->dev.parent = &adapter->dev;
259 afu->dev.release = cxl_ops->release_afu;
260 afu->slice = slice;
261 idr_init(&afu->contexts_idr);
262 mutex_init(&afu->contexts_lock);
263 spin_lock_init(&afu->afu_cntl_lock);
264
265 afu->prefault_mode = CXL_PREFAULT_NONE;
266 afu->irqs_max = afu->adapter->user_irqs;
267
268 return afu;
269}
270
177int cxl_afu_select_best_mode(struct cxl_afu *afu) 271int cxl_afu_select_best_mode(struct cxl_afu *afu)
178{ 272{
179 if (afu->modes_supported & CXL_MODE_DIRECTED) 273 if (afu->modes_supported & CXL_MODE_DIRECTED)
180 return cxl_afu_activate_mode(afu, CXL_MODE_DIRECTED); 274 return cxl_ops->afu_activate_mode(afu, CXL_MODE_DIRECTED);
181 275
182 if (afu->modes_supported & CXL_MODE_DEDICATED) 276 if (afu->modes_supported & CXL_MODE_DEDICATED)
183 return cxl_afu_activate_mode(afu, CXL_MODE_DEDICATED); 277 return cxl_ops->afu_activate_mode(afu, CXL_MODE_DEDICATED);
184 278
185 dev_warn(&afu->dev, "No supported programming modes available\n"); 279 dev_warn(&afu->dev, "No supported programming modes available\n");
186 /* We don't fail this so the user can inspect sysfs */ 280 /* We don't fail this so the user can inspect sysfs */
@@ -191,9 +285,6 @@ static int __init init_cxl(void)
191{ 285{
192 int rc = 0; 286 int rc = 0;
193 287
194 if (!cpu_has_feature(CPU_FTR_HVMODE))
195 return -EPERM;
196
197 if ((rc = cxl_file_init())) 288 if ((rc = cxl_file_init()))
198 return rc; 289 return rc;
199 290
@@ -202,7 +293,17 @@ static int __init init_cxl(void)
202 if ((rc = register_cxl_calls(&cxl_calls))) 293 if ((rc = register_cxl_calls(&cxl_calls)))
203 goto err; 294 goto err;
204 295
205 if ((rc = pci_register_driver(&cxl_pci_driver))) 296 if (cpu_has_feature(CPU_FTR_HVMODE)) {
297 cxl_ops = &cxl_native_ops;
298 rc = pci_register_driver(&cxl_pci_driver);
299 }
300#ifdef CONFIG_PPC_PSERIES
301 else {
302 cxl_ops = &cxl_guest_ops;
303 rc = platform_driver_register(&cxl_of_driver);
304 }
305#endif
306 if (rc)
206 goto err1; 307 goto err1;
207 308
208 return 0; 309 return 0;
@@ -217,7 +318,12 @@ err:
217 318
218static void exit_cxl(void) 319static void exit_cxl(void)
219{ 320{
220 pci_unregister_driver(&cxl_pci_driver); 321 if (cpu_has_feature(CPU_FTR_HVMODE))
322 pci_unregister_driver(&cxl_pci_driver);
323#ifdef CONFIG_PPC_PSERIES
324 else
325 platform_driver_unregister(&cxl_of_driver);
326#endif
221 327
222 cxl_debugfs_exit(); 328 cxl_debugfs_exit();
223 cxl_file_exit(); 329 cxl_file_exit();
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index f40909793490..387fcbdf9793 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -42,7 +42,7 @@ static int afu_control(struct cxl_afu *afu, u64 command,
42 goto out; 42 goto out;
43 } 43 }
44 44
45 if (!cxl_adapter_link_ok(afu->adapter)) { 45 if (!cxl_ops->link_ok(afu->adapter, afu)) {
46 afu->enabled = enabled; 46 afu->enabled = enabled;
47 rc = -EIO; 47 rc = -EIO;
48 goto out; 48 goto out;
@@ -80,7 +80,7 @@ int cxl_afu_disable(struct cxl_afu *afu)
80} 80}
81 81
82/* This will disable as well as reset */ 82/* This will disable as well as reset */
83int __cxl_afu_reset(struct cxl_afu *afu) 83static int native_afu_reset(struct cxl_afu *afu)
84{ 84{
85 pr_devel("AFU reset request\n"); 85 pr_devel("AFU reset request\n");
86 86
@@ -90,9 +90,9 @@ int __cxl_afu_reset(struct cxl_afu *afu)
90 false); 90 false);
91} 91}
92 92
93int cxl_afu_check_and_enable(struct cxl_afu *afu) 93static int native_afu_check_and_enable(struct cxl_afu *afu)
94{ 94{
95 if (!cxl_adapter_link_ok(afu->adapter)) { 95 if (!cxl_ops->link_ok(afu->adapter, afu)) {
96 WARN(1, "Refusing to enable afu while link down!\n"); 96 WARN(1, "Refusing to enable afu while link down!\n");
97 return -EIO; 97 return -EIO;
98 } 98 }
@@ -114,7 +114,7 @@ int cxl_psl_purge(struct cxl_afu *afu)
114 114
115 pr_devel("PSL purge request\n"); 115 pr_devel("PSL purge request\n");
116 116
117 if (!cxl_adapter_link_ok(afu->adapter)) { 117 if (!cxl_ops->link_ok(afu->adapter, afu)) {
118 dev_warn(&afu->dev, "PSL Purge called with link down, ignoring\n"); 118 dev_warn(&afu->dev, "PSL Purge called with link down, ignoring\n");
119 rc = -EIO; 119 rc = -EIO;
120 goto out; 120 goto out;
@@ -136,7 +136,7 @@ int cxl_psl_purge(struct cxl_afu *afu)
136 rc = -EBUSY; 136 rc = -EBUSY;
137 goto out; 137 goto out;
138 } 138 }
139 if (!cxl_adapter_link_ok(afu->adapter)) { 139 if (!cxl_ops->link_ok(afu->adapter, afu)) {
140 rc = -EIO; 140 rc = -EIO;
141 goto out; 141 goto out;
142 } 142 }
@@ -186,22 +186,22 @@ static int spa_max_procs(int spa_size)
186int cxl_alloc_spa(struct cxl_afu *afu) 186int cxl_alloc_spa(struct cxl_afu *afu)
187{ 187{
188 /* Work out how many pages to allocate */ 188 /* Work out how many pages to allocate */
189 afu->spa_order = 0; 189 afu->native->spa_order = 0;
190 do { 190 do {
191 afu->spa_order++; 191 afu->native->spa_order++;
192 afu->spa_size = (1 << afu->spa_order) * PAGE_SIZE; 192 afu->native->spa_size = (1 << afu->native->spa_order) * PAGE_SIZE;
193 afu->spa_max_procs = spa_max_procs(afu->spa_size); 193 afu->native->spa_max_procs = spa_max_procs(afu->native->spa_size);
194 } while (afu->spa_max_procs < afu->num_procs); 194 } while (afu->native->spa_max_procs < afu->num_procs);
195 195
196 WARN_ON(afu->spa_size > 0x100000); /* Max size supported by the hardware */ 196 WARN_ON(afu->native->spa_size > 0x100000); /* Max size supported by the hardware */
197 197
198 if (!(afu->spa = (struct cxl_process_element *) 198 if (!(afu->native->spa = (struct cxl_process_element *)
199 __get_free_pages(GFP_KERNEL | __GFP_ZERO, afu->spa_order))) { 199 __get_free_pages(GFP_KERNEL | __GFP_ZERO, afu->native->spa_order))) {
200 pr_err("cxl_alloc_spa: Unable to allocate scheduled process area\n"); 200 pr_err("cxl_alloc_spa: Unable to allocate scheduled process area\n");
201 return -ENOMEM; 201 return -ENOMEM;
202 } 202 }
203 pr_devel("spa pages: %i afu->spa_max_procs: %i afu->num_procs: %i\n", 203 pr_devel("spa pages: %i afu->spa_max_procs: %i afu->num_procs: %i\n",
204 1<<afu->spa_order, afu->spa_max_procs, afu->num_procs); 204 1<<afu->native->spa_order, afu->native->spa_max_procs, afu->num_procs);
205 205
206 return 0; 206 return 0;
207} 207}
@@ -210,13 +210,15 @@ static void attach_spa(struct cxl_afu *afu)
210{ 210{
211 u64 spap; 211 u64 spap;
212 212
213 afu->sw_command_status = (__be64 *)((char *)afu->spa + 213 afu->native->sw_command_status = (__be64 *)((char *)afu->native->spa +
214 ((afu->spa_max_procs + 3) * 128)); 214 ((afu->native->spa_max_procs + 3) * 128));
215 215
216 spap = virt_to_phys(afu->spa) & CXL_PSL_SPAP_Addr; 216 spap = virt_to_phys(afu->native->spa) & CXL_PSL_SPAP_Addr;
217 spap |= ((afu->spa_size >> (12 - CXL_PSL_SPAP_Size_Shift)) - 1) & CXL_PSL_SPAP_Size; 217 spap |= ((afu->native->spa_size >> (12 - CXL_PSL_SPAP_Size_Shift)) - 1) & CXL_PSL_SPAP_Size;
218 spap |= CXL_PSL_SPAP_V; 218 spap |= CXL_PSL_SPAP_V;
219 pr_devel("cxl: SPA allocated at 0x%p. Max processes: %i, sw_command_status: 0x%p CXL_PSL_SPAP_An=0x%016llx\n", afu->spa, afu->spa_max_procs, afu->sw_command_status, spap); 219 pr_devel("cxl: SPA allocated at 0x%p. Max processes: %i, sw_command_status: 0x%p CXL_PSL_SPAP_An=0x%016llx\n",
220 afu->native->spa, afu->native->spa_max_procs,
221 afu->native->sw_command_status, spap);
220 cxl_p1n_write(afu, CXL_PSL_SPAP_An, spap); 222 cxl_p1n_write(afu, CXL_PSL_SPAP_An, spap);
221} 223}
222 224
@@ -227,9 +229,10 @@ static inline void detach_spa(struct cxl_afu *afu)
227 229
228void cxl_release_spa(struct cxl_afu *afu) 230void cxl_release_spa(struct cxl_afu *afu)
229{ 231{
230 if (afu->spa) { 232 if (afu->native->spa) {
231 free_pages((unsigned long) afu->spa, afu->spa_order); 233 free_pages((unsigned long) afu->native->spa,
232 afu->spa = NULL; 234 afu->native->spa_order);
235 afu->native->spa = NULL;
233 } 236 }
234} 237}
235 238
@@ -247,7 +250,7 @@ int cxl_tlb_slb_invalidate(struct cxl *adapter)
247 dev_warn(&adapter->dev, "WARNING: CXL adapter wide TLBIA timed out!\n"); 250 dev_warn(&adapter->dev, "WARNING: CXL adapter wide TLBIA timed out!\n");
248 return -EBUSY; 251 return -EBUSY;
249 } 252 }
250 if (!cxl_adapter_link_ok(adapter)) 253 if (!cxl_ops->link_ok(adapter, NULL))
251 return -EIO; 254 return -EIO;
252 cpu_relax(); 255 cpu_relax();
253 } 256 }
@@ -258,28 +261,7 @@ int cxl_tlb_slb_invalidate(struct cxl *adapter)
258 dev_warn(&adapter->dev, "WARNING: CXL adapter wide SLBIA timed out!\n"); 261 dev_warn(&adapter->dev, "WARNING: CXL adapter wide SLBIA timed out!\n");
259 return -EBUSY; 262 return -EBUSY;
260 } 263 }
261 if (!cxl_adapter_link_ok(adapter)) 264 if (!cxl_ops->link_ok(adapter, NULL))
262 return -EIO;
263 cpu_relax();
264 }
265 return 0;
266}
267
268int cxl_afu_slbia(struct cxl_afu *afu)
269{
270 unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
271
272 pr_devel("cxl_afu_slbia issuing SLBIA command\n");
273 cxl_p2n_write(afu, CXL_SLBIA_An, CXL_TLB_SLB_IQ_ALL);
274 while (cxl_p2n_read(afu, CXL_SLBIA_An) & CXL_TLB_SLB_P) {
275 if (time_after_eq(jiffies, timeout)) {
276 dev_warn(&afu->dev, "WARNING: CXL AFU SLBIA timed out!\n");
277 return -EBUSY;
278 }
279 /* If the adapter has gone down, we can assume that we
280 * will PERST it and that will invalidate everything.
281 */
282 if (!cxl_adapter_link_ok(afu->adapter))
283 return -EIO; 265 return -EIO;
284 cpu_relax(); 266 cpu_relax();
285 } 267 }
@@ -312,7 +294,7 @@ static void slb_invalid(struct cxl_context *ctx)
312 struct cxl *adapter = ctx->afu->adapter; 294 struct cxl *adapter = ctx->afu->adapter;
313 u64 slbia; 295 u64 slbia;
314 296
315 WARN_ON(!mutex_is_locked(&ctx->afu->spa_mutex)); 297 WARN_ON(!mutex_is_locked(&ctx->afu->native->spa_mutex));
316 298
317 cxl_p1_write(adapter, CXL_PSL_LBISEL, 299 cxl_p1_write(adapter, CXL_PSL_LBISEL,
318 ((u64)be32_to_cpu(ctx->elem->common.pid) << 32) | 300 ((u64)be32_to_cpu(ctx->elem->common.pid) << 32) |
@@ -320,7 +302,7 @@ static void slb_invalid(struct cxl_context *ctx)
320 cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_LPIDPID); 302 cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_LPIDPID);
321 303
322 while (1) { 304 while (1) {
323 if (!cxl_adapter_link_ok(adapter)) 305 if (!cxl_ops->link_ok(adapter, NULL))
324 break; 306 break;
325 slbia = cxl_p1_read(adapter, CXL_PSL_SLBIA); 307 slbia = cxl_p1_read(adapter, CXL_PSL_SLBIA);
326 if (!(slbia & CXL_TLB_SLB_P)) 308 if (!(slbia & CXL_TLB_SLB_P))
@@ -342,7 +324,7 @@ static int do_process_element_cmd(struct cxl_context *ctx,
342 324
343 ctx->elem->software_state = cpu_to_be32(pe_state); 325 ctx->elem->software_state = cpu_to_be32(pe_state);
344 smp_wmb(); 326 smp_wmb();
345 *(ctx->afu->sw_command_status) = cpu_to_be64(cmd | 0 | ctx->pe); 327 *(ctx->afu->native->sw_command_status) = cpu_to_be64(cmd | 0 | ctx->pe);
346 smp_mb(); 328 smp_mb();
347 cxl_p1n_write(ctx->afu, CXL_PSL_LLCMD_An, cmd | ctx->pe); 329 cxl_p1n_write(ctx->afu, CXL_PSL_LLCMD_An, cmd | ctx->pe);
348 while (1) { 330 while (1) {
@@ -351,12 +333,12 @@ static int do_process_element_cmd(struct cxl_context *ctx,
351 rc = -EBUSY; 333 rc = -EBUSY;
352 goto out; 334 goto out;
353 } 335 }
354 if (!cxl_adapter_link_ok(ctx->afu->adapter)) { 336 if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) {
355 dev_warn(&ctx->afu->dev, "WARNING: Device link down, aborting Process Element Command!\n"); 337 dev_warn(&ctx->afu->dev, "WARNING: Device link down, aborting Process Element Command!\n");
356 rc = -EIO; 338 rc = -EIO;
357 goto out; 339 goto out;
358 } 340 }
359 state = be64_to_cpup(ctx->afu->sw_command_status); 341 state = be64_to_cpup(ctx->afu->native->sw_command_status);
360 if (state == ~0ULL) { 342 if (state == ~0ULL) {
361 pr_err("cxl: Error adding process element to AFU\n"); 343 pr_err("cxl: Error adding process element to AFU\n");
362 rc = -1; 344 rc = -1;
@@ -384,12 +366,12 @@ static int add_process_element(struct cxl_context *ctx)
384{ 366{
385 int rc = 0; 367 int rc = 0;
386 368
387 mutex_lock(&ctx->afu->spa_mutex); 369 mutex_lock(&ctx->afu->native->spa_mutex);
388 pr_devel("%s Adding pe: %i started\n", __func__, ctx->pe); 370 pr_devel("%s Adding pe: %i started\n", __func__, ctx->pe);
389 if (!(rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_ADD, CXL_PE_SOFTWARE_STATE_V))) 371 if (!(rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_ADD, CXL_PE_SOFTWARE_STATE_V)))
390 ctx->pe_inserted = true; 372 ctx->pe_inserted = true;
391 pr_devel("%s Adding pe: %i finished\n", __func__, ctx->pe); 373 pr_devel("%s Adding pe: %i finished\n", __func__, ctx->pe);
392 mutex_unlock(&ctx->afu->spa_mutex); 374 mutex_unlock(&ctx->afu->native->spa_mutex);
393 return rc; 375 return rc;
394} 376}
395 377
@@ -401,18 +383,18 @@ static int terminate_process_element(struct cxl_context *ctx)
401 if (!(ctx->elem->software_state & cpu_to_be32(CXL_PE_SOFTWARE_STATE_V))) 383 if (!(ctx->elem->software_state & cpu_to_be32(CXL_PE_SOFTWARE_STATE_V)))
402 return rc; 384 return rc;
403 385
404 mutex_lock(&ctx->afu->spa_mutex); 386 mutex_lock(&ctx->afu->native->spa_mutex);
405 pr_devel("%s Terminate pe: %i started\n", __func__, ctx->pe); 387 pr_devel("%s Terminate pe: %i started\n", __func__, ctx->pe);
406 /* We could be asked to terminate when the hw is down. That 388 /* We could be asked to terminate when the hw is down. That
407 * should always succeed: it's not running if the hw has gone 389 * should always succeed: it's not running if the hw has gone
408 * away and is being reset. 390 * away and is being reset.
409 */ 391 */
410 if (cxl_adapter_link_ok(ctx->afu->adapter)) 392 if (cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
411 rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_TERMINATE, 393 rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_TERMINATE,
412 CXL_PE_SOFTWARE_STATE_V | CXL_PE_SOFTWARE_STATE_T); 394 CXL_PE_SOFTWARE_STATE_V | CXL_PE_SOFTWARE_STATE_T);
413 ctx->elem->software_state = 0; /* Remove Valid bit */ 395 ctx->elem->software_state = 0; /* Remove Valid bit */
414 pr_devel("%s Terminate pe: %i finished\n", __func__, ctx->pe); 396 pr_devel("%s Terminate pe: %i finished\n", __func__, ctx->pe);
415 mutex_unlock(&ctx->afu->spa_mutex); 397 mutex_unlock(&ctx->afu->native->spa_mutex);
416 return rc; 398 return rc;
417} 399}
418 400
@@ -420,20 +402,20 @@ static int remove_process_element(struct cxl_context *ctx)
420{ 402{
421 int rc = 0; 403 int rc = 0;
422 404
423 mutex_lock(&ctx->afu->spa_mutex); 405 mutex_lock(&ctx->afu->native->spa_mutex);
424 pr_devel("%s Remove pe: %i started\n", __func__, ctx->pe); 406 pr_devel("%s Remove pe: %i started\n", __func__, ctx->pe);
425 407
426 /* We could be asked to remove when the hw is down. Again, if 408 /* We could be asked to remove when the hw is down. Again, if
427 * the hw is down, the PE is gone, so we succeed. 409 * the hw is down, the PE is gone, so we succeed.
428 */ 410 */
429 if (cxl_adapter_link_ok(ctx->afu->adapter)) 411 if (cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
430 rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_REMOVE, 0); 412 rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_REMOVE, 0);
431 413
432 if (!rc) 414 if (!rc)
433 ctx->pe_inserted = false; 415 ctx->pe_inserted = false;
434 slb_invalid(ctx); 416 slb_invalid(ctx);
435 pr_devel("%s Remove pe: %i finished\n", __func__, ctx->pe); 417 pr_devel("%s Remove pe: %i finished\n", __func__, ctx->pe);
436 mutex_unlock(&ctx->afu->spa_mutex); 418 mutex_unlock(&ctx->afu->native->spa_mutex);
437 419
438 return rc; 420 return rc;
439} 421}
@@ -446,7 +428,7 @@ void cxl_assign_psn_space(struct cxl_context *ctx)
446 ctx->psn_size = ctx->afu->adapter->ps_size; 428 ctx->psn_size = ctx->afu->adapter->ps_size;
447 } else { 429 } else {
448 ctx->psn_phys = ctx->afu->psn_phys + 430 ctx->psn_phys = ctx->afu->psn_phys +
449 (ctx->afu->pp_offset + ctx->afu->pp_size * ctx->pe); 431 (ctx->afu->native->pp_offset + ctx->afu->pp_size * ctx->pe);
450 ctx->psn_size = ctx->afu->pp_size; 432 ctx->psn_size = ctx->afu->pp_size;
451 } 433 }
452} 434}
@@ -458,7 +440,7 @@ static int activate_afu_directed(struct cxl_afu *afu)
458 dev_info(&afu->dev, "Activating AFU directed mode\n"); 440 dev_info(&afu->dev, "Activating AFU directed mode\n");
459 441
460 afu->num_procs = afu->max_procs_virtualised; 442 afu->num_procs = afu->max_procs_virtualised;
461 if (afu->spa == NULL) { 443 if (afu->native->spa == NULL) {
462 if (cxl_alloc_spa(afu)) 444 if (cxl_alloc_spa(afu))
463 return -ENOMEM; 445 return -ENOMEM;
464 } 446 }
@@ -552,7 +534,7 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)
552 ctx->elem->common.wed = cpu_to_be64(wed); 534 ctx->elem->common.wed = cpu_to_be64(wed);
553 535
554 /* first guy needs to enable */ 536 /* first guy needs to enable */
555 if ((result = cxl_afu_check_and_enable(ctx->afu))) 537 if ((result = cxl_ops->afu_check_and_enable(ctx->afu)))
556 return result; 538 return result;
557 539
558 return add_process_element(ctx); 540 return add_process_element(ctx);
@@ -568,7 +550,7 @@ static int deactivate_afu_directed(struct cxl_afu *afu)
568 cxl_sysfs_afu_m_remove(afu); 550 cxl_sysfs_afu_m_remove(afu);
569 cxl_chardev_afu_remove(afu); 551 cxl_chardev_afu_remove(afu);
570 552
571 __cxl_afu_reset(afu); 553 cxl_ops->afu_reset(afu);
572 cxl_afu_disable(afu); 554 cxl_afu_disable(afu);
573 cxl_psl_purge(afu); 555 cxl_psl_purge(afu);
574 556
@@ -632,7 +614,7 @@ static int attach_dedicated(struct cxl_context *ctx, u64 wed, u64 amr)
632 /* master only context for dedicated */ 614 /* master only context for dedicated */
633 cxl_assign_psn_space(ctx); 615 cxl_assign_psn_space(ctx);
634 616
635 if ((rc = __cxl_afu_reset(afu))) 617 if ((rc = cxl_ops->afu_reset(afu)))
636 return rc; 618 return rc;
637 619
638 cxl_p2n_write(afu, CXL_PSL_WED_An, wed); 620 cxl_p2n_write(afu, CXL_PSL_WED_An, wed);
@@ -652,7 +634,7 @@ static int deactivate_dedicated_process(struct cxl_afu *afu)
652 return 0; 634 return 0;
653} 635}
654 636
655int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode) 637static int native_afu_deactivate_mode(struct cxl_afu *afu, int mode)
656{ 638{
657 if (mode == CXL_MODE_DIRECTED) 639 if (mode == CXL_MODE_DIRECTED)
658 return deactivate_afu_directed(afu); 640 return deactivate_afu_directed(afu);
@@ -661,19 +643,14 @@ int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode)
661 return 0; 643 return 0;
662} 644}
663 645
664int cxl_afu_deactivate_mode(struct cxl_afu *afu) 646static int native_afu_activate_mode(struct cxl_afu *afu, int mode)
665{
666 return _cxl_afu_deactivate_mode(afu, afu->current_mode);
667}
668
669int cxl_afu_activate_mode(struct cxl_afu *afu, int mode)
670{ 647{
671 if (!mode) 648 if (!mode)
672 return 0; 649 return 0;
673 if (!(mode & afu->modes_supported)) 650 if (!(mode & afu->modes_supported))
674 return -EINVAL; 651 return -EINVAL;
675 652
676 if (!cxl_adapter_link_ok(afu->adapter)) { 653 if (!cxl_ops->link_ok(afu->adapter, afu)) {
677 WARN(1, "Device link is down, refusing to activate!\n"); 654 WARN(1, "Device link is down, refusing to activate!\n");
678 return -EIO; 655 return -EIO;
679 } 656 }
@@ -686,9 +663,10 @@ int cxl_afu_activate_mode(struct cxl_afu *afu, int mode)
686 return -EINVAL; 663 return -EINVAL;
687} 664}
688 665
689int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr) 666static int native_attach_process(struct cxl_context *ctx, bool kernel,
667 u64 wed, u64 amr)
690{ 668{
691 if (!cxl_adapter_link_ok(ctx->afu->adapter)) { 669 if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) {
692 WARN(1, "Device link is down, refusing to attach process!\n"); 670 WARN(1, "Device link is down, refusing to attach process!\n");
693 return -EIO; 671 return -EIO;
694 } 672 }
@@ -705,7 +683,7 @@ int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr)
705 683
706static inline int detach_process_native_dedicated(struct cxl_context *ctx) 684static inline int detach_process_native_dedicated(struct cxl_context *ctx)
707{ 685{
708 __cxl_afu_reset(ctx->afu); 686 cxl_ops->afu_reset(ctx->afu);
709 cxl_afu_disable(ctx->afu); 687 cxl_afu_disable(ctx->afu);
710 cxl_psl_purge(ctx->afu); 688 cxl_psl_purge(ctx->afu);
711 return 0; 689 return 0;
@@ -723,7 +701,7 @@ static inline int detach_process_native_afu_directed(struct cxl_context *ctx)
723 return 0; 701 return 0;
724} 702}
725 703
726int cxl_detach_process(struct cxl_context *ctx) 704static int native_detach_process(struct cxl_context *ctx)
727{ 705{
728 trace_cxl_detach(ctx); 706 trace_cxl_detach(ctx);
729 707
@@ -733,14 +711,14 @@ int cxl_detach_process(struct cxl_context *ctx)
733 return detach_process_native_afu_directed(ctx); 711 return detach_process_native_afu_directed(ctx);
734} 712}
735 713
736int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info) 714static int native_get_irq_info(struct cxl_afu *afu, struct cxl_irq_info *info)
737{ 715{
738 u64 pidtid; 716 u64 pidtid;
739 717
740 /* If the adapter has gone away, we can't get any meaningful 718 /* If the adapter has gone away, we can't get any meaningful
741 * information. 719 * information.
742 */ 720 */
743 if (!cxl_adapter_link_ok(afu->adapter)) 721 if (!cxl_ops->link_ok(afu->adapter, afu))
744 return -EIO; 722 return -EIO;
745 723
746 info->dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An); 724 info->dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
@@ -751,10 +729,214 @@ int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info)
751 info->tid = pidtid & 0xffffffff; 729 info->tid = pidtid & 0xffffffff;
752 info->afu_err = cxl_p2n_read(afu, CXL_AFU_ERR_An); 730 info->afu_err = cxl_p2n_read(afu, CXL_AFU_ERR_An);
753 info->errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An); 731 info->errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An);
732 info->proc_handle = 0;
733
734 return 0;
735}
736
737static irqreturn_t native_handle_psl_slice_error(struct cxl_context *ctx,
738 u64 dsisr, u64 errstat)
739{
740 u64 fir1, fir2, fir_slice, serr, afu_debug;
741
742 fir1 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR1);
743 fir2 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR2);
744 fir_slice = cxl_p1n_read(ctx->afu, CXL_PSL_FIR_SLICE_An);
745 serr = cxl_p1n_read(ctx->afu, CXL_PSL_SERR_An);
746 afu_debug = cxl_p1n_read(ctx->afu, CXL_AFU_DEBUG_An);
747
748 dev_crit(&ctx->afu->dev, "PSL ERROR STATUS: 0x%016llx\n", errstat);
749 dev_crit(&ctx->afu->dev, "PSL_FIR1: 0x%016llx\n", fir1);
750 dev_crit(&ctx->afu->dev, "PSL_FIR2: 0x%016llx\n", fir2);
751 dev_crit(&ctx->afu->dev, "PSL_SERR_An: 0x%016llx\n", serr);
752 dev_crit(&ctx->afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice);
753 dev_crit(&ctx->afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug);
754
755 dev_crit(&ctx->afu->dev, "STOPPING CXL TRACE\n");
756 cxl_stop_trace(ctx->afu->adapter);
757
758 return cxl_ops->ack_irq(ctx, 0, errstat);
759}
760
761static irqreturn_t fail_psl_irq(struct cxl_afu *afu, struct cxl_irq_info *irq_info)
762{
763 if (irq_info->dsisr & CXL_PSL_DSISR_TRANS)
764 cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);
765 else
766 cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A);
767
768 return IRQ_HANDLED;
769}
770
771static irqreturn_t native_irq_multiplexed(int irq, void *data)
772{
773 struct cxl_afu *afu = data;
774 struct cxl_context *ctx;
775 struct cxl_irq_info irq_info;
776 int ph = cxl_p2n_read(afu, CXL_PSL_PEHandle_An) & 0xffff;
777 int ret;
778
779 if ((ret = native_get_irq_info(afu, &irq_info))) {
780 WARN(1, "Unable to get CXL IRQ Info: %i\n", ret);
781 return fail_psl_irq(afu, &irq_info);
782 }
783
784 rcu_read_lock();
785 ctx = idr_find(&afu->contexts_idr, ph);
786 if (ctx) {
787 ret = cxl_irq(irq, ctx, &irq_info);
788 rcu_read_unlock();
789 return ret;
790 }
791 rcu_read_unlock();
792
793 WARN(1, "Unable to demultiplex CXL PSL IRQ for PE %i DSISR %016llx DAR"
794 " %016llx\n(Possible AFU HW issue - was a term/remove acked"
795 " with outstanding transactions?)\n", ph, irq_info.dsisr,
796 irq_info.dar);
797 return fail_psl_irq(afu, &irq_info);
798}
799
800static irqreturn_t native_slice_irq_err(int irq, void *data)
801{
802 struct cxl_afu *afu = data;
803 u64 fir_slice, errstat, serr, afu_debug;
804
805 WARN(irq, "CXL SLICE ERROR interrupt %i\n", irq);
806
807 serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
808 fir_slice = cxl_p1n_read(afu, CXL_PSL_FIR_SLICE_An);
809 errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An);
810 afu_debug = cxl_p1n_read(afu, CXL_AFU_DEBUG_An);
811 dev_crit(&afu->dev, "PSL_SERR_An: 0x%016llx\n", serr);
812 dev_crit(&afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice);
813 dev_crit(&afu->dev, "CXL_PSL_ErrStat_An: 0x%016llx\n", errstat);
814 dev_crit(&afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug);
815
816 cxl_p1n_write(afu, CXL_PSL_SERR_An, serr);
817
818 return IRQ_HANDLED;
819}
820
821static irqreturn_t native_irq_err(int irq, void *data)
822{
823 struct cxl *adapter = data;
824 u64 fir1, fir2, err_ivte;
825
826 WARN(1, "CXL ERROR interrupt %i\n", irq);
827
828 err_ivte = cxl_p1_read(adapter, CXL_PSL_ErrIVTE);
829 dev_crit(&adapter->dev, "PSL_ErrIVTE: 0x%016llx\n", err_ivte);
830
831 dev_crit(&adapter->dev, "STOPPING CXL TRACE\n");
832 cxl_stop_trace(adapter);
833
834 fir1 = cxl_p1_read(adapter, CXL_PSL_FIR1);
835 fir2 = cxl_p1_read(adapter, CXL_PSL_FIR2);
836
837 dev_crit(&adapter->dev, "PSL_FIR1: 0x%016llx\nPSL_FIR2: 0x%016llx\n", fir1, fir2);
838
839 return IRQ_HANDLED;
840}
841
842int cxl_native_register_psl_err_irq(struct cxl *adapter)
843{
844 int rc;
845
846 adapter->irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
847 dev_name(&adapter->dev));
848 if (!adapter->irq_name)
849 return -ENOMEM;
850
851 if ((rc = cxl_register_one_irq(adapter, native_irq_err, adapter,
852 &adapter->native->err_hwirq,
853 &adapter->native->err_virq,
854 adapter->irq_name))) {
855 kfree(adapter->irq_name);
856 adapter->irq_name = NULL;
857 return rc;
858 }
859
860 cxl_p1_write(adapter, CXL_PSL_ErrIVTE, adapter->native->err_hwirq & 0xffff);
861
862 return 0;
863}
864
865void cxl_native_release_psl_err_irq(struct cxl *adapter)
866{
867 if (adapter->native->err_virq != irq_find_mapping(NULL, adapter->native->err_hwirq))
868 return;
869
870 cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000);
871 cxl_unmap_irq(adapter->native->err_virq, adapter);
872 cxl_ops->release_one_irq(adapter, adapter->native->err_hwirq);
873 kfree(adapter->irq_name);
874}
875
876int cxl_native_register_serr_irq(struct cxl_afu *afu)
877{
878 u64 serr;
879 int rc;
880
881 afu->err_irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
882 dev_name(&afu->dev));
883 if (!afu->err_irq_name)
884 return -ENOMEM;
885
886 if ((rc = cxl_register_one_irq(afu->adapter, native_slice_irq_err, afu,
887 &afu->serr_hwirq,
888 &afu->serr_virq, afu->err_irq_name))) {
889 kfree(afu->err_irq_name);
890 afu->err_irq_name = NULL;
891 return rc;
892 }
893
894 serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
895 serr = (serr & 0x00ffffffffff0000ULL) | (afu->serr_hwirq & 0xffff);
896 cxl_p1n_write(afu, CXL_PSL_SERR_An, serr);
754 897
755 return 0; 898 return 0;
756} 899}
757 900
901void cxl_native_release_serr_irq(struct cxl_afu *afu)
902{
903 if (afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq))
904 return;
905
906 cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000);
907 cxl_unmap_irq(afu->serr_virq, afu);
908 cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq);
909 kfree(afu->err_irq_name);
910}
911
912int cxl_native_register_psl_irq(struct cxl_afu *afu)
913{
914 int rc;
915
916 afu->psl_irq_name = kasprintf(GFP_KERNEL, "cxl-%s",
917 dev_name(&afu->dev));
918 if (!afu->psl_irq_name)
919 return -ENOMEM;
920
921 if ((rc = cxl_register_one_irq(afu->adapter, native_irq_multiplexed,
922 afu, &afu->native->psl_hwirq, &afu->native->psl_virq,
923 afu->psl_irq_name))) {
924 kfree(afu->psl_irq_name);
925 afu->psl_irq_name = NULL;
926 }
927 return rc;
928}
929
930void cxl_native_release_psl_irq(struct cxl_afu *afu)
931{
932 if (afu->native->psl_virq != irq_find_mapping(NULL, afu->native->psl_hwirq))
933 return;
934
935 cxl_unmap_irq(afu->native->psl_virq, afu);
936 cxl_ops->release_one_irq(afu->adapter, afu->native->psl_hwirq);
937 kfree(afu->psl_irq_name);
938}
939
758static void recover_psl_err(struct cxl_afu *afu, u64 errstat) 940static void recover_psl_err(struct cxl_afu *afu, u64 errstat)
759{ 941{
760 u64 dsisr; 942 u64 dsisr;
@@ -769,7 +951,7 @@ static void recover_psl_err(struct cxl_afu *afu, u64 errstat)
769 cxl_p2n_write(afu, CXL_PSL_ErrStat_An, errstat); 951 cxl_p2n_write(afu, CXL_PSL_ErrStat_An, errstat);
770} 952}
771 953
772int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask) 954static int native_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask)
773{ 955{
774 trace_cxl_psl_irq_ack(ctx, tfc); 956 trace_cxl_psl_irq_ack(ctx, tfc);
775 if (tfc) 957 if (tfc)
@@ -784,3 +966,132 @@ int cxl_check_error(struct cxl_afu *afu)
784{ 966{
785 return (cxl_p1n_read(afu, CXL_PSL_SCNTL_An) == ~0ULL); 967 return (cxl_p1n_read(afu, CXL_PSL_SCNTL_An) == ~0ULL);
786} 968}
969
970static bool native_support_attributes(const char *attr_name,
971 enum cxl_attrs type)
972{
973 return true;
974}
975
976static int native_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off, u64 *out)
977{
978 if (unlikely(!cxl_ops->link_ok(afu->adapter, afu)))
979 return -EIO;
980 if (unlikely(off >= afu->crs_len))
981 return -ERANGE;
982 *out = in_le64(afu->native->afu_desc_mmio + afu->crs_offset +
983 (cr * afu->crs_len) + off);
984 return 0;
985}
986
987static int native_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off, u32 *out)
988{
989 if (unlikely(!cxl_ops->link_ok(afu->adapter, afu)))
990 return -EIO;
991 if (unlikely(off >= afu->crs_len))
992 return -ERANGE;
993 *out = in_le32(afu->native->afu_desc_mmio + afu->crs_offset +
994 (cr * afu->crs_len) + off);
995 return 0;
996}
997
998static int native_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off, u16 *out)
999{
1000 u64 aligned_off = off & ~0x3L;
1001 u32 val;
1002 int rc;
1003
1004 rc = native_afu_cr_read32(afu, cr, aligned_off, &val);
1005 if (!rc)
1006 *out = (val >> ((off & 0x3) * 8)) & 0xffff;
1007 return rc;
1008}
1009
1010static int native_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off, u8 *out)
1011{
1012 u64 aligned_off = off & ~0x3L;
1013 u32 val;
1014 int rc;
1015
1016 rc = native_afu_cr_read32(afu, cr, aligned_off, &val);
1017 if (!rc)
1018 *out = (val >> ((off & 0x3) * 8)) & 0xff;
1019 return rc;
1020}
1021
1022static int native_afu_cr_write32(struct cxl_afu *afu, int cr, u64 off, u32 in)
1023{
1024 if (unlikely(!cxl_ops->link_ok(afu->adapter, afu)))
1025 return -EIO;
1026 if (unlikely(off >= afu->crs_len))
1027 return -ERANGE;
1028 out_le32(afu->native->afu_desc_mmio + afu->crs_offset +
1029 (cr * afu->crs_len) + off, in);
1030 return 0;
1031}
1032
1033static int native_afu_cr_write16(struct cxl_afu *afu, int cr, u64 off, u16 in)
1034{
1035 u64 aligned_off = off & ~0x3L;
1036 u32 val32, mask, shift;
1037 int rc;
1038
1039 rc = native_afu_cr_read32(afu, cr, aligned_off, &val32);
1040 if (rc)
1041 return rc;
1042 shift = (off & 0x3) * 8;
1043 WARN_ON(shift == 24);
1044 mask = 0xffff << shift;
1045 val32 = (val32 & ~mask) | (in << shift);
1046
1047 rc = native_afu_cr_write32(afu, cr, aligned_off, val32);
1048 return rc;
1049}
1050
1051static int native_afu_cr_write8(struct cxl_afu *afu, int cr, u64 off, u8 in)
1052{
1053 u64 aligned_off = off & ~0x3L;
1054 u32 val32, mask, shift;
1055 int rc;
1056
1057 rc = native_afu_cr_read32(afu, cr, aligned_off, &val32);
1058 if (rc)
1059 return rc;
1060 shift = (off & 0x3) * 8;
1061 mask = 0xff << shift;
1062 val32 = (val32 & ~mask) | (in << shift);
1063
1064 rc = native_afu_cr_write32(afu, cr, aligned_off, val32);
1065 return rc;
1066}
1067
1068const struct cxl_backend_ops cxl_native_ops = {
1069 .module = THIS_MODULE,
1070 .adapter_reset = cxl_pci_reset,
1071 .alloc_one_irq = cxl_pci_alloc_one_irq,
1072 .release_one_irq = cxl_pci_release_one_irq,
1073 .alloc_irq_ranges = cxl_pci_alloc_irq_ranges,
1074 .release_irq_ranges = cxl_pci_release_irq_ranges,
1075 .setup_irq = cxl_pci_setup_irq,
1076 .handle_psl_slice_error = native_handle_psl_slice_error,
1077 .psl_interrupt = NULL,
1078 .ack_irq = native_ack_irq,
1079 .attach_process = native_attach_process,
1080 .detach_process = native_detach_process,
1081 .support_attributes = native_support_attributes,
1082 .link_ok = cxl_adapter_link_ok,
1083 .release_afu = cxl_pci_release_afu,
1084 .afu_read_err_buffer = cxl_pci_afu_read_err_buffer,
1085 .afu_check_and_enable = native_afu_check_and_enable,
1086 .afu_activate_mode = native_afu_activate_mode,
1087 .afu_deactivate_mode = native_afu_deactivate_mode,
1088 .afu_reset = native_afu_reset,
1089 .afu_cr_read8 = native_afu_cr_read8,
1090 .afu_cr_read16 = native_afu_cr_read16,
1091 .afu_cr_read32 = native_afu_cr_read32,
1092 .afu_cr_read64 = native_afu_cr_read64,
1093 .afu_cr_write8 = native_afu_cr_write8,
1094 .afu_cr_write16 = native_afu_cr_write16,
1095 .afu_cr_write32 = native_afu_cr_write32,
1096 .read_adapter_vpd = cxl_pci_read_adapter_vpd,
1097};
diff --git a/drivers/misc/cxl/of.c b/drivers/misc/cxl/of.c
new file mode 100644
index 000000000000..edc458395f68
--- /dev/null
+++ b/drivers/misc/cxl/of.c
@@ -0,0 +1,513 @@
1/*
2 * Copyright 2015 IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/platform_device.h>
13#include <linux/slab.h>
14#include <linux/of_address.h>
15#include <linux/of_platform.h>
16
17#include "cxl.h"
18
19
20static const __be32 *read_prop_string(const struct device_node *np,
21 const char *prop_name)
22{
23 const __be32 *prop;
24
25 prop = of_get_property(np, prop_name, NULL);
26 if (cxl_verbose && prop)
27 pr_info("%s: %s\n", prop_name, (char *) prop);
28 return prop;
29}
30
31static const __be32 *read_prop_dword(const struct device_node *np,
32 const char *prop_name, u32 *val)
33{
34 const __be32 *prop;
35
36 prop = of_get_property(np, prop_name, NULL);
37 if (prop)
38 *val = be32_to_cpu(prop[0]);
39 if (cxl_verbose && prop)
40 pr_info("%s: %#x (%u)\n", prop_name, *val, *val);
41 return prop;
42}
43
44static const __be64 *read_prop64_dword(const struct device_node *np,
45 const char *prop_name, u64 *val)
46{
47 const __be64 *prop;
48
49 prop = of_get_property(np, prop_name, NULL);
50 if (prop)
51 *val = be64_to_cpu(prop[0]);
52 if (cxl_verbose && prop)
53 pr_info("%s: %#llx (%llu)\n", prop_name, *val, *val);
54 return prop;
55}
56
57
58static int read_handle(struct device_node *np, u64 *handle)
59{
60 const __be32 *prop;
61 u64 size;
62
63 /* Get address and size of the node */
64 prop = of_get_address(np, 0, &size, NULL);
65 if (size)
66 return -EINVAL;
67
68 /* Helper to read a big number; size is in cells (not bytes) */
69 *handle = of_read_number(prop, of_n_addr_cells(np));
70 return 0;
71}
72
73static int read_phys_addr(struct device_node *np, char *prop_name,
74 struct cxl_afu *afu)
75{
76 int i, len, entry_size, naddr, nsize, type;
77 u64 addr, size;
78 const __be32 *prop;
79
80 naddr = of_n_addr_cells(np);
81 nsize = of_n_size_cells(np);
82
83 prop = of_get_property(np, prop_name, &len);
84 if (prop) {
85 entry_size = naddr + nsize;
86 for (i = 0; i < (len / 4); i += entry_size, prop += entry_size) {
87 type = be32_to_cpu(prop[0]);
88 addr = of_read_number(prop, naddr);
89 size = of_read_number(&prop[naddr], nsize);
90 switch (type) {
91 case 0: /* unit address */
92 afu->guest->handle = addr;
93 break;
94 case 1: /* p2 area */
95 afu->guest->p2n_phys += addr;
96 afu->guest->p2n_size = size;
97 break;
98 case 2: /* problem state area */
99 afu->psn_phys += addr;
100 afu->adapter->ps_size = size;
101 break;
102 default:
103 pr_err("Invalid address type %d found in %s property of AFU\n",
104 type, prop_name);
105 return -EINVAL;
106 }
107 if (cxl_verbose)
108 pr_info("%s: %#x %#llx (size %#llx)\n",
109 prop_name, type, addr, size);
110 }
111 }
112 return 0;
113}
114
115static int read_vpd(struct cxl *adapter, struct cxl_afu *afu)
116{
117 char vpd[256];
118 int rc;
119 size_t len = sizeof(vpd);
120
121 memset(vpd, 0, len);
122
123 if (adapter)
124 rc = cxl_guest_read_adapter_vpd(adapter, vpd, len);
125 else
126 rc = cxl_guest_read_afu_vpd(afu, vpd, len);
127
128 if (rc > 0) {
129 cxl_dump_debug_buffer(vpd, rc);
130 rc = 0;
131 }
132 return rc;
133}
134
135int cxl_of_read_afu_handle(struct cxl_afu *afu, struct device_node *afu_np)
136{
137 if (read_handle(afu_np, &afu->guest->handle))
138 return -EINVAL;
139 pr_devel("AFU handle: 0x%.16llx\n", afu->guest->handle);
140
141 return 0;
142}
143
144int cxl_of_read_afu_properties(struct cxl_afu *afu, struct device_node *np)
145{
146 int i, len, rc;
147 char *p;
148 const __be32 *prop;
149 u16 device_id, vendor_id;
150 u32 val = 0, class_code;
151
152 /* Properties are read in the same order as listed in PAPR */
153
154 if (cxl_verbose) {
155 pr_info("Dump of the 'ibm,coherent-platform-function' node properties:\n");
156
157 prop = of_get_property(np, "compatible", &len);
158 i = 0;
159 while (i < len) {
160 p = (char *) prop + i;
161 pr_info("compatible: %s\n", p);
162 i += strlen(p) + 1;
163 }
164 read_prop_string(np, "name");
165 }
166
167 rc = read_phys_addr(np, "reg", afu);
168 if (rc)
169 return rc;
170
171 rc = read_phys_addr(np, "assigned-addresses", afu);
172 if (rc)
173 return rc;
174
175 if (afu->psn_phys == 0)
176 afu->psa = false;
177 else
178 afu->psa = true;
179
180 if (cxl_verbose) {
181 read_prop_string(np, "ibm,loc-code");
182 read_prop_string(np, "device_type");
183 }
184
185 read_prop_dword(np, "ibm,#processes", &afu->max_procs_virtualised);
186
187 if (cxl_verbose) {
188 read_prop_dword(np, "ibm,scratchpad-size", &val);
189 read_prop_dword(np, "ibm,programmable", &val);
190 read_prop_string(np, "ibm,phandle");
191 read_vpd(NULL, afu);
192 }
193
194 read_prop_dword(np, "ibm,max-ints-per-process", &afu->guest->max_ints);
195 afu->irqs_max = afu->guest->max_ints;
196
197 prop = read_prop_dword(np, "ibm,min-ints-per-process", &afu->pp_irqs);
198 if (prop) {
199 /* One extra interrupt for the PSL interrupt is already
200 * included. Remove it now to keep only AFU interrupts and
201 * match the native case.
202 */
203 afu->pp_irqs--;
204 }
205
206 if (cxl_verbose) {
207 read_prop_dword(np, "ibm,max-ints", &val);
208 read_prop_dword(np, "ibm,vpd-size", &val);
209 }
210
211 read_prop64_dword(np, "ibm,error-buffer-size", &afu->eb_len);
212 afu->eb_offset = 0;
213
214 if (cxl_verbose)
215 read_prop_dword(np, "ibm,config-record-type", &val);
216
217 read_prop64_dword(np, "ibm,config-record-size", &afu->crs_len);
218 afu->crs_offset = 0;
219
220 read_prop_dword(np, "ibm,#config-records", &afu->crs_num);
221
222 if (cxl_verbose) {
223 for (i = 0; i < afu->crs_num; i++) {
224 rc = cxl_ops->afu_cr_read16(afu, i, PCI_DEVICE_ID,
225 &device_id);
226 if (!rc)
227 pr_info("record %d - device-id: %#x\n",
228 i, device_id);
229 rc = cxl_ops->afu_cr_read16(afu, i, PCI_VENDOR_ID,
230 &vendor_id);
231 if (!rc)
232 pr_info("record %d - vendor-id: %#x\n",
233 i, vendor_id);
234 rc = cxl_ops->afu_cr_read32(afu, i, PCI_CLASS_REVISION,
235 &class_code);
236 if (!rc) {
237 class_code >>= 8;
238 pr_info("record %d - class-code: %#x\n",
239 i, class_code);
240 }
241 }
242
243 read_prop_dword(np, "ibm,function-number", &val);
244 read_prop_dword(np, "ibm,privileged-function", &val);
245 read_prop_dword(np, "vendor-id", &val);
246 read_prop_dword(np, "device-id", &val);
247 read_prop_dword(np, "revision-id", &val);
248 read_prop_dword(np, "class-code", &val);
249 read_prop_dword(np, "subsystem-vendor-id", &val);
250 read_prop_dword(np, "subsystem-id", &val);
251 }
252 /*
253 * if "ibm,process-mmio" doesn't exist then per-process mmio is
254 * not supported
255 */
256 val = 0;
257 prop = read_prop_dword(np, "ibm,process-mmio", &val);
258 if (prop && val == 1)
259 afu->pp_psa = true;
260 else
261 afu->pp_psa = false;
262
263 if (cxl_verbose) {
264 read_prop_dword(np, "ibm,supports-aur", &val);
265 read_prop_dword(np, "ibm,supports-csrp", &val);
266 read_prop_dword(np, "ibm,supports-prr", &val);
267 }
268
269 prop = read_prop_dword(np, "ibm,function-error-interrupt", &val);
270 if (prop)
271 afu->serr_hwirq = val;
272
273 pr_devel("AFU handle: %#llx\n", afu->guest->handle);
274 pr_devel("p2n_phys: %#llx (size %#llx)\n",
275 afu->guest->p2n_phys, afu->guest->p2n_size);
276 pr_devel("psn_phys: %#llx (size %#llx)\n",
277 afu->psn_phys, afu->adapter->ps_size);
278 pr_devel("Max number of processes virtualised=%i\n",
279 afu->max_procs_virtualised);
280 pr_devel("Per-process irqs min=%i, max=%i\n", afu->pp_irqs,
281 afu->irqs_max);
282 pr_devel("Slice error interrupt=%#lx\n", afu->serr_hwirq);
283
284 return 0;
285}
286
287static int read_adapter_irq_config(struct cxl *adapter, struct device_node *np)
288{
289 const __be32 *ranges;
290 int len, nranges, i;
291 struct irq_avail *cur;
292
293 ranges = of_get_property(np, "interrupt-ranges", &len);
294 if (ranges == NULL || len < (2 * sizeof(int)))
295 return -EINVAL;
296
297 /*
298 * encoded array of two cells per entry, each cell encoded as
299 * with encode-int
300 */
301 nranges = len / (2 * sizeof(int));
302 if (nranges == 0 || (nranges * 2 * sizeof(int)) != len)
303 return -EINVAL;
304
305 adapter->guest->irq_avail = kzalloc(nranges * sizeof(struct irq_avail),
306 GFP_KERNEL);
307 if (adapter->guest->irq_avail == NULL)
308 return -ENOMEM;
309
310 adapter->guest->irq_base_offset = be32_to_cpu(ranges[0]);
311 for (i = 0; i < nranges; i++) {
312 cur = &adapter->guest->irq_avail[i];
313 cur->offset = be32_to_cpu(ranges[i * 2]);
314 cur->range = be32_to_cpu(ranges[i * 2 + 1]);
315 cur->bitmap = kcalloc(BITS_TO_LONGS(cur->range),
316 sizeof(*cur->bitmap), GFP_KERNEL);
317 if (cur->bitmap == NULL)
318 goto err;
319 if (cur->offset < adapter->guest->irq_base_offset)
320 adapter->guest->irq_base_offset = cur->offset;
321 if (cxl_verbose)
322 pr_info("available IRQ range: %#lx-%#lx (%lu)\n",
323 cur->offset, cur->offset + cur->range - 1,
324 cur->range);
325 }
326 adapter->guest->irq_nranges = nranges;
327 spin_lock_init(&adapter->guest->irq_alloc_lock);
328
329 return 0;
330err:
331 for (i--; i >= 0; i--) {
332 cur = &adapter->guest->irq_avail[i];
333 kfree(cur->bitmap);
334 }
335 kfree(adapter->guest->irq_avail);
336 adapter->guest->irq_avail = NULL;
337 return -ENOMEM;
338}
339
340int cxl_of_read_adapter_handle(struct cxl *adapter, struct device_node *np)
341{
342 if (read_handle(np, &adapter->guest->handle))
343 return -EINVAL;
344 pr_devel("Adapter handle: 0x%.16llx\n", adapter->guest->handle);
345
346 return 0;
347}
348
349int cxl_of_read_adapter_properties(struct cxl *adapter, struct device_node *np)
350{
351 int rc, len, naddr, i;
352 char *p;
353 const __be32 *prop;
354 u32 val = 0;
355
356 /* Properties are read in the same order as listed in PAPR */
357
358 naddr = of_n_addr_cells(np);
359
360 if (cxl_verbose) {
361 pr_info("Dump of the 'ibm,coherent-platform-facility' node properties:\n");
362
363 read_prop_dword(np, "#address-cells", &val);
364 read_prop_dword(np, "#size-cells", &val);
365
366 prop = of_get_property(np, "compatible", &len);
367 i = 0;
368 while (i < len) {
369 p = (char *) prop + i;
370 pr_info("compatible: %s\n", p);
371 i += strlen(p) + 1;
372 }
373 read_prop_string(np, "name");
374 read_prop_string(np, "model");
375
376 prop = of_get_property(np, "reg", NULL);
377 if (prop) {
378 pr_info("reg: addr:%#llx size:%#x\n",
379 of_read_number(prop, naddr),
380 be32_to_cpu(prop[naddr]));
381 }
382
383 read_prop_string(np, "ibm,loc-code");
384 }
385
386 if ((rc = read_adapter_irq_config(adapter, np)))
387 return rc;
388
389 if (cxl_verbose) {
390 read_prop_string(np, "device_type");
391 read_prop_string(np, "ibm,phandle");
392 }
393
394 prop = read_prop_dword(np, "ibm,caia-version", &val);
395 if (prop) {
396 adapter->caia_major = (val & 0xFF00) >> 8;
397 adapter->caia_minor = val & 0xFF;
398 }
399
400 prop = read_prop_dword(np, "ibm,psl-revision", &val);
401 if (prop)
402 adapter->psl_rev = val;
403
404 prop = read_prop_string(np, "status");
405 if (prop) {
406 adapter->guest->status = kasprintf(GFP_KERNEL, "%s", (char *) prop);
407 if (adapter->guest->status == NULL)
408 return -ENOMEM;
409 }
410
411 prop = read_prop_dword(np, "vendor-id", &val);
412 if (prop)
413 adapter->guest->vendor = val;
414
415 prop = read_prop_dword(np, "device-id", &val);
416 if (prop)
417 adapter->guest->device = val;
418
419 if (cxl_verbose) {
420 read_prop_dword(np, "ibm,privileged-facility", &val);
421 read_prop_dword(np, "revision-id", &val);
422 read_prop_dword(np, "class-code", &val);
423 }
424
425 prop = read_prop_dword(np, "subsystem-vendor-id", &val);
426 if (prop)
427 adapter->guest->subsystem_vendor = val;
428
429 prop = read_prop_dword(np, "subsystem-id", &val);
430 if (prop)
431 adapter->guest->subsystem = val;
432
433 if (cxl_verbose)
434 read_vpd(adapter, NULL);
435
436 return 0;
437}
438
439static int cxl_of_remove(struct platform_device *pdev)
440{
441 struct cxl *adapter;
442 int afu;
443
444 adapter = dev_get_drvdata(&pdev->dev);
445 for (afu = 0; afu < adapter->slices; afu++)
446 cxl_guest_remove_afu(adapter->afu[afu]);
447
448 cxl_guest_remove_adapter(adapter);
449 return 0;
450}
451
452static void cxl_of_shutdown(struct platform_device *pdev)
453{
454 cxl_of_remove(pdev);
455}
456
457int cxl_of_probe(struct platform_device *pdev)
458{
459 struct device_node *np = NULL;
460 struct device_node *afu_np = NULL;
461 struct cxl *adapter = NULL;
462 int ret;
463 int slice, slice_ok;
464
465 pr_devel("in %s\n", __func__);
466
467 np = pdev->dev.of_node;
468 if (np == NULL)
469 return -ENODEV;
470
471 /* init adapter */
472 adapter = cxl_guest_init_adapter(np, pdev);
473 if (IS_ERR(adapter)) {
474 dev_err(&pdev->dev, "guest_init_adapter failed: %li\n", PTR_ERR(adapter));
475 return PTR_ERR(adapter);
476 }
477
478 /* init afu */
479 slice_ok = 0;
480 for (afu_np = NULL, slice = 0; (afu_np = of_get_next_child(np, afu_np)); slice++) {
481 if ((ret = cxl_guest_init_afu(adapter, slice, afu_np)))
482 dev_err(&pdev->dev, "AFU %i failed to initialise: %i\n",
483 slice, ret);
484 else
485 slice_ok++;
486 }
487
488 if (slice_ok == 0) {
489 dev_info(&pdev->dev, "No active AFU");
490 adapter->slices = 0;
491 }
492
493 if (afu_np)
494 of_node_put(afu_np);
495 return 0;
496}
497
498static const struct of_device_id cxl_of_match[] = {
499 { .compatible = "ibm,coherent-platform-facility",},
500 {},
501};
502MODULE_DEVICE_TABLE(of, cxl_of_match);
503
504struct platform_driver cxl_of_driver = {
505 .driver = {
506 .name = "cxl_of",
507 .of_match_table = cxl_of_match,
508 .owner = THIS_MODULE
509 },
510 .probe = cxl_of_probe,
511 .remove = cxl_of_remove,
512 .shutdown = cxl_of_shutdown,
513};
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index a89608334ed5..2844e975bf79 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -89,8 +89,8 @@
89 89
90/* This works a little different than the p1/p2 register accesses to make it 90/* This works a little different than the p1/p2 register accesses to make it
91 * easier to pull out individual fields */ 91 * easier to pull out individual fields */
92#define AFUD_READ(afu, off) in_be64(afu->afu_desc_mmio + off) 92#define AFUD_READ(afu, off) in_be64(afu->native->afu_desc_mmio + off)
93#define AFUD_READ_LE(afu, off) in_le64(afu->afu_desc_mmio + off) 93#define AFUD_READ_LE(afu, off) in_le64(afu->native->afu_desc_mmio + off)
94#define EXTRACT_PPC_BIT(val, bit) (!!(val & PPC_BIT(bit))) 94#define EXTRACT_PPC_BIT(val, bit) (!!(val & PPC_BIT(bit)))
95#define EXTRACT_PPC_BITS(val, bs, be) ((val & PPC_BITMASK(bs, be)) >> PPC_BITLSHIFT(be)) 95#define EXTRACT_PPC_BITS(val, bs, be) ((val & PPC_BITMASK(bs, be)) >> PPC_BITLSHIFT(be))
96 96
@@ -115,24 +115,6 @@
115#define AFUD_EB_LEN(val) EXTRACT_PPC_BITS(val, 8, 63) 115#define AFUD_EB_LEN(val) EXTRACT_PPC_BITS(val, 8, 63)
116#define AFUD_READ_EB_OFF(afu) AFUD_READ(afu, 0x48) 116#define AFUD_READ_EB_OFF(afu) AFUD_READ(afu, 0x48)
117 117
118u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off)
119{
120 u64 aligned_off = off & ~0x3L;
121 u32 val;
122
123 val = cxl_afu_cr_read32(afu, cr, aligned_off);
124 return (val >> ((off & 0x2) * 8)) & 0xffff;
125}
126
127u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off)
128{
129 u64 aligned_off = off & ~0x3L;
130 u32 val;
131
132 val = cxl_afu_cr_read32(afu, cr, aligned_off);
133 return (val >> ((off & 0x3) * 8)) & 0xff;
134}
135
136static const struct pci_device_id cxl_pci_tbl[] = { 118static const struct pci_device_id cxl_pci_tbl[] = {
137 { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0477), }, 119 { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0477), },
138 { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x044b), }, 120 { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x044b), },
@@ -432,8 +414,8 @@ static int init_implementation_afu_regs(struct cxl_afu *afu)
432 return 0; 414 return 0;
433} 415}
434 416
435int cxl_setup_irq(struct cxl *adapter, unsigned int hwirq, 417int cxl_pci_setup_irq(struct cxl *adapter, unsigned int hwirq,
436 unsigned int virq) 418 unsigned int virq)
437{ 419{
438 struct pci_dev *dev = to_pci_dev(adapter->dev.parent); 420 struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
439 421
@@ -475,28 +457,30 @@ int cxl_update_image_control(struct cxl *adapter)
475 return 0; 457 return 0;
476} 458}
477 459
478int cxl_alloc_one_irq(struct cxl *adapter) 460int cxl_pci_alloc_one_irq(struct cxl *adapter)
479{ 461{
480 struct pci_dev *dev = to_pci_dev(adapter->dev.parent); 462 struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
481 463
482 return pnv_cxl_alloc_hwirqs(dev, 1); 464 return pnv_cxl_alloc_hwirqs(dev, 1);
483} 465}
484 466
485void cxl_release_one_irq(struct cxl *adapter, int hwirq) 467void cxl_pci_release_one_irq(struct cxl *adapter, int hwirq)
486{ 468{
487 struct pci_dev *dev = to_pci_dev(adapter->dev.parent); 469 struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
488 470
489 return pnv_cxl_release_hwirqs(dev, hwirq, 1); 471 return pnv_cxl_release_hwirqs(dev, hwirq, 1);
490} 472}
491 473
492int cxl_alloc_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter, unsigned int num) 474int cxl_pci_alloc_irq_ranges(struct cxl_irq_ranges *irqs,
475 struct cxl *adapter, unsigned int num)
493{ 476{
494 struct pci_dev *dev = to_pci_dev(adapter->dev.parent); 477 struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
495 478
496 return pnv_cxl_alloc_hwirq_ranges(irqs, dev, num); 479 return pnv_cxl_alloc_hwirq_ranges(irqs, dev, num);
497} 480}
498 481
499void cxl_release_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter) 482void cxl_pci_release_irq_ranges(struct cxl_irq_ranges *irqs,
483 struct cxl *adapter)
500{ 484{
501 struct pci_dev *dev = to_pci_dev(adapter->dev.parent); 485 struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
502 486
@@ -557,7 +541,7 @@ static int switch_card_to_cxl(struct pci_dev *dev)
557 return 0; 541 return 0;
558} 542}
559 543
560static int cxl_map_slice_regs(struct cxl_afu *afu, struct cxl *adapter, struct pci_dev *dev) 544static int pci_map_slice_regs(struct cxl_afu *afu, struct cxl *adapter, struct pci_dev *dev)
561{ 545{
562 u64 p1n_base, p2n_base, afu_desc; 546 u64 p1n_base, p2n_base, afu_desc;
563 const u64 p1n_size = 0x100; 547 const u64 p1n_size = 0x100;
@@ -565,15 +549,15 @@ static int cxl_map_slice_regs(struct cxl_afu *afu, struct cxl *adapter, struct p
565 549
566 p1n_base = p1_base(dev) + 0x10000 + (afu->slice * p1n_size); 550 p1n_base = p1_base(dev) + 0x10000 + (afu->slice * p1n_size);
567 p2n_base = p2_base(dev) + (afu->slice * p2n_size); 551 p2n_base = p2_base(dev) + (afu->slice * p2n_size);
568 afu->psn_phys = p2_base(dev) + (adapter->ps_off + (afu->slice * adapter->ps_size)); 552 afu->psn_phys = p2_base(dev) + (adapter->native->ps_off + (afu->slice * adapter->ps_size));
569 afu_desc = p2_base(dev) + adapter->afu_desc_off + (afu->slice * adapter->afu_desc_size); 553 afu_desc = p2_base(dev) + adapter->native->afu_desc_off + (afu->slice * adapter->native->afu_desc_size);
570 554
571 if (!(afu->p1n_mmio = ioremap(p1n_base, p1n_size))) 555 if (!(afu->native->p1n_mmio = ioremap(p1n_base, p1n_size)))
572 goto err; 556 goto err;
573 if (!(afu->p2n_mmio = ioremap(p2n_base, p2n_size))) 557 if (!(afu->p2n_mmio = ioremap(p2n_base, p2n_size)))
574 goto err1; 558 goto err1;
575 if (afu_desc) { 559 if (afu_desc) {
576 if (!(afu->afu_desc_mmio = ioremap(afu_desc, adapter->afu_desc_size))) 560 if (!(afu->native->afu_desc_mmio = ioremap(afu_desc, adapter->native->afu_desc_size)))
577 goto err2; 561 goto err2;
578 } 562 }
579 563
@@ -581,62 +565,41 @@ static int cxl_map_slice_regs(struct cxl_afu *afu, struct cxl *adapter, struct p
581err2: 565err2:
582 iounmap(afu->p2n_mmio); 566 iounmap(afu->p2n_mmio);
583err1: 567err1:
584 iounmap(afu->p1n_mmio); 568 iounmap(afu->native->p1n_mmio);
585err: 569err:
586 dev_err(&afu->dev, "Error mapping AFU MMIO regions\n"); 570 dev_err(&afu->dev, "Error mapping AFU MMIO regions\n");
587 return -ENOMEM; 571 return -ENOMEM;
588} 572}
589 573
590static void cxl_unmap_slice_regs(struct cxl_afu *afu) 574static void pci_unmap_slice_regs(struct cxl_afu *afu)
591{ 575{
592 if (afu->p2n_mmio) { 576 if (afu->p2n_mmio) {
593 iounmap(afu->p2n_mmio); 577 iounmap(afu->p2n_mmio);
594 afu->p2n_mmio = NULL; 578 afu->p2n_mmio = NULL;
595 } 579 }
596 if (afu->p1n_mmio) { 580 if (afu->native->p1n_mmio) {
597 iounmap(afu->p1n_mmio); 581 iounmap(afu->native->p1n_mmio);
598 afu->p1n_mmio = NULL; 582 afu->native->p1n_mmio = NULL;
599 } 583 }
600 if (afu->afu_desc_mmio) { 584 if (afu->native->afu_desc_mmio) {
601 iounmap(afu->afu_desc_mmio); 585 iounmap(afu->native->afu_desc_mmio);
602 afu->afu_desc_mmio = NULL; 586 afu->native->afu_desc_mmio = NULL;
603 } 587 }
604} 588}
605 589
606static void cxl_release_afu(struct device *dev) 590void cxl_pci_release_afu(struct device *dev)
607{ 591{
608 struct cxl_afu *afu = to_cxl_afu(dev); 592 struct cxl_afu *afu = to_cxl_afu(dev);
609 593
610 pr_devel("cxl_release_afu\n"); 594 pr_devel("%s\n", __func__);
611 595
612 idr_destroy(&afu->contexts_idr); 596 idr_destroy(&afu->contexts_idr);
613 cxl_release_spa(afu); 597 cxl_release_spa(afu);
614 598
599 kfree(afu->native);
615 kfree(afu); 600 kfree(afu);
616} 601}
617 602
618static struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice)
619{
620 struct cxl_afu *afu;
621
622 if (!(afu = kzalloc(sizeof(struct cxl_afu), GFP_KERNEL)))
623 return NULL;
624
625 afu->adapter = adapter;
626 afu->dev.parent = &adapter->dev;
627 afu->dev.release = cxl_release_afu;
628 afu->slice = slice;
629 idr_init(&afu->contexts_idr);
630 mutex_init(&afu->contexts_lock);
631 spin_lock_init(&afu->afu_cntl_lock);
632 mutex_init(&afu->spa_mutex);
633
634 afu->prefault_mode = CXL_PREFAULT_NONE;
635 afu->irqs_max = afu->adapter->user_irqs;
636
637 return afu;
638}
639
640/* Expects AFU struct to have recently been zeroed out */ 603/* Expects AFU struct to have recently been zeroed out */
641static int cxl_read_afu_descriptor(struct cxl_afu *afu) 604static int cxl_read_afu_descriptor(struct cxl_afu *afu)
642{ 605{
@@ -658,7 +621,7 @@ static int cxl_read_afu_descriptor(struct cxl_afu *afu)
658 afu->pp_size = AFUD_PPPSA_LEN(val) * 4096; 621 afu->pp_size = AFUD_PPPSA_LEN(val) * 4096;
659 afu->psa = AFUD_PPPSA_PSA(val); 622 afu->psa = AFUD_PPPSA_PSA(val);
660 if ((afu->pp_psa = AFUD_PPPSA_PP(val))) 623 if ((afu->pp_psa = AFUD_PPPSA_PP(val)))
661 afu->pp_offset = AFUD_READ_PPPSA_OFF(afu); 624 afu->native->pp_offset = AFUD_READ_PPPSA_OFF(afu);
662 625
663 val = AFUD_READ_CR(afu); 626 val = AFUD_READ_CR(afu);
664 afu->crs_len = AFUD_CR_LEN(val) * 256; 627 afu->crs_len = AFUD_CR_LEN(val) * 256;
@@ -685,10 +648,11 @@ static int cxl_read_afu_descriptor(struct cxl_afu *afu)
685 648
686static int cxl_afu_descriptor_looks_ok(struct cxl_afu *afu) 649static int cxl_afu_descriptor_looks_ok(struct cxl_afu *afu)
687{ 650{
688 int i; 651 int i, rc;
652 u32 val;
689 653
690 if (afu->psa && afu->adapter->ps_size < 654 if (afu->psa && afu->adapter->ps_size <
691 (afu->pp_offset + afu->pp_size*afu->max_procs_virtualised)) { 655 (afu->native->pp_offset + afu->pp_size*afu->max_procs_virtualised)) {
692 dev_err(&afu->dev, "per-process PSA can't fit inside the PSA!\n"); 656 dev_err(&afu->dev, "per-process PSA can't fit inside the PSA!\n");
693 return -ENODEV; 657 return -ENODEV;
694 } 658 }
@@ -697,7 +661,8 @@ static int cxl_afu_descriptor_looks_ok(struct cxl_afu *afu)
697 dev_warn(&afu->dev, "AFU uses < PAGE_SIZE per-process PSA!"); 661 dev_warn(&afu->dev, "AFU uses < PAGE_SIZE per-process PSA!");
698 662
699 for (i = 0; i < afu->crs_num; i++) { 663 for (i = 0; i < afu->crs_num; i++) {
700 if ((cxl_afu_cr_read32(afu, i, 0) == 0)) { 664 rc = cxl_ops->afu_cr_read32(afu, i, 0, &val);
665 if (rc || val == 0) {
701 dev_err(&afu->dev, "ABORTING: AFU configuration record %i is invalid\n", i); 666 dev_err(&afu->dev, "ABORTING: AFU configuration record %i is invalid\n", i);
702 return -EINVAL; 667 return -EINVAL;
703 } 668 }
@@ -718,7 +683,7 @@ static int sanitise_afu_regs(struct cxl_afu *afu)
718 reg = cxl_p2n_read(afu, CXL_AFU_Cntl_An); 683 reg = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
719 if ((reg & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) { 684 if ((reg & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) {
720 dev_warn(&afu->dev, "WARNING: AFU was not disabled: %#016llx\n", reg); 685 dev_warn(&afu->dev, "WARNING: AFU was not disabled: %#016llx\n", reg);
721 if (__cxl_afu_reset(afu)) 686 if (cxl_ops->afu_reset(afu))
722 return -EIO; 687 return -EIO;
723 if (cxl_afu_disable(afu)) 688 if (cxl_afu_disable(afu))
724 return -EIO; 689 return -EIO;
@@ -766,13 +731,13 @@ static int sanitise_afu_regs(struct cxl_afu *afu)
766 * 4/8 bytes aligned access. So in case the requested offset/count arent 8 byte 731 * 4/8 bytes aligned access. So in case the requested offset/count arent 8 byte
767 * aligned the function uses a bounce buffer which can be max PAGE_SIZE. 732 * aligned the function uses a bounce buffer which can be max PAGE_SIZE.
768 */ 733 */
769ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf, 734ssize_t cxl_pci_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
770 loff_t off, size_t count) 735 loff_t off, size_t count)
771{ 736{
772 loff_t aligned_start, aligned_end; 737 loff_t aligned_start, aligned_end;
773 size_t aligned_length; 738 size_t aligned_length;
774 void *tbuf; 739 void *tbuf;
775 const void __iomem *ebuf = afu->afu_desc_mmio + afu->eb_offset; 740 const void __iomem *ebuf = afu->native->afu_desc_mmio + afu->eb_offset;
776 741
777 if (count == 0 || off < 0 || (size_t)off >= afu->eb_len) 742 if (count == 0 || off < 0 || (size_t)off >= afu->eb_len)
778 return 0; 743 return 0;
@@ -803,18 +768,18 @@ ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
803 return count; 768 return count;
804} 769}
805 770
806static int cxl_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pci_dev *dev) 771static int pci_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pci_dev *dev)
807{ 772{
808 int rc; 773 int rc;
809 774
810 if ((rc = cxl_map_slice_regs(afu, adapter, dev))) 775 if ((rc = pci_map_slice_regs(afu, adapter, dev)))
811 return rc; 776 return rc;
812 777
813 if ((rc = sanitise_afu_regs(afu))) 778 if ((rc = sanitise_afu_regs(afu)))
814 goto err1; 779 goto err1;
815 780
816 /* We need to reset the AFU before we can read the AFU descriptor */ 781 /* We need to reset the AFU before we can read the AFU descriptor */
817 if ((rc = __cxl_afu_reset(afu))) 782 if ((rc = cxl_ops->afu_reset(afu)))
818 goto err1; 783 goto err1;
819 784
820 if (cxl_verbose) 785 if (cxl_verbose)
@@ -829,44 +794,50 @@ static int cxl_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pc
829 if ((rc = init_implementation_afu_regs(afu))) 794 if ((rc = init_implementation_afu_regs(afu)))
830 goto err1; 795 goto err1;
831 796
832 if ((rc = cxl_register_serr_irq(afu))) 797 if ((rc = cxl_native_register_serr_irq(afu)))
833 goto err1; 798 goto err1;
834 799
835 if ((rc = cxl_register_psl_irq(afu))) 800 if ((rc = cxl_native_register_psl_irq(afu)))
836 goto err2; 801 goto err2;
837 802
838 return 0; 803 return 0;
839 804
840err2: 805err2:
841 cxl_release_serr_irq(afu); 806 cxl_native_release_serr_irq(afu);
842err1: 807err1:
843 cxl_unmap_slice_regs(afu); 808 pci_unmap_slice_regs(afu);
844 return rc; 809 return rc;
845} 810}
846 811
847static void cxl_deconfigure_afu(struct cxl_afu *afu) 812static void pci_deconfigure_afu(struct cxl_afu *afu)
848{ 813{
849 cxl_release_psl_irq(afu); 814 cxl_native_release_psl_irq(afu);
850 cxl_release_serr_irq(afu); 815 cxl_native_release_serr_irq(afu);
851 cxl_unmap_slice_regs(afu); 816 pci_unmap_slice_regs(afu);
852} 817}
853 818
854static int cxl_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev) 819static int pci_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev)
855{ 820{
856 struct cxl_afu *afu; 821 struct cxl_afu *afu;
857 int rc; 822 int rc = -ENOMEM;
858 823
859 afu = cxl_alloc_afu(adapter, slice); 824 afu = cxl_alloc_afu(adapter, slice);
860 if (!afu) 825 if (!afu)
861 return -ENOMEM; 826 return -ENOMEM;
862 827
828 afu->native = kzalloc(sizeof(struct cxl_afu_native), GFP_KERNEL);
829 if (!afu->native)
830 goto err_free_afu;
831
832 mutex_init(&afu->native->spa_mutex);
833
863 rc = dev_set_name(&afu->dev, "afu%i.%i", adapter->adapter_num, slice); 834 rc = dev_set_name(&afu->dev, "afu%i.%i", adapter->adapter_num, slice);
864 if (rc) 835 if (rc)
865 goto err_free; 836 goto err_free_native;
866 837
867 rc = cxl_configure_afu(afu, adapter, dev); 838 rc = pci_configure_afu(afu, adapter, dev);
868 if (rc) 839 if (rc)
869 goto err_free; 840 goto err_free_native;
870 841
871 /* Don't care if this fails */ 842 /* Don't care if this fails */
872 cxl_debugfs_afu_add(afu); 843 cxl_debugfs_afu_add(afu);
@@ -889,24 +860,27 @@ static int cxl_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev)
889 return 0; 860 return 0;
890 861
891err_put1: 862err_put1:
892 cxl_deconfigure_afu(afu); 863 pci_deconfigure_afu(afu);
893 cxl_debugfs_afu_remove(afu); 864 cxl_debugfs_afu_remove(afu);
894 device_unregister(&afu->dev); 865 device_unregister(&afu->dev);
895 return rc; 866 return rc;
896 867
897err_free: 868err_free_native:
869 kfree(afu->native);
870err_free_afu:
898 kfree(afu); 871 kfree(afu);
899 return rc; 872 return rc;
900 873
901} 874}
902 875
903static void cxl_remove_afu(struct cxl_afu *afu) 876static void cxl_pci_remove_afu(struct cxl_afu *afu)
904{ 877{
905 pr_devel("cxl_remove_afu\n"); 878 pr_devel("%s\n", __func__);
906 879
907 if (!afu) 880 if (!afu)
908 return; 881 return;
909 882
883 cxl_pci_vphb_remove(afu);
910 cxl_sysfs_afu_remove(afu); 884 cxl_sysfs_afu_remove(afu);
911 cxl_debugfs_afu_remove(afu); 885 cxl_debugfs_afu_remove(afu);
912 886
@@ -915,13 +889,13 @@ static void cxl_remove_afu(struct cxl_afu *afu)
915 spin_unlock(&afu->adapter->afu_list_lock); 889 spin_unlock(&afu->adapter->afu_list_lock);
916 890
917 cxl_context_detach_all(afu); 891 cxl_context_detach_all(afu);
918 cxl_afu_deactivate_mode(afu); 892 cxl_ops->afu_deactivate_mode(afu, afu->current_mode);
919 893
920 cxl_deconfigure_afu(afu); 894 pci_deconfigure_afu(afu);
921 device_unregister(&afu->dev); 895 device_unregister(&afu->dev);
922} 896}
923 897
924int cxl_reset(struct cxl *adapter) 898int cxl_pci_reset(struct cxl *adapter)
925{ 899{
926 struct pci_dev *dev = to_pci_dev(adapter->dev.parent); 900 struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
927 int rc; 901 int rc;
@@ -955,17 +929,17 @@ static int cxl_map_adapter_regs(struct cxl *adapter, struct pci_dev *dev)
955 pr_devel("cxl_map_adapter_regs: p1: %#016llx %#llx, p2: %#016llx %#llx", 929 pr_devel("cxl_map_adapter_regs: p1: %#016llx %#llx, p2: %#016llx %#llx",
956 p1_base(dev), p1_size(dev), p2_base(dev), p2_size(dev)); 930 p1_base(dev), p1_size(dev), p2_base(dev), p2_size(dev));
957 931
958 if (!(adapter->p1_mmio = ioremap(p1_base(dev), p1_size(dev)))) 932 if (!(adapter->native->p1_mmio = ioremap(p1_base(dev), p1_size(dev))))
959 goto err3; 933 goto err3;
960 934
961 if (!(adapter->p2_mmio = ioremap(p2_base(dev), p2_size(dev)))) 935 if (!(adapter->native->p2_mmio = ioremap(p2_base(dev), p2_size(dev))))
962 goto err4; 936 goto err4;
963 937
964 return 0; 938 return 0;
965 939
966err4: 940err4:
967 iounmap(adapter->p1_mmio); 941 iounmap(adapter->native->p1_mmio);
968 adapter->p1_mmio = NULL; 942 adapter->native->p1_mmio = NULL;
969err3: 943err3:
970 pci_release_region(dev, 0); 944 pci_release_region(dev, 0);
971err2: 945err2:
@@ -976,14 +950,14 @@ err1:
976 950
977static void cxl_unmap_adapter_regs(struct cxl *adapter) 951static void cxl_unmap_adapter_regs(struct cxl *adapter)
978{ 952{
979 if (adapter->p1_mmio) { 953 if (adapter->native->p1_mmio) {
980 iounmap(adapter->p1_mmio); 954 iounmap(adapter->native->p1_mmio);
981 adapter->p1_mmio = NULL; 955 adapter->native->p1_mmio = NULL;
982 pci_release_region(to_pci_dev(adapter->dev.parent), 2); 956 pci_release_region(to_pci_dev(adapter->dev.parent), 2);
983 } 957 }
984 if (adapter->p2_mmio) { 958 if (adapter->native->p2_mmio) {
985 iounmap(adapter->p2_mmio); 959 iounmap(adapter->native->p2_mmio);
986 adapter->p2_mmio = NULL; 960 adapter->native->p2_mmio = NULL;
987 pci_release_region(to_pci_dev(adapter->dev.parent), 0); 961 pci_release_region(to_pci_dev(adapter->dev.parent), 0);
988 } 962 }
989} 963}
@@ -1024,10 +998,10 @@ static int cxl_read_vsec(struct cxl *adapter, struct pci_dev *dev)
1024 998
1025 /* Convert everything to bytes, because there is NO WAY I'd look at the 999 /* Convert everything to bytes, because there is NO WAY I'd look at the
1026 * code a month later and forget what units these are in ;-) */ 1000 * code a month later and forget what units these are in ;-) */
1027 adapter->ps_off = ps_off * 64 * 1024; 1001 adapter->native->ps_off = ps_off * 64 * 1024;
1028 adapter->ps_size = ps_size * 64 * 1024; 1002 adapter->ps_size = ps_size * 64 * 1024;
1029 adapter->afu_desc_off = afu_desc_off * 64 * 1024; 1003 adapter->native->afu_desc_off = afu_desc_off * 64 * 1024;
1030 adapter->afu_desc_size = afu_desc_size *64 * 1024; 1004 adapter->native->afu_desc_size = afu_desc_size * 64 * 1024;
1031 1005
1032 /* Total IRQs - 1 PSL ERROR - #AFU*(1 slice error + 1 DSI) */ 1006 /* Total IRQs - 1 PSL ERROR - #AFU*(1 slice error + 1 DSI) */
1033 adapter->user_irqs = pnv_cxl_get_irq_count(dev) - 1 - 2*adapter->slices; 1007 adapter->user_irqs = pnv_cxl_get_irq_count(dev) - 1 - 2*adapter->slices;
@@ -1078,21 +1052,26 @@ static int cxl_vsec_looks_ok(struct cxl *adapter, struct pci_dev *dev)
1078 return -EINVAL; 1052 return -EINVAL;
1079 } 1053 }
1080 1054
1081 if (!adapter->afu_desc_off || !adapter->afu_desc_size) { 1055 if (!adapter->native->afu_desc_off || !adapter->native->afu_desc_size) {
1082 dev_err(&dev->dev, "ABORTING: VSEC shows no AFU descriptors\n"); 1056 dev_err(&dev->dev, "ABORTING: VSEC shows no AFU descriptors\n");
1083 return -EINVAL; 1057 return -EINVAL;
1084 } 1058 }
1085 1059
1086 if (adapter->ps_size > p2_size(dev) - adapter->ps_off) { 1060 if (adapter->ps_size > p2_size(dev) - adapter->native->ps_off) {
1087 dev_err(&dev->dev, "ABORTING: Problem state size larger than " 1061 dev_err(&dev->dev, "ABORTING: Problem state size larger than "
1088 "available in BAR2: 0x%llx > 0x%llx\n", 1062 "available in BAR2: 0x%llx > 0x%llx\n",
1089 adapter->ps_size, p2_size(dev) - adapter->ps_off); 1063 adapter->ps_size, p2_size(dev) - adapter->native->ps_off);
1090 return -EINVAL; 1064 return -EINVAL;
1091 } 1065 }
1092 1066
1093 return 0; 1067 return 0;
1094} 1068}
1095 1069
1070ssize_t cxl_pci_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len)
1071{
1072 return pci_read_vpd(to_pci_dev(adapter->dev.parent), 0, len, buf);
1073}
1074
1096static void cxl_release_adapter(struct device *dev) 1075static void cxl_release_adapter(struct device *dev)
1097{ 1076{
1098 struct cxl *adapter = to_cxl_adapter(dev); 1077 struct cxl *adapter = to_cxl_adapter(dev);
@@ -1101,33 +1080,10 @@ static void cxl_release_adapter(struct device *dev)
1101 1080
1102 cxl_remove_adapter_nr(adapter); 1081 cxl_remove_adapter_nr(adapter);
1103 1082
1083 kfree(adapter->native);
1104 kfree(adapter); 1084 kfree(adapter);
1105} 1085}
1106 1086
1107static struct cxl *cxl_alloc_adapter(void)
1108{
1109 struct cxl *adapter;
1110
1111 if (!(adapter = kzalloc(sizeof(struct cxl), GFP_KERNEL)))
1112 return NULL;
1113
1114 spin_lock_init(&adapter->afu_list_lock);
1115
1116 if (cxl_alloc_adapter_nr(adapter))
1117 goto err1;
1118
1119 if (dev_set_name(&adapter->dev, "card%i", adapter->adapter_num))
1120 goto err2;
1121
1122 return adapter;
1123
1124err2:
1125 cxl_remove_adapter_nr(adapter);
1126err1:
1127 kfree(adapter);
1128 return NULL;
1129}
1130
1131#define CXL_PSL_ErrIVTE_tberror (0x1ull << (63-31)) 1087#define CXL_PSL_ErrIVTE_tberror (0x1ull << (63-31))
1132 1088
1133static int sanitise_adapter_regs(struct cxl *adapter) 1089static int sanitise_adapter_regs(struct cxl *adapter)
@@ -1191,7 +1147,7 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev)
1191 if ((rc = cxl_setup_psl_timebase(adapter, dev))) 1147 if ((rc = cxl_setup_psl_timebase(adapter, dev)))
1192 goto err; 1148 goto err;
1193 1149
1194 if ((rc = cxl_register_psl_err_irq(adapter))) 1150 if ((rc = cxl_native_register_psl_err_irq(adapter)))
1195 goto err; 1151 goto err;
1196 1152
1197 return 0; 1153 return 0;
@@ -1206,13 +1162,13 @@ static void cxl_deconfigure_adapter(struct cxl *adapter)
1206{ 1162{
1207 struct pci_dev *pdev = to_pci_dev(adapter->dev.parent); 1163 struct pci_dev *pdev = to_pci_dev(adapter->dev.parent);
1208 1164
1209 cxl_release_psl_err_irq(adapter); 1165 cxl_native_release_psl_err_irq(adapter);
1210 cxl_unmap_adapter_regs(adapter); 1166 cxl_unmap_adapter_regs(adapter);
1211 1167
1212 pci_disable_device(pdev); 1168 pci_disable_device(pdev);
1213} 1169}
1214 1170
1215static struct cxl *cxl_init_adapter(struct pci_dev *dev) 1171static struct cxl *cxl_pci_init_adapter(struct pci_dev *dev)
1216{ 1172{
1217 struct cxl *adapter; 1173 struct cxl *adapter;
1218 int rc; 1174 int rc;
@@ -1221,6 +1177,12 @@ static struct cxl *cxl_init_adapter(struct pci_dev *dev)
1221 if (!adapter) 1177 if (!adapter)
1222 return ERR_PTR(-ENOMEM); 1178 return ERR_PTR(-ENOMEM);
1223 1179
1180 adapter->native = kzalloc(sizeof(struct cxl_native), GFP_KERNEL);
1181 if (!adapter->native) {
1182 rc = -ENOMEM;
1183 goto err_release;
1184 }
1185
1224 /* Set defaults for parameters which need to persist over 1186 /* Set defaults for parameters which need to persist over
1225 * configure/reconfigure 1187 * configure/reconfigure
1226 */ 1188 */
@@ -1230,8 +1192,7 @@ static struct cxl *cxl_init_adapter(struct pci_dev *dev)
1230 rc = cxl_configure_adapter(adapter, dev); 1192 rc = cxl_configure_adapter(adapter, dev);
1231 if (rc) { 1193 if (rc) {
1232 pci_disable_device(dev); 1194 pci_disable_device(dev);
1233 cxl_release_adapter(&adapter->dev); 1195 goto err_release;
1234 return ERR_PTR(rc);
1235 } 1196 }
1236 1197
1237 /* Don't care if this one fails: */ 1198 /* Don't care if this one fails: */
@@ -1257,9 +1218,13 @@ err_put1:
1257 cxl_deconfigure_adapter(adapter); 1218 cxl_deconfigure_adapter(adapter);
1258 device_unregister(&adapter->dev); 1219 device_unregister(&adapter->dev);
1259 return ERR_PTR(rc); 1220 return ERR_PTR(rc);
1221
1222err_release:
1223 cxl_release_adapter(&adapter->dev);
1224 return ERR_PTR(rc);
1260} 1225}
1261 1226
1262static void cxl_remove_adapter(struct cxl *adapter) 1227static void cxl_pci_remove_adapter(struct cxl *adapter)
1263{ 1228{
1264 pr_devel("cxl_remove_adapter\n"); 1229 pr_devel("cxl_remove_adapter\n");
1265 1230
@@ -1277,17 +1242,22 @@ static int cxl_probe(struct pci_dev *dev, const struct pci_device_id *id)
1277 int slice; 1242 int slice;
1278 int rc; 1243 int rc;
1279 1244
1245 if (cxl_pci_is_vphb_device(dev)) {
1246 dev_dbg(&dev->dev, "cxl_init_adapter: Ignoring cxl vphb device\n");
1247 return -ENODEV;
1248 }
1249
1280 if (cxl_verbose) 1250 if (cxl_verbose)
1281 dump_cxl_config_space(dev); 1251 dump_cxl_config_space(dev);
1282 1252
1283 adapter = cxl_init_adapter(dev); 1253 adapter = cxl_pci_init_adapter(dev);
1284 if (IS_ERR(adapter)) { 1254 if (IS_ERR(adapter)) {
1285 dev_err(&dev->dev, "cxl_init_adapter failed: %li\n", PTR_ERR(adapter)); 1255 dev_err(&dev->dev, "cxl_init_adapter failed: %li\n", PTR_ERR(adapter));
1286 return PTR_ERR(adapter); 1256 return PTR_ERR(adapter);
1287 } 1257 }
1288 1258
1289 for (slice = 0; slice < adapter->slices; slice++) { 1259 for (slice = 0; slice < adapter->slices; slice++) {
1290 if ((rc = cxl_init_afu(adapter, slice, dev))) { 1260 if ((rc = pci_init_afu(adapter, slice, dev))) {
1291 dev_err(&dev->dev, "AFU %i failed to initialise: %i\n", slice, rc); 1261 dev_err(&dev->dev, "AFU %i failed to initialise: %i\n", slice, rc);
1292 continue; 1262 continue;
1293 } 1263 }
@@ -1312,10 +1282,9 @@ static void cxl_remove(struct pci_dev *dev)
1312 */ 1282 */
1313 for (i = 0; i < adapter->slices; i++) { 1283 for (i = 0; i < adapter->slices; i++) {
1314 afu = adapter->afu[i]; 1284 afu = adapter->afu[i];
1315 cxl_pci_vphb_remove(afu); 1285 cxl_pci_remove_afu(afu);
1316 cxl_remove_afu(afu);
1317 } 1286 }
1318 cxl_remove_adapter(adapter); 1287 cxl_pci_remove_adapter(adapter);
1319} 1288}
1320 1289
1321static pci_ers_result_t cxl_vphb_error_detected(struct cxl_afu *afu, 1290static pci_ers_result_t cxl_vphb_error_detected(struct cxl_afu *afu,
@@ -1461,8 +1430,8 @@ static pci_ers_result_t cxl_pci_error_detected(struct pci_dev *pdev,
1461 return result; 1430 return result;
1462 1431
1463 cxl_context_detach_all(afu); 1432 cxl_context_detach_all(afu);
1464 cxl_afu_deactivate_mode(afu); 1433 cxl_ops->afu_deactivate_mode(afu, afu->current_mode);
1465 cxl_deconfigure_afu(afu); 1434 pci_deconfigure_afu(afu);
1466 } 1435 }
1467 cxl_deconfigure_adapter(adapter); 1436 cxl_deconfigure_adapter(adapter);
1468 1437
@@ -1485,14 +1454,12 @@ static pci_ers_result_t cxl_pci_slot_reset(struct pci_dev *pdev)
1485 for (i = 0; i < adapter->slices; i++) { 1454 for (i = 0; i < adapter->slices; i++) {
1486 afu = adapter->afu[i]; 1455 afu = adapter->afu[i];
1487 1456
1488 if (cxl_configure_afu(afu, adapter, pdev)) 1457 if (pci_configure_afu(afu, adapter, pdev))
1489 goto err; 1458 goto err;
1490 1459
1491 if (cxl_afu_select_best_mode(afu)) 1460 if (cxl_afu_select_best_mode(afu))
1492 goto err; 1461 goto err;
1493 1462
1494 cxl_pci_vphb_reconfigure(afu);
1495
1496 list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) { 1463 list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
1497 /* Reset the device context. 1464 /* Reset the device context.
1498 * TODO: make this less disruptive 1465 * TODO: make this less disruptive
@@ -1508,7 +1475,7 @@ static pci_ers_result_t cxl_pci_slot_reset(struct pci_dev *pdev)
1508 1475
1509 afu_dev->dev.archdata.cxl_ctx = ctx; 1476 afu_dev->dev.archdata.cxl_ctx = ctx;
1510 1477
1511 if (cxl_afu_check_and_enable(afu)) 1478 if (cxl_ops->afu_check_and_enable(afu))
1512 goto err; 1479 goto err;
1513 1480
1514 afu_dev->error_state = pci_channel_io_normal; 1481 afu_dev->error_state = pci_channel_io_normal;
diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c
index 038af5d45145..25913c08794c 100644
--- a/drivers/misc/cxl/sysfs.c
+++ b/drivers/misc/cxl/sysfs.c
@@ -69,7 +69,7 @@ static ssize_t reset_adapter_store(struct device *device,
69 if ((rc != 1) || (val != 1)) 69 if ((rc != 1) || (val != 1))
70 return -EINVAL; 70 return -EINVAL;
71 71
72 if ((rc = cxl_reset(adapter))) 72 if ((rc = cxl_ops->adapter_reset(adapter)))
73 return rc; 73 return rc;
74 return count; 74 return count;
75} 75}
@@ -165,7 +165,7 @@ static ssize_t pp_mmio_off_show(struct device *device,
165{ 165{
166 struct cxl_afu *afu = to_afu_chardev_m(device); 166 struct cxl_afu *afu = to_afu_chardev_m(device);
167 167
168 return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->pp_offset); 168 return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->native->pp_offset);
169} 169}
170 170
171static ssize_t pp_mmio_len_show(struct device *device, 171static ssize_t pp_mmio_len_show(struct device *device,
@@ -211,7 +211,7 @@ static ssize_t reset_store_afu(struct device *device,
211 goto err; 211 goto err;
212 } 212 }
213 213
214 if ((rc = __cxl_afu_reset(afu))) 214 if ((rc = cxl_ops->afu_reset(afu)))
215 goto err; 215 goto err;
216 216
217 rc = count; 217 rc = count;
@@ -253,8 +253,14 @@ static ssize_t irqs_max_store(struct device *device,
253 if (irqs_max < afu->pp_irqs) 253 if (irqs_max < afu->pp_irqs)
254 return -EINVAL; 254 return -EINVAL;
255 255
256 if (irqs_max > afu->adapter->user_irqs) 256 if (cpu_has_feature(CPU_FTR_HVMODE)) {
257 return -EINVAL; 257 if (irqs_max > afu->adapter->user_irqs)
258 return -EINVAL;
259 } else {
260 /* pHyp sets a per-AFU limit */
261 if (irqs_max > afu->guest->max_ints)
262 return -EINVAL;
263 }
258 264
259 afu->irqs_max = irqs_max; 265 afu->irqs_max = irqs_max;
260 return count; 266 return count;
@@ -348,7 +354,7 @@ static ssize_t mode_store(struct device *device, struct device_attribute *attr,
348 } 354 }
349 355
350 /* 356 /*
351 * cxl_afu_deactivate_mode needs to be done outside the lock, prevent 357 * afu_deactivate_mode needs to be done outside the lock, prevent
352 * other contexts coming in before we are ready: 358 * other contexts coming in before we are ready:
353 */ 359 */
354 old_mode = afu->current_mode; 360 old_mode = afu->current_mode;
@@ -357,9 +363,9 @@ static ssize_t mode_store(struct device *device, struct device_attribute *attr,
357 363
358 mutex_unlock(&afu->contexts_lock); 364 mutex_unlock(&afu->contexts_lock);
359 365
360 if ((rc = _cxl_afu_deactivate_mode(afu, old_mode))) 366 if ((rc = cxl_ops->afu_deactivate_mode(afu, old_mode)))
361 return rc; 367 return rc;
362 if ((rc = cxl_afu_activate_mode(afu, mode))) 368 if ((rc = cxl_ops->afu_activate_mode(afu, mode)))
363 return rc; 369 return rc;
364 370
365 return count; 371 return count;
@@ -388,7 +394,7 @@ static ssize_t afu_eb_read(struct file *filp, struct kobject *kobj,
388{ 394{
389 struct cxl_afu *afu = to_cxl_afu(kobj_to_dev(kobj)); 395 struct cxl_afu *afu = to_cxl_afu(kobj_to_dev(kobj));
390 396
391 return cxl_afu_read_err_buffer(afu, buf, off, count); 397 return cxl_ops->afu_read_err_buffer(afu, buf, off, count);
392} 398}
393 399
394static struct device_attribute afu_attrs[] = { 400static struct device_attribute afu_attrs[] = {
@@ -405,24 +411,39 @@ static struct device_attribute afu_attrs[] = {
405 411
406int cxl_sysfs_adapter_add(struct cxl *adapter) 412int cxl_sysfs_adapter_add(struct cxl *adapter)
407{ 413{
414 struct device_attribute *dev_attr;
408 int i, rc; 415 int i, rc;
409 416
410 for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) { 417 for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) {
411 if ((rc = device_create_file(&adapter->dev, &adapter_attrs[i]))) 418 dev_attr = &adapter_attrs[i];
412 goto err; 419 if (cxl_ops->support_attributes(dev_attr->attr.name,
420 CXL_ADAPTER_ATTRS)) {
421 if ((rc = device_create_file(&adapter->dev, dev_attr)))
422 goto err;
423 }
413 } 424 }
414 return 0; 425 return 0;
415err: 426err:
416 for (i--; i >= 0; i--) 427 for (i--; i >= 0; i--) {
417 device_remove_file(&adapter->dev, &adapter_attrs[i]); 428 dev_attr = &adapter_attrs[i];
429 if (cxl_ops->support_attributes(dev_attr->attr.name,
430 CXL_ADAPTER_ATTRS))
431 device_remove_file(&adapter->dev, dev_attr);
432 }
418 return rc; 433 return rc;
419} 434}
435
420void cxl_sysfs_adapter_remove(struct cxl *adapter) 436void cxl_sysfs_adapter_remove(struct cxl *adapter)
421{ 437{
438 struct device_attribute *dev_attr;
422 int i; 439 int i;
423 440
424 for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) 441 for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) {
425 device_remove_file(&adapter->dev, &adapter_attrs[i]); 442 dev_attr = &adapter_attrs[i];
443 if (cxl_ops->support_attributes(dev_attr->attr.name,
444 CXL_ADAPTER_ATTRS))
445 device_remove_file(&adapter->dev, dev_attr);
446 }
426} 447}
427 448
428struct afu_config_record { 449struct afu_config_record {
@@ -468,10 +489,12 @@ static ssize_t afu_read_config(struct file *filp, struct kobject *kobj,
468 struct afu_config_record *cr = to_cr(kobj); 489 struct afu_config_record *cr = to_cr(kobj);
469 struct cxl_afu *afu = to_cxl_afu(kobj_to_dev(kobj->parent)); 490 struct cxl_afu *afu = to_cxl_afu(kobj_to_dev(kobj->parent));
470 491
471 u64 i, j, val; 492 u64 i, j, val, rc;
472 493
473 for (i = 0; i < count;) { 494 for (i = 0; i < count;) {
474 val = cxl_afu_cr_read64(afu, cr->cr, off & ~0x7); 495 rc = cxl_ops->afu_cr_read64(afu, cr->cr, off & ~0x7, &val);
496 if (rc)
497 val = ~0ULL;
475 for (j = off & 0x7; j < 8 && i < count; i++, j++, off++) 498 for (j = off & 0x7; j < 8 && i < count; i++, j++, off++)
476 buf[i] = (val >> (j * 8)) & 0xff; 499 buf[i] = (val >> (j * 8)) & 0xff;
477 } 500 }
@@ -516,14 +539,22 @@ static struct afu_config_record *cxl_sysfs_afu_new_cr(struct cxl_afu *afu, int c
516 return ERR_PTR(-ENOMEM); 539 return ERR_PTR(-ENOMEM);
517 540
518 cr->cr = cr_idx; 541 cr->cr = cr_idx;
519 cr->device = cxl_afu_cr_read16(afu, cr_idx, PCI_DEVICE_ID); 542
520 cr->vendor = cxl_afu_cr_read16(afu, cr_idx, PCI_VENDOR_ID); 543 rc = cxl_ops->afu_cr_read16(afu, cr_idx, PCI_DEVICE_ID, &cr->device);
521 cr->class = cxl_afu_cr_read32(afu, cr_idx, PCI_CLASS_REVISION) >> 8; 544 if (rc)
545 goto err;
546 rc = cxl_ops->afu_cr_read16(afu, cr_idx, PCI_VENDOR_ID, &cr->vendor);
547 if (rc)
548 goto err;
549 rc = cxl_ops->afu_cr_read32(afu, cr_idx, PCI_CLASS_REVISION, &cr->class);
550 if (rc)
551 goto err;
552 cr->class >>= 8;
522 553
523 /* 554 /*
524 * Export raw AFU PCIe like config record. For now this is read only by 555 * Export raw AFU PCIe like config record. For now this is read only by
525 * root - we can expand that later to be readable by non-root and maybe 556 * root - we can expand that later to be readable by non-root and maybe
526 * even writable provided we have a good use-case. Once we suport 557 * even writable provided we have a good use-case. Once we support
527 * exposing AFUs through a virtual PHB they will get that for free from 558 * exposing AFUs through a virtual PHB they will get that for free from
528 * Linux' PCI infrastructure, but until then it's not clear that we 559 * Linux' PCI infrastructure, but until then it's not clear that we
529 * need it for anything since the main use case is just identifying 560 * need it for anything since the main use case is just identifying
@@ -561,6 +592,7 @@ err:
561 592
562void cxl_sysfs_afu_remove(struct cxl_afu *afu) 593void cxl_sysfs_afu_remove(struct cxl_afu *afu)
563{ 594{
595 struct device_attribute *dev_attr;
564 struct afu_config_record *cr, *tmp; 596 struct afu_config_record *cr, *tmp;
565 int i; 597 int i;
566 598
@@ -568,8 +600,12 @@ void cxl_sysfs_afu_remove(struct cxl_afu *afu)
568 if (afu->eb_len) 600 if (afu->eb_len)
569 device_remove_bin_file(&afu->dev, &afu->attr_eb); 601 device_remove_bin_file(&afu->dev, &afu->attr_eb);
570 602
571 for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) 603 for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) {
572 device_remove_file(&afu->dev, &afu_attrs[i]); 604 dev_attr = &afu_attrs[i];
605 if (cxl_ops->support_attributes(dev_attr->attr.name,
606 CXL_AFU_ATTRS))
607 device_remove_file(&afu->dev, &afu_attrs[i]);
608 }
573 609
574 list_for_each_entry_safe(cr, tmp, &afu->crs, list) { 610 list_for_each_entry_safe(cr, tmp, &afu->crs, list) {
575 sysfs_remove_bin_file(&cr->kobj, &cr->config_attr); 611 sysfs_remove_bin_file(&cr->kobj, &cr->config_attr);
@@ -579,14 +615,19 @@ void cxl_sysfs_afu_remove(struct cxl_afu *afu)
579 615
580int cxl_sysfs_afu_add(struct cxl_afu *afu) 616int cxl_sysfs_afu_add(struct cxl_afu *afu)
581{ 617{
618 struct device_attribute *dev_attr;
582 struct afu_config_record *cr; 619 struct afu_config_record *cr;
583 int i, rc; 620 int i, rc;
584 621
585 INIT_LIST_HEAD(&afu->crs); 622 INIT_LIST_HEAD(&afu->crs);
586 623
587 for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) { 624 for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) {
588 if ((rc = device_create_file(&afu->dev, &afu_attrs[i]))) 625 dev_attr = &afu_attrs[i];
589 goto err; 626 if (cxl_ops->support_attributes(dev_attr->attr.name,
627 CXL_AFU_ATTRS)) {
628 if ((rc = device_create_file(&afu->dev, &afu_attrs[i])))
629 goto err;
630 }
590 } 631 }
591 632
592 /* conditionally create the add the binary file for error info buffer */ 633 /* conditionally create the add the binary file for error info buffer */
@@ -625,32 +666,50 @@ err:
625 /* reset the eb_len as we havent created the bin attr */ 666 /* reset the eb_len as we havent created the bin attr */
626 afu->eb_len = 0; 667 afu->eb_len = 0;
627 668
628 for (i--; i >= 0; i--) 669 for (i--; i >= 0; i--) {
670 dev_attr = &afu_attrs[i];
671 if (cxl_ops->support_attributes(dev_attr->attr.name,
672 CXL_AFU_ATTRS))
629 device_remove_file(&afu->dev, &afu_attrs[i]); 673 device_remove_file(&afu->dev, &afu_attrs[i]);
674 }
630 return rc; 675 return rc;
631} 676}
632 677
633int cxl_sysfs_afu_m_add(struct cxl_afu *afu) 678int cxl_sysfs_afu_m_add(struct cxl_afu *afu)
634{ 679{
680 struct device_attribute *dev_attr;
635 int i, rc; 681 int i, rc;
636 682
637 for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) { 683 for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) {
638 if ((rc = device_create_file(afu->chardev_m, &afu_master_attrs[i]))) 684 dev_attr = &afu_master_attrs[i];
639 goto err; 685 if (cxl_ops->support_attributes(dev_attr->attr.name,
686 CXL_AFU_MASTER_ATTRS)) {
687 if ((rc = device_create_file(afu->chardev_m, &afu_master_attrs[i])))
688 goto err;
689 }
640 } 690 }
641 691
642 return 0; 692 return 0;
643 693
644err: 694err:
645 for (i--; i >= 0; i--) 695 for (i--; i >= 0; i--) {
646 device_remove_file(afu->chardev_m, &afu_master_attrs[i]); 696 dev_attr = &afu_master_attrs[i];
697 if (cxl_ops->support_attributes(dev_attr->attr.name,
698 CXL_AFU_MASTER_ATTRS))
699 device_remove_file(afu->chardev_m, &afu_master_attrs[i]);
700 }
647 return rc; 701 return rc;
648} 702}
649 703
650void cxl_sysfs_afu_m_remove(struct cxl_afu *afu) 704void cxl_sysfs_afu_m_remove(struct cxl_afu *afu)
651{ 705{
706 struct device_attribute *dev_attr;
652 int i; 707 int i;
653 708
654 for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) 709 for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) {
655 device_remove_file(afu->chardev_m, &afu_master_attrs[i]); 710 dev_attr = &afu_master_attrs[i];
711 if (cxl_ops->support_attributes(dev_attr->attr.name,
712 CXL_AFU_MASTER_ATTRS))
713 device_remove_file(afu->chardev_m, &afu_master_attrs[i]);
714 }
656} 715}
diff --git a/drivers/misc/cxl/trace.h b/drivers/misc/cxl/trace.h
index 6e1e2adfba8e..751d6119683e 100644
--- a/drivers/misc/cxl/trace.h
+++ b/drivers/misc/cxl/trace.h
@@ -450,6 +450,199 @@ DEFINE_EVENT(cxl_pe_class, cxl_slbia,
450 TP_ARGS(ctx) 450 TP_ARGS(ctx)
451); 451);
452 452
453TRACE_EVENT(cxl_hcall,
454 TP_PROTO(u64 unit_address, u64 process_token, long rc),
455
456 TP_ARGS(unit_address, process_token, rc),
457
458 TP_STRUCT__entry(
459 __field(u64, unit_address)
460 __field(u64, process_token)
461 __field(long, rc)
462 ),
463
464 TP_fast_assign(
465 __entry->unit_address = unit_address;
466 __entry->process_token = process_token;
467 __entry->rc = rc;
468 ),
469
470 TP_printk("unit_address=0x%016llx process_token=0x%016llx rc=%li",
471 __entry->unit_address,
472 __entry->process_token,
473 __entry->rc
474 )
475);
476
477TRACE_EVENT(cxl_hcall_control,
478 TP_PROTO(u64 unit_address, char *fct, u64 p1, u64 p2, u64 p3,
479 u64 p4, unsigned long r4, long rc),
480
481 TP_ARGS(unit_address, fct, p1, p2, p3, p4, r4, rc),
482
483 TP_STRUCT__entry(
484 __field(u64, unit_address)
485 __field(char *, fct)
486 __field(u64, p1)
487 __field(u64, p2)
488 __field(u64, p3)
489 __field(u64, p4)
490 __field(unsigned long, r4)
491 __field(long, rc)
492 ),
493
494 TP_fast_assign(
495 __entry->unit_address = unit_address;
496 __entry->fct = fct;
497 __entry->p1 = p1;
498 __entry->p2 = p2;
499 __entry->p3 = p3;
500 __entry->p4 = p4;
501 __entry->r4 = r4;
502 __entry->rc = rc;
503 ),
504
505 TP_printk("unit_address=%#.16llx %s(%#llx, %#llx, %#llx, %#llx, R4: %#lx)): %li",
506 __entry->unit_address,
507 __entry->fct,
508 __entry->p1,
509 __entry->p2,
510 __entry->p3,
511 __entry->p4,
512 __entry->r4,
513 __entry->rc
514 )
515);
516
517TRACE_EVENT(cxl_hcall_attach,
518 TP_PROTO(u64 unit_address, u64 phys_addr, unsigned long process_token,
519 unsigned long mmio_addr, unsigned long mmio_size, long rc),
520
521 TP_ARGS(unit_address, phys_addr, process_token,
522 mmio_addr, mmio_size, rc),
523
524 TP_STRUCT__entry(
525 __field(u64, unit_address)
526 __field(u64, phys_addr)
527 __field(unsigned long, process_token)
528 __field(unsigned long, mmio_addr)
529 __field(unsigned long, mmio_size)
530 __field(long, rc)
531 ),
532
533 TP_fast_assign(
534 __entry->unit_address = unit_address;
535 __entry->phys_addr = phys_addr;
536 __entry->process_token = process_token;
537 __entry->mmio_addr = mmio_addr;
538 __entry->mmio_size = mmio_size;
539 __entry->rc = rc;
540 ),
541
542 TP_printk("unit_address=0x%016llx phys_addr=0x%016llx "
543 "token=0x%.8lx mmio_addr=0x%lx mmio_size=0x%lx rc=%li",
544 __entry->unit_address,
545 __entry->phys_addr,
546 __entry->process_token,
547 __entry->mmio_addr,
548 __entry->mmio_size,
549 __entry->rc
550 )
551);
552
553DEFINE_EVENT(cxl_hcall, cxl_hcall_detach,
554 TP_PROTO(u64 unit_address, u64 process_token, long rc),
555 TP_ARGS(unit_address, process_token, rc)
556);
557
558DEFINE_EVENT(cxl_hcall_control, cxl_hcall_control_function,
559 TP_PROTO(u64 unit_address, char *fct, u64 p1, u64 p2, u64 p3,
560 u64 p4, unsigned long r4, long rc),
561 TP_ARGS(unit_address, fct, p1, p2, p3, p4, r4, rc)
562);
563
564DEFINE_EVENT(cxl_hcall, cxl_hcall_collect_int_info,
565 TP_PROTO(u64 unit_address, u64 process_token, long rc),
566 TP_ARGS(unit_address, process_token, rc)
567);
568
569TRACE_EVENT(cxl_hcall_control_faults,
570 TP_PROTO(u64 unit_address, u64 process_token,
571 u64 control_mask, u64 reset_mask, unsigned long r4,
572 long rc),
573
574 TP_ARGS(unit_address, process_token,
575 control_mask, reset_mask, r4, rc),
576
577 TP_STRUCT__entry(
578 __field(u64, unit_address)
579 __field(u64, process_token)
580 __field(u64, control_mask)
581 __field(u64, reset_mask)
582 __field(unsigned long, r4)
583 __field(long, rc)
584 ),
585
586 TP_fast_assign(
587 __entry->unit_address = unit_address;
588 __entry->process_token = process_token;
589 __entry->control_mask = control_mask;
590 __entry->reset_mask = reset_mask;
591 __entry->r4 = r4;
592 __entry->rc = rc;
593 ),
594
595 TP_printk("unit_address=0x%016llx process_token=0x%llx "
596 "control_mask=%#llx reset_mask=%#llx r4=%#lx rc=%li",
597 __entry->unit_address,
598 __entry->process_token,
599 __entry->control_mask,
600 __entry->reset_mask,
601 __entry->r4,
602 __entry->rc
603 )
604);
605
606DEFINE_EVENT(cxl_hcall_control, cxl_hcall_control_facility,
607 TP_PROTO(u64 unit_address, char *fct, u64 p1, u64 p2, u64 p3,
608 u64 p4, unsigned long r4, long rc),
609 TP_ARGS(unit_address, fct, p1, p2, p3, p4, r4, rc)
610);
611
612TRACE_EVENT(cxl_hcall_download_facility,
613 TP_PROTO(u64 unit_address, char *fct, u64 list_address, u64 num,
614 unsigned long r4, long rc),
615
616 TP_ARGS(unit_address, fct, list_address, num, r4, rc),
617
618 TP_STRUCT__entry(
619 __field(u64, unit_address)
620 __field(char *, fct)
621 __field(u64, list_address)
622 __field(u64, num)
623 __field(unsigned long, r4)
624 __field(long, rc)
625 ),
626
627 TP_fast_assign(
628 __entry->unit_address = unit_address;
629 __entry->fct = fct;
630 __entry->list_address = list_address;
631 __entry->num = num;
632 __entry->r4 = r4;
633 __entry->rc = rc;
634 ),
635
636 TP_printk("%#.16llx, %s(%#llx, %#llx), %#lx): %li",
637 __entry->unit_address,
638 __entry->fct,
639 __entry->list_address,
640 __entry->num,
641 __entry->r4,
642 __entry->rc
643 )
644);
645
453#endif /* _CXL_TRACE_H */ 646#endif /* _CXL_TRACE_H */
454 647
455/* This part must be outside protection */ 648/* This part must be outside protection */
diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c
index cbd4331fb45c..cdc7723b845d 100644
--- a/drivers/misc/cxl/vphb.c
+++ b/drivers/misc/cxl/vphb.c
@@ -49,7 +49,7 @@ static bool cxl_pci_enable_device_hook(struct pci_dev *dev)
49 phb = pci_bus_to_host(dev->bus); 49 phb = pci_bus_to_host(dev->bus);
50 afu = (struct cxl_afu *)phb->private_data; 50 afu = (struct cxl_afu *)phb->private_data;
51 51
52 if (!cxl_adapter_link_ok(afu->adapter)) { 52 if (!cxl_ops->link_ok(afu->adapter, afu)) {
53 dev_warn(&dev->dev, "%s: Device link is down, refusing to enable AFU\n", __func__); 53 dev_warn(&dev->dev, "%s: Device link is down, refusing to enable AFU\n", __func__);
54 return false; 54 return false;
55 } 55 }
@@ -66,7 +66,7 @@ static bool cxl_pci_enable_device_hook(struct pci_dev *dev)
66 return false; 66 return false;
67 dev->dev.archdata.cxl_ctx = ctx; 67 dev->dev.archdata.cxl_ctx = ctx;
68 68
69 return (cxl_afu_check_and_enable(afu) == 0); 69 return (cxl_ops->afu_check_and_enable(afu) == 0);
70} 70}
71 71
72static void cxl_pci_disable_device(struct pci_dev *dev) 72static void cxl_pci_disable_device(struct pci_dev *dev)
@@ -99,113 +99,90 @@ static int cxl_pcie_cfg_record(u8 bus, u8 devfn)
99 return (bus << 8) + devfn; 99 return (bus << 8) + devfn;
100} 100}
101 101
102static unsigned long cxl_pcie_cfg_addr(struct pci_controller* phb,
103 u8 bus, u8 devfn, int offset)
104{
105 int record = cxl_pcie_cfg_record(bus, devfn);
106
107 return (unsigned long)phb->cfg_addr + ((unsigned long)phb->cfg_data * record) + offset;
108}
109
110
111static int cxl_pcie_config_info(struct pci_bus *bus, unsigned int devfn, 102static int cxl_pcie_config_info(struct pci_bus *bus, unsigned int devfn,
112 int offset, int len, 103 struct cxl_afu **_afu, int *_record)
113 volatile void __iomem **ioaddr,
114 u32 *mask, int *shift)
115{ 104{
116 struct pci_controller *phb; 105 struct pci_controller *phb;
117 struct cxl_afu *afu; 106 struct cxl_afu *afu;
118 unsigned long addr; 107 int record;
119 108
120 phb = pci_bus_to_host(bus); 109 phb = pci_bus_to_host(bus);
121 if (phb == NULL) 110 if (phb == NULL)
122 return PCIBIOS_DEVICE_NOT_FOUND; 111 return PCIBIOS_DEVICE_NOT_FOUND;
123 afu = (struct cxl_afu *)phb->private_data;
124 112
125 if (cxl_pcie_cfg_record(bus->number, devfn) > afu->crs_num) 113 afu = (struct cxl_afu *)phb->private_data;
114 record = cxl_pcie_cfg_record(bus->number, devfn);
115 if (record > afu->crs_num)
126 return PCIBIOS_DEVICE_NOT_FOUND; 116 return PCIBIOS_DEVICE_NOT_FOUND;
127 if (offset >= (unsigned long)phb->cfg_data)
128 return PCIBIOS_BAD_REGISTER_NUMBER;
129 addr = cxl_pcie_cfg_addr(phb, bus->number, devfn, offset);
130 117
131 *ioaddr = (void *)(addr & ~0x3ULL); 118 *_afu = afu;
132 *shift = ((addr & 0x3) * 8); 119 *_record = record;
133 switch (len) {
134 case 1:
135 *mask = 0xff;
136 break;
137 case 2:
138 *mask = 0xffff;
139 break;
140 default:
141 *mask = 0xffffffff;
142 break;
143 }
144 return 0; 120 return 0;
145} 121}
146 122
147
148static inline bool cxl_config_link_ok(struct pci_bus *bus)
149{
150 struct pci_controller *phb;
151 struct cxl_afu *afu;
152
153 /* Config space IO is based on phb->cfg_addr, which is based on
154 * afu_desc_mmio. This isn't safe to read/write when the link
155 * goes down, as EEH tears down MMIO space.
156 *
157 * Check if the link is OK before proceeding.
158 */
159
160 phb = pci_bus_to_host(bus);
161 if (phb == NULL)
162 return false;
163 afu = (struct cxl_afu *)phb->private_data;
164 return cxl_adapter_link_ok(afu->adapter);
165}
166
167static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn, 123static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
168 int offset, int len, u32 *val) 124 int offset, int len, u32 *val)
169{ 125{
170 volatile void __iomem *ioaddr; 126 int rc, record;
171 int shift, rc; 127 struct cxl_afu *afu;
172 u32 mask; 128 u8 val8;
129 u16 val16;
130 u32 val32;
173 131
174 rc = cxl_pcie_config_info(bus, devfn, offset, len, &ioaddr, 132 rc = cxl_pcie_config_info(bus, devfn, &afu, &record);
175 &mask, &shift);
176 if (rc) 133 if (rc)
177 return rc; 134 return rc;
178 135
179 if (!cxl_config_link_ok(bus)) 136 switch (len) {
137 case 1:
138 rc = cxl_ops->afu_cr_read8(afu, record, offset, &val8);
139 *val = val8;
140 break;
141 case 2:
142 rc = cxl_ops->afu_cr_read16(afu, record, offset, &val16);
143 *val = val16;
144 break;
145 case 4:
146 rc = cxl_ops->afu_cr_read32(afu, record, offset, &val32);
147 *val = val32;
148 break;
149 default:
150 WARN_ON(1);
151 }
152
153 if (rc)
180 return PCIBIOS_DEVICE_NOT_FOUND; 154 return PCIBIOS_DEVICE_NOT_FOUND;
181 155
182 /* Can only read 32 bits */
183 *val = (in_le32(ioaddr) >> shift) & mask;
184 return PCIBIOS_SUCCESSFUL; 156 return PCIBIOS_SUCCESSFUL;
185} 157}
186 158
187static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn, 159static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
188 int offset, int len, u32 val) 160 int offset, int len, u32 val)
189{ 161{
190 volatile void __iomem *ioaddr; 162 int rc, record;
191 u32 v, mask; 163 struct cxl_afu *afu;
192 int shift, rc;
193 164
194 rc = cxl_pcie_config_info(bus, devfn, offset, len, &ioaddr, 165 rc = cxl_pcie_config_info(bus, devfn, &afu, &record);
195 &mask, &shift);
196 if (rc) 166 if (rc)
197 return rc; 167 return rc;
198 168
199 if (!cxl_config_link_ok(bus)) 169 switch (len) {
200 return PCIBIOS_DEVICE_NOT_FOUND; 170 case 1:
201 171 rc = cxl_ops->afu_cr_write8(afu, record, offset, val & 0xff);
202 /* Can only write 32 bits so do read-modify-write */ 172 break;
203 mask <<= shift; 173 case 2:
204 val <<= shift; 174 rc = cxl_ops->afu_cr_write16(afu, record, offset, val & 0xffff);
175 break;
176 case 4:
177 rc = cxl_ops->afu_cr_write32(afu, record, offset, val);
178 break;
179 default:
180 WARN_ON(1);
181 }
205 182
206 v = (in_le32(ioaddr) & ~mask) | (val & mask); 183 if (rc)
184 return PCIBIOS_SET_FAILED;
207 185
208 out_le32(ioaddr, v);
209 return PCIBIOS_SUCCESSFUL; 186 return PCIBIOS_SUCCESSFUL;
210} 187}
211 188
@@ -233,23 +210,31 @@ int cxl_pci_vphb_add(struct cxl_afu *afu)
233{ 210{
234 struct pci_dev *phys_dev; 211 struct pci_dev *phys_dev;
235 struct pci_controller *phb, *phys_phb; 212 struct pci_controller *phb, *phys_phb;
236 213 struct device_node *vphb_dn;
237 phys_dev = to_pci_dev(afu->adapter->dev.parent); 214 struct device *parent;
238 phys_phb = pci_bus_to_host(phys_dev->bus); 215
216 if (cpu_has_feature(CPU_FTR_HVMODE)) {
217 phys_dev = to_pci_dev(afu->adapter->dev.parent);
218 phys_phb = pci_bus_to_host(phys_dev->bus);
219 vphb_dn = phys_phb->dn;
220 parent = &phys_dev->dev;
221 } else {
222 vphb_dn = afu->adapter->dev.parent->of_node;
223 parent = afu->adapter->dev.parent;
224 }
239 225
240 /* Alloc and setup PHB data structure */ 226 /* Alloc and setup PHB data structure */
241 phb = pcibios_alloc_controller(phys_phb->dn); 227 phb = pcibios_alloc_controller(vphb_dn);
242
243 if (!phb) 228 if (!phb)
244 return -ENODEV; 229 return -ENODEV;
245 230
246 /* Setup parent in sysfs */ 231 /* Setup parent in sysfs */
247 phb->parent = &phys_dev->dev; 232 phb->parent = parent;
248 233
249 /* Setup the PHB using arch provided callback */ 234 /* Setup the PHB using arch provided callback */
250 phb->ops = &cxl_pcie_pci_ops; 235 phb->ops = &cxl_pcie_pci_ops;
251 phb->cfg_addr = afu->afu_desc_mmio + afu->crs_offset; 236 phb->cfg_addr = NULL;
252 phb->cfg_data = (void *)(u64)afu->crs_len; 237 phb->cfg_data = 0;
253 phb->private_data = afu; 238 phb->private_data = afu;
254 phb->controller_ops = cxl_pci_controller_ops; 239 phb->controller_ops = cxl_pci_controller_ops;
255 240
@@ -272,15 +257,6 @@ int cxl_pci_vphb_add(struct cxl_afu *afu)
272 return 0; 257 return 0;
273} 258}
274 259
275void cxl_pci_vphb_reconfigure(struct cxl_afu *afu)
276{
277 /* When we are reconfigured, the AFU's MMIO space is unmapped
278 * and remapped. We need to reflect this in the PHB's view of
279 * the world.
280 */
281 afu->phb->cfg_addr = afu->afu_desc_mmio + afu->crs_offset;
282}
283
284void cxl_pci_vphb_remove(struct cxl_afu *afu) 260void cxl_pci_vphb_remove(struct cxl_afu *afu)
285{ 261{
286 struct pci_controller *phb; 262 struct pci_controller *phb;
@@ -296,6 +272,15 @@ void cxl_pci_vphb_remove(struct cxl_afu *afu)
296 pcibios_free_controller(phb); 272 pcibios_free_controller(phb);
297} 273}
298 274
275bool cxl_pci_is_vphb_device(struct pci_dev *dev)
276{
277 struct pci_controller *phb;
278
279 phb = pci_bus_to_host(dev->bus);
280
281 return (phb->ops == &cxl_pcie_pci_ops);
282}
283
299struct cxl_afu *cxl_pci_to_afu(struct pci_dev *dev) 284struct cxl_afu *cxl_pci_to_afu(struct pci_dev *dev)
300{ 285{
301 struct pci_controller *phb; 286 struct pci_controller *phb;
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index f2187d491475..6c9f5467bc5f 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -271,6 +271,8 @@ bool pci_bus_clip_resource(struct pci_dev *dev, int idx)
271 271
272void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { } 272void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { }
273 273
274void __weak pcibios_bus_add_device(struct pci_dev *pdev) { }
275
274/** 276/**
275 * pci_bus_add_device - start driver for a single device 277 * pci_bus_add_device - start driver for a single device
276 * @dev: device to add 278 * @dev: device to add
@@ -285,6 +287,7 @@ void pci_bus_add_device(struct pci_dev *dev)
285 * Can not put in pci_device_add yet because resources 287 * Can not put in pci_device_add yet because resources
286 * are not assigned yet for some devices. 288 * are not assigned yet for some devices.
287 */ 289 */
290 pcibios_bus_add_device(dev);
288 pci_fixup_device(pci_fixup_final, dev); 291 pci_fixup_device(pci_fixup_final, dev);
289 pci_create_sysfs_dev_files(dev); 292 pci_create_sysfs_dev_files(dev);
290 pci_proc_attach_device(dev); 293 pci_proc_attach_device(dev);
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index fe4bd0aa91a6..2194b447201d 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -113,7 +113,7 @@ resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno)
113 return dev->sriov->barsz[resno - PCI_IOV_RESOURCES]; 113 return dev->sriov->barsz[resno - PCI_IOV_RESOURCES];
114} 114}
115 115
116static int virtfn_add(struct pci_dev *dev, int id, int reset) 116int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset)
117{ 117{
118 int i; 118 int i;
119 int rc = -ENOMEM; 119 int rc = -ENOMEM;
@@ -188,7 +188,7 @@ failed:
188 return rc; 188 return rc;
189} 189}
190 190
191static void virtfn_remove(struct pci_dev *dev, int id, int reset) 191void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset)
192{ 192{
193 char buf[VIRTFN_ID_LEN]; 193 char buf[VIRTFN_ID_LEN];
194 struct pci_dev *virtfn; 194 struct pci_dev *virtfn;
@@ -321,7 +321,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
321 } 321 }
322 322
323 for (i = 0; i < initial; i++) { 323 for (i = 0; i < initial; i++) {
324 rc = virtfn_add(dev, i, 0); 324 rc = pci_iov_add_virtfn(dev, i, 0);
325 if (rc) 325 if (rc)
326 goto failed; 326 goto failed;
327 } 327 }
@@ -333,7 +333,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
333 333
334failed: 334failed:
335 while (i--) 335 while (i--)
336 virtfn_remove(dev, i, 0); 336 pci_iov_remove_virtfn(dev, i, 0);
337 337
338 pcibios_sriov_disable(dev); 338 pcibios_sriov_disable(dev);
339err_pcibios: 339err_pcibios:
@@ -359,7 +359,7 @@ static void sriov_disable(struct pci_dev *dev)
359 return; 359 return;
360 360
361 for (i = 0; i < iov->num_VFs; i++) 361 for (i = 0; i < iov->num_VFs; i++)
362 virtfn_remove(dev, i, 0); 362 pci_iov_remove_virtfn(dev, i, 0);
363 363
364 pcibios_sriov_disable(dev); 364 pcibios_sriov_disable(dev);
365 365
diff --git a/drivers/scsi/cxlflash/common.h b/drivers/scsi/cxlflash/common.h
index a8ac4c0a1493..6e6815545a71 100644
--- a/drivers/scsi/cxlflash/common.h
+++ b/drivers/scsi/cxlflash/common.h
@@ -108,7 +108,6 @@ struct cxlflash_cfg {
108 atomic_t scan_host_needed; 108 atomic_t scan_host_needed;
109 109
110 struct cxl_afu *cxl_afu; 110 struct cxl_afu *cxl_afu;
111 struct pci_dev *parent_dev;
112 111
113 atomic_t recovery_threads; 112 atomic_t recovery_threads;
114 struct mutex ctx_recovery_mutex; 113 struct mutex ctx_recovery_mutex;
diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c
index 3879b46d79e1..35968bdb4866 100644
--- a/drivers/scsi/cxlflash/main.c
+++ b/drivers/scsi/cxlflash/main.c
@@ -1355,7 +1355,7 @@ static int start_context(struct cxlflash_cfg *cfg)
1355 */ 1355 */
1356static int read_vpd(struct cxlflash_cfg *cfg, u64 wwpn[]) 1356static int read_vpd(struct cxlflash_cfg *cfg, u64 wwpn[])
1357{ 1357{
1358 struct pci_dev *dev = cfg->parent_dev; 1358 struct pci_dev *dev = cfg->dev;
1359 int rc = 0; 1359 int rc = 0;
1360 int ro_start, ro_size, i, j, k; 1360 int ro_start, ro_size, i, j, k;
1361 ssize_t vpd_size; 1361 ssize_t vpd_size;
@@ -1364,7 +1364,7 @@ static int read_vpd(struct cxlflash_cfg *cfg, u64 wwpn[])
1364 char *wwpn_vpd_tags[NUM_FC_PORTS] = { "V5", "V6" }; 1364 char *wwpn_vpd_tags[NUM_FC_PORTS] = { "V5", "V6" };
1365 1365
1366 /* Get the VPD data from the device */ 1366 /* Get the VPD data from the device */
1367 vpd_size = pci_read_vpd(dev, 0, sizeof(vpd_data), vpd_data); 1367 vpd_size = cxl_read_adapter_vpd(dev, vpd_data, sizeof(vpd_data));
1368 if (unlikely(vpd_size <= 0)) { 1368 if (unlikely(vpd_size <= 0)) {
1369 dev_err(&dev->dev, "%s: Unable to read VPD (size = %ld)\n", 1369 dev_err(&dev->dev, "%s: Unable to read VPD (size = %ld)\n",
1370 __func__, vpd_size); 1370 __func__, vpd_size);
@@ -2350,7 +2350,6 @@ static int cxlflash_probe(struct pci_dev *pdev,
2350{ 2350{
2351 struct Scsi_Host *host; 2351 struct Scsi_Host *host;
2352 struct cxlflash_cfg *cfg = NULL; 2352 struct cxlflash_cfg *cfg = NULL;
2353 struct device *phys_dev;
2354 struct dev_dependent_vals *ddv; 2353 struct dev_dependent_vals *ddv;
2355 int rc = 0; 2354 int rc = 0;
2356 2355
@@ -2416,19 +2415,6 @@ static int cxlflash_probe(struct pci_dev *pdev,
2416 2415
2417 pci_set_drvdata(pdev, cfg); 2416 pci_set_drvdata(pdev, cfg);
2418 2417
2419 /*
2420 * Use the special service provided to look up the physical
2421 * PCI device, since we are called on the probe of the virtual
2422 * PCI host bus (vphb)
2423 */
2424 phys_dev = cxl_get_phys_dev(pdev);
2425 if (!dev_is_pci(phys_dev)) {
2426 dev_err(&pdev->dev, "%s: not a pci dev\n", __func__);
2427 rc = -ENODEV;
2428 goto out_remove;
2429 }
2430 cfg->parent_dev = to_pci_dev(phys_dev);
2431
2432 cfg->cxl_afu = cxl_pci_to_afu(pdev); 2418 cfg->cxl_afu = cxl_pci_to_afu(pdev);
2433 2419
2434 rc = init_pci(cfg); 2420 rc = init_pci(cfg);
diff --git a/drivers/soc/fsl/qe/qe_common.c b/drivers/soc/fsl/qe/qe_common.c
index 419fa5b7be4d..41eff805a904 100644
--- a/drivers/soc/fsl/qe/qe_common.c
+++ b/drivers/soc/fsl/qe/qe_common.c
@@ -103,6 +103,39 @@ out_muram:
103} 103}
104 104
105/* 105/*
106 * cpm_muram_alloc_common - cpm_muram_alloc common code
107 * @size: number of bytes to allocate
108 * @algo: algorithm for alloc.
109 * @data: data for genalloc's algorithm.
110 *
111 * This function returns an offset into the muram area.
112 */
113static unsigned long cpm_muram_alloc_common(unsigned long size,
114 genpool_algo_t algo, void *data)
115{
116 struct muram_block *entry;
117 unsigned long start;
118
119 start = gen_pool_alloc_algo(muram_pool, size, algo, data);
120 if (!start)
121 goto out2;
122 start = start - GENPOOL_OFFSET;
123 memset_io(cpm_muram_addr(start), 0, size);
124 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
125 if (!entry)
126 goto out1;
127 entry->start = start;
128 entry->size = size;
129 list_add(&entry->head, &muram_block_list);
130
131 return start;
132out1:
133 gen_pool_free(muram_pool, start, size);
134out2:
135 return (unsigned long)-ENOMEM;
136}
137
138/*
106 * cpm_muram_alloc - allocate the requested size worth of multi-user ram 139 * cpm_muram_alloc - allocate the requested size worth of multi-user ram
107 * @size: number of bytes to allocate 140 * @size: number of bytes to allocate
108 * @align: requested alignment, in bytes 141 * @align: requested alignment, in bytes
@@ -175,39 +208,6 @@ unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size)
175} 208}
176EXPORT_SYMBOL(cpm_muram_alloc_fixed); 209EXPORT_SYMBOL(cpm_muram_alloc_fixed);
177 210
178/*
179 * cpm_muram_alloc_common - cpm_muram_alloc common code
180 * @size: number of bytes to allocate
181 * @algo: algorithm for alloc.
182 * @data: data for genalloc's algorithm.
183 *
184 * This function returns an offset into the muram area.
185 */
186unsigned long cpm_muram_alloc_common(unsigned long size, genpool_algo_t algo,
187 void *data)
188{
189 struct muram_block *entry;
190 unsigned long start;
191
192 start = gen_pool_alloc_algo(muram_pool, size, algo, data);
193 if (!start)
194 goto out2;
195 start = start - GENPOOL_OFFSET;
196 memset_io(cpm_muram_addr(start), 0, size);
197 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
198 if (!entry)
199 goto out1;
200 entry->start = start;
201 entry->size = size;
202 list_add(&entry->head, &muram_block_list);
203
204 return start;
205out1:
206 gen_pool_free(muram_pool, start, size);
207out2:
208 return (unsigned long)-ENOMEM;
209}
210
211/** 211/**
212 * cpm_muram_addr - turn a muram offset into a virtual address 212 * cpm_muram_addr - turn a muram offset into a virtual address
213 * @offset: muram offset to convert 213 * @offset: muram offset to convert
diff --git a/drivers/soc/fsl/qe/qe_ic.c b/drivers/soc/fsl/qe/qe_ic.c
index b77d01ff8330..ec2ca864b0c5 100644
--- a/drivers/soc/fsl/qe/qe_ic.c
+++ b/drivers/soc/fsl/qe/qe_ic.c
@@ -259,6 +259,11 @@ static int qe_ic_host_map(struct irq_domain *h, unsigned int virq,
259 struct qe_ic *qe_ic = h->host_data; 259 struct qe_ic *qe_ic = h->host_data;
260 struct irq_chip *chip; 260 struct irq_chip *chip;
261 261
262 if (hw >= ARRAY_SIZE(qe_ic_info)) {
263 pr_err("%s: Invalid hw irq number for QEIC\n", __func__);
264 return -EINVAL;
265 }
266
262 if (qe_ic_info[hw].mask == 0) { 267 if (qe_ic_info[hw].mask == 0) {
263 printk(KERN_ERR "Can't map reserved IRQ\n"); 268 printk(KERN_ERR "Can't map reserved IRQ\n");
264 return -EINVAL; 269 return -EINVAL;
@@ -407,7 +412,8 @@ int qe_ic_set_priority(unsigned int virq, unsigned int priority)
407 412
408 if (priority > 8 || priority == 0) 413 if (priority > 8 || priority == 0)
409 return -EINVAL; 414 return -EINVAL;
410 if (src > 127) 415 if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info),
416 "%s: Invalid hw irq number for QEIC\n", __func__))
411 return -EINVAL; 417 return -EINVAL;
412 if (qe_ic_info[src].pri_reg == 0) 418 if (qe_ic_info[src].pri_reg == 0)
413 return -EINVAL; 419 return -EINVAL;
@@ -436,6 +442,9 @@ int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high)
436 442
437 if (priority > 2 || priority == 0) 443 if (priority > 2 || priority == 0)
438 return -EINVAL; 444 return -EINVAL;
445 if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info),
446 "%s: Invalid hw irq number for QEIC\n", __func__))
447 return -EINVAL;
439 448
440 switch (qe_ic_info[src].pri_reg) { 449 switch (qe_ic_info[src].pri_reg) {
441 case QEIC_CIPZCC: 450 case QEIC_CIPZCC:
diff --git a/include/linux/atomic.h b/include/linux/atomic.h
index 6c502cb13c95..df4f369254c0 100644
--- a/include/linux/atomic.h
+++ b/include/linux/atomic.h
@@ -34,20 +34,29 @@
34 * The idea here is to build acquire/release variants by adding explicit 34 * The idea here is to build acquire/release variants by adding explicit
35 * barriers on top of the relaxed variant. In the case where the relaxed 35 * barriers on top of the relaxed variant. In the case where the relaxed
36 * variant is already fully ordered, no additional barriers are needed. 36 * variant is already fully ordered, no additional barriers are needed.
37 *
38 * Besides, if an arch has a special barrier for acquire/release, it could
39 * implement its own __atomic_op_* and use the same framework for building
40 * variants
37 */ 41 */
42#ifndef __atomic_op_acquire
38#define __atomic_op_acquire(op, args...) \ 43#define __atomic_op_acquire(op, args...) \
39({ \ 44({ \
40 typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \ 45 typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \
41 smp_mb__after_atomic(); \ 46 smp_mb__after_atomic(); \
42 __ret; \ 47 __ret; \
43}) 48})
49#endif
44 50
51#ifndef __atomic_op_release
45#define __atomic_op_release(op, args...) \ 52#define __atomic_op_release(op, args...) \
46({ \ 53({ \
47 smp_mb__before_atomic(); \ 54 smp_mb__before_atomic(); \
48 op##_relaxed(args); \ 55 op##_relaxed(args); \
49}) 56})
57#endif
50 58
59#ifndef __atomic_op_fence
51#define __atomic_op_fence(op, args...) \ 60#define __atomic_op_fence(op, args...) \
52({ \ 61({ \
53 typeof(op##_relaxed(args)) __ret; \ 62 typeof(op##_relaxed(args)) __ret; \
@@ -56,6 +65,7 @@
56 smp_mb__after_atomic(); \ 65 smp_mb__after_atomic(); \
57 __ret; \ 66 __ret; \
58}) 67})
68#endif
59 69
60/* atomic_add_return_relaxed */ 70/* atomic_add_return_relaxed */
61#ifndef atomic_add_return_relaxed 71#ifndef atomic_add_return_relaxed
diff --git a/include/linux/bug.h b/include/linux/bug.h
index 7f4818673c41..e51b0709e78d 100644
--- a/include/linux/bug.h
+++ b/include/linux/bug.h
@@ -20,6 +20,7 @@ struct pt_regs;
20#define BUILD_BUG_ON_MSG(cond, msg) (0) 20#define BUILD_BUG_ON_MSG(cond, msg) (0)
21#define BUILD_BUG_ON(condition) (0) 21#define BUILD_BUG_ON(condition) (0)
22#define BUILD_BUG() (0) 22#define BUILD_BUG() (0)
23#define MAYBE_BUILD_BUG_ON(cond) (0)
23#else /* __CHECKER__ */ 24#else /* __CHECKER__ */
24 25
25/* Force a compilation error if a constant expression is not a power of 2 */ 26/* Force a compilation error if a constant expression is not a power of 2 */
@@ -83,6 +84,14 @@ struct pt_regs;
83 */ 84 */
84#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed") 85#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
85 86
87#define MAYBE_BUILD_BUG_ON(cond) \
88 do { \
89 if (__builtin_constant_p((cond))) \
90 BUILD_BUG_ON(cond); \
91 else \
92 BUG_ON(cond); \
93 } while (0)
94
86#endif /* __CHECKER__ */ 95#endif /* __CHECKER__ */
87 96
88#ifdef CONFIG_GENERIC_BUG 97#ifdef CONFIG_GENERIC_BUG
diff --git a/include/linux/fsl/guts.h b/include/linux/fsl/guts.h
index 84d971ff3fba..649e9171a9b3 100644
--- a/include/linux/fsl/guts.h
+++ b/include/linux/fsl/guts.h
@@ -189,4 +189,109 @@ static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts,
189 189
190#endif 190#endif
191 191
192struct ccsr_rcpm_v1 {
193 u8 res0000[4];
194 __be32 cdozsr; /* 0x0004 Core Doze Status Register */
195 u8 res0008[4];
196 __be32 cdozcr; /* 0x000c Core Doze Control Register */
197 u8 res0010[4];
198 __be32 cnapsr; /* 0x0014 Core Nap Status Register */
199 u8 res0018[4];
200 __be32 cnapcr; /* 0x001c Core Nap Control Register */
201 u8 res0020[4];
202 __be32 cdozpsr; /* 0x0024 Core Doze Previous Status Register */
203 u8 res0028[4];
204 __be32 cnappsr; /* 0x002c Core Nap Previous Status Register */
205 u8 res0030[4];
206 __be32 cwaitsr; /* 0x0034 Core Wait Status Register */
207 u8 res0038[4];
208 __be32 cwdtdsr; /* 0x003c Core Watchdog Detect Status Register */
209 __be32 powmgtcsr; /* 0x0040 PM Control&Status Register */
210#define RCPM_POWMGTCSR_SLP 0x00020000
211 u8 res0044[12];
212 __be32 ippdexpcr; /* 0x0050 IP Powerdown Exception Control Register */
213 u8 res0054[16];
214 __be32 cpmimr; /* 0x0064 Core PM IRQ Mask Register */
215 u8 res0068[4];
216 __be32 cpmcimr; /* 0x006c Core PM Critical IRQ Mask Register */
217 u8 res0070[4];
218 __be32 cpmmcmr; /* 0x0074 Core PM Machine Check Mask Register */
219 u8 res0078[4];
220 __be32 cpmnmimr; /* 0x007c Core PM NMI Mask Register */
221 u8 res0080[4];
222 __be32 ctbenr; /* 0x0084 Core Time Base Enable Register */
223 u8 res0088[4];
224 __be32 ctbckselr; /* 0x008c Core Time Base Clock Select Register */
225 u8 res0090[4];
226 __be32 ctbhltcr; /* 0x0094 Core Time Base Halt Control Register */
227 u8 res0098[4];
228 __be32 cmcpmaskcr; /* 0x00a4 Core Machine Check Mask Register */
229};
230
231struct ccsr_rcpm_v2 {
232 u8 res_00[12];
233 __be32 tph10sr0; /* Thread PH10 Status Register */
234 u8 res_10[12];
235 __be32 tph10setr0; /* Thread PH10 Set Control Register */
236 u8 res_20[12];
237 __be32 tph10clrr0; /* Thread PH10 Clear Control Register */
238 u8 res_30[12];
239 __be32 tph10psr0; /* Thread PH10 Previous Status Register */
240 u8 res_40[12];
241 __be32 twaitsr0; /* Thread Wait Status Register */
242 u8 res_50[96];
243 __be32 pcph15sr; /* Physical Core PH15 Status Register */
244 __be32 pcph15setr; /* Physical Core PH15 Set Control Register */
245 __be32 pcph15clrr; /* Physical Core PH15 Clear Control Register */
246 __be32 pcph15psr; /* Physical Core PH15 Prev Status Register */
247 u8 res_c0[16];
248 __be32 pcph20sr; /* Physical Core PH20 Status Register */
249 __be32 pcph20setr; /* Physical Core PH20 Set Control Register */
250 __be32 pcph20clrr; /* Physical Core PH20 Clear Control Register */
251 __be32 pcph20psr; /* Physical Core PH20 Prev Status Register */
252 __be32 pcpw20sr; /* Physical Core PW20 Status Register */
253 u8 res_e0[12];
254 __be32 pcph30sr; /* Physical Core PH30 Status Register */
255 __be32 pcph30setr; /* Physical Core PH30 Set Control Register */
256 __be32 pcph30clrr; /* Physical Core PH30 Clear Control Register */
257 __be32 pcph30psr; /* Physical Core PH30 Prev Status Register */
258 u8 res_100[32];
259 __be32 ippwrgatecr; /* IP Power Gating Control Register */
260 u8 res_124[12];
261 __be32 powmgtcsr; /* Power Management Control & Status Reg */
262#define RCPM_POWMGTCSR_LPM20_RQ 0x00100000
263#define RCPM_POWMGTCSR_LPM20_ST 0x00000200
264#define RCPM_POWMGTCSR_P_LPM20_ST 0x00000100
265 u8 res_134[12];
266 __be32 ippdexpcr[4]; /* IP Powerdown Exception Control Reg */
267 u8 res_150[12];
268 __be32 tpmimr0; /* Thread PM Interrupt Mask Reg */
269 u8 res_160[12];
270 __be32 tpmcimr0; /* Thread PM Crit Interrupt Mask Reg */
271 u8 res_170[12];
272 __be32 tpmmcmr0; /* Thread PM Machine Check Interrupt Mask Reg */
273 u8 res_180[12];
274 __be32 tpmnmimr0; /* Thread PM NMI Mask Reg */
275 u8 res_190[12];
276 __be32 tmcpmaskcr0; /* Thread Machine Check Mask Control Reg */
277 __be32 pctbenr; /* Physical Core Time Base Enable Reg */
278 __be32 pctbclkselr; /* Physical Core Time Base Clock Select */
279 __be32 tbclkdivr; /* Time Base Clock Divider Register */
280 u8 res_1ac[4];
281 __be32 ttbhltcr[4]; /* Thread Time Base Halt Control Register */
282 __be32 clpcl10sr; /* Cluster PCL10 Status Register */
283 __be32 clpcl10setr; /* Cluster PCL30 Set Control Register */
284 __be32 clpcl10clrr; /* Cluster PCL30 Clear Control Register */
285 __be32 clpcl10psr; /* Cluster PCL30 Prev Status Register */
286 __be32 cddslpsetr; /* Core Domain Deep Sleep Set Register */
287 __be32 cddslpclrr; /* Core Domain Deep Sleep Clear Register */
288 __be32 cdpwroksetr; /* Core Domain Power OK Set Register */
289 __be32 cdpwrokclrr; /* Core Domain Power OK Clear Register */
290 __be32 cdpwrensr; /* Core Domain Power Enable Status Register */
291 __be32 cddslsr; /* Core Domain Deep Sleep Status Register */
292 u8 res_1e8[8];
293 __be32 dslpcntcr[8]; /* Deep Sleep Counter Cfg Register */
294 u8 res_300[3568];
295};
296
192#endif 297#endif
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index 5307dfb3f8ec..79b0ef6aaa14 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -111,9 +111,6 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
111void split_huge_pmd_address(struct vm_area_struct *vma, unsigned long address, 111void split_huge_pmd_address(struct vm_area_struct *vma, unsigned long address,
112 bool freeze, struct page *page); 112 bool freeze, struct page *page);
113 113
114#if HPAGE_PMD_ORDER >= MAX_ORDER
115#error "hugepages can't be allocated by the buddy allocator"
116#endif
117extern int hugepage_madvise(struct vm_area_struct *vma, 114extern int hugepage_madvise(struct vm_area_struct *vma,
118 unsigned long *vm_flags, int advice); 115 unsigned long *vm_flags, int advice);
119extern void vma_adjust_trans_huge(struct vm_area_struct *vma, 116extern void vma_adjust_trans_huge(struct vm_area_struct *vma,
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 17e17c2ee1e6..004b8133417d 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -784,6 +784,7 @@ extern struct list_head pci_root_buses; /* list of all known PCI buses */
784int no_pci_devices(void); 784int no_pci_devices(void);
785 785
786void pcibios_resource_survey_bus(struct pci_bus *bus); 786void pcibios_resource_survey_bus(struct pci_bus *bus);
787void pcibios_bus_add_device(struct pci_dev *pdev);
787void pcibios_add_bus(struct pci_bus *bus); 788void pcibios_add_bus(struct pci_bus *bus);
788void pcibios_remove_bus(struct pci_bus *bus); 789void pcibios_remove_bus(struct pci_bus *bus);
789void pcibios_fixup_bus(struct pci_bus *); 790void pcibios_fixup_bus(struct pci_bus *);
@@ -1733,6 +1734,8 @@ int pci_iov_virtfn_devfn(struct pci_dev *dev, int id);
1733 1734
1734int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); 1735int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn);
1735void pci_disable_sriov(struct pci_dev *dev); 1736void pci_disable_sriov(struct pci_dev *dev);
1737int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset);
1738void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset);
1736int pci_num_vf(struct pci_dev *dev); 1739int pci_num_vf(struct pci_dev *dev);
1737int pci_vfs_assigned(struct pci_dev *dev); 1740int pci_vfs_assigned(struct pci_dev *dev);
1738int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); 1741int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs);
@@ -1749,6 +1752,12 @@ static inline int pci_iov_virtfn_devfn(struct pci_dev *dev, int id)
1749} 1752}
1750static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) 1753static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn)
1751{ return -ENODEV; } 1754{ return -ENODEV; }
1755static inline int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset)
1756{
1757 return -ENOSYS;
1758}
1759static inline void pci_iov_remove_virtfn(struct pci_dev *dev,
1760 int id, int reset) { }
1752static inline void pci_disable_sriov(struct pci_dev *dev) { } 1761static inline void pci_disable_sriov(struct pci_dev *dev) { }
1753static inline int pci_num_vf(struct pci_dev *dev) { return 0; } 1762static inline int pci_num_vf(struct pci_dev *dev) { return 0; }
1754static inline int pci_vfs_assigned(struct pci_dev *dev) 1763static inline int pci_vfs_assigned(struct pci_dev *dev)
diff --git a/include/misc/cxl.h b/include/misc/cxl.h
index f2ffe5bd720d..7d5e2613c7b8 100644
--- a/include/misc/cxl.h
+++ b/include/misc/cxl.h
@@ -30,9 +30,6 @@ struct cxl_afu *cxl_pci_to_afu(struct pci_dev *dev);
30/* Get the AFU conf record number associated with a pci_dev */ 30/* Get the AFU conf record number associated with a pci_dev */
31unsigned int cxl_pci_to_cfg_record(struct pci_dev *dev); 31unsigned int cxl_pci_to_cfg_record(struct pci_dev *dev);
32 32
33/* Get the physical device (ie. the PCIe card) which the AFU is attached */
34struct device *cxl_get_phys_dev(struct pci_dev *dev);
35
36 33
37/* 34/*
38 * Context lifetime overview: 35 * Context lifetime overview:
@@ -210,4 +207,9 @@ ssize_t cxl_fd_read(struct file *file, char __user *buf, size_t count,
210void cxl_perst_reloads_same_image(struct cxl_afu *afu, 207void cxl_perst_reloads_same_image(struct cxl_afu *afu,
211 bool perst_reloads_same_image); 208 bool perst_reloads_same_image);
212 209
210/*
211 * Read the VPD for the card where the AFU resides
212 */
213ssize_t cxl_read_adapter_vpd(struct pci_dev *dev, void *buf, size_t count);
214
213#endif /* _MISC_CXL_H */ 215#endif /* _MISC_CXL_H */
diff --git a/include/soc/fsl/qe/qe.h b/include/soc/fsl/qe/qe.h
index c7fa36c335c9..33b29ead3d55 100644
--- a/include/soc/fsl/qe/qe.h
+++ b/include/soc/fsl/qe/qe.h
@@ -103,8 +103,6 @@ int cpm_muram_init(void);
103unsigned long cpm_muram_alloc(unsigned long size, unsigned long align); 103unsigned long cpm_muram_alloc(unsigned long size, unsigned long align);
104int cpm_muram_free(unsigned long offset); 104int cpm_muram_free(unsigned long offset);
105unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size); 105unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size);
106unsigned long cpm_muram_alloc_common(unsigned long size, genpool_algo_t algo,
107 void *data);
108void __iomem *cpm_muram_addr(unsigned long offset); 106void __iomem *cpm_muram_addr(unsigned long offset);
109unsigned long cpm_muram_offset(void __iomem *addr); 107unsigned long cpm_muram_offset(void __iomem *addr);
110dma_addr_t cpm_muram_dma(void __iomem *addr); 108dma_addr_t cpm_muram_dma(void __iomem *addr);
diff --git a/include/uapi/misc/cxl.h b/include/uapi/misc/cxl.h
index 1e889aa8a36e..8cd334f99ddc 100644
--- a/include/uapi/misc/cxl.h
+++ b/include/uapi/misc/cxl.h
@@ -55,11 +55,35 @@ struct cxl_afu_id {
55 __u64 reserved6; 55 __u64 reserved6;
56}; 56};
57 57
58/* base adapter image header is included in the image */
59#define CXL_AI_NEED_HEADER 0x0000000000000001ULL
60#define CXL_AI_ALL CXL_AI_NEED_HEADER
61
62#define CXL_AI_HEADER_SIZE 128
63#define CXL_AI_BUFFER_SIZE 4096
64#define CXL_AI_MAX_ENTRIES 256
65#define CXL_AI_MAX_CHUNK_SIZE (CXL_AI_BUFFER_SIZE * CXL_AI_MAX_ENTRIES)
66
67struct cxl_adapter_image {
68 __u64 flags;
69 __u64 data;
70 __u64 len_data;
71 __u64 len_image;
72 __u64 reserved1;
73 __u64 reserved2;
74 __u64 reserved3;
75 __u64 reserved4;
76};
77
58/* ioctl numbers */ 78/* ioctl numbers */
59#define CXL_MAGIC 0xCA 79#define CXL_MAGIC 0xCA
80/* AFU devices */
60#define CXL_IOCTL_START_WORK _IOW(CXL_MAGIC, 0x00, struct cxl_ioctl_start_work) 81#define CXL_IOCTL_START_WORK _IOW(CXL_MAGIC, 0x00, struct cxl_ioctl_start_work)
61#define CXL_IOCTL_GET_PROCESS_ELEMENT _IOR(CXL_MAGIC, 0x01, __u32) 82#define CXL_IOCTL_GET_PROCESS_ELEMENT _IOR(CXL_MAGIC, 0x01, __u32)
62#define CXL_IOCTL_GET_AFU_ID _IOR(CXL_MAGIC, 0x02, struct cxl_afu_id) 83#define CXL_IOCTL_GET_AFU_ID _IOR(CXL_MAGIC, 0x02, struct cxl_afu_id)
84/* adapter devices */
85#define CXL_IOCTL_DOWNLOAD_IMAGE _IOW(CXL_MAGIC, 0x0A, struct cxl_adapter_image)
86#define CXL_IOCTL_VALIDATE_IMAGE _IOW(CXL_MAGIC, 0x0B, struct cxl_adapter_image)
63 87
64#define CXL_READ_MIN_SIZE 0x1000 /* 4K */ 88#define CXL_READ_MIN_SIZE 0x1000 /* 4K */
65 89
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 021db1781872..fbfb1b8d6726 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -83,7 +83,7 @@ unsigned long transparent_hugepage_flags __read_mostly =
83 (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG); 83 (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG);
84 84
85/* default scan 8*512 pte (or vmas) every 30 second */ 85/* default scan 8*512 pte (or vmas) every 30 second */
86static unsigned int khugepaged_pages_to_scan __read_mostly = HPAGE_PMD_NR*8; 86static unsigned int khugepaged_pages_to_scan __read_mostly;
87static unsigned int khugepaged_pages_collapsed; 87static unsigned int khugepaged_pages_collapsed;
88static unsigned int khugepaged_full_scans; 88static unsigned int khugepaged_full_scans;
89static unsigned int khugepaged_scan_sleep_millisecs __read_mostly = 10000; 89static unsigned int khugepaged_scan_sleep_millisecs __read_mostly = 10000;
@@ -98,7 +98,7 @@ static DECLARE_WAIT_QUEUE_HEAD(khugepaged_wait);
98 * it would have happened if the vma was large enough during page 98 * it would have happened if the vma was large enough during page
99 * fault. 99 * fault.
100 */ 100 */
101static unsigned int khugepaged_max_ptes_none __read_mostly = HPAGE_PMD_NR-1; 101static unsigned int khugepaged_max_ptes_none __read_mostly;
102 102
103static int khugepaged(void *none); 103static int khugepaged(void *none);
104static int khugepaged_slab_init(void); 104static int khugepaged_slab_init(void);
@@ -669,6 +669,18 @@ static int __init hugepage_init(void)
669 return -EINVAL; 669 return -EINVAL;
670 } 670 }
671 671
672 khugepaged_pages_to_scan = HPAGE_PMD_NR * 8;
673 khugepaged_max_ptes_none = HPAGE_PMD_NR - 1;
674 /*
675 * hugepages can't be allocated by the buddy allocator
676 */
677 MAYBE_BUILD_BUG_ON(HPAGE_PMD_ORDER >= MAX_ORDER);
678 /*
679 * we use page->mapping and page->index in second tail page
680 * as list_head: assuming THP order >= 2
681 */
682 MAYBE_BUILD_BUG_ON(HPAGE_PMD_ORDER < 2);
683
672 err = hugepage_init_sysfs(&hugepage_kobj); 684 err = hugepage_init_sysfs(&hugepage_kobj);
673 if (err) 685 if (err)
674 goto err_sysfs; 686 goto err_sysfs;
@@ -773,7 +785,6 @@ void prep_transhuge_page(struct page *page)
773 * we use page->mapping and page->indexlru in second tail page 785 * we use page->mapping and page->indexlru in second tail page
774 * as list_head: assuming THP order >= 2 786 * as list_head: assuming THP order >= 2
775 */ 787 */
776 BUILD_BUG_ON(HPAGE_PMD_ORDER < 2);
777 788
778 INIT_LIST_HEAD(page_deferred_list(page)); 789 INIT_LIST_HEAD(page_deferred_list(page));
779 set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); 790 set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR);
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index 0c2706bda330..b08f77cbe31b 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -8,7 +8,7 @@ ifeq ($(ARCH),powerpc)
8 8
9GIT_VERSION = $(shell git describe --always --long --dirty || echo "unknown") 9GIT_VERSION = $(shell git describe --always --long --dirty || echo "unknown")
10 10
11CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CURDIR) $(CFLAGS) 11CFLAGS := -Wall -O2 -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CURDIR) $(CFLAGS)
12 12
13export CFLAGS 13export CFLAGS
14 14
@@ -22,7 +22,8 @@ SUB_DIRS = benchmarks \
22 switch_endian \ 22 switch_endian \
23 syscalls \ 23 syscalls \
24 tm \ 24 tm \
25 vphn 25 vphn \
26 math
26 27
27endif 28endif
28 29
diff --git a/tools/testing/selftests/powerpc/basic_asm.h b/tools/testing/selftests/powerpc/basic_asm.h
new file mode 100644
index 000000000000..3349a0704d1a
--- /dev/null
+++ b/tools/testing/selftests/powerpc/basic_asm.h
@@ -0,0 +1,70 @@
1#ifndef _SELFTESTS_POWERPC_BASIC_ASM_H
2#define _SELFTESTS_POWERPC_BASIC_ASM_H
3
4#include <ppc-asm.h>
5#include <asm/unistd.h>
6
7#define LOAD_REG_IMMEDIATE(reg,expr) \
8 lis reg,(expr)@highest; \
9 ori reg,reg,(expr)@higher; \
10 rldicr reg,reg,32,31; \
11 oris reg,reg,(expr)@high; \
12 ori reg,reg,(expr)@l;
13
14/*
15 * Note: These macros assume that variables being stored on the stack are
16 * doublewords, while this is usually the case it may not always be the
17 * case for each use case.
18 */
19#if defined(_CALL_ELF) && _CALL_ELF == 2
20#define STACK_FRAME_MIN_SIZE 32
21#define STACK_FRAME_TOC_POS 24
22#define __STACK_FRAME_PARAM(_param) (32 + ((_param)*8))
23#define __STACK_FRAME_LOCAL(_num_params,_var_num) ((STACK_FRAME_PARAM(_num_params)) + ((_var_num)*8))
24#else
25#define STACK_FRAME_MIN_SIZE 112
26#define STACK_FRAME_TOC_POS 40
27#define __STACK_FRAME_PARAM(i) (48 + ((i)*8))
28
29/*
30 * Caveat: if a function passed more than 8 doublewords, the caller will have
31 * made more space... which would render the 112 incorrect.
32 */
33#define __STACK_FRAME_LOCAL(_num_params,_var_num) (112 + ((_var_num)*8))
34#endif
35
36/* Parameter x saved to the stack */
37#define STACK_FRAME_PARAM(var) __STACK_FRAME_PARAM(var)
38
39/* Local variable x saved to the stack after x parameters */
40#define STACK_FRAME_LOCAL(num_params,var) __STACK_FRAME_LOCAL(num_params,var)
41#define STACK_FRAME_LR_POS 16
42#define STACK_FRAME_CR_POS 8
43
44/*
45 * It is very important to note here that _extra is the extra amount of
46 * stack space needed. This space can be accessed using STACK_FRAME_PARAM()
47 * or STACK_FRAME_LOCAL() macros.
48 *
49 * r1 and r2 are not defined in ppc-asm.h (instead they are defined as sp
50 * and toc). Kernel programmers tend to prefer rX even for r1 and r2, hence
51 * %1 and %r2. r0 is defined in ppc-asm.h and therefore %r0 gets
52 * preprocessed incorrectly, hence r0.
53 */
54#define PUSH_BASIC_STACK(_extra) \
55 mflr r0; \
56 std r0,STACK_FRAME_LR_POS(%r1); \
57 stdu %r1,-(_extra + STACK_FRAME_MIN_SIZE)(%r1); \
58 mfcr r0; \
59 stw r0,STACK_FRAME_CR_POS(%r1); \
60 std %r2,STACK_FRAME_TOC_POS(%r1);
61
62#define POP_BASIC_STACK(_extra) \
63 ld %r2,STACK_FRAME_TOC_POS(%r1); \
64 lwz r0,STACK_FRAME_CR_POS(%r1); \
65 mtcr r0; \
66 addi %r1,%r1,(_extra + STACK_FRAME_MIN_SIZE); \
67 ld r0,STACK_FRAME_LR_POS(%r1); \
68 mtlr r0;
69
70#endif /* _SELFTESTS_POWERPC_BASIC_ASM_H */
diff --git a/tools/testing/selftests/powerpc/math/.gitignore b/tools/testing/selftests/powerpc/math/.gitignore
new file mode 100644
index 000000000000..4fe13a439fd7
--- /dev/null
+++ b/tools/testing/selftests/powerpc/math/.gitignore
@@ -0,0 +1,6 @@
1fpu_syscall
2vmx_syscall
3fpu_preempt
4vmx_preempt
5fpu_signal
6vmx_signal
diff --git a/tools/testing/selftests/powerpc/math/Makefile b/tools/testing/selftests/powerpc/math/Makefile
new file mode 100644
index 000000000000..5b88875d5955
--- /dev/null
+++ b/tools/testing/selftests/powerpc/math/Makefile
@@ -0,0 +1,19 @@
1TEST_PROGS := fpu_syscall fpu_preempt fpu_signal vmx_syscall vmx_preempt vmx_signal
2
3all: $(TEST_PROGS)
4
5$(TEST_PROGS): ../harness.c
6$(TEST_PROGS): CFLAGS += -O2 -g -pthread -m64 -maltivec
7
8fpu_syscall: fpu_asm.S
9fpu_preempt: fpu_asm.S
10fpu_signal: fpu_asm.S
11
12vmx_syscall: vmx_asm.S
13vmx_preempt: vmx_asm.S
14vmx_signal: vmx_asm.S
15
16include ../../lib.mk
17
18clean:
19 rm -f $(TEST_PROGS) *.o
diff --git a/tools/testing/selftests/powerpc/math/fpu_asm.S b/tools/testing/selftests/powerpc/math/fpu_asm.S
new file mode 100644
index 000000000000..f3711d80e709
--- /dev/null
+++ b/tools/testing/selftests/powerpc/math/fpu_asm.S
@@ -0,0 +1,198 @@
1/*
2 * Copyright 2015, Cyril Bur, IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#include "../basic_asm.h"
11
12#define PUSH_FPU(pos) \
13 stfd f14,pos(sp); \
14 stfd f15,pos+8(sp); \
15 stfd f16,pos+16(sp); \
16 stfd f17,pos+24(sp); \
17 stfd f18,pos+32(sp); \
18 stfd f19,pos+40(sp); \
19 stfd f20,pos+48(sp); \
20 stfd f21,pos+56(sp); \
21 stfd f22,pos+64(sp); \
22 stfd f23,pos+72(sp); \
23 stfd f24,pos+80(sp); \
24 stfd f25,pos+88(sp); \
25 stfd f26,pos+96(sp); \
26 stfd f27,pos+104(sp); \
27 stfd f28,pos+112(sp); \
28 stfd f29,pos+120(sp); \
29 stfd f30,pos+128(sp); \
30 stfd f31,pos+136(sp);
31
32#define POP_FPU(pos) \
33 lfd f14,pos(sp); \
34 lfd f15,pos+8(sp); \
35 lfd f16,pos+16(sp); \
36 lfd f17,pos+24(sp); \
37 lfd f18,pos+32(sp); \
38 lfd f19,pos+40(sp); \
39 lfd f20,pos+48(sp); \
40 lfd f21,pos+56(sp); \
41 lfd f22,pos+64(sp); \
42 lfd f23,pos+72(sp); \
43 lfd f24,pos+80(sp); \
44 lfd f25,pos+88(sp); \
45 lfd f26,pos+96(sp); \
46 lfd f27,pos+104(sp); \
47 lfd f28,pos+112(sp); \
48 lfd f29,pos+120(sp); \
49 lfd f30,pos+128(sp); \
50 lfd f31,pos+136(sp);
51
52# Careful calling this, it will 'clobber' fpu (by design)
53# Don't call this from C
54FUNC_START(load_fpu)
55 lfd f14,0(r3)
56 lfd f15,8(r3)
57 lfd f16,16(r3)
58 lfd f17,24(r3)
59 lfd f18,32(r3)
60 lfd f19,40(r3)
61 lfd f20,48(r3)
62 lfd f21,56(r3)
63 lfd f22,64(r3)
64 lfd f23,72(r3)
65 lfd f24,80(r3)
66 lfd f25,88(r3)
67 lfd f26,96(r3)
68 lfd f27,104(r3)
69 lfd f28,112(r3)
70 lfd f29,120(r3)
71 lfd f30,128(r3)
72 lfd f31,136(r3)
73 blr
74FUNC_END(load_fpu)
75
76FUNC_START(check_fpu)
77 mr r4,r3
78 li r3,1 # assume a bad result
79 lfd f0,0(r4)
80 fcmpu cr1,f0,f14
81 bne cr1,1f
82 lfd f0,8(r4)
83 fcmpu cr1,f0,f15
84 bne cr1,1f
85 lfd f0,16(r4)
86 fcmpu cr1,f0,f16
87 bne cr1,1f
88 lfd f0,24(r4)
89 fcmpu cr1,f0,f17
90 bne cr1,1f
91 lfd f0,32(r4)
92 fcmpu cr1,f0,f18
93 bne cr1,1f
94 lfd f0,40(r4)
95 fcmpu cr1,f0,f19
96 bne cr1,1f
97 lfd f0,48(r4)
98 fcmpu cr1,f0,f20
99 bne cr1,1f
100 lfd f0,56(r4)
101 fcmpu cr1,f0,f21
102 bne cr1,1f
103 lfd f0,64(r4)
104 fcmpu cr1,f0,f22
105 bne cr1,1f
106 lfd f0,72(r4)
107 fcmpu cr1,f0,f23
108 bne cr1,1f
109 lfd f0,80(r4)
110 fcmpu cr1,f0,f24
111 bne cr1,1f
112 lfd f0,88(r4)
113 fcmpu cr1,f0,f25
114 bne cr1,1f
115 lfd f0,96(r4)
116 fcmpu cr1,f0,f26
117 bne cr1,1f
118 lfd f0,104(r4)
119 fcmpu cr1,f0,f27
120 bne cr1,1f
121 lfd f0,112(r4)
122 fcmpu cr1,f0,f28
123 bne cr1,1f
124 lfd f0,120(r4)
125 fcmpu cr1,f0,f29
126 bne cr1,1f
127 lfd f0,128(r4)
128 fcmpu cr1,f0,f30
129 bne cr1,1f
130 lfd f0,136(r4)
131 fcmpu cr1,f0,f31
132 bne cr1,1f
133 li r3,0 # Success!!!
1341: blr
135
136FUNC_START(test_fpu)
137 # r3 holds pointer to where to put the result of fork
138 # r4 holds pointer to the pid
139 # f14-f31 are non volatiles
140 PUSH_BASIC_STACK(256)
141 std r3,STACK_FRAME_PARAM(0)(sp) # Address of darray
142 std r4,STACK_FRAME_PARAM(1)(sp) # Address of pid
143 PUSH_FPU(STACK_FRAME_LOCAL(2,0))
144
145 bl load_fpu
146 nop
147 li r0,__NR_fork
148 sc
149
150 # pass the result of the fork to the caller
151 ld r9,STACK_FRAME_PARAM(1)(sp)
152 std r3,0(r9)
153
154 ld r3,STACK_FRAME_PARAM(0)(sp)
155 bl check_fpu
156 nop
157
158 POP_FPU(STACK_FRAME_LOCAL(2,0))
159 POP_BASIC_STACK(256)
160 blr
161FUNC_END(test_fpu)
162
163# int preempt_fpu(double *darray, int *threads_running, int *running)
164# On starting will (atomically) decrement not_ready as a signal that the FPU
165# has been loaded with darray. Will proceed to check the validity of the FPU
166# registers while running is not zero.
167FUNC_START(preempt_fpu)
168 PUSH_BASIC_STACK(256)
169 std r3,STACK_FRAME_PARAM(0)(sp) # double *darray
170 std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting
171 std r5,STACK_FRAME_PARAM(2)(sp) # int *running
172 PUSH_FPU(STACK_FRAME_LOCAL(3,0))
173
174 bl load_fpu
175 nop
176
177 sync
178 # Atomic DEC
179 ld r3,STACK_FRAME_PARAM(1)(sp)
1801: lwarx r4,0,r3
181 addi r4,r4,-1
182 stwcx. r4,0,r3
183 bne- 1b
184
1852: ld r3,STACK_FRAME_PARAM(0)(sp)
186 bl check_fpu
187 nop
188 cmpdi r3,0
189 bne 3f
190 ld r4,STACK_FRAME_PARAM(2)(sp)
191 ld r5,0(r4)
192 cmpwi r5,0
193 bne 2b
194
1953: POP_FPU(STACK_FRAME_LOCAL(3,0))
196 POP_BASIC_STACK(256)
197 blr
198FUNC_END(preempt_fpu)
diff --git a/tools/testing/selftests/powerpc/math/fpu_preempt.c b/tools/testing/selftests/powerpc/math/fpu_preempt.c
new file mode 100644
index 000000000000..0f85b79d883d
--- /dev/null
+++ b/tools/testing/selftests/powerpc/math/fpu_preempt.c
@@ -0,0 +1,113 @@
1/*
2 * Copyright 2015, Cyril Bur, IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * This test attempts to see if the FPU registers change across preemption.
10 * Two things should be noted here a) The check_fpu function in asm only checks
11 * the non volatile registers as it is reused from the syscall test b) There is
12 * no way to be sure preemption happened so this test just uses many threads
13 * and a long wait. As such, a successful test doesn't mean much but a failure
14 * is bad.
15 */
16
17#include <stdio.h>
18#include <unistd.h>
19#include <sys/syscall.h>
20#include <sys/time.h>
21#include <sys/types.h>
22#include <sys/wait.h>
23#include <stdlib.h>
24#include <pthread.h>
25
26#include "utils.h"
27
28/* Time to wait for workers to get preempted (seconds) */
29#define PREEMPT_TIME 20
30/*
31 * Factor by which to multiply number of online CPUs for total number of
32 * worker threads
33 */
34#define THREAD_FACTOR 8
35
36
37__thread double darray[] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0,
38 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0,
39 2.1};
40
41int threads_starting;
42int running;
43
44extern void preempt_fpu(double *darray, int *threads_starting, int *running);
45
46void *preempt_fpu_c(void *p)
47{
48 int i;
49 srand(pthread_self());
50 for (i = 0; i < 21; i++)
51 darray[i] = rand();
52
53 /* Test failed if it ever returns */
54 preempt_fpu(darray, &threads_starting, &running);
55
56 return p;
57}
58
59int test_preempt_fpu(void)
60{
61 int i, rc, threads;
62 pthread_t *tids;
63
64 threads = sysconf(_SC_NPROCESSORS_ONLN) * THREAD_FACTOR;
65 tids = malloc((threads) * sizeof(pthread_t));
66 FAIL_IF(!tids);
67
68 running = true;
69 threads_starting = threads;
70 for (i = 0; i < threads; i++) {
71 rc = pthread_create(&tids[i], NULL, preempt_fpu_c, NULL);
72 FAIL_IF(rc);
73 }
74
75 setbuf(stdout, NULL);
76 /* Not really necessary but nice to wait for every thread to start */
77 printf("\tWaiting for all workers to start...");
78 while(threads_starting)
79 asm volatile("": : :"memory");
80 printf("done\n");
81
82 printf("\tWaiting for %d seconds to let some workers get preempted...", PREEMPT_TIME);
83 sleep(PREEMPT_TIME);
84 printf("done\n");
85
86 printf("\tStopping workers...");
87 /*
88 * Working are checking this value every loop. In preempt_fpu 'cmpwi r5,0; bne 2b'.
89 * r5 will have loaded the value of running.
90 */
91 running = 0;
92 for (i = 0; i < threads; i++) {
93 void *rc_p;
94 pthread_join(tids[i], &rc_p);
95
96 /*
97 * Harness will say the fail was here, look at why preempt_fpu
98 * returned
99 */
100 if ((long) rc_p)
101 printf("oops\n");
102 FAIL_IF((long) rc_p);
103 }
104 printf("done\n");
105
106 free(tids);
107 return 0;
108}
109
110int main(int argc, char *argv[])
111{
112 return test_harness(test_preempt_fpu, "fpu_preempt");
113}
diff --git a/tools/testing/selftests/powerpc/math/fpu_signal.c b/tools/testing/selftests/powerpc/math/fpu_signal.c
new file mode 100644
index 000000000000..888aa51b4204
--- /dev/null
+++ b/tools/testing/selftests/powerpc/math/fpu_signal.c
@@ -0,0 +1,135 @@
1/*
2 * Copyright 2015, Cyril Bur, IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * This test attempts to see if the FPU registers are correctly reported in a
10 * signal context. Each worker just spins checking its FPU registers, at some
11 * point a signal will interrupt it and C code will check the signal context
12 * ensuring it is also the same.
13 */
14
15#include <stdio.h>
16#include <unistd.h>
17#include <sys/syscall.h>
18#include <sys/time.h>
19#include <sys/types.h>
20#include <sys/wait.h>
21#include <stdlib.h>
22#include <pthread.h>
23
24#include "utils.h"
25
26/* Number of times each thread should receive the signal */
27#define ITERATIONS 10
28/*
29 * Factor by which to multiply number of online CPUs for total number of
30 * worker threads
31 */
32#define THREAD_FACTOR 8
33
34__thread double darray[] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0,
35 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0,
36 2.1};
37
38bool bad_context;
39int threads_starting;
40int running;
41
42extern long preempt_fpu(double *darray, int *threads_starting, int *running);
43
44void signal_fpu_sig(int sig, siginfo_t *info, void *context)
45{
46 int i;
47 ucontext_t *uc = context;
48 mcontext_t *mc = &uc->uc_mcontext;
49
50 /* Only the non volatiles were loaded up */
51 for (i = 14; i < 32; i++) {
52 if (mc->fp_regs[i] != darray[i - 14]) {
53 bad_context = true;
54 break;
55 }
56 }
57}
58
59void *signal_fpu_c(void *p)
60{
61 int i;
62 long rc;
63 struct sigaction act;
64 act.sa_sigaction = signal_fpu_sig;
65 act.sa_flags = SA_SIGINFO;
66 rc = sigaction(SIGUSR1, &act, NULL);
67 if (rc)
68 return p;
69
70 srand(pthread_self());
71 for (i = 0; i < 21; i++)
72 darray[i] = rand();
73
74 rc = preempt_fpu(darray, &threads_starting, &running);
75
76 return (void *) rc;
77}
78
79int test_signal_fpu(void)
80{
81 int i, j, rc, threads;
82 void *rc_p;
83 pthread_t *tids;
84
85 threads = sysconf(_SC_NPROCESSORS_ONLN) * THREAD_FACTOR;
86 tids = malloc(threads * sizeof(pthread_t));
87 FAIL_IF(!tids);
88
89 running = true;
90 threads_starting = threads;
91 for (i = 0; i < threads; i++) {
92 rc = pthread_create(&tids[i], NULL, signal_fpu_c, NULL);
93 FAIL_IF(rc);
94 }
95
96 setbuf(stdout, NULL);
97 printf("\tWaiting for all workers to start...");
98 while (threads_starting)
99 asm volatile("": : :"memory");
100 printf("done\n");
101
102 printf("\tSending signals to all threads %d times...", ITERATIONS);
103 for (i = 0; i < ITERATIONS; i++) {
104 for (j = 0; j < threads; j++) {
105 pthread_kill(tids[j], SIGUSR1);
106 }
107 sleep(1);
108 }
109 printf("done\n");
110
111 printf("\tStopping workers...");
112 running = 0;
113 for (i = 0; i < threads; i++) {
114 pthread_join(tids[i], &rc_p);
115
116 /*
117 * Harness will say the fail was here, look at why signal_fpu
118 * returned
119 */
120 if ((long) rc_p || bad_context)
121 printf("oops\n");
122 if (bad_context)
123 fprintf(stderr, "\t!! bad_context is true\n");
124 FAIL_IF((long) rc_p || bad_context);
125 }
126 printf("done\n");
127
128 free(tids);
129 return 0;
130}
131
132int main(int argc, char *argv[])
133{
134 return test_harness(test_signal_fpu, "fpu_signal");
135}
diff --git a/tools/testing/selftests/powerpc/math/fpu_syscall.c b/tools/testing/selftests/powerpc/math/fpu_syscall.c
new file mode 100644
index 000000000000..949e6721256d
--- /dev/null
+++ b/tools/testing/selftests/powerpc/math/fpu_syscall.c
@@ -0,0 +1,90 @@
1/*
2 * Copyright 2015, Cyril Bur, IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * This test attempts to see if the FPU registers change across a syscall (fork).
10 */
11
12#include <stdio.h>
13#include <unistd.h>
14#include <sys/syscall.h>
15#include <sys/time.h>
16#include <sys/types.h>
17#include <sys/wait.h>
18#include <stdlib.h>
19
20#include "utils.h"
21
22extern int test_fpu(double *darray, pid_t *pid);
23
24double darray[] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0,
25 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0,
26 2.1};
27
28int syscall_fpu(void)
29{
30 pid_t fork_pid;
31 int i;
32 int ret;
33 int child_ret;
34 for (i = 0; i < 1000; i++) {
35 /* test_fpu will fork() */
36 ret = test_fpu(darray, &fork_pid);
37 if (fork_pid == -1)
38 return -1;
39 if (fork_pid == 0)
40 exit(ret);
41 waitpid(fork_pid, &child_ret, 0);
42 if (ret || child_ret)
43 return 1;
44 }
45
46 return 0;
47}
48
49int test_syscall_fpu(void)
50{
51 /*
52 * Setup an environment with much context switching
53 */
54 pid_t pid2;
55 pid_t pid = fork();
56 int ret;
57 int child_ret;
58 FAIL_IF(pid == -1);
59
60 pid2 = fork();
61 /* Can't FAIL_IF(pid2 == -1); because already forked once */
62 if (pid2 == -1) {
63 /*
64 * Couldn't fork, ensure test is a fail
65 */
66 child_ret = ret = 1;
67 } else {
68 ret = syscall_fpu();
69 if (pid2)
70 waitpid(pid2, &child_ret, 0);
71 else
72 exit(ret);
73 }
74
75 ret |= child_ret;
76
77 if (pid)
78 waitpid(pid, &child_ret, 0);
79 else
80 exit(ret);
81
82 FAIL_IF(ret || child_ret);
83 return 0;
84}
85
86int main(int argc, char *argv[])
87{
88 return test_harness(test_syscall_fpu, "syscall_fpu");
89
90}
diff --git a/tools/testing/selftests/powerpc/math/vmx_asm.S b/tools/testing/selftests/powerpc/math/vmx_asm.S
new file mode 100644
index 000000000000..1b8c248b3ac1
--- /dev/null
+++ b/tools/testing/selftests/powerpc/math/vmx_asm.S
@@ -0,0 +1,235 @@
1/*
2 * Copyright 2015, Cyril Bur, IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#include "../basic_asm.h"
11
12# POS MUST BE 16 ALIGNED!
13#define PUSH_VMX(pos,reg) \
14 li reg,pos; \
15 stvx v20,reg,sp; \
16 addi reg,reg,16; \
17 stvx v21,reg,sp; \
18 addi reg,reg,16; \
19 stvx v22,reg,sp; \
20 addi reg,reg,16; \
21 stvx v23,reg,sp; \
22 addi reg,reg,16; \
23 stvx v24,reg,sp; \
24 addi reg,reg,16; \
25 stvx v25,reg,sp; \
26 addi reg,reg,16; \
27 stvx v26,reg,sp; \
28 addi reg,reg,16; \
29 stvx v27,reg,sp; \
30 addi reg,reg,16; \
31 stvx v28,reg,sp; \
32 addi reg,reg,16; \
33 stvx v29,reg,sp; \
34 addi reg,reg,16; \
35 stvx v30,reg,sp; \
36 addi reg,reg,16; \
37 stvx v31,reg,sp;
38
39# POS MUST BE 16 ALIGNED!
40#define POP_VMX(pos,reg) \
41 li reg,pos; \
42 lvx v20,reg,sp; \
43 addi reg,reg,16; \
44 lvx v21,reg,sp; \
45 addi reg,reg,16; \
46 lvx v22,reg,sp; \
47 addi reg,reg,16; \
48 lvx v23,reg,sp; \
49 addi reg,reg,16; \
50 lvx v24,reg,sp; \
51 addi reg,reg,16; \
52 lvx v25,reg,sp; \
53 addi reg,reg,16; \
54 lvx v26,reg,sp; \
55 addi reg,reg,16; \
56 lvx v27,reg,sp; \
57 addi reg,reg,16; \
58 lvx v28,reg,sp; \
59 addi reg,reg,16; \
60 lvx v29,reg,sp; \
61 addi reg,reg,16; \
62 lvx v30,reg,sp; \
63 addi reg,reg,16; \
64 lvx v31,reg,sp;
65
66# Carefull this will 'clobber' vmx (by design)
67# Don't call this from C
68FUNC_START(load_vmx)
69 li r5,0
70 lvx v20,r5,r3
71 addi r5,r5,16
72 lvx v21,r5,r3
73 addi r5,r5,16
74 lvx v22,r5,r3
75 addi r5,r5,16
76 lvx v23,r5,r3
77 addi r5,r5,16
78 lvx v24,r5,r3
79 addi r5,r5,16
80 lvx v25,r5,r3
81 addi r5,r5,16
82 lvx v26,r5,r3
83 addi r5,r5,16
84 lvx v27,r5,r3
85 addi r5,r5,16
86 lvx v28,r5,r3
87 addi r5,r5,16
88 lvx v29,r5,r3
89 addi r5,r5,16
90 lvx v30,r5,r3
91 addi r5,r5,16
92 lvx v31,r5,r3
93 blr
94FUNC_END(load_vmx)
95
96# Should be safe from C, only touches r4, r5 and v0,v1,v2
97FUNC_START(check_vmx)
98 PUSH_BASIC_STACK(32)
99 mr r4,r3
100 li r3,1 # assume a bad result
101 li r5,0
102 lvx v0,r5,r4
103 vcmpequd. v1,v0,v20
104 vmr v2,v1
105
106 addi r5,r5,16
107 lvx v0,r5,r4
108 vcmpequd. v1,v0,v21
109 vand v2,v2,v1
110
111 addi r5,r5,16
112 lvx v0,r5,r4
113 vcmpequd. v1,v0,v22
114 vand v2,v2,v1
115
116 addi r5,r5,16
117 lvx v0,r5,r4
118 vcmpequd. v1,v0,v23
119 vand v2,v2,v1
120
121 addi r5,r5,16
122 lvx v0,r5,r4
123 vcmpequd. v1,v0,v24
124 vand v2,v2,v1
125
126 addi r5,r5,16
127 lvx v0,r5,r4
128 vcmpequd. v1,v0,v25
129 vand v2,v2,v1
130
131 addi r5,r5,16
132 lvx v0,r5,r4
133 vcmpequd. v1,v0,v26
134 vand v2,v2,v1
135
136 addi r5,r5,16
137 lvx v0,r5,r4
138 vcmpequd. v1,v0,v27
139 vand v2,v2,v1
140
141 addi r5,r5,16
142 lvx v0,r5,r4
143 vcmpequd. v1,v0,v28
144 vand v2,v2,v1
145
146 addi r5,r5,16
147 lvx v0,r5,r4
148 vcmpequd. v1,v0,v29
149 vand v2,v2,v1
150
151 addi r5,r5,16
152 lvx v0,r5,r4
153 vcmpequd. v1,v0,v30
154 vand v2,v2,v1
155
156 addi r5,r5,16
157 lvx v0,r5,r4
158 vcmpequd. v1,v0,v31
159 vand v2,v2,v1
160
161 li r5,STACK_FRAME_LOCAL(0,0)
162 stvx v2,r5,sp
163 ldx r0,r5,sp
164 cmpdi r0,0xffffffffffffffff
165 bne 1f
166 li r3,0
1671: POP_BASIC_STACK(32)
168 blr
169FUNC_END(check_vmx)
170
171# Safe from C
172FUNC_START(test_vmx)
173 # r3 holds pointer to where to put the result of fork
174 # r4 holds pointer to the pid
175 # v20-v31 are non-volatile
176 PUSH_BASIC_STACK(512)
177 std r3,STACK_FRAME_PARAM(0)(sp) # Address of varray
178 std r4,STACK_FRAME_PARAM(1)(sp) # address of pid
179 PUSH_VMX(STACK_FRAME_LOCAL(2,0),r4)
180
181 bl load_vmx
182 nop
183
184 li r0,__NR_fork
185 sc
186 # Pass the result of fork back to the caller
187 ld r9,STACK_FRAME_PARAM(1)(sp)
188 std r3,0(r9)
189
190 ld r3,STACK_FRAME_PARAM(0)(sp)
191 bl check_vmx
192 nop
193
194 POP_VMX(STACK_FRAME_LOCAL(2,0),r4)
195 POP_BASIC_STACK(512)
196 blr
197FUNC_END(test_vmx)
198
199# int preempt_vmx(vector int *varray, int *threads_starting, int *running)
200# On starting will (atomically) decrement threads_starting as a signal that
201# the VMX have been loaded with varray. Will proceed to check the validity of
202# the VMX registers while running is not zero.
203FUNC_START(preempt_vmx)
204 PUSH_BASIC_STACK(512)
205 std r3,STACK_FRAME_PARAM(0)(sp) # vector int *varray
206 std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting
207 std r5,STACK_FRAME_PARAM(2)(sp) # int *running
208 # VMX need to write to 16 byte aligned addresses, skip STACK_FRAME_LOCAL(3,0)
209 PUSH_VMX(STACK_FRAME_LOCAL(4,0),r4)
210
211 bl load_vmx
212 nop
213
214 sync
215 # Atomic DEC
216 ld r3,STACK_FRAME_PARAM(1)(sp)
2171: lwarx r4,0,r3
218 addi r4,r4,-1
219 stwcx. r4,0,r3
220 bne- 1b
221
2222: ld r3,STACK_FRAME_PARAM(0)(sp)
223 bl check_vmx
224 nop
225 cmpdi r3,0
226 bne 3f
227 ld r4,STACK_FRAME_PARAM(2)(sp)
228 ld r5,0(r4)
229 cmpwi r5,0
230 bne 2b
231
2323: POP_VMX(STACK_FRAME_LOCAL(4,0),r4)
233 POP_BASIC_STACK(512)
234 blr
235FUNC_END(preempt_vmx)
diff --git a/tools/testing/selftests/powerpc/math/vmx_preempt.c b/tools/testing/selftests/powerpc/math/vmx_preempt.c
new file mode 100644
index 000000000000..9ef376c55b13
--- /dev/null
+++ b/tools/testing/selftests/powerpc/math/vmx_preempt.c
@@ -0,0 +1,112 @@
1/*
2 * Copyright 2015, Cyril Bur, IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * This test attempts to see if the VMX registers change across preemption.
10 * Two things should be noted here a) The check_vmx function in asm only checks
11 * the non volatile registers as it is reused from the syscall test b) There is
12 * no way to be sure preemption happened so this test just uses many threads
13 * and a long wait. As such, a successful test doesn't mean much but a failure
14 * is bad.
15 */
16
17#include <stdio.h>
18#include <unistd.h>
19#include <sys/syscall.h>
20#include <sys/time.h>
21#include <sys/types.h>
22#include <sys/wait.h>
23#include <stdlib.h>
24#include <pthread.h>
25
26#include "utils.h"
27
28/* Time to wait for workers to get preempted (seconds) */
29#define PREEMPT_TIME 20
30/*
31 * Factor by which to multiply number of online CPUs for total number of
32 * worker threads
33 */
34#define THREAD_FACTOR 8
35
36__thread vector int varray[] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10,11,12},
37 {13,14,15,16},{17,18,19,20},{21,22,23,24},
38 {25,26,27,28},{29,30,31,32},{33,34,35,36},
39 {37,38,39,40},{41,42,43,44},{45,46,47,48}};
40
41int threads_starting;
42int running;
43
44extern void preempt_vmx(vector int *varray, int *threads_starting, int *running);
45
46void *preempt_vmx_c(void *p)
47{
48 int i, j;
49 srand(pthread_self());
50 for (i = 0; i < 12; i++)
51 for (j = 0; j < 4; j++)
52 varray[i][j] = rand();
53
54 /* Test fails if it ever returns */
55 preempt_vmx(varray, &threads_starting, &running);
56 return p;
57}
58
59int test_preempt_vmx(void)
60{
61 int i, rc, threads;
62 pthread_t *tids;
63
64 threads = sysconf(_SC_NPROCESSORS_ONLN) * THREAD_FACTOR;
65 tids = malloc(threads * sizeof(pthread_t));
66 FAIL_IF(!tids);
67
68 running = true;
69 threads_starting = threads;
70 for (i = 0; i < threads; i++) {
71 rc = pthread_create(&tids[i], NULL, preempt_vmx_c, NULL);
72 FAIL_IF(rc);
73 }
74
75 setbuf(stdout, NULL);
76 /* Not really nessesary but nice to wait for every thread to start */
77 printf("\tWaiting for all workers to start...");
78 while(threads_starting)
79 asm volatile("": : :"memory");
80 printf("done\n");
81
82 printf("\tWaiting for %d seconds to let some workers get preempted...", PREEMPT_TIME);
83 sleep(PREEMPT_TIME);
84 printf("done\n");
85
86 printf("\tStopping workers...");
87 /*
88 * Working are checking this value every loop. In preempt_vmx 'cmpwi r5,0; bne 2b'.
89 * r5 will have loaded the value of running.
90 */
91 running = 0;
92 for (i = 0; i < threads; i++) {
93 void *rc_p;
94 pthread_join(tids[i], &rc_p);
95
96 /*
97 * Harness will say the fail was here, look at why preempt_vmx
98 * returned
99 */
100 if ((long) rc_p)
101 printf("oops\n");
102 FAIL_IF((long) rc_p);
103 }
104 printf("done\n");
105
106 return 0;
107}
108
109int main(int argc, char *argv[])
110{
111 return test_harness(test_preempt_vmx, "vmx_preempt");
112}
diff --git a/tools/testing/selftests/powerpc/math/vmx_signal.c b/tools/testing/selftests/powerpc/math/vmx_signal.c
new file mode 100644
index 000000000000..671d7533a557
--- /dev/null
+++ b/tools/testing/selftests/powerpc/math/vmx_signal.c
@@ -0,0 +1,156 @@
1/*
2 * Copyright 2015, Cyril Bur, IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * This test attempts to see if the VMX registers are correctly reported in a
10 * signal context. Each worker just spins checking its VMX registers, at some
11 * point a signal will interrupt it and C code will check the signal context
12 * ensuring it is also the same.
13 */
14
15#include <stdio.h>
16#include <unistd.h>
17#include <sys/syscall.h>
18#include <sys/time.h>
19#include <sys/types.h>
20#include <sys/wait.h>
21#include <stdlib.h>
22#include <string.h>
23#include <pthread.h>
24#include <altivec.h>
25
26#include "utils.h"
27
28/* Number of times each thread should receive the signal */
29#define ITERATIONS 10
30/*
31 * Factor by which to multiply number of online CPUs for total number of
32 * worker threads
33 */
34#define THREAD_FACTOR 8
35
36__thread vector int varray[] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10,11,12},
37 {13,14,15,16},{17,18,19,20},{21,22,23,24},
38 {25,26,27,28},{29,30,31,32},{33,34,35,36},
39 {37,38,39,40},{41,42,43,44},{45,46,47,48}};
40
41bool bad_context;
42int running;
43int threads_starting;
44
45extern int preempt_vmx(vector int *varray, int *threads_starting, int *sentinal);
46
47void signal_vmx_sig(int sig, siginfo_t *info, void *context)
48{
49 int i;
50 ucontext_t *uc = context;
51 mcontext_t *mc = &uc->uc_mcontext;
52
53 /* Only the non volatiles were loaded up */
54 for (i = 20; i < 32; i++) {
55 if (memcmp(mc->v_regs->vrregs[i], &varray[i - 20], 16)) {
56 int j;
57 /*
58 * Shouldn't printf() in a signal handler, however, this is a
59 * test and we've detected failure. Understanding what failed
60 * is paramount. All that happens after this is tests exit with
61 * failure.
62 */
63 printf("VMX mismatch at reg %d!\n", i);
64 printf("Reg | Actual | Expected\n");
65 for (j = 20; j < 32; j++) {
66 printf("%d | 0x%04x%04x%04x%04x | 0x%04x%04x%04x%04x\n", j, mc->v_regs->vrregs[j][0],
67 mc->v_regs->vrregs[j][1], mc->v_regs->vrregs[j][2], mc->v_regs->vrregs[j][3],
68 varray[j - 20][0], varray[j - 20][1], varray[j - 20][2], varray[j - 20][3]);
69 }
70 bad_context = true;
71 break;
72 }
73 }
74}
75
76void *signal_vmx_c(void *p)
77{
78 int i, j;
79 long rc;
80 struct sigaction act;
81 act.sa_sigaction = signal_vmx_sig;
82 act.sa_flags = SA_SIGINFO;
83 rc = sigaction(SIGUSR1, &act, NULL);
84 if (rc)
85 return p;
86
87 srand(pthread_self());
88 for (i = 0; i < 12; i++)
89 for (j = 0; j < 4; j++)
90 varray[i][j] = rand();
91
92 rc = preempt_vmx(varray, &threads_starting, &running);
93
94 return (void *) rc;
95}
96
97int test_signal_vmx(void)
98{
99 int i, j, rc, threads;
100 void *rc_p;
101 pthread_t *tids;
102
103 threads = sysconf(_SC_NPROCESSORS_ONLN) * THREAD_FACTOR;
104 tids = malloc(threads * sizeof(pthread_t));
105 FAIL_IF(!tids);
106
107 running = true;
108 threads_starting = threads;
109 for (i = 0; i < threads; i++) {
110 rc = pthread_create(&tids[i], NULL, signal_vmx_c, NULL);
111 FAIL_IF(rc);
112 }
113
114 setbuf(stdout, NULL);
115 printf("\tWaiting for %d workers to start... %d", threads, threads_starting);
116 while (threads_starting) {
117 asm volatile("": : :"memory");
118 usleep(1000);
119 printf(", %d", threads_starting);
120 }
121 printf(" ...done\n");
122
123 printf("\tSending signals to all threads %d times...", ITERATIONS);
124 for (i = 0; i < ITERATIONS; i++) {
125 for (j = 0; j < threads; j++) {
126 pthread_kill(tids[j], SIGUSR1);
127 }
128 sleep(1);
129 }
130 printf("done\n");
131
132 printf("\tKilling workers...");
133 running = 0;
134 for (i = 0; i < threads; i++) {
135 pthread_join(tids[i], &rc_p);
136
137 /*
138 * Harness will say the fail was here, look at why signal_vmx
139 * returned
140 */
141 if ((long) rc_p || bad_context)
142 printf("oops\n");
143 if (bad_context)
144 fprintf(stderr, "\t!! bad_context is true\n");
145 FAIL_IF((long) rc_p || bad_context);
146 }
147 printf("done\n");
148
149 free(tids);
150 return 0;
151}
152
153int main(int argc, char *argv[])
154{
155 return test_harness(test_signal_vmx, "vmx_signal");
156}
diff --git a/tools/testing/selftests/powerpc/math/vmx_syscall.c b/tools/testing/selftests/powerpc/math/vmx_syscall.c
new file mode 100644
index 000000000000..a017918ee1ca
--- /dev/null
+++ b/tools/testing/selftests/powerpc/math/vmx_syscall.c
@@ -0,0 +1,91 @@
1/*
2 * Copyright 2015, Cyril Bur, IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * This test attempts to see if the VMX registers change across a syscall (fork).
10 */
11
12#include <altivec.h>
13#include <stdio.h>
14#include <unistd.h>
15#include <sys/syscall.h>
16#include <sys/time.h>
17#include <stdlib.h>
18#include <sys/types.h>
19#include <sys/wait.h>
20#include "utils.h"
21
22vector int varray[] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10,11,12},
23 {13,14,15,16},{17,18,19,20},{21,22,23,24},
24 {25,26,27,28},{29,30,31,32},{33,34,35,36},
25 {37,38,39,40},{41,42,43,44},{45,46,47,48}};
26
27extern int test_vmx(vector int *varray, pid_t *pid);
28
29int vmx_syscall(void)
30{
31 pid_t fork_pid;
32 int i;
33 int ret;
34 int child_ret;
35 for (i = 0; i < 1000; i++) {
36 /* test_vmx will fork() */
37 ret = test_vmx(varray, &fork_pid);
38 if (fork_pid == -1)
39 return -1;
40 if (fork_pid == 0)
41 exit(ret);
42 waitpid(fork_pid, &child_ret, 0);
43 if (ret || child_ret)
44 return 1;
45 }
46
47 return 0;
48}
49
50int test_vmx_syscall(void)
51{
52 /*
53 * Setup an environment with much context switching
54 */
55 pid_t pid2;
56 pid_t pid = fork();
57 int ret;
58 int child_ret;
59 FAIL_IF(pid == -1);
60
61 pid2 = fork();
62 ret = vmx_syscall();
63 /* Can't FAIL_IF(pid2 == -1); because we've already forked */
64 if (pid2 == -1) {
65 /*
66 * Couldn't fork, ensure child_ret is set and is a fail
67 */
68 ret = child_ret = 1;
69 } else {
70 if (pid2)
71 waitpid(pid2, &child_ret, 0);
72 else
73 exit(ret);
74 }
75
76 ret |= child_ret;
77
78 if (pid)
79 waitpid(pid, &child_ret, 0);
80 else
81 exit(ret);
82
83 FAIL_IF(ret || child_ret);
84 return 0;
85}
86
87int main(int argc, char *argv[])
88{
89 return test_harness(test_vmx_syscall, "vmx_syscall");
90
91}
diff --git a/tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c b/tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c
index d86653f282b1..8c54d18b3e9a 100644
--- a/tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c
+++ b/tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c
@@ -40,7 +40,7 @@ void signal_usr1(int signum, siginfo_t *info, void *uc)
40#ifdef __powerpc64__ 40#ifdef __powerpc64__
41 ucp->uc_mcontext.gp_regs[PT_MSR] |= (7ULL << 32); 41 ucp->uc_mcontext.gp_regs[PT_MSR] |= (7ULL << 32);
42#else 42#else
43 ucp->uc_mcontext.regs->gpr[PT_MSR] |= (7ULL); 43 ucp->uc_mcontext.uc_regs->gregs[PT_MSR] |= (7ULL);
44#endif 44#endif
45 /* Should segv on return becuase of invalid context */ 45 /* Should segv on return becuase of invalid context */
46 segv_expected = 1; 46 segv_expected = 1;